利用redis實現elasticsearch入庫去重


			<div class="entry-content">
		<h1></h1>

背景

公司有一個業務場景,數據庫的修改需要同步到Elasticsearch里,但是該場景的修改頻率有點高,經常會出現一條記錄短時間內多次的變化,如果每次變化都作為一次ES同步任務,那ES肯定是受不住的。

思路

通過估算請求規模,主要有如下2方面的解決思路:

  • 高頻變化去重:因為同一條記錄短時間內多次變化,其實同步一次最終的狀態即可,所以可以考慮犧牲一定的實時性,在一定時間窗口內做變化通知的去重。
  • 批量導入:每條記錄變化作為獨立請求推送給ES,實際上遠不如多條記錄批量推送ES的吞吐要高。

方案

  • 在線去重:因為在線業務本身是高頻的,所以需要一個高頻的存儲介質來實現去重,想到redis的set/zset數據結構。
  • 離線批量:利用離線JOB定時的將一段時間內去重的變動集合推送給ES,其核心問題在於在線set集合如何離線化,保證互不影響。

 

整體架構如下:

 

假設變動的是用戶的積分等高頻資產信息,那么在線部分一旦數據庫發生變動,則將用戶uid向zset_w在線集合寫入,可以實現實時去重。

離線JOB則首先檢查zset_r離線集合是否有剩余變動任務未處理,若zset_r集合為空則執行redis的rename操作將在線集合zset_w重命名為zset_r,這個過程對redis來說是原子性的。

此后離線JOB繼續處理zset_r中已經去重的變化uid集合,而在線部分繼續向新的zset_w集合添加最新變動的uid即可,如此往復。

優化

隨着在線高頻變更量的增多,該方案可以實施橫向擴展,即准備N對(zset_w、zset_r)並令在線部分按uid打散流量,從而可以為每一對zset啟動獨立的離線JOB,實現並行處理。

鑒於在線部分操作redis異常導致通知丟失,可以通過長周期的全庫離線補償實現,在此不做說明。

結論

該業務場景的思想本質包含了2點:

  • 流式轉批量 換取更高的吞吐。
  • 大問題拆小 實現橫向的擴展。

總是思考是否有更簡單的方案,做到簡單可依賴。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM