0%

[從零開始做水平擴展] 3.討論與提案-2

承上一篇,在測試完 mongo 與 redis 後,這篇要來討論的是如何將 worker 做水平擴展

需求與限制:

  1. 動態擴展:

    由於 iot 的使用情境很多變,上傳的資料量在一天的不同時候差異很大,希望能透過 k8s 內建的擴展機制,自動根據 cpu、memory、net worker traffic 擴展 worker instance 數量

  2. 不處理重複資料:

    worker 應該透過某種分配機制,讓設備上傳的資料分配到有空的 worker 去做,而不是兩個 worker 拿到一樣的資料去處理造成性能浪費

  3. 資料順序性:

    由於 archiver 計算 recording data 時,需要資料按照資料時間依序傳給 archiver 計算,所以 worker 產出的資料須確保資料順序性

提案:

  1. Load balancer:

    Untitled (3)

    透過一個 load balancer 去訂閱設備上傳上來的消息,之後根據 device id % worker instance 數量來分配資料給 worker

    優點:

    1. worker 收到的訊息有順序性

    缺點:

    1. load balancer 不能 scale
    2. worker 死掉 or 新開 worker 後,topic 內殘存資料應該如何分配
  2. Delayed queue:

    Untitled (4)

    使用 amqp 競爭消費的特性,讓 worker 自動根據自身處理能力去 rabbitmq 中爭搶訊息來處理,但由於不同 worker 處理速度快慢,處理完的資料可能順序會錯亂,所以需要透過第二層的 delayed queue 去將資料排序後再傳給 archiver 計算

    優點:

    1. worker scale 起來方便,不需維護狀態

    缺點:

    1. 為了排序,須將資料留在 Delayed Queue 中一段時間,可能會有延遲問題
    2. worker 死掉 or 新開 worker 後,topic 內殘存資料應該如何分配
  3. Save to db then query:

    Untitled (5)

    worker 一樣去搶消息,處理完資料後直接塞到 mongodb,archiver 改成過一段時間去 mongodb 撈資料出來算,算完再存回去

    另外 mongo db 要開 replica set 做讀寫分離減低 mongo 壓力

    優點:

    1. worker scale 方便,不用維護狀態
    2. archiver scale 方便

    缺點:

    1. mongo 壓力很大

取捨:

load balancer 方案因為不好 scale 以及 worker instance 數量增加/減少時需要處理的事情很多,因此先 pass

save to db then query 雖然整體架構最簡單,但在之前使用經驗中,問題常常都是因為 mongodb 的速度太慢導致,現在如果還要加上讓 archiver 去 mongo 拿資料,怕負擔會更重

於是折衷選了 delay queue 方案,讓 worker 去搶消息,之後在 delay queue 中停留一段時間排序後再給 archiver 處理