第七章:druid.io實踐分享之Realtime+kafka 二

本節重點介紹在運行過程中,這兩個組件會出現什麼問題及解決方式
場景如下:
場景1、第一次上線kafka的partition與realtime的個數關係
場景2、kafka數據寫入最優方式
場景3、realtime配置文件在實際過程的變化及重點參數
場景4、segment堆積產生的原因及如何避免
場景5、realtime對JVM的要求
場景6、多個dataSource,大小表拆分,多topic消費

場景一

初次上線要當前的數據量、集羣規模等因素來綜合考慮。基本定律是(以一個topic爲例):
partitions=N*realtimes
partitions表示當前topic的分區數
N表示每臺realtime消費的partition的個數
realtimes表示realtime節點總數

舉例說明:
3個partitions,3臺realtime,那麼N就是1。表示每臺realtime節點消費1個partitions。
6個partitions,3臺realtime,那麼N就是2。表示每臺realtime節點消費2個partitions。
同理都是類似方式計算。
爲撒這樣計算?主要考慮就是均衡,充分利用好每臺realtime節點的資源。

隨着數據量的增加,會碰到當前topic的消費速率變慢的情況,這個時候就會對kafka集羣增加節點或增加kafka節點硬盤或擴展partition個數。
增加節點和增加硬盤都屬於kafka本身的操作,不會影響到realtime這層。但擴展partition個數時,realtime節點在水平擴展的時候,就需要考慮下realtime節點增加的個數(參考上面的公式來算)。

場景二

kafka寫入最優方式是均衡,如果不均衡,會影響到兩個點:

  1. kafka節點有些硬盤會報警並且通過監控平臺會發現有些機器負載高,有些負載低。
  2. 接着帶來就是realtime消費的不均衡,也會導致有些機器負載高,有些負載低。

所以使用新的hash算法(這個調整後一定要進行測試驗證),我們重新開發了分配算法。默認情況下,Kafka根據傳遞消息的key來進行分區的分配,即hash(key) % numPartitions。
但因爲Key的關係默認情況下,寫入各partition數據還是會出現不均衡的。
調整成輪訓方式即可。

場景三

這裏先說的參數重點是指runtime.properties文件裏屬性druid.realtime.specFile所對應的json文件內容。涉及的參數如下:
第一:shardSpec
第二:rejectionPolicy
第三:intermediatePersistPeriod ≤ windowPeriod < segmentGranularity 和 queryGranularity ≤ segmentGranularity

**shardSpec**

默認設置成

"shardSpec": {"type": "none"}

這種情況單機版還可以玩一玩。在多個realtime節點的情況下,這個不能這樣設置了。
現在官方文檔提供:linear and numbered,但在源碼中還提供了另一種SingleDimensionShardSpec,這種使用較少。
這裏可以給大家分享一下,當多個realtime節點時還配置成默認值的效果(這是當初文檔沒有現在這麼詳細導致我們疏忽了),那麼就是當前小時範圍內的數據是跳躍的,簡單的說,就是同一個查詢條件發多次,返回的結果集大小不同,有時候返回30多條,有時候又返回50多條。在當時對初學的人來說很緊張,後面通過源碼分析和大家的努力,終於發現了是這個參數配置失誤導致。
但這個調整是有要求的,就是調整完後,必須對當前時間段realtime所有節點已經存儲的數據要刪除掉,不然查詢的結果還是跳躍的。
舉例說明:
當前時間段是12點-13點(假設segment是按小時進行),我是在12點20分調整此參數,那麼再重啓全部realtime節點之前,必須把12點-13點之間已經持久化的數據要刪除掉,不然調整成linear後,是沒有任何效果的。這個步驟非常重要
另外注意下:
realtime 節點1設置爲:
“partitionNum” : 1
realtime 節點2設置爲:
“partitionNum” : 2
realtime 節點3設置爲:
“partitionNum” : 3
依次類推。
關於numbered和linear的區別很小,主要在查詢上面的限制,大家查看官方文檔再實踐下就知道了。

**rejectionPolicy**

此參數要是不理解,帶來的效果就是丟失數據,會讓你誤認爲系統有bug。
有三個值:serverTime(推薦使用)、messageTime、none。
如果想不丟棄數據就用none,另外一個用系統時間作爲參考,一個用event裏的timestamp作爲參考。如果此參數是none的話,windowPeriod這個參數就沒有什麼效果了。
所以當數據有丟失的時候,首先檢查時間戳和這個參數。也就是檢查數據裏面的timestamp和系統時間是否有較大的誤差。(提醒下:首先要保證json數據格式要能正常解析)

**intermediatePersistPeriod、windowPeriod、segmentGranularity和queryGranularity**

在實際的使用過程中,這幾個參數的關聯關係一定要當心。
首先介紹下intermediatePersistPeriod、windowPeriod、segmentGranularity三個是緊密關聯的,特別windowPeriod這個參數不光控制數據消費延遲,也控制着segment合併持久化。
並且intermediatePersistPeriod參與的邏輯部分和windowPeriod參與的邏輯部分,是兩個線程分開進行的。
舉例說明下:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章