系列目錄
內存吞金獸(Elasticsearch)的那些事兒 -- 認識一下
內存吞金獸(Elasticsearch)的那些事兒 -- 數據結構及巧妙算法
內存吞金獸(Elasticsearch)的那些事兒 -- 架構&三高保證
內存吞金獸(Elasticsearch)的那些事兒 -- 寫入&檢索原理
內存吞金獸(Elasticsearch)的那些事兒 -- 常見問題痛點及解決方案
ES 本質上是一個支持全文搜索的分布式內存數據庫,特別適合用於構建搜索系統。ES 之所以能有非常好的全文搜索性能,最重要的原因就是采用了倒排索引。倒排索引是一種特別為搜索而設計的索引結構,倒排索引先對需要索引的字段進行分詞,然后以分詞為索引組成一個查找樹,這樣就把一個全文匹配的查找轉換成了對樹的查找,這是倒排索引能夠快速進行搜索的根本原因。
背景及常見術語
背景
Elasticsearch 是一個開源的搜索引擎,建立在一個全文搜索引擎庫 Apache Lucene™ 基礎之上。 Lucene 可以說是當下最先進、高性能、全功能的搜索引擎庫—無論是開源還是私有。
但是 Lucene 僅僅只是一個庫。為了充分發揮其功能,你需要使用 Java 並將 Lucene 直接集成到應用程序中。 更糟糕的是,您可能需要獲得信息檢索學位才能了解其工作原理。Lucene 非常 復雜。
Elasticsearch 也是使用 Java 編寫的,它的內部使用 Lucene 做索引與搜索,但是它的目的是使全文檢索變得簡單, 通過隱藏 Lucene 的復雜性,取而代之的提供一套簡單一致的 RESTful API。
然而,Elasticsearch 不僅僅是 Lucene,並且也不僅僅只是一個全文搜索引擎。 它可以被下面這樣准確的形容:
- 一個分布式的實時文檔存儲,每個字段 可以被索引與搜索
- 一個分布式實時分析搜索引擎
- 能勝任上百個服務節點的擴展,並支持 PB 級別的結構化或者非結構化數據
Elasticsearch 將所有的功能打包成一個單獨的服務,可以通過程序與它提供的簡單的 RESTful API 進行通信, 可以使用自己喜歡的編程語言充當 web 客戶端,甚至可以使用命令行(去充當這個客戶端)。
面向文檔
Elasticsearch 是 面向文檔 的,意味着它存儲整個對象或 文檔。Elasticsearch 不僅存儲文檔,而且 索引 每個文檔的內容,使之可以被檢索。在 Elasticsearch 中,我們對文檔進行索引、檢索、排序和過濾—而不是對行列數據。這是一種完全不同的思考數據的方式,也是 Elasticsearch 能支持復雜全文檢索的原因。
幾個關鍵詞
- 實時
- 分布式
- 搜索
- 分析
優勢
- Elasticsearch對模糊搜索非常擅長(搜索速度很快)
- 從Elasticsearch搜索到的數據可以根據評分過濾掉大部分的,只要返回評分高的給用戶就好了(原生就支持排序)
- 沒有那么准確的關鍵字也能搜出相關的結果(能匹配有相關性的記錄)
常見術語
- Index:Elasticsearch的Index相當於數據庫的Table
- Type:這個在新的Elasticsearch版本已經廢除(在以前的Elasticsearch版本,一個Index下支持多個Type--有點類似於消息隊列一個topic下多個group的概念)
- Document:Document相當於數據庫的一行記錄
- Field:相當於數據庫的Column的概念
- Mapping:相當於數據庫的Schema的概念(個人感覺這個解釋不太合理,說白了其實就是靜態類型映射)
- DSL:相當於數據庫的SQL(給我們讀取Elasticsearch數據的API)
- cluster:一組擁有共同的 cluster name 的節點
- node:集群中的一個 實例
- primary shard: 索引的子集,索引可以切分成多個分片,分布在不同的節點,分片對應的是lucene中的索引
- replica shard:代表索引副本,Elasticsearch可以設置多個索引的副本,副本具有以下作用:
提高系統的容錯性,當某個節點某個分片損壞或丟失時可以從副本中恢復。
提高Elasticsearch的查詢效率,Elasticsearch會自動對搜索請求進行負載均衡。 - allocation:將分片分配給某個節點的過程,包括分配主分片或副本。如果是副本,還包括從主分片復制數據的過程
客戶端
節點客戶端(Node client)
節點客戶端作為一個非數據節點加入到本地集群中。換句話說,它本身不保存任何數據,但是它知道數據在集群中的哪個節點中,並且可以把請求轉發到正確的節點。
傳輸客戶端(Transport client)
輕量級的傳輸客戶端可以將請求發送到遠程集群。它本身不加入集群,但是它可以將請求轉發到集群中的一個節點上。
注意⚠️
兩個 客戶端都是通過 端口並使用 Elasticsearch 的原生 傳輸 協議和集群交互。集群中的節點通過端口 彼此通信。如果端口沒有打開,節點將無法形成一個集群。
客戶端作為節點必須和 Elasticsearch 有相同的 主要 版本;否則,它們之間將無法互相理解。
應用場景
如果要將應用程序和 Elasticsearch 集群進行解耦,傳輸客戶端是一個理想的選擇。例如,如果您的應用程序需要快速的創建和銷毀到集群的連接,傳輸客戶端比節點客戶端”輕”,因為它不是一個集群的一部分。
類似地,如果您需要創建成千上萬的連接,你不想有成千上萬節點加入集群。傳輸客戶端( TC )將是一個更好的選擇。
另一方面,如果你只需要有少數的、長期持久的對象連接到集群,客戶端節點可以更高效,因為它知道集群的布局。但是它會使你的應用程序和集群耦合在一起,所以從防火牆的角度,它可能會構成問題。
RESTful API with JSON over HTTP
可以使用 RESTful API 通過端口 和 Elasticsearch 使用類GraphQL語義進行通信,可以用任何一個 web 客戶端訪問 Elasticsearch
java - spring接入方式
https://spring.io/projects/spring-data-elasticsearch