0%

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

問題拆解:

經過幾天的討論,我們整理出了幾個需要先確認的問題

  1. 將 raw data 依照 device id 做 partition 存放在不同的 collection 裡面對於寫入 mongo 速度有多大提升
  2. 將 device config 先存放到 redis,worker 改從 redis 找到 device config 不從 postgres 中拿出來放到 memory,這樣子速度有沒有問題
  3. worker 水平擴展方式

MongoDB raw data partition:

為了得知 partition 對寫入速度的提升,我寫了一隻測試程式,先將 raw data 依照 device id % 32 後存放到 32 個 collection 中,測試 2000 個設備,每個設備 250 個點,每 30 秒一筆資料,得出的結果如下:

collection 空的:16 sec 將 500,000 筆資料寫入完成

持續寫入 9 hr 後:22 sec 將 500,000 筆資料寫入完成

持續寫入 24 hr 後:26 sec 將 500,000 筆資料寫入完成

一個的寫入容量:

  • storage size (compressed):730.9 MB
  • data size:3.9 GB

所有 collection 的儲存容量:32 * 730.9 MB = 22.84 GB / Day

測試結果的確對寫入速度有提升,從原本 100 ~ 200 秒縮減到在 30 秒內就能寫入完畢

從 Redis 讀取 device config:

設備上傳資料時,在 rabbitmq 的 topic 中會有設備的 id (mac address or scada id),我們會先另外用一隻微服務將存在 postgres 的 device config 寫到 redis,並用設備的 id 當作 key,這樣設備資料上來後,透過 topic 中的 id 就可以找到這個設備的 config

測試方式一樣是模擬 2000 個設備,每個設備 250 個點

測試結果:

  1. 一個一個 tag 拿 (only read):
    1. 拿 2000 個 device: 0.864 secon
    2. 拿 2000*250 個 tag: 166 second
  2. 250 個 tag 一起拿 (用 redis pipe) (only read):
    1. 拿 2000 個 device: 0.694 second
    2. 拿 2000*250 個 tag: 8.5 second
  3. 250 個 tag 一起拿 (用 redis pipe) (read & write):
    1. 拿 2000 個 device: 0.803 second
    2. 拿 2000*250 個 tag: 9.396 second

速度也還可以接受