1. 程式人生 > >實時搜尋引擎Elasticsearch(1)——基礎概念、安裝和執行

實時搜尋引擎Elasticsearch(1)——基礎概念、安裝和執行

Elasticsearch(簡稱ES)是一個基於Apache Lucene(TM)的開源搜尋引擎,無論在開源還是專有領域,Lucene可以被認為是迄今為止最先進、效能最好的、功能最全的搜尋引擎庫。

Elasticsearch簡介

Elasticsearch是什麼

Elasticsearch是一個基於Apache Lucene(TM)的開源搜尋引擎,無論在開源還是專有領域,Lucene可以被認為是迄今為止最先進、效能最好的、功能最全的搜尋引擎庫。  但是,Lucene只是一個庫。想要發揮其強大的作用,你需使用Java並要將其整合到你的應用中。Lucene非常複雜,你需要深入的瞭解檢索相關知識來理解它是如何工作的。  Elasticsearch也是使用Java編寫並使用Lucene來建立索引並實現搜尋功能,但是它的目的是通過簡單連貫的RESTful API讓全文搜尋變得簡單並隱藏Lucene的複雜性。  不過,Elasticsearch不僅僅是Lucene和全文搜尋引擎,它還提供:

  • 分散式的實時檔案儲存,每個欄位都被索引並可被搜尋
  • 實時分析的分散式搜尋引擎
  • 可以擴充套件到上百臺伺服器,處理PB級結構化或非結構化資料

而且,所有的這些功能被整合到一臺伺服器,你的應用可以通過簡單的RESTful API、各種語言的客戶端甚至命令列與之互動。上手Elasticsearch非常簡單,它提供了許多合理的預設值,並對初學者隱藏了複雜的搜尋引擎理論。它開箱即用(安裝即可使用),只需很少的學習既可在生產環境中使用。Elasticsearch在Apache 2 license下許可使用,可以免費下載、使用和修改。  隨著知識的積累,你可以根據不同的問題領域定製Elasticsearch的高階特性,這一切都是可配置的,並且配置非常靈活。

Elasticsearch中涉及到的重要概念

Elasticsearch有幾個核心概念。從一開始理解這些概念會對整個學習過程有莫大的幫助。

(1) 接近實時(NRT)  Elasticsearch是一個接近實時的搜尋平臺。這意味著,從索引一個文件直到這個文件能夠被搜尋到有一個輕微的延遲(通常是1秒)。

(2) 叢集(cluster)  一個叢集就是由一個或多個節點組織在一起,它們共同持有你整個的資料,並一起提供索引和搜尋功能。一個叢集由一個唯一的名字標識,這個名字預設就是“elasticsearch”。這個名字是重要的,因為一個節點只能通過指定某個叢集的名字,來加入這個叢集。在產品環境中顯式地設定這個名字是一個好習慣,但是使用預設值來進行測試/開發也是不錯的。

(3) 節點(node)  一個節點是你叢集中的一個伺服器,作為叢集的一部分,它儲存你的資料,參與叢集的索引和搜尋功能。和叢集類似,一個節點也是由一個名字來標識的,預設情況下,這個名字是一個隨機的漫威漫畫角色的名字,這個名字會在啟動的時候賦予節點。這個名字對於管理工作來說挺重要的,因為在這個管理過程中,你會去確定網路中的哪些伺服器對應於Elasticsearch叢集中的哪些節點。

一個節點可以通過配置叢集名稱的方式來加入一個指定的叢集。預設情況下,每個節點都會被安排加入到一個叫做“elasticsearch”的叢集中,這意味著,如果你在你的網路中啟動了若干個節點,並假定它們能夠相互發現彼此,它們將會自動地形成並加入到一個叫做“elasticsearch”的叢集中。

在一個叢集裡,只要你想,可以擁有任意多個節點。而且,如果當前你的網路中沒有執行任何Elasticsearch節點,這時啟動一個節點,會預設建立並加入一個叫做“elasticsearch”的叢集。

(4) 索引(index)  一個索引就是一個擁有幾分相似特徵的文件的集合。比如說,你可以有一個客戶資料的索引,另一個產品目錄的索引,還有一個訂單資料的索引。一個索引由一個名字來標識(必須全部是小寫字母的),並且當我們要對對應於這個索引中的文件進行索引、搜尋、更新和刪除的時候,都要使用到這個名字。索引類似於關係型資料庫中Database的概念。在一個叢集中,如果你想,可以定義任意多的索引。

(5) 型別(type)  在一個索引中,你可以定義一種或多種型別。一個型別是你的索引的一個邏輯上的分類/分割槽,其語義完全由你來定。通常,會為具有一組共同欄位的文件定義一個型別。比如說,我們假設你運營一個部落格平臺並且將你所有的資料儲存到一個索引中。在這個索引中,你可以為使用者資料定義一個型別,為部落格資料定義另一個型別,當然,也可以為評論資料定義另一個型別。型別類似於關係型資料庫中Table的概念。

(6)文件(document)  一個文件是一個可被索引的基礎資訊單元。比如,你可以擁有某一個客戶的文件,某一個產品的一個文件,當然,也可以擁有某個訂單的一個文件。文件以JSON(Javascript Object Notation)格式來表示,而JSON是一個到處存在的網際網路資料互動格式。  在一個index/type裡面,只要你想,你可以儲存任意多的文件。注意,儘管一個文件,物理上存在於一個索引之中,文件必須被索引/賦予一個索引的type。文件類似於關係型資料庫中Record的概念。實際上一個文件除了使用者定義的資料外,還包括_index_type_id欄位。

(7) 分片和複製(shards & replicas)  一個索引可以儲存超出單個結點硬體限制的大量資料。比如,一個具有10億文件的索引佔據1TB的磁碟空間,而任一節點都沒有這樣大的磁碟空間;或者單個節點處理搜尋請求,響應太慢。

為了解決這個問題,Elasticsearch提供了將索引劃分成多份的能力,這些份就叫做分片。當你建立一個索引的時候,你可以指定你想要的分片的數量。每個分片本身也是一個功能完善並且獨立的“索引”,這個“索引”可以被放置到叢集中的任何節點上。  分片之所以重要,主要有兩方面的原因:

  • 允許你水平分割/擴充套件你的內容容量
  • 允許你在分片(潛在地,位於多個節點上)之上進行分散式的、並行的操作,進而提高效能/吞吐量

至於一個分片怎樣分佈,它的文件怎樣聚合回搜尋請求,是完全由Elasticsearch管理的,對於作為使用者的你來說,這些都是透明的。

在一個網路/雲的環境裡,失敗隨時都可能發生,在某個分片/節點不知怎麼的就處於離線狀態,或者由於任何原因消失了。這種情況下,有一個故障轉移機制是非常有用並且是強烈推薦的。為此目的,Elasticsearch允許你建立分片的一份或多份拷貝,這些拷貝叫做複製分片,或者直接叫複製。複製之所以重要,主要有兩方面的原因:

  • 在分片/節點失敗的情況下,提供了高可用性。因為這個原因,注意到複製分片從不與原/主要(original/primary)分片置於同一節點上是非常重要的。
  • 擴充套件你的搜尋量/吞吐量,因為搜尋可以在所有的複製上並行執行

總之,每個索引可以被分成多個分片。一個索引也可以被複制0次(意思是沒有複製)或多次。一旦複製了,每個索引就有了主分片(作為複製源的原來的分片)和複製分片(主分片的拷貝)之別。分片和複製的數量可以在索引建立的時候指定。在索引建立之後,你可以在任何時候動態地改變複製數量,但是不能改變分片的數量

預設情況下,Elasticsearch中的每個索引被分片5個主分片和1個複製,這意味著,如果你的叢集中至少有兩個節點,你的索引將會有5個主分片和另外5個複製分片(1個完全拷貝),這樣的話每個索引總共就有10個分片。一個索引的多個分片可以存放在叢集中的一臺主機上,也可以存放在多臺主機上,這取決於你的叢集機器數量。主分片和複製分片的具體位置是由ES內在的策略所決定的。

Elasticsearch安裝與配置

安裝與執行

(1) 從這裡下載Elasticsearch安裝包。一共提供4種格式的安裝包(ZIP、TAR.GZ、DEB和RPM),可以根據自己所使用的系統平臺選擇相應格式的安裝包進行下載。(建議使用Linux系統,本人在2臺windows機器上嘗試啟動過,一臺機器上無法正常啟動,另外一臺可以)

(2) 對下載的安裝包進行解壓縮即可完成安裝操作。下面以在Ubuntu作業系統下使用TAR.GZ格式的1.5.0版本的安裝包為例進行安裝。在Linux shell中輸入下面的命令解壓縮。

tar –vxf elasticsearch-1.5.0.tar.gz
  • 1

安裝成功,下面執行ES。

   注意:Elasticsearch需要Java虛擬機器的支援,在執行之前保證機器上安裝了JDK,並且JDK版本不能低於1.7_55。
  • 1

(3) 現在可以直接使用預設配置啟動Elasticsearch了。  假設安裝包解壓後的目錄路徑為【/home/elasticsearch/elasticsearch-1.5.0】,下面軍用$ES_HOME來表示這個路徑。執行下面的命令:

 cd /home/elasticsearch/elasticsearch-1.5.0/bin/
 chmod +x * 
 ./elasticsearch
  • 1
  • 2
  • 3

如果出現如圖所示的介面(最後打印出started),則說明Elasticsearch啟動成功。 啟動成功介面

下面來驗證一下是否真的啟動成功。開啟瀏覽器,訪問網址 http://host:9200(這裡的host是ES的安裝主機地址,如果安裝在本機,就是http://127.0.0.1:9200)。如果顯示下面的資訊,則表示ES安裝成功。

{
  "status" : 200,
  "name" : "Captain Zero",
  "cluster_name" : "elasticsearch",
  "version" : {
    "number" : "1.5.0",
    "build_hash" : "544816042d40151d3ce4ba4f95399d7860dc2e92",
    "build_timestamp" : "2015-03-23T14:30:58Z",
    "build_snapshot" : false,
    "lucene_version" : "4.10.4"
  },
  "tagline" : "You Know, for Search"
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

上面是前臺啟動方式,一旦關閉Linux shell,ES服務就會停止。所以是實際使用過程中,絕對不會使用這種方式去啟動ES。除了上面的啟動方式外,還可以加上一定的啟動引數。例如:

 ./elasticsearch –d #在後臺執行Elasticsearch
  • 1
 ./elasticsearch -d -Xmx2g -Xms2g #後臺啟動,啟動時指定記憶體大小(2G)
  • 1
 ./elasticsearch -d -Des.logger.level=DEBUG  #可以在日誌中打印出更加詳細的資訊。
  • 1

ES的配置

配置檔案所在的目錄路徑如下:$ES_HOME/config/elasticsearch.yml。  下面介紹一些重要的配置項及其含義。

(1)cluster.name: elasticsearch

配置elasticsearch的叢集名稱,預設是elasticsearch。elasticsearch會自動發現在同一網段下的叢集名為elasticsearch的主機,如果在同一網段下有多個叢集,就可以用這個屬性來區分不同的叢集。生成環境時建議更改。

(2)node.name: “Franz Kafka”

節點名,預設隨機指定一個name列表中名字,該列表在elasticsearch的jar包中config資料夾裡name.txt檔案中,其中有很多作者新增的有趣名字,大部分是漫威動漫裡面的人物名字。生成環境中建議更改以能方便的指定叢集中的節點對應的機器

(3)node.master: true

指定該節點是否有資格被選舉成為node,預設是true,elasticsearch預設叢集中的第一臺啟動的機器為master,如果這臺機掛了就會重新選舉master。

(4)node.data: true

指定該節點是否儲存索引資料,預設為true。如果節點配置node.master:false並且node.data: false,則該節點將起到負載均衡的作用

(5)index.number_of_shards: 5

設定預設索引分片個數,預設為5片。經本人測試,索引分片對ES的查詢效能有很大的影響,在應用環境,應該選擇適合的分片大小。

(6)index.number_of_replicas:

設定預設索引副本個數,預設為1個副本。此處的1個副本是指index.number_of_shards的一個完全拷貝;預設5個分片1個拷貝;即總分片數為10。

(7)path.conf: /path/to/conf

設定配置檔案的儲存路徑,預設是es根目錄下的config資料夾。

(8)path.data:/path/to/data1,/path/to/data2

設定索引資料的儲存路徑,預設是es根目錄下的data資料夾,可以設定多個儲存路徑,用逗號隔開。

(9)path.work:/path/to/work

設定臨時檔案的儲存路徑,預設是es根目錄下的work資料夾。

(10)path.logs: /path/to/logs

設定日誌檔案的儲存路徑,預設是es根目錄下的logs資料夾

(11)path.plugins: /path/to/plugins

設定外掛的存放路徑,預設是es根目錄下的plugins資料夾

(12)bootstrap.mlockall: true

設定為true來鎖住記憶體。因為當jvm開始swapping時es的效率會降低,所以要保證它不swap,可以把ES_MIN_MEM和ES_MAX_MEM兩個環境變數設定成同一個值,並且保證機器有足夠的記憶體分配給es。同時也要允許elasticsearch的程序可以鎖住記憶體,linux下可以通過ulimit -l unlimited命令。

(13)network.bind_host: 192.168.0.1

設定繫結的ip地址,可以是ipv4或ipv6的,預設為0.0.0.0。

(14)network.publish_host: 192.168.0.1

設定其它節點和該節點互動的ip地址,如果不設定它會自動判斷,值必須是個真實的ip地址。

(15)network.host: 192.168.0.1

這個引數是用來同時設定bind_host和publish_host上面兩個引數。

(16)transport.tcp.port: 9300

設定節點間互動的tcp埠,預設是9300。

(17)transport.tcp.compress: true

設定是否壓縮tcp傳輸時的資料,預設為false,不壓縮。

(18)http.port: 9200

設定對外服務的http埠,預設為9200。

(19)http.max_content_length: 100mb

設定內容的最大容量,預設100mb

(20)http.enabled: false

是否使用http協議對外提供服務,預設為true,開啟。

(21)gateway.type: local

gateway的型別,預設為local即為本地檔案系統,可以設定為本地檔案系統,分散式檔案系統,hadoop的HDFS,和amazon的s3伺服器,其它檔案系統的設定。

(22)gateway.recover_after_nodes: 1

設定叢集中N個節點啟動時進行資料恢復,預設為1。

(23)gateway.recover_after_time: 5m

設定初始化資料恢復程序的超時時間,預設是5分鐘。

(24)gateway.expected_nodes: 2

設定這個叢集中節點的數量,預設為2,一旦這N個節點啟動,就會立即進行資料恢復。

(25)cluster.routing.allocation.node_initial_primaries_recoveries: 4

初始化資料恢復時,併發恢復執行緒的個數,預設為4。

(26)cluster.routing.allocation.node_concurrent_recoveries: 2

新增刪除節點或負載均衡時併發恢復執行緒的個數,預設為4。

(27)indices.recovery.max_size_per_sec: 0

設定資料恢復時限制的頻寬,如入100mb,預設為0,即無限制。

(28)indices.recovery.concurrent_streams: 5

設定這個引數來限制從其它分片恢復資料時最大同時開啟併發流的個數,預設為5。

(29)discovery.zen.minimum_master_nodes: 1

設定這個引數來保證叢集中的節點可以知道其它N個有master資格的節點。預設為1,對於大的叢集來說,可以設定大一點的值(2-4)

(30)discovery.zen.ping.timeout: 3s

設定叢集中自動發現其它節點時ping連線超時時間,預設為3秒,對於比較差的網路環境可以高點的值來防止自動發現時出錯。

(31)discovery.zen.ping.multicast.enabled: false

設定是否開啟多播發現節點,預設是true。

(32)discovery.zen.ping.unicast.hosts: [“host1”, “host2:port”, “host3 [portX-portY] “]

設定叢集中master節點的初始列表,可以通過這些節點來自動發現新加入叢集的節點。

除了上面的在安裝時配置檔案中就自帶的配置項外,本人在實際使用過程還使用到了下面的配置:

threadpool:
    search:
        type: fixed
        min: 60
        max: 80
        queue_size: 1000
// 配置es伺服器的執行查詢操作時所用執行緒池,fix固定執行緒數的執行緒池。
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
index :
    store:
        type: memory
// 表示索引儲存在記憶體中,當然es不太建議這麼做。經本人測試,做查詢時,使用記憶體索引並不會比正常的索引快。
  • 1
  • 2
  • 3
  • 4
index.mapper.dynamic: false
// 禁止自動建立mapping。預設情況下,es可以根據資料型別自動建立mapping。配置成這樣,可以禁止自動建立mapping的行為。至於什麼是mapping,在之後的博文中再介紹。
  • 1
  • 2
index.query.parse.allow_unmapped_fields: false 
// 不能查詢沒有在mapping中定義的屬性
  • 1
  • 2

總結

本文介紹了Elasticsearch中的一些基礎知識,包括其中的一些核心概念。只有理解了ES中的這些核心概念,才能對更加得心應手地使用ES,發揮其強大的搜尋能力。同時,也介紹了ES的安裝和執行,ES的安裝和執行是很簡單的,只需要極少的簡單步驟,就可以開始體驗ES。ES的配置非常豐富,安裝時自帶的配置檔案只包含一部分比較核心的配置項,更多的配置內容需要自己去閱讀ES的原始碼時才能被發現。

下一篇準備介紹ES的使用,特別是其封裝的及其豐富的Rest API的使用。