一、與ES的邂逅
如果問自己最近幾年最喜歡研究的技術,我會毫不猶豫地選擇ES。源于5年前參加工作時接觸到的一個産品,它最具有競争力的功能就在于搜尋,資料源是實時更新的,需要滿足使用者能實時搜尋的核心需求。基于随着版本的疊代、資料量的快速增長這一特點,急需一種搜尋性能良好且易于部署的搜尋引擎滿足産品需求,通過查閱資料以及專業的資料庫綜合測評網站:DBRanking,結果就這樣邂逅了ES,下面正式開啟ES之旅。
二、ES的研究之路
為什麼選擇它
這幾年随着移動網際網路、物聯網的興起,資訊量呈現爆炸式的增長,早期的關系型資料庫已無法滿足從海量資料中快速篩選出所需資訊的要求。資料種類與格式日益增多,不再局限于文本資料,而且現在需要從海量資料中提取出關鍵詞,再根據關鍵詞搜尋出相關的資料記錄,正常的模糊比對無法滿足性能名額。
除了高性能的檢索,它的分布式特性,簡單易用的DSL可以建構滿足各種需求的聚合及資料分析,這些都是一般的SQL語句所不具備的。是以無論是基于ES開發業務層面的應用,還是做成一個通用的名額資料監控平台,它都是不二之選!DB-engines調查的資料庫排名也說明在搜尋引擎領域,也是位居首位!
應用場景
在我參與的研發中,主要是和Kafka配合做資料的存儲和實時展示。其實ES的最常用的核心功能:檢索和聚合在很多場景中都有落地實作,如:日志分析和輿情監控,資料聚合分析,安全監控,運維管理平台等等。在我們的日常生活中,比如打車軟體、購物平台、地圖搜尋都有ES的身影,對于研發人員沒有使用的Github,Wikipedia,裡面的代碼檢索就是用ES做的。
- 雲托管服務:阿裡雲ES叢集托管
- 搜尋領域:滴滴打車、高德地圖、站内檢索
- 安全領域:阿裡安全在安全業務中的實踐
- 資料查詢:将ES作為NoSQL的替代方案,加速資料的查詢
- 日志分析:通過Elastic Stack中的ELK可以完成日志的采集、存儲、分析、搜尋、監控、展示等整個流程;
架構初探
從架構圖中可以看到,從底向上大體可以分為如下幾層:
- 最底層是存儲索引的檔案系統;
- 往上一層是ES的基礎:分布式的Lucene架構;
- 基于Lucene是搜尋和索引子產品,映射解析子產品;
- 中間層就是節點發現與選舉的子產品,支援腳本語言的嵌入子產品,而且支援第三方的插件接入;
- 接近使用者層的傳輸子產品,ES的管理子產品;
- 最上層就是與使用者交換的應用層,通過restful接口與ES叢集互動資料。
進階特性
- 分布式特性:叢集内的節點能自動配置設定平衡資料;
- 近實時搜尋:從資料接入到可查詢這個過程會有1秒的延時,是以稱為近實時;
- 高可用:部分節點不可用不會導緻這個ES挂掉,叢集節點具有容錯機制;
- 動态映射:根據索引的資料,自動判斷字段的類型生成mapping,把索引存入ES;
- restful接口:使用json的結構,通過http請求可以很友善高效地與ES互動,支援多用戶端;
分布式架構
分布式架構帶來的好處是,支援水準擴容,提升系統的可用性,部分節點挂掉不影響整個叢集的服務。
容易帶來腦裂問題:
腦裂其實是分布式中的網絡問題,由于網絡出現問題,導緻一個節點無法與其他節點連接配接,node2和node3會重新選舉,node1單獨作為一個叢集選舉,出現了多個master,當網絡恢複時,無法正确恢複。
寫資料底層原理
寫資料的大緻流程是:記憶體緩沖區 —> refresh -> 作業系統緩存 -> translog -> commit -> flush -> buffer區的資料寫入segment file
1.資料先寫入記憶體buffer,每隔1秒重新整理資料到作業系統緩存(把資料寫入segment),此時資料就能被搜尋到(因為從segment寫入磁盤相對比較耗時,借助作業系統的緩存,重新整理階段把segment先寫入緩存以開放查詢,這裡解釋了為什麼是近實時搜尋)
2.為了保證資料不丢失,索引資料的同時,每隔5秒,把資料寫入translog檔案,它預設會落盤(即使機器當機,最多丢失5秒的資料)。【注:在第一步執行重新整理操作時,記憶體buffer的資料會被清空,translog檔案不會清空】
3.當translog檔案大到一定程度,或預設每隔30分鐘,觸發commit操作,把緩沖區的資料flush到segment file磁盤檔案中,此時就建好了反向索引。具體就是此階段會調用fsync,将segment寫入磁盤,同時清空translog檔案
反向索引
通常作資料搜尋的思路是:在資料的字段中模糊比對關鍵詞,如果比對成功,則傳回對應的資料。但是這裡的有個最大的問題是,模糊比對很耗費性能,影響檢索效率,在大文本資料中展現得尤其明顯。ES采取了非正常的思路,設計了反向索引的資料結構,就是把文本進行分詞處理,提取出其中的詞項,然後建立詞項到文檔的映射關系,形成反向索引表。
反向索引:其實由單詞詞典、倒排清單和倒排檔案組成。
- 單詞詞典:是文檔集合中所有的單詞的集合;
- 倒排清單記錄了詞項到文檔的映射關系,每個倒排清單項包含:詞項,文檔id集合,詞項在文檔中的次數,出現的偏移位置等;
- 倒排檔案:用于存儲所有單詞對應的倒排清單,這裡是存儲反向索引的實體檔案。
通過圖示了解如下:
建立反向索引步驟大緻以下幾步:
- 分詞器處理;
- 單詞處理器,自然語言了解;
- 合成倒排清單,生成索引;
問題思考:
為什麼ES檢索比MySQL快?
MySQL:隻有詞項字典這一層,底層用的是B+樹的資料結構存儲,檢索一個詞項需要若幹次的磁盤随機讀寫;
ES:Lucene在詞項字典的基礎上增加了詞項索引這一層,它以字典樹的資料結構緩存在記憶體,根據詞項索引找到詞項字典中的位置之後,再去磁盤查找詞項,這樣減少了磁盤的随機讀寫次數,大大地提升了檢索性能。圖示了解如下:
搜尋機制
搜尋文檔的步驟:
- 查詢分析;
- 分詞處理;
- 關鍵詞檢索;
- 搜素排序,傳回結果;
示例如下,假設有如下四個文檔:
通過建立反向索引,建立詞項到文檔的映射表:
如果要根據某個關鍵詞查找出對應的文檔,會經曆如下圖示的過程:
圖中從第一象限到第四象限,表示整個的搜尋流程:
- 文檔寫入ES之後,經過分詞、過濾操作後會生成反向索引;
- 使用者發送搜尋請求,背景收到請求會到倒排清單中查詢詞項對應的文檔集合清單;
- 背景經過評分、排序、高亮等處理之後,最終傳回結果給使用者;
分布式更新文檔
更新過程:
- 使用者發送更新請求到Coordinate Node,它根據hash路由算法把請求路由到另一個節點;
- 節點node先執行删除操作,再執行index操作;
- 最後寫入成功之後,發送成功結果給使用者;
分布式删除文檔
删除過程:
- 使用者發送删除請求到Coordinate Node(協調節點),根據hash路由算法把請求路由到主分片節點;
- 把删除副本的請求發送給協調節點,執行删除操作,删除完成之後傳回删除成功給主分片節點;
- 主分片節點把删除成功的結果傳回給協調節點,最後傳回響應結果給使用者;
三、ES學習不止
ES的探究之路目前還隻停留在應用層面,底層原理及源碼層面還涉獵甚少。在官方的版本快速疊代下,弄清楚新版本的改進點及引進的新特性實屬非常有必要,接下來的學習腳步将會繼續下去,不僅僅是ES本身這一項技術,學習其它的技術也是一樣,既然選擇了學習一項技術,就要徹底弄懂它。
四、ES未來的無限可能
随着物聯網5G時代的來臨,大資料的檢索需求也會趨于多元化,更加智能化,在更新的版本中,官方也在其中引入了機器學習子產品,順應了日志監控,安全異常檢測等系統越來越智能化的趨勢。随着ECS的推出,擁抱K8s已成必然,目前提供了叢集的管理和更新,彈性伸縮的能力,更好地支援雲原生,最後,個人很看好Elastic Stack在未來的進一步發展!
道可頓悟,事需漸修!