Elasticsearch

  • 2020 年 5 月 14 日
  • 筆記

1 Elasticsearch介紹

  1、什麼是 Elasticsearch ?

      1. 使用 java 語言開發的一套開源的全文搜索引擎,建立在全文搜索引擎 Apache Lucene(TM) 基礎上的搜索引擎

      2. 用於搜索、日誌管理、安全分析、指標分析、業務分析、應用性能監控等多個領域

      3. 底層基於 Lucene 開源庫開發,提供 restAPI,可以被任何語言調用

      4. 支持分佈式部署,可水平擴展

      5. 更新迭代快、社區活躍、文檔豐富

  2、es功能

      1. 分佈式的搜索引擎和數據分析引擎

      2. 數據分析:電商網站,最近7天牙膏銷量排行前十商家(舉例)

      3. 全文檢索,結構化檢索,數據分析

      4. 全文檢索:我想搜索商品名稱包含牙膏的商品,select * from products where product_name like 「%牙膏%」

      5. 結構化檢索:我想搜索商品分類為日化用品的商品都有哪些,select * from products where category_id=』日化用品』

      6. 部分匹配、自動完成、搜索糾錯、搜索推薦

      7. 數據分析:我們分析每一個商品分類下有多少個商品,select category_id,count(*) from products group by category_id

      8. 對海量數據進行實時的處理

  3、es特點

      1. 可以作為一個大型分佈式集群(數百台服務器)技術,處理PB級數據,服務大公司;也可以運行在單機上,服務小公司

      2. Elasticsearch不是什麼新技術,主要是將全文檢索、數據分析以及分佈式技術,合併在了一起,才形成了獨一無二的ES;

      3. lucene(全文檢索),商用的數據分析軟件(也是有的),分佈式數據庫(mycat)

      4. 對用戶而言,是開箱即用的,非常簡單,作為中小型的應用,直接3分鐘部署一下ES,就可以作為生產環境的系統來使用了,數據量不大,操作不是太複雜

      5. 數據庫的功能面對很多領域是不夠用的(事務,還有各種聯機事務型的操作);

      6. 特殊的功能,比如全文檢索,同義詞處理,相關度排名,複雜數據分析,海量數據的近實時處理;

      7. Elasticsearch作為傳統數據庫的一個補充,提供了數據庫所不不能提供的很多功能

2 Elasticsearch基本概念

  1、概念說明

      1. ElasticSearch 是分佈式數據庫,允許多台服務器協同工作,每台服務器可以運行多個實例。

      2. 單個實例稱為一個節點(node)

      3. 一組節點構成一個集群(cluster)。

      4. 分片是底層的工作單元,文檔保存在分片內,分片又被分配到集群內的各個節點裏,每個分片僅保存全部數據的一部分。

      

  2、索引(Index)[數據庫]

      1. ES將數據存儲於一個或多個索引中,索引是具有類似特性的文檔的集合。

      2. 類比傳統的關係型數據庫領域來說,索引相當於SQL中的一個數據庫,或者一個數據存儲方案(schema)。

      3. 索引由其名稱(必須為全小寫字符)進行標識,並通過引用此名稱完成文檔的創建、搜索、更新及刪除操作。

      4. 一個ES集群中可以按需創建任意數目的索引。

  3、類型(Type)[表]

      1. 類型是索引內部的邏輯分區(category/partition),然而其意義完全取決於用戶需求。

      2. 因此,一個索引內部可定義一個或多個類型(type)。

      3. 一般來說,類型就是為那些擁有相同的域的文檔做的預定義。

      4. 例如,在索引中,可以定義一個用於存儲用戶數據的類型,一個存儲日誌數據的類型,以及一個存儲評論數據的類型。

      5. 類比傳統的關係型數據庫領域來說,類型相當於「表」。

  4、文檔(Document)

      1. 文檔是索引和搜索的原子單位,它是包含了一個或多個域(Field)的容器,基於JSON格式進行表示。

      2. 文檔由一個或多個域組成,每個域擁有一個名字及一個或多個值,有多個值的域通常稱為「多值域」。

      3. 每個文檔可以存儲不同的域集,但同一類型下的文檔至應該有某種程度上的相似之處。

  5、節點(Node)

      1. 一個運行中的 Elasticsearch 實例稱為一個節點

      2. 而集群是由一個或者多個擁有相同cluster.name配置的節點組成, 它們共同承擔數據和負載的壓力。

      3. ES集群中的節點有三種不同的類型:

        1)主節點:負責管理集群範圍內的所有變更,例如增加、刪除索引,或者增加、刪除節點等。 主節點並不需要涉及到文檔級別的變更和搜索等操作。可以通過屬性node.master進行設置。

        2)數據節點:存儲數據和其對應的倒排索引,默認每一個節點都是數據節點(包括主節點),可以通過node.data屬性進行設置。

        3)協調節點:如果node.master和node.data屬性均為false,則此節點稱為協調節點,用來響應客戶請求,均衡每個節點的負載。

  6、分片(Shard)

      1. 一個索引中的數據保存在多個分片中,相當於水平分表。

      2. 一個分片便是一個Lucene 的實例,它本身就是一個完整的搜索引擎。

      3. 我們的文檔被存儲和索引到分片內,但是應用程序是直接與索引而不是與分片進行交互。

      4. ES實際上就是利用分片來實現分佈式。

      5. 分片是數據的容器,文檔保存在分片內,分片又被分配到集群內的各個節點裏。

      6. 當你的集群規模擴大或者縮小時, ES會自動的在各節點中遷移分片,使得數據仍然均勻分佈在集群里。

      7.主分片 與 副分片

        1)索引內任意一個文檔都歸屬於一個主分片,所以主分片的數目決定着索引能夠保存的最大數據量。

        2)一個副本分片只是一個主分片的拷貝。

        3)副本分片作為硬件故障時保護數據不丟失的冗餘備份,並為搜索和返迴文檔等讀操作提供服務。

3 Elasticsearch增刪改查原理

  1、增加原理

      1. 當用戶向一個節點提交了一個索引新文檔的請求,節點會計算新文檔應該加入到哪個分片(shard)中。

      2. 每個節點都存儲有每個分片存儲在哪個節點的信息,因此協調節點會將請求發送給對應的節點。

      3. 注意這個請求會發送給主分片,等主分片完成索引,會並行將請求發送到其所有副本分片,保證每個分片都持有最新數據。

      4. 每次寫入新文檔時,都會先寫入內存中,並將這一操作寫入一個translog文件(transaction log)中,此時如果執行搜索操作,這個新文檔還不能被索引到。

      5. ES會每隔1秒時間(這個時間可以修改)進行一次刷新操作(refresh)

      6. 此時在這1秒時間內寫入內存的新文檔都會被寫入一個文件系統緩存(filesystem cache)中,並構成一個分段(segment)。

      7. 此時這個segment里的文檔可以被搜索到,但是尚未寫入硬盤,即如果此時發生斷電,則這些文檔可能會丟失。

      8.不斷有新的文檔寫入,則這一過程將不斷重複執行。每隔一秒將生成一個新的segment,而translog文件將越來越大。

      9.不斷有新的文檔寫入,則這一過程將不斷重複執行。每隔一秒將生成一個新的segment,而translog文件將越來越大。

      說明:

        1)由上面的流程可以看出,在兩次fsync操作之間,存儲在內存和文件系統緩存中的文檔是不安全的,一旦出現斷電這些文檔就會丟失。

        2)所以ES引入了translog來記錄兩次fsync之間所有的操作,這樣機器從故障中恢復或者重新啟動,ES便可以根據translog進行還原。

         

  2、刪除(Delete)文檔

      1. ES的索引是不能修改的,因此更新和刪除操作並不是直接在原索引上直接執行。

      2. 每一個磁盤上的segment都會維護一個del文件,用來記錄被刪除的文件。

      3. 每當用戶提出一個刪除請求,文檔並沒有被真正刪除,索引也沒有發生改變,而是在del文件中標記該文檔已被刪除。

      4. 因此,被刪除的文檔依然可以被檢索到,只是在返回檢索結果時被過濾掉了。

      5. 每次在啟動segment合併工作時,那些被標記為刪除的文檔才會被真正刪除。

  3、更新(Update)

      1. 更新文檔會首先查找原文檔,得到該文檔的版本號。

      2. 然後將修改後的文檔寫入內存,此過程與寫入一個新文檔相同。

      3. 同時,舊版本文檔被標記為刪除,同理,該文檔可以被搜索到,只是最終被過濾掉。

  4、讀操作(Read):查詢過程

      1. 查詢的過程大體上分為查詢(query)和取回(fetch)兩個階段。

      2. 這個節點的任務是廣播查詢請求到所有相關分片,並將它們的響應整合成全局排序後的結果集合,這個結果集合會返回給客戶端。

      3. 查詢階段

        1)當一個節點接收到一個搜索請求,則這個節點就變成了協調節點。

        2)第一步是廣播請求到索引中每一個節點的分片拷貝。

        3)協調節點會將所有分片的結果匯總,並進行全局排序,得到最終的查詢排序結果。

      4. 取回階段

        1)查詢過程得到的是一個排序結果,標記出哪些文檔是符合搜索要求的,此時仍然需要獲取這些文檔返回客戶端。

        2)協調節點會確定實際需要返回的文檔,並向含有該文檔的分片發送get請求;

        3)分片獲取文檔返回給協調節點;協調節點將結果返回給客戶端。