Solr 15 - Solr添加和更新索引的過程(文檔的路由細節)

来源:https://www.cnblogs.com/shoufeng/archive/2019/03/28/10615693.html
-Advertisement-
Play Games

SolrCloud底層 添加/更新 文檔的過程是怎樣的? 它怎麼確定文檔要發給哪個Shard? 文檔的路由是做什麼的? 有什麼路由策略? 連同一些高效的實踐建議, 統統告訴你~ ...


目錄

1 添加文檔的細節

1.1 註冊觀察者 - watcher

Solr單機服務中, 與Solr內部進行交互的類是HttpSolrServer.
SolrCloud集群中, 與Solr內部進行交互的類是CloudSolrServer.
這裡以SolrCloud集群為例講解添加文檔的相關細節.

當Solr客戶端向CloudSolrServer發送add/update請求時, CloudSolrServer會從ZooKeeper獲取當前SolrCloud的集群狀態,併在ZooKeeper管理的配置文件/clusterstate.json/live_nodes中註冊觀察者watcher, 便於監視ZooKeeper和SolrCloud.

註冊觀察者的好處是:

CloudSolrServer獲得SolrCloud的狀態後, 就能直接把要添加/修改的document發往Solr集群的leader, 從而降低網路轉發上的消耗;
② 註冊watcher有利於添加索引時的負載均衡: 如果有個節點的leader下線了, CloudSolrServer就能立刻感知到, 它就會停止往已下線的leader發送請求.

1.2 文檔的路由 - document route

CloudSolrServer添加document時, 需要確定該document發往哪個Shard. SolrCloud集群中, 每個Shard都有一個Hash區間, 添加時, SolrCloud會計算該文檔的Hash值, 然後根據它的Hash值, 把它發送到對應Hash區間的Shard.

—— 上述過程稱為文檔的分發, 由Solr的document route(文檔路由)組件來完成.

1.2.1 路由演算法

SolrCloud提供了兩種路由演算法, 創建Collection(集合, 類似於MySQL中的表)時, 需要通過router.name來指定路由策略.

① compositeId - 預設的路由演算法:

  • 該策略是一致性哈希路由, Shards的哈希範圍是80000000~7fffffff;
  • 創建Collection的時候必須指定numShards, 這個路由演算法將根據Shard的個數, 計算出每個Shard的哈希範圍;
  • 索引數據會均勻分佈在每個Shard上;
  • 這個路由策略不支持擴展Shard, 否則會導致一些已經索引到Solr中的文檔無法被檢索.

② implicit - 絕對路由策略:

  • 該路由策略是直接指定索引文檔落到具體的某個Shard上;
  • 索引數據並不會均勻分佈到每個Shard上;
  • 使用implicit路由策略的Collection才支持 創建/擴展 Shard.

1.2.2 Solr路由的實現類

Solr中路由的基類是DocRouter, 它有2個子類: CompositeIdRouter(預設使用的), 和ImplicitDocRouter.

我們可以通過繼承DocRouter類來定製自己的document route組件.

1.2.3 implicit路由演算法的使用

  • 通過SolrJ創建文檔索引時, 使用implicit策略指定文檔的所屬Shard:

    代碼如下:

    doc.addField("route", "shard_X");

    同時, 要在schema.xml約束文件中添加欄位:

    <field name="_route_" type="string"/>
  • 利用URL創建implicit路由方式的Collection:

    http://ip:port/solr/admin/collections?action=CREATE&name=coll&router.name=implicit&shards=shard1,shard2,shard3

1.2.4 Solr獲取文檔Hash值的要求

① Hash值的計算速度必須很快, 這是分散式創建索引的第一步;

② Hash值必須能均勻地分佈到每一個Shard上. 如果某個Shard中document數量遠多於其他Shard, 那麼在查詢等操作中, 文檔數量多的Shard所花的時間就會大於其他Shard, 而SolrCloud的查詢是 先分給各個Shard查詢, 然後彙總返回 的過程, 也就是說SolrCloud的查詢速度是由最慢的Shard決定的.

基於以上兩點, Solr的底層引擎Lucene使用了MurmurHash演算法, 用來提高Hash值的計算速度和均勻分佈.

關於MurmurHash哈希演算法, 可參考文末的相關鏈接.


2 添加索引的過程

SolrCloud添加索引的過程

參照上圖, 解析添加索引的過程:

(1) 用戶把要添加的文檔提交給任意一個Replica(副本, 可以是主副本, 也可以是從副本);

(2) 如果接收到請求的Replica不是Leader, 它會把請求轉給同Shard中的Leader;

(3) Leader把文檔路由給本Shard的其他所有Replica;

(III) 如果根據路由規則, 當前文檔並不屬於當前的Shard, 這個Leader就會把它轉交給對應Shard的Leader;

(VI) 對應的Leader會把文檔路由給本Shard的每個Replica, 從而完成添加操作.

註意:

添加索引時, 單個document的路由非常簡單.

但是SolrCloud支持批量添加索引, 也就是說對多個document同時進行路由, 這時SolrCloud會根據document路由的去向分開存放document, 然後併發傳送到相應的Shard, 這就需要SolrCloud具有較高的併發能力.


3 更新索引的過程

(1) Leader接受到update請求後, 先將需要修改的文檔存放到本地的update log, 同時Leader還會對這個文檔分配新的version(版本信息), 對於已經存在的文檔, 如果新版本值大於舊版本值, 就會拋棄舊版本;

(2) 一旦document經過驗證並修改了version後, 就會被並行轉發到所有上線的Replica;

SolrCloud並不關註那些已經下線的Replica, 因為當它們上線之後就會有Recovery恢復進程對它們進行恢復. 如果Replica處於recovering(恢復中)的狀態, 那這個Replica就會把update放入update transaction日誌, 等待恢復完成後再做同步.

(3) 當Leader接受到所有的Replica的成功反饋後, 它才會向客戶端反饋操作成功的信息;

Shard中就算只有一個Replica是active的, Solr都會繼續接受update請求 —— 這個策略犧牲了一致性, 換取了寫入的有效性.

有一個很重要的參數: leaderVoteWait: 只有一個Replica的時候, 這個Replica進入recovering狀態並持續一段時間等待Leader的重新上線. 如果在這段時間內Leader沒有上線, 它就會轉成Leader. 期間可能會導致部分document丟失.

==> 可以借鑒ZooKeeper的選舉策略, 使用majority quorum(大多數法定人數)策略來避免這個情況: 比如當多數Replica下線了, 客戶端的寫請求就會失敗.

(4) 索引的commit(提交)有兩種:

① softcommit(軟提交): 在記憶體中生成segment, 此時document是可見的, 可以供客戶端請求查詢, 但是還沒有寫入磁碟, 系統斷電等故障後數據會丟失;

② hardcommit(硬提交): 直接把記憶體中的數據寫入磁碟, 知道寫入完成才可見.

—— 軟提交的近實時性更強, 硬提交的安全性更高.


4 Solr創建和更新索引的總結

4.1 Leader的轉發規則

(1) 請求來自Leader轉發: 只需要把數據寫到本地的ulog, 不需要轉發給Leader, 也不需要轉發給其它的Replicas. 如果當前Replica處於非活躍狀態, 就會將請求數據接受並寫入ulog, 但不會寫入索引; 如果發現有重覆的更新, 會丟棄舊版本的更新;

(2) 請求不是來自Leader, 但自己就是Leader: 需要把請求寫到本地, 並分發給其他的Replicas;

(3) 請求不是來自Leader, 自己也不是Leader: 該請求應該是最原始的請求, 就需要將請求寫到本地ulog, 順便轉發給Leader, 再由Leader分發給同一個Shard下的Replica.

(4) 每commit一次(生成新的提交點), 就會重新生成一個ulog更新日誌. 當伺服器掛掉、記憶體數據丟失的時候, 數據就可以從ulog中恢復.

4.2 高效實踐的建議

(1) 創建索引的時候最好使用CloudSolrServer: 因為CloudSolrServer會直接向Leader發送update請求, 避免了網路的額外開銷;

(2) 批量添加索引的時候, 建議在客戶端提前做好document的路由, 因為在SolrCloud內進行文檔路由的開銷比較大.

參考資料

SolrCloud之分散式索引及與Zookeeper的集成

SolrCloud 5.0 路由、Collection創建與數據遷移

一致性哈希演算法與Java實現

MurmurHash演算法

版權聲明

作者: ma_shoufeng(馬瘦風)

出處: 博客園 馬瘦風的博客

您的支持是對博主的極大鼓勵, 感謝您的閱讀.

本文版權歸博主所有, 歡迎轉載, 但請保留此段聲明, 併在文章頁面明顯位置給出原文鏈接, 否則博主保留追究相關人員法律責任的權利.


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 第一次在博客園寫博客,寫的不好,請大家多多評論,也希望自己以後對技術探索的更深。 今天下班之後,由於晚上要發版本,所以開發同事必須留下,突然收到一封公司監控預警郵件。 瞄了幾眼,大致的意思就是說 視圖無效。由於視圖查詢的是表,所以開始做實驗測試。 實驗一: 當基表drop列的時候,視圖是否還是有效? ...
  • 本篇博文介紹瞭如何在URL中直接發起HTTP請求, 操作Solr的文檔? 如何通過Solr的Web界面添加、修改、刪除文檔? 還涉及到常見的Solr刪除文檔的方式: URL發起HTTP請求, Solr Web中的document中提交請求. ...
  • Redis 三大特性: Redis 支持數據的持久化,可以將記憶體中的數據保存在磁碟中,重啟的時候可以再次載入進行使用 Redis 不僅支持簡單的 鍵 * 值 類型的數據, 還提供list、set、zset、hash 等數據結構存儲 Redis 支持數據的備份,即master -slave模式的數據備 ...
  • 原理:多個msyql/mariadb之間可以實時同步,任意節點的操作可以立即同步到其他節點,底層採用galera插件同步,類似rsync,上層mysql相對於galera是透明的,可以實現多節點同時讀寫(無法實現讀寫分離)。 NOTE:普通的msyql/mariadb無法集成galera,要想使用g ...
  • zookeeper簡介 1.官網:http://zookeeper.apache.org/ 介紹:Apache ZooKeeper致力於開發和維護開源伺服器,實現高度可靠的分散式協調。 ZooKeeper是一種集中式服務,用於維護配置信息,命名,提供分散式同步和提供組服務。 所有這些類型的服務都以分 ...
  • 創建鏈接伺服器註意事項 當我們要跨本地資料庫,訪問另外一個資料庫表中的數據時,本地資料庫中就必須要創建遠程資料庫的DBLINK,通過DBLINNK資料庫可以像訪問本地資料庫一樣訪問遠程資料庫表中的數據。 鏈接伺服器允許訪問針對OLE DB數據源的分散式異構查詢。創建鏈接伺服器後,可以針對此伺服器運行 ...
  • 我們知道,HBASE在創建表的時候,會自動為表分配一個Region,當一個Region過大達到預設的閾值時(預設10GB大小),HBase中該Region將會進行split,分裂為2個Region,以此類推。表在進行split的時候,會耗費大量的資源,頻繁的分區對HBase的性能有巨大的影響。所以, ...
  • ODI(Oracle Data Integrator)是Oracle公司提供的一種數據集成工具,能高效地實現批量數據的抽取、轉換和載入。ODI可以實現當今大多數的主流關係型資料庫(Oracle、DB2、SQL Server、MySQL、SyBase)的集成。ODI提供了圖形化客戶端和agent(代理... ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...