廣告倒排索引架構與優化

倒排索引架構

在廣告系統中倒排索引發着相當重要的做用,當請求過來時,須要根據定向信息從倒排索引中匹配合適的廣告。咱們的倒排索引採用的是ElasticSearch(後面簡稱ES),考慮點是社區活躍,相關採集、可視化、監控以及報警等組件比較完善,同時ES基於java開發,因此調優和二次開發相對方便java

先看下咱們的倒排索引的架構圖node

file

這個架構設計成如上圖這樣,通過了下面的思考與迭代算法

索引問題與優化

單點與穩定性問題數據庫

採用多節點部署架構

其中 A builder和 B builder都是兩個節點,一個主和一個備,他們經過爭搶鎖(用zookeeper實現)來決定誰是主性能

多個節點會帶來數據不一致問題優化

  1. 多生產者多消費者產生消息時序問題ui

    把消息設置成無狀態的線程

file

查詢數據庫獲取最新數據(訂單和創意更新頻率低,因此對數據庫壓力不大)架構設計

  1. 由於出異常致使數據不一致

    採用重試(冪等)和定時任務處理異常

  2. 全量更新索引,影響線上索引查詢功能

    採用主備索引

    主備索引切換流程:更新備用索引->驗證備用索引->主備切換->更新主索引

    file

索引查詢與重建索引問題與優化

壓測ES QPS不高、CPU負載高、YGC頻繁、索引重建索引耗時長

咱們分別從查詢和重建兩個方向來看

查詢

  1. 1s一次YGC,STW約10ms,對低延遲系統影響較大

    調整 -Xmn 3g->7g,調整後10s一次YGC,STW約12ms

    調整前YGC頻繁,對低延遲系統影響較大,因此想增大YGC的時間間隔,下降性能抖動,考慮到YGC採用複製算法,每次垃圾回收時間主要包括掃描年輕代存活對象和複製存活對象,掃描對象的成本遠低於複製對象,因此YGC的時間主要取決於存活對象的數量,在對象生命週期沒有較大變化的狀況下,YGC的時間天然不會有較大變化

    調整後,YGC的時間間隔有了很大改善,GC時間並無線性增長

  2. 調整分片數和副本數,減小線程損耗、較少IO

    ES默認分片數是5,默認條件下,索引會被分配到不一樣的節點,這樣每一個節點只有部分索引,會致使一次請求須要合併多個節點的數據,IO數多

    如圖所示,假設有3個節點,2個主分片,每一個分片有一個副本。當一次查詢過來的時候

    查詢流程大體爲:首先是node3收到請求,它可能會把請求轉發到node2的R0或node1的P0,而後完成檢索後把數據聚集到node3,最後返回。其中每一個索引的內部,數據會保存到多個segment中,而對segment的查詢是串行的

file

而咱們的場景是請求量大,索引小(100M之內),因此把主分片調整爲1,副本調整爲節點數-1,這樣能保證每一個節點都存儲全部索引,這樣只會有一次io操做,以下圖所示

file

  1. ES(lucencu) 串行讀取全部segment

    索引更新會使segment數量增長,es對segment的查詢是串行的,因此咱們採用每分鐘定時用 _forcemerge將segment降爲1

  2. 熱點方法排查發現JSON反序列化佔50%cpu

    禁用source只採用field存儲必要字段

  3. 指定查詢偏向本機節點

    設置preference:_local

重建

  1. 全量重建前關閉從分片,禁用實時索引

    replicas:0 refresh_interval:-1

    減小索引在重建過程當中索引同步帶來的消耗

  2. 批量重建索引

    使用 bulk批量重建索引,提升建索引的性能

後記

咱們採用的方案,有些並不符合業界經常使用和推薦的方式,可是符合咱們本身的業務,因此方案必定要適合本身團隊的業務,沒有最好的方案,只有更適合的方案

相關文章
相關標籤/搜索