solr6.2源碼解析


最近一直有研究solr源碼,所以也做一個分享吧,網(wǎng)上的話對SolrCloud的分享比較少,后續(xù)會對SolrCloud的分布式特性做一個介紹,如果有時間的話。由于沒有牽扯到代碼,所以只是流程上的分析。后續(xù)如果有時間的話,再對代碼做一個詳細的解釋。請多多指出批評意見。

1. 首先是solrcloud的結(jié)構(gòu)

這個在網(wǎng)上差不多都能找到相應的分析,基本就是這個概念,沒有更多新的東西。

圖1 Solrcloud的基本結(jié)構(gòu)

  圖中就是一個collection基本結(jié)構(gòu)的展示。虛線的部分可以理解為一個邏輯結(jié)構(gòu),實線部分就是一個物理結(jié)構(gòu),一個SolrServer就是一個完整的solr結(jié)構(gòu),可以進行單獨的運行,在cloud的邏輯中使結(jié)合zk的使用,實現(xiàn)一個分布式的功能,其中比較重要的一點就是OverSeer的結(jié)構(gòu),后續(xù)會進行詳細說明。根據(jù)概念可以知道,一個shard只保存一份數(shù)據(jù),leader和replica之間進行數(shù)據(jù)的同步(PeerSync以及Replication,后續(xù)也會進行說明),存儲的數(shù)據(jù)是相同的。

2. colction級別的一個請求下發(fā)?

  請求下發(fā)的時候,就要用到OverSeer這個關鍵的概念了,因為每個SolrServer都是一個完整的solr代碼在運行,那么既然有cloud的特性就一定需要,單個節(jié)點的相互協(xié)調(diào),Overseer就起到了這個這作用。


圖2 Solrcloud請求下發(fā)

  簡單做一下解釋,就是cloud的單個節(jié)點啟動的時候,各個節(jié)點的OverSeer會在zk進行注冊,然后需要選出leader做集中做分布式系統(tǒng)的消息處理。代碼中使有一個while循環(huán),一直等待著分布式隊列的數(shù)據(jù)輸入。一旦有節(jié)點的插入就開始處理相關數(shù)據(jù),圖中是以reload的請求為例。

3. 索引添加流程

  索引添加的時候,需要考慮的幾個重要的問題。

  1、各個replica之間的數(shù)據(jù)同步問題

  2、分布式請求轉(zhuǎn)發(fā)的問題

  3、為了保證數(shù)據(jù)的安全性,日志如何處理


  下面對問題進行簡單的分析,此部分的分布式請求和solr查詢的流程類似,所以在查詢流程上詳細展開。

  1、添加索引時會進行TranssactionLog的持久化寫入,出現(xiàn)意外情況的時候可進行恢復。

  2、tlog通過一個version信息進行標示,為主節(jié)點寫入數(shù)據(jù)的時間戳,再轉(zhuǎn)發(fā)給子節(jié)點。

  3、如果是replica節(jié)點接收到數(shù)據(jù)會轉(zhuǎn)發(fā)給Leader節(jié)點進行處理。

  4、leader節(jié)點接收到數(shù)據(jù)會轉(zhuǎn)發(fā)給相應的replica。

  5、solr內(nèi)部使用hash算法保證index的平均分配,所以轉(zhuǎn)發(fā)時只轉(zhuǎn)發(fā)給目標shard。

4. 索引查詢流程

  查詢流程在分布式的思維上與添加流程類似。SolrCloud提供的就是一個分布式的結(jié)構(gòu),所以solr的整體框架很大程度上就是提供一個分布式的完整性的實現(xiàn)。

  分布式節(jié)點:

  1、分布式節(jié)點流程上只處理,分布式請求的下發(fā)和數(shù)據(jù)的匯總。

  2、請求的下發(fā)不是特定發(fā)往leader節(jié)點而是通過一個LB進行分發(fā),因為一個shard的所有節(jié)點都保存相同的數(shù)據(jù)。

  3、分布式的流程上分為四個階段,第三個階段負責數(shù)據(jù)的查詢,向下發(fā)送查詢請求。如果row為默認的10,也就是在每個shard查詢10條數(shù)據(jù),然后分布式節(jié)點會根據(jù)返回的score進行合并成最終的10個id,這個階段獲去到的數(shù)據(jù)只有一個id和score,不包含其它屬性的數(shù)據(jù)。然后進行第四個節(jié)點的RETURN_FIELDS的請求下發(fā),這次會將對應的*ids*發(fā)送,只查詢這些id對應的所有數(shù)據(jù)。

  4、writeResponse再對第四個階段返回的數(shù)據(jù),根據(jù)wt的類別寫入到最終的response中,進行返回。

  本地節(jié)點:

  1、第一次接收到的請求是查詢符合條件的doc,QueryComponent的process方法中進行處理。返回的數(shù)據(jù)是DocListAndSet,只包含id和score。再經(jīng)過writeResponse方法構(gòu)造最終的response,以javabin的形式進行返回。

  2、第二次請求的時候,請求參數(shù)中有ids這個屬性,在process處理之后,也只是一個DocListAndSet。wirteResponse階段會對docList進行遍歷,*關注一下DocStream類的next方法,會對id再進行一次查詢*,這次才生成最終返回的SolrDocumentList,包含了所有的數(shù)據(jù)信息。不是很明白為什么不在查詢的時候直接返回,而是在writeResponse的時候再一次查詢,但是代碼流程就是這樣。最終的返回值就以javabin的形式寫入到response,交給分布式節(jié)點進行處理。

  3、總結(jié)一下,本地節(jié)點是要進行兩次查詢。

5. 添加replica流程

  添加replica目的就是創(chuàng)建一個core備份,重點還是在數(shù)據(jù)恢復上。

  1、PeerSync流程主要是用于leader節(jié)點數(shù)據(jù)不多的情況,進行數(shù)據(jù)的恢復,依靠日志就可以進行恢復。

  2、如果數(shù)據(jù)較多的情況下,就直接進行Replication操作,這部分的邏輯上還是有點復雜的??梢躁P注一下ReplicationHandler的http請求處理方式。這里面包含了獲取待同步的文件列表,獲取version信息等等的請求回復處理流程。

  3、如果在recoverying的時候還有數(shù)據(jù)的添加操作,replication結(jié)束之后還會進行tlog的replay操作,將恢復時未寫入的這部分數(shù)據(jù)進行寫入。

  4、創(chuàng)建core的流程就是走一個分布式的請求,重點還是在數(shù)據(jù)恢復上。當然還有一些其他的選舉操作等等。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容