你可以這么形容 Elasticsearch :
Elasticsearch 是一個實時分布式搜索和分析引擎,建立在一個全文搜索引擎庫 Apache Lucene 基礎之上,而 Lucene 是當下最先進、高性能、全功能的搜索引擎庫。
但是 Lucene 僅僅只是一個庫。為了充分發(fā)揮其功能,你需要使用 Java 并將 Lucene 直接集成到應用程序中。 更糟糕的是,您可能需要獲得信息檢索學位才能了解其工作原理,因為 Lucene 非常復雜。
Elasticsearch 也是使用 Java 編寫的,它的內(nèi)部使用 Lucene 做索引與搜索,但是它的目的是使全文檢索變得簡單,通過隱藏 Lucene 的復雜性,取而代之的提供一套簡單一致的 RESTful API。
Elasticsearch 不僅用于大型企業(yè),它還讓像 DataDog 以及 Klout 這樣的創(chuàng)業(yè)公司將最初的想法變成可擴展的解決方案,Elasticsearch 可以在你的筆記本上運行,也可以在數(shù)以百計的服務器上處理 PB 級別的數(shù)據(jù)。
JSON 格式,Elasticsearch 存儲的最小單位,可以理解為是關系型數(shù)據(jù)庫中的一條記錄,每個文檔都有自己的一個 unique id。
文檔元數(shù)據(jù),用于標注文檔的相關信息
_score 相關度是一個很重要的概念,闡明了 Elasticsearch 在全文屬性上搜索并返回相關性最強的結(jié)果,這是完全區(qū)別于傳統(tǒng)關系型數(shù)據(jù)庫的一個概念,數(shù)據(jù)庫中的一條記錄要么匹配要么不匹配。
文檔(Document)是不可變的:它們不能被修改,只能被替換。因此對于 Document 的所有修改操作,在其內(nèi)部都要經(jīng)歷檢索-修改-重建索引的處理過程。
索引(Index)是文檔的一個容器,類比于關系型數(shù)據(jù)庫的數(shù)據(jù)庫概念,索引中的 setting 里定義有多少個 shards 來存儲索引數(shù)據(jù),數(shù)據(jù)是如何分布。
PUT /blogs
{
"settings" : {
"number_of_shards" : 3,
"number_of_replicas" : 1
}
}
類型(Type)可以理解成關系型數(shù)據(jù)庫中的 Table。
因此 每個索引(Index)包含多個類型(Type),不同的類型存儲著多個文檔(Document),每個文檔又有多個屬性(Field)
一個運行中的 Lucene 實例稱為一個分片,分片是數(shù)據(jù)的容器,文檔保存在分片內(nèi),分片又被分配到集群內(nèi)的各個節(jié)點里。當你的集群規(guī)模擴大或者縮小時,Elasticsearch 會自動的在各節(jié)點中遷移分片,使得數(shù)據(jù)仍然均勻分布在集群里。
一個分片可以是主分片或者副本分片。
主分片用于解決水平擴展問題,將索引海量數(shù)據(jù)分布到集群內(nèi)所有的節(jié)點之上(默認通過 id 的 hash),主分片在索引創(chuàng)建的時候確定,后續(xù)不允許修改(除非 Reindex 操作進行修改)。
副本分片是用于解決高可用問題,當主分配出現(xiàn)問題時,副本分片會被集群升級為主分片,副本分片個數(shù)的決定了寫入性能和讀取吞吐量,副本數(shù)量越多寫入性能越差,但讀取吞吐量就會越高,在運行中的集群上是可以動態(tài)調(diào)整副本分片數(shù)目的。
PUT /blogs/_settings
{
"number_of_replicas" : 2
}
如果主分片和副本分片都集中在一個節(jié)點上,那是沒辦法做到高可用的。ES 的集群監(jiān)控狀態(tài)會返回 yellow(表示全部主分片都正常運行,副本分片沒有全部處在正常狀態(tài))。因此,需要啟動更多的節(jié)點來承載副本分片。
一個運行中的 Elasticsearch 實例稱為一個節(jié)點,而集群是由一個或者多個擁有相同 cluster.name 配置的節(jié)點組成,它們共同承擔數(shù)據(jù)和負載的壓力。當有節(jié)點加入集群中或者從集群中移除節(jié)點時,集群將會重新平均分布所有的數(shù)據(jù)。
Master 節(jié)點,負責管理集群范圍內(nèi)的所有變更,例如增加、刪除索引,或者增加、刪除節(jié)點等,而 Master 節(jié)點并不需要涉及到文檔級別的變更和搜索等操作。
Data 節(jié)點,存儲數(shù)據(jù)節(jié)點。
Coordinating (協(xié)調(diào))節(jié)點,負責接收客戶端請求,分發(fā)請求到其他節(jié)點,最后再將數(shù)據(jù)匯集響應給客戶端。集群中得任何節(jié)點都可以作為協(xié)調(diào)節(jié)點,包括主節(jié)點,每個節(jié)點都知道任意文檔所處的位置。
集群中的節(jié)點通過端口 9300 彼此通信。如果這個端口沒有打開,節(jié)點將無法形成一個集群。
Elasticsearch 是面向文檔的,使用 JSON 作為文檔的序列化格式,而且 Elasticsearch 不僅存儲文檔,還索引每個文檔的內(nèi)容,使之可以被檢索、排序和過濾,而這也是 Elasticsearch 能支持復雜全文檢索的原因。
在 Elasticsearch 中, 每個字段的所有數(shù)據(jù)都是默認被索引的。即每個字段都有為了快速檢索設置的專用倒排索引。而且,不像其他多數(shù)的數(shù)據(jù)庫,它能在同一個查詢中使用所有這些倒排索引,并以驚人的速度返回結(jié)果。
我們可以使用 RESTful API 通過端口 9200(默認)和 Elasticsearch 進行通信,可以使用 kibana 訪問 Elasticsearch ,甚至可以直接使用 curl 命令來和 Elasticsearch 交互。
curl -X<VERB> '<PROTOCOL>://<HOST>:<PORT>/<PATH>?<QUERY_STRING>' -d '<BODY>'
VERB:適當?shù)?HTTP 方法或謂詞 : GET、POST、PUT、HEAD 或者 DELETE。
PROTOCOL:http 或者 https。
HOST:Elasticsearch 集群中任意節(jié)點的主機名,或者用 localhost 代表本地機器上的節(jié)點。
PORT:Elasticsearch HTTP 服務的端口號,默認是 9200.
PATH:API 的終端路徑(例如 _count 將返回集群中文檔數(shù)量)。Path 可能包含多個組件,例如:_cluster/stats 和 _nodes/stats/jvm 。
QUERY_STRING:可選,查詢字符串參數(shù) (例如 ?pretty 將格式化地輸出 JSON 返回值,使其更容易閱讀)
BODY:可選,一個 JSON 格式的請求體
更多 DSL 語法可以參考:https://www.elastic.co/guide/en/elasticsearch/reference/7.9/search-search.html
如果你正在使用 Java,在代碼中你可以使用 Elasticsearch 內(nèi)置的兩個客戶端:
節(jié)點客戶端(Node client)
節(jié)點客戶端作為一個非數(shù)據(jù)節(jié)點加入到本地集群中。換句話說,它本身不保存任何數(shù)據(jù),但是它知道數(shù)據(jù)在集群中的哪個節(jié)點中,并且可以把請求轉(zhuǎn)發(fā)到正確的節(jié)點。
傳輸客戶端(Transport client)
輕量級的傳輸客戶端可以將請求發(fā)送到遠程集群。它本身不加入集群,但是它可以將請求轉(zhuǎn)發(fā)到集群中的一個節(jié)點上。
兩個 Java 客戶端都是通過 9300 端口并使用 Elasticsearch 的原生傳輸協(xié)議和集群交互。