ElasticSearch架構反向思路
作者:豬兒笨笨 來源:雲棲社群
原文連結: https://yq.aliyun.com/articles/617479?spm=a2c4e.11153940.bloghomeflow.526.162d291aRoS8gf
我曾經在多個場合說過,我分析一個系統的設計思路,往往不是一開始就去看看這個系統的設計文件或者原始碼,而是去看系統的基本介紹,特別是框架類的功能詳細介紹,然後根據介紹可以大概瞭解這樣一個系統用來解決什麼問題,有哪些特色,然後基於自己對這些問題的想法,根據自己的經驗來同樣設計一個系統,看包含哪些內容,使用哪些架構模式和思路,然後帶著自己設計的東西再去看另一個系統的設計思路,可能再更加清楚,也會反思自己的設計是否哪些地方存在問題,可以加以改進。
最近正好準備玩ElasticSearch,本來在2013年就想玩這個,但由於工作原因耽誤了,現在又翻出來看看有什麼好玩的,下面就詳細地記錄了我對ElasticSearch的反向架構思考。順便補充一句,目前用來研究的ElasticSearch的版本號是6.3
先來看看一份對ElasticSearch比較典型的介紹:
Elasticsearch是一個基於Apache Lucene(TM)的開源搜尋引擎。無論在開源還是專有領域,Lucene可以被認為是迄今為止最先進、效能最好的、功能最全的搜尋引擎庫。 但是,Lucene只是一個庫。想要使用它,你必須使用Java來作為開發語言並將其直接整合到你的應用中,更糟糕的是,Lucene非常複雜,你需要深入瞭解檢索的相關知識來理解它是如何工作的。 Elasticsearch也使用Java開發並使用Lucene作為其核心來實現所有索引和搜尋的功能,但是它的目的是透過簡單的RESTful API來隱藏Lucene的複雜性,從而讓全文搜尋變得簡單。 不過,Elasticsearch不僅僅是Lucene和全文搜尋,我們還能這樣去描述它: 分散式的實時檔案儲存,每個欄位都被索引並可被搜尋 分散式的實時分析搜尋引擎 可以擴充套件到上百臺伺服器,處理PB級結構化或非結構化資料 而且,所有的這些功能被整合到一個服務裡面,你的應用可以透過簡單的RESTful API、各種語言的客戶端甚至命令列與之互動。 上手Elasticsearch非常容易。它提供了許多合理的預設值,並對初學者隱藏了複雜的搜尋引擎理論。它開箱即用(安裝即可使用),只需很少的學習既可在生產環境中使用。 隨著你對Elasticsearch的理解加深,你可以根據不同的問題領域定製Elasticsearch的高階特性,這一切都是可配置的,並且配置非常靈活。
幸虧以前使用過Lucene做IDE底層專案模型關係的管理,對Lucene還算比較熟悉,否則還得先去看看Lucene的功能和用法。
從上面的介紹可以看出幾個關鍵內容:
-
Lucene在做索引的時候本身就有儲存功能,所以儲存這個東西是天然就有的,反而不用花時間考慮。
-
效能是一個比較關鍵的東西,特別是要做實時引擎,怎麼保證高效能。
-
ElasticSearch是一個分散式的系統,那麼必然存在多結點通訊,協作等問題,比如使用ZooKeeper之類的系統進行註冊和協同,當然也保不齊他自己玩一套。
-
既然是分散式系統,那麼資料儲存就不可能完全單機化,也就是存在Sharding的情況,如何Sharding,如何同步,在查詢結果的時候,如何聚合。
-
分散式系統,只要涉及到資料更新,必然存在資料不一致問題,怎麼解決。
-
由於索引本身原因,一旦出現Sharding,就很難做聯合的查詢,這個應該不能實現的,至少說不可能很簡單得實現。
-
有一個網路層或者說對外服務介面層,用來進行互動,看介紹,支援多種協議,比如Client直接呼叫,或者是Restful風格。
-
參考服務介面層,還允許很多地方進行配置,那麼很顯然,應該是使用了類似於外掛的技術來支援很多功能。
我的習慣是從使用者角度來倒推系統架構
-
對外服務,稱為Interface,這個其實還相對簡單,應該提供兩個基本功能,即BuildIndex(不一定要區分Create和Update,但Delete肯定要有)和Query(應該基於主Key和Condition兩種查詢),把這兩個基本介面設計好,然後在上面加不同的封裝或者透過Netty之類網路架構提供Rest服務,也可能基於Stub類似的機制提供RPC呼叫。
-
查詢功能,是採用SQL還是Query模型的方式,我更傾向於後者,因為關聯查詢等很多功能是無法提供的,SQL校驗會是比較麻煩的事情。
-
不管是BuildIndex還是Query,肯定要找到一臺機器或者多臺機器進行處理,由於這是一個分散式系統,而且還支援Sharding,那麼可以肯定,需要分組,即Group,一個Group中包括若干個Node,用來支援服務。
-
怎麼分組,正常可能是分兩級,一種是基於模型定義的,比如對於某一些資料,象商品,使用者這些資料可能分成一類資料對應一個Group來處理,這種處理比較直觀,也簡單。也就是說每一類模型會對應一個Group,而一個Group可能對著多個模型,特別是資料相對較少的時候。還有一種就是Sharding,通常來說,是對一類資料,根據某一個或者幾個欄位(Field),進行條件分組,也就說在這種分組情況下,每個Node的資料都是不全的,需要將多個Node合併在一起,才會形成完整的資料集。這兩種分組都需要支援的。
-
對於BuildIndex和Query,當系統分成多個Group的時候,肯定要有一個Router的概念,即一個BuildIndex或者Query服務來的時候,得找到相應的Group(應該是Group下的Node),因為Lucene中的Document和Term特性,應該需要設計一個類似於資料庫中的Table模型,一個Group負責處理多個Table。在BuildIndex和Query請求裡,1. 必須帶有Table的準確定義,比如User,Item等。
按照前面的思考,Group是肯定應該存在的,但是每個Group否需要一個MasterNode呢? -
當一個Query請求定義清楚後,會以路由的方式找到一個Group,如果資料量不大的話,一個Group中的Node應該是資料對等的,那麼請求落到任何一個Node上都可以得到相應的結果。如果資料量很大,出現Sharding,就分兩種情況,一種是Query中的條件,能夠符合Sharding的定義條件,那麼落到任何一個Node上以後,透過轉發的方式,總是可以拿到請求,應該有兩種實現方式,一是請求發到某個Node上以後,由Node分析後,將可以導向的Node返回,由請求方再次將指定的Node傳送請求,二是任意Node直接向可以導向的Node轉發請求,並拿到結果後返回給請求方,第二種對客戶端友好,但如果資料量大的話,可能不太合適。還有一種情況就是,如果Query中的條件不能夠符合Sharding定義,那麼就出現類似於資料庫查詢的FullScan,由收到的Node將請求轉發給相應的Node,構成全量搜尋,然後由該Node合併後,返回。如果這樣看,最好的方式還是Node統一處理,對請求方更友好一些,也更一致。
-
當BuildIndex的時候,必然是發給一個Node,由其完成Index後,再同步給其它Node,此時同步,是有一個MasterNode還是沒有好呢?感覺設計一個MasterNode可能使得邏輯更簡單。即大的Group裡,MasterNode主要負責協作和BuildIndex同步,而Query則可以儘可能地落到DataNode側。
-
雖然有了MasterNode,但仍然是可以將BuildIndex請求發給DataNode,由DataNode轉發給MasterNode,這樣會更加簡單和友好。
-
考慮到BuildIndex和Query會有不同步的情況,那麼怎麼減少這種不一致性呢?如果由MasterNode或者指定的一個DataNode進行BuildIndex的時候,對其它Node的Query都會產生資料不一致性問題。假設由MasterNode給其它DataNode全部上鎖,此時查詢效能急速下降,這種方法不是非常建議,容易形成堵塞,不過如果資料很少更新,而且對資料一致性有較高要求,也可以支援,那裡可能得在這個地方允許使用者配置一致性優先還是效能優先了。如果是後者的話,按照我對Lucene的瞭解,此時每個DataNode最好有一個DiskStore和一個MemoryStore,查詢時將兩者合併查詢,這樣在保證高效能的情況下可以減少不一致性。或者更靈活一點,允許在BuildIndex的時候允許指定是否加鎖,但這樣可能會增加複雜度,需要再思考一下。
-
同樣是資料不一致問題,除了上面的內容以外,還需要使用Log,這樣MasterNode先記錄Log,然後進行Index,同時分發給DataNode,DataNode也是先記錄Log,這樣一旦出現問題,可以隨時在啟動時從Log處Redo。
-
維護和管理功能:動態擴容,Reindex(擴容時肯定要用到),啟動時先與多個DataNode同步Log,再根據Log進行Redo,保證資料的一致性。
-
外掛化設計沒什麼難點,不管是類似於OSGi,還是說直接寫一個Plugin的介面,然後加一個PluginManager都可以解決問題。但關鍵是Plugin需要在哪些情況下呼叫,以便讓開發者可以更多的加入自己的定製。我猜可能有以下幾個點:網路請求的Before和After處理(比如支援不同的資料模型,不同的安全檢查等,記錄日誌,流量控制等),啟動後的After處理(比如對Log進行Check,以便Redo),BuildIndex和Query的Before和After處理(其實就可以透過這個擴充套件來處理資料同步的問題)。
-
上面說的外掛化設計並不難,但是否使用統一的Plugin介面,還是分開,需要考慮一下,畢竟可以提供擴充套件點的地方太多了。如果是我設計,大概是三大級繼承,最頂層的有一個Plugin或者Extension的介面,提供Name,Desription,Dependecy等內容的定義,這個和Equinox都類似,其實不帶任何業務支援的,第二層是業務級別的,比如說網路請求的,日誌處理的,第三層就是具體實現了。再多就有點複雜了,有一個最頂層介面的好處是,在Eclipse裡,查下繼承關係,就得到所有實現了,方便分析程式碼,如果只設計二和三層,哈哈,就有得找了。
基於以上分析,可以列出來幾個基本的元素和服務:
-
Node+Group+MasterNode+DataNode
-
Table+Field+Key+Condition
-
BuildIndex+Query
-
Log
-
Plugin
下面是大致的架構域圖:
還有幾個難點,需要再考慮一下:
-
Query可能會有Paging的需要,那麼一旦出現Sharding的話,需要將多個DataNode的結果Merge後,進行Sort,再計算Paging後返回。這個對效能的要求比較高,特別是當頁面翻到幾十頁的時候,效能損失非常大,如何處理?還是說技術層面上不做解決,直接讓業務方來自行規劃。
-
因為ElasticSearch是基於Lucene的,而Lucene並不提供事務操作,比如先行鎖再Update,因此一旦出現衝突時,因為網路延時等原因,有可能後面的資料覆蓋前面的資料,這種情況怎麼考慮,是加一個時間版本號還是忽略這種情況?
-
另外ElasticSearch對資料一致性不可能提供太好的解決方案,因此最好還是將一些非核心業務資料進行查詢,比如日誌,就不會出現修改,再比如電商中的商品表,修改相對並不頻繁,但如果商品表裡包含商品數量,那麼就掛了,所有必須減少將頻繁更新的資料放入搜尋。
-
有點記不清楚Lucene的儲存機制了,是否支援類似於資料庫的Update語句,只更新部分資料。如果不支援,那麼ElasticSearch是否需要支援呢?如果是我,應該不會支援,做太多的事情更容易出錯。
-
當MasterNode當掉,顯然可以透過選舉或者別的方法找到一個新的MasterNode,但如果一個MasterNode或者DataNode收到一個BuildIndex請求後,再當掉,最好是通知Client失敗,由Client發起重試。由於所有BuildIndex請求都是發給MasterNode來處理的,那麼就相對簡單了,如果MasterNode失敗後重新加入Group,由於此時它不再是Master,就可以丟棄這個日誌,保證資料一致性。這塊的細節會比較多,記錄Log,然後如何Redo,如何Sync,如何拋棄,都需要深入分析。不在這裡折騰了。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31473948/viewspace-2168506/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- elasticsearch(4)- 架構概念Elasticsearch架構
- 元件化 構架思路元件化
- 資訊架構的設計思路 .架構
- ElasticSearch實戰系列十: ElasticSearch冷熱分離架構Elasticsearch架構
- 剖析ElasticSearch基礎分散式架構Elasticsearch分散式架構
- 分散式系統的架構思路分散式架構
- 系統架構效能優化思路架構優化
- 高效能伺服器架構思路,不僅是思路伺服器架構
- 滴滴 Elasticsearch 多叢集架構實踐Elasticsearch架構
- 架構 秒殺系統優化思路架構優化
- 秒殺系統架構優化思路架構優化
- 高效能伺服器架構思路伺服器架構
- 分散式搜尋引擎Elasticsearch的架構分析分散式Elasticsearch架構
- 分析阿里前端-自動化架構思路-react阿里前端架構React
- 大型 SaaS 平臺產品架構設計思路架構
- 阿里P8級架構師淺析秒殺架構設計實踐思路阿里架構
- 從Elasticsearch來看分散式系統架構設計Elasticsearch分散式架構
- 分散式重複提交問題架構設計思路分散式架構
- 億級流量架構之服務限流思路與方法架構
- 【思路】混合雲與多雲管理進入架構時代!架構
- 記一次引入Elasticsearch的系統架構實戰Elasticsearch架構
- Django ElasticSearch Ionic 打造 GIS 移動應用 —— 架構設計DjangoElasticsearch架構
- 億級流量架構之分散式事務思路及方法架構分散式
- 億級流量架構之資源隔離思路與方法架構
- 億級流量架構之服務降級思路與方法架構
- 網上商城架構設計之表設計思路(三)架構
- 圖解Nginx,系統架構演變 + Nginx反向代理與負載均衡圖解Nginx架構負載
- HBase+Elasticsearch,百億級資料中心架構設計實踐Elasticsearch架構
- Elasticsearch基礎結構Elasticsearch
- 如何構建千萬使用者級別後臺資料庫架構設計的思路資料庫架構
- 億級流量架構之伺服器擴容思路及問題分析架構伺服器
- MVP+Dagger2設計,MVP架構模式實現新思路 (Demo)MVP架構模式
- 架構之:serverless架構架構Server
- PB級資料實時查詢,滴滴Elasticsearch多叢集架構實踐Elasticsearch架構
- ELK系統設計:Elasticsearch+logstash + Kibana+Grafana技術架構ElasticsearchGrafana架構
- SaaS架構:流程架構分析架構
- 四個典型的車聯網案例,給你資料架構升級思路架構
- 淺談12306 核心模型設計思路和架構設計模型架構