一、Elasticsearch 簡介
你可以這麼形容 Elasticsearch :
- 一個分布式的實時文檔存儲,每個字段都可以被索引與搜尋
- 一個分布式近實時分析搜尋引擎
- 能勝任上百個服務節點的擴充,并支援 PB 級别的結構化或者非結構化資料
Elasticsearch 是一個實時分布式搜尋和分析引擎,建立在一個全文搜尋引擎庫 Apache Lucene 基礎之上,而 Lucene 是當下最先進、高性能、全功能的搜尋引擎庫。
但是 Lucene 僅僅隻是一個庫。為了充分發揮其功能,你需要使用 Java 并将 Lucene 直接內建到應用程式中。 更糟糕的是,您可能需要獲得資訊檢索學位才能了解其工作原理,因為 Lucene 非常複雜。
Elasticsearch 也是使用 Java 編寫的,它的内部使用 Lucene 做索引與搜尋,但是它的目的是使全文檢索變得簡單,通過隐藏 Lucene 的複雜性,取而代之的提供一套簡單一緻的 RESTful API。
- 維基百科使用 Elasticsearch 提供全文搜尋并高亮關鍵字,以及輸入實時搜尋(search-asyou-type)和搜尋糾錯(did-you-mean)等搜尋建議功能。
- 英國衛報使用 Elasticsearch 結合使用者日志和社交網絡資料提供給他們的編輯以實時的回報,以便及時了解公衆對新發表的文章的回應。
- StackOverflow 結合全文搜尋與地理位置查詢,以及 more-like-this 功能來找到相關的問題和答案。
- Github 使用 Elasticsearch 檢索 1300 億行的代碼。
- ...
Elasticsearch 不僅用于大型企業,它還讓像 DataDog 以及 Klout 這樣的創業公司将最初的想法變成可擴充的解決方案,Elasticsearch 可以在你的筆記本上運作,也可以在數以百計的伺服器上處理 PB 級别的資料。
二、Elasticsearch 安裝
- Installing Elasticsearch
- Docker 下安裝 ElasticSearch 和 Kibana
- kibana 7.* 設定中文漢化
- Docker-compose 部署 ELK
三、Elasticsearch 基本概念
文檔(Document)
JSON 格式,Elasticsearch 存儲的最小機關,可以了解為是關系型資料庫中的一條記錄,每個文檔都有自己的一個 unique id。

文檔中繼資料,用于标注文檔的相關資訊
- _index:文檔所屬的索引名
- _type:文檔所屬的類型名
- _source:文檔的原始Json資料
- _id:文檔唯一id
- _version:文檔版本資訊
- _score:文檔相關度打分
_score 相關度是一個很重要的概念,闡明了 Elasticsearch 在全文屬性上搜尋并傳回相關性最強的結果,這是完全差別于傳統關系型資料庫的一個概念,資料庫中的一條記錄要麼比對要麼不比對。
文檔(Document)是不可變的:它們不能被修改,隻能被替換。是以對于 Document 的所有修改操作,在其内部都要經曆檢索-修改-重建索引的處理過程。
索引(Index)、類型(Type)
索引(Index)是文檔的一個容器,類比于關系型資料庫的資料庫概念,索引中的 setting 裡定義有多少個 shards 來存儲索引資料,資料是如何分布。
PUT /blogs
{
"settings" : {
"number_of_shards" : 3,
"number_of_replicas" : 1
}
}
類型(Type)可以了解成關系型資料庫中的 Table。
是以 每個索引(Index)包含多個類型(Type),不同的類型存儲着多個文檔(Document),每個文檔又有多個屬性(Field)
分片、副本
一個運作中的 Lucene 執行個體稱為一個分片,分片是資料的容器,文檔儲存在分片内,分片又被配置設定到叢集内的各個節點裡。當你的叢集規模擴大或者縮小時,Elasticsearch 會自動的在各節點中遷移分片,使得資料仍然均勻分布在叢集裡。
一個分片可以是主分片或者副本分片。
主分片用于解決水準擴充問題,将索引海量資料分布到叢集内所有的節點之上(預設通過 id 的 hash),主分片在索引建立的時候确定,後續不允許修改(除非 Reindex 操作進行修改)。
副本分片是用于解決高可用問題,當主配置設定出現問題時,副本分片會被叢集更新為主分片,副本分片個數的決定了寫入性能和讀取吞吐量,副本數量越多寫入性能越差,但讀取吞吐量就會越高,在運作中的叢集上是可以動态調整副本分片數目的。
PUT /blogs/_settings
{
"number_of_replicas" : 2
}
如果主分片和副本分片都集中在一個節點上,那是沒辦法做到高可用的。ES 的叢集監控狀态會傳回 yellow(表示全部主分片都正常運作,副本分片沒有全部處在正常狀态)。是以,需要啟動更多的節點來承載副本分片。
叢集、節點
一個運作中的 Elasticsearch 執行個體稱為一個節點,而叢集是由一個或者多個擁有相同 cluster.name 配置的節點組成,它們共同承擔資料和負載的壓力。當有節點加入叢集中或者從叢集中移除節點時,叢集将會重新平均分布所有的資料。
Master 節點,負責管理叢集範圍内的所有變更,例如增加、删除索引,或者增加、删除節點等,而 Master 節點并不需要涉及到文檔級别的變更和搜尋等操作。
Data 節點,存儲資料節點。
Coordinating (協調)節點,負責接收用戶端請求,分發請求到其他節點,最後再将資料彙集響應給用戶端。叢集中得任何節點都可以作為協調節點,包括主節點,每個節點都知道任意文檔所處的位置。
叢集中的節點通過端口 9300 彼此通信。如果這個端口沒有打開,節點将無法形成一個叢集。
四、Elasticsearch 資料和檢索
Elasticsearch 是面向文檔的,使用 JSON 作為文檔的序列化格式,而且 Elasticsearch 不僅存儲文檔,還索引每個文檔的内容,使之可以被檢索、排序和過濾,而這也是 Elasticsearch 能支援複雜全文檢索的原因。
在 Elasticsearch 中, 每個字段的所有資料都是預設被索引的。即每個字段都有為了快速檢索設定的專用反向索引。而且,不像其他多數的資料庫,它能在同一個查詢中使用所有這些反向索引,并以驚人的速度傳回結果。
我們可以使用 RESTful API 通過端口 9200(預設)和 Elasticsearch 進行通信,可以使用 kibana 通路 Elasticsearch ,甚至可以直接使用 curl 指令來和 Elasticsearch 互動。
curl -X<VERB> '<PROTOCOL>://<HOST>:<PORT>/<PATH>?<QUERY_STRING>' -d '<BODY>'
VERB:适當的 HTTP 方法或謂詞 : GET、POST、PUT、HEAD 或者 DELETE。
PROTOCOL:http 或者 https。
HOST:Elasticsearch 叢集中任意節點的主機名,或者用 localhost 代表本地機器上的節點。
PORT:Elasticsearch HTTP 服務的端口号,預設是 9200.
PATH:API 的終端路徑(例如 _count 将傳回叢集中文檔數量)。Path 可能包含多個元件,例如:_cluster/stats 和 _nodes/stats/jvm 。
QUERY_STRING:可選,查詢字元串參數 (例如 ?pretty 将格式化地輸出 JSON 傳回值,使其更容易閱讀)
BODY:可選,一個 JSON 格式的請求體
更多 DSL 文法可以參考:https://www.elastic.co/guide/en/elasticsearch/reference/7.9/search-search.html
如果你正在使用 Java,在代碼中你可以使用 Elasticsearch 内置的兩個用戶端:
節點用戶端(Node client)
節點用戶端作為一個非資料節點加入到本地叢集中。換句話說,它本身不儲存任何資料,但是它知道資料在叢集中的哪個節點中,并且可以把請求轉發到正确的節點。
傳輸用戶端(Transport client)
輕量級的傳輸用戶端可以将請求發送到遠端叢集。它本身不加入叢集,但是它可以将請求轉發到叢集中的一個節點上。
兩個 Java 用戶端都是通過 9300 端口并使用 Elasticsearch 的原生傳輸協定和叢集互動。