跳轉至

部署和維護 / 架構、擴容與限制資源

本文主要介紹 DataFlux Func 的整體架構,以及如何進行擴容來提高處理能力。

1. 架構

在系統內部,是典型的「生產者 -> 消費者」模型。任何一次 Python 函數的執行,都會經過「生成任務 -> 入隊 -> 出隊 -> 執行 -> 返回結果」的流程。

任何 Python 函數,實際都會先包裝成「任務」進入其所屬的「工作隊列」(從 #0 開始編號),之後由對應的「工作單元」(從 worker-0 開始編號)從隊列取出後執行。

flowchart TB
    USER[用户]
    FUNC_SERVER[Func Server 服務]
    REDIS_QUEUE_N[Redis 隊列 #N]
    FUNC_WORKER_N[Func Worker-N 服務]
    FUNC_BEAT[Func Beat 服務]

    USER --HTTP 請求--> FUNC_SERVER

    FUNC_SERVER --函數執行任務入隊--> REDIS_QUEUE_N

    REDIS_QUEUE_N --函數執行任務出隊--> FUNC_WORKER_N

    FUNC_BEAT --"函數執行任務入隊
    (定時任務)"--> REDIS_QUEUE_N

1.1 服務及其用途

DataFlux Func 包含多個服務,每個服務都有其不同的職責,具體服務如下:

服務 用途
server Web 服務,提供如下功能:
1. Web 界面
2. API 接口
3. 維護訂閲器
worker-{隊列序號} 工作單元,用於執行用户腳本,包括:
1. 函數 API
2. 函數 API
3. 定時任務
同時也會處理一些系統級後台任務
具體見隊列説明
beat 定時任務的觸發器
mysql 數據庫
redis 緩存 / 函數執行任務隊列

1.2 工作單元與隊列監聽關係

對於服務 worker-{隊列序號}(工作單元),每個 Worker 服務都僅監聽特定的若干個隊列:

隊列與工作單元之間不必一一對應

隊列與工作單元並不是必須一一對應,如:工作單元 worker-0 並非只能監聽隊列 #0 的任務,每個工作單元都可以監聽任意一個或多個隊列

並且,同一個隊列也可以被多個工作單元同時監聽,也可以不被監聽(不推薦)

獨立部署 Func 與 數據平台附屬 Func 的隊列不同

由於大部分獨立部署 Func 都是較為輕度使用,為了減少不必要的資源消耗,獨立部署 Func 的工作單元數量小於隊列數量

相反,數據平台附屬 Func 由於承接監控器、消息發送模塊(Message Desk)等重度業務,工作單元與隊列一一對應,且比獨立部署 Func 存在更多編號的工作單元和隊列

工作單元 隊列
獨立部署
隊列
數據平台附屬
worker-0 #0, #4, #7, #8, #9 #0
worker-1 #1 #1
worker-2 #2 #2
worker-3 #3 #3
worker-4 - #4
worker-5 #5 #5
worker-6 #6 #6
worker-7 - #7
worker-8 - #8
worker-9 - #9
worker-10 - #10
worker-11 - #11
worker-12 - #12
worker-13 - #13
worker-14 - #14
worker-15 - #15
工作單元 隊列
獨立部署
隊列
數據平台附屬
worker-0 #0, #4, #7, #8, #9 #0
worker-1 #1 #1
worker-2 #2 #2
worker-3 #3 #3
worker-4 - #4
worker-5 #5 #5
worker-6 #6 #6
worker-7 - #7
worker-8 - #8
worker-9 - #9
工作單元 隊列
worker-0 #0
worker-1-6 #1, #2, #3, #4, #5, #6
worker-7 #7
worker-8-9 #8, #9

2. 服務 / 隊列及其職責與擴容建議

擴容需要更多硬件投入

擴容需要所在服務器提供更高的性能要求,包括且不限於服務器本身、數據庫服務、Redis 等

一般來説,對 DataFlux Func 的擴容實際只需要增加對應服務的副本數即可,因此,用於應當首先了解自己實際業務情況,以便針對性地進行擴容。

完整的服務、隊列及其職責、擴容建議如下:

服務 / 隊列 職責
獨立部署
職責
數據平台附屬
默認 Pod 數量
數據平台附屬
擴容建議
server Web 服務,提供如下功能:
1. Web 界面
2. API 接口
3. 維護訂閲器
← 同左 1 一般不需要擴容
server-inner (無此服務) Web 服務,專供在集羣內部調用 API 1 一般不需要擴容
worker-0
隊列 #0
系統工作單元,不直接參與用户代碼的處理 ← 同左 2 一般不需要擴容
worker-1
隊列 #1
執行來自同步執行的函數 API的函數任務 ← 同左 1 需要提高同步執行的函數 API 併發量時可擴容
worker-2
隊列 #2
執行來自定時任務的函數任務 ← 同左 1 需要提高定時任務併發量時可擴容
worker-3
隊列 #3
執行來自異步執行的函數 API的函數任務 ← 同左 1 需要提高異步執行的函數 API 併發量時可擴容
worker-4
隊列 #4
(預留) (預留) 0 不需要擴容
worker-5
隊列 #5
調試代碼執行
即在 Web 界面直接運行函數
← 同左 1 需要支持更多用户同時開發腳本時擴容
worker-6
隊列 #6
執行來自連接器訂閲消息處理的函數任務 ← 同左 1 需要提高連接器訂閲消息處理併發量時可擴容
worker-7
隊列 #7
(預留) 執行數據平台系統業務的函數任務
如:通過數據平台後台管理員登錄、更新各類緩存、釋放消息聚合池等
2 監控器總數量較多時擴容
worker-8
隊列 #8
(預留) 執行數據平台閾值檢測等普通監控器、指標生成等相關的函數任務 5 當普通監控器數量較多時擴容
worker-9
隊列 #9
(預留) 執行數據平台高級檢測、智能監控的函數任務 3 當普通高級檢測、智能監控器數量較多時擴容
worker-10
隊列 #10
(無此服務) 執行數據平台接收用户上報事件的函數任務 1 當用户上報事件量較大時擴容
worker-11
隊列 #11
(無此服務) 執行 Message Desk 消息發送任務 3 當消息發送量較大時擴容
worker-12
隊列 #12
(無此服務) (預留) 0 不需要擴容
worker-13
隊列 #13
(無此服務) (預留) 0 不需要擴容
worker-14
隊列 #14
(無此服務) 執行需要立即響應用户操作的 AI 相關處理
如:調用「自動編寫 Pipeline」等
2 當需要支持更多用户同時編寫 Pipleline 人數較多時擴容
worker-15
隊列 #15
(無此服務) 執行需要立即響應用户操作的 AI 相關處理
如:調用「告警壓縮合並」的處理等
2 當使用 AI 聚合告警的監控器較多時擴容
beat 定時任務的觸發器 ← 同左 1 不得擴容,保證全局單副本
mysql 數據庫 (無此服務) - 不需要擴容,有更高需求可選擇自建或雲服務
redis 緩存 / 函數執行任務隊列 (無此服務) - 不需要擴容,有更高需求可選擇自建或雲服務
服務 / 隊列 職責
獨立部署
職責
數據平台附屬
擴容建議
server Web 服務,提供如下功能:
1. Web 界面
2. API 接口
3. 維護訂閲器
← 同左 一般不需要擴容
server-inner (無此服務) Web 服務,專供在集羣內部調用 API 一般不需要擴容
worker-0
隊列 #0
系統工作單元,不直接參與用户代碼的處理 ← 同左 一般不需要擴容
worker-1
隊列 #1
執行來自同步執行的函數 API的函數任務 ← 同左 需要提高同步執行的函數 API併發量時可擴容
worker-2
隊列 #2
執行來自定時任務的函數任務 ← 同左 需要提高定時任務併發量時可擴容
worker-3
隊列 #3
執行來自異步執行的函數 API的函數任務 ← 同左 需要提高異步執行的函數 API併發量時可擴容
worker-4
隊列 #4
(預留) (預留) 不需要擴容
worker-5
隊列 #5
調試代碼執行
即在 Web 界面直接運行函數
← 同左 需要支持更多用户同時開發腳本時擴容
worker-6
隊列 #6
執行來自連接器訂閲消息處理的函數任務 ← 同左 需要提高連接器訂閲消息處理併發量時可擴容
worker-7
隊列 #7
(預留) 執行數據平台系統業務、消息發送的函數任務
如:通過數據平台後台管理員登錄、更新各類緩存、釋放消息聚合池、Message Desk 消息發送
當消息發送量大時擴容
worker-8
隊列 #8
(預留) 執行數據平台閾值檢測等普通監控器相關的函數任務 當普通監控器數量較多時擴容
worker-9
隊列 #9
(預留) 執行數據平台高級檢測、智能監控的函數任務 當普通高級檢測、智能監控器數量較多時擴容
beat 定時任務的觸發器 ← 同左 不得擴容,保證全局單副本
mysql 數據庫 (無此服務) 不需要擴容,有更高需求可選擇自建或雲服務
redis 緩存 / 函數執行任務隊列 (無此服務) 不需要擴容,有更高需求可選擇自建或雲服務
服務 職責 擴容建議
server Web 服務,提供如下功能:
1. Web 界面
2. API 接口
3. 維護訂閲器
一般不需要擴容
worker-0
隊列 #0
系統工作單元,不直接參與用户代碼的處理 一般不需要擴容
worker-1-6
隊列 #1、#2、#3、#4、#5、#6
默認情況下,負責函數同步調用處理,如:
1. 同步執行的函數 API
2. 訂閲消息處理
需要提高同步執行的函數 API、訂閲消息處理併發數時可擴容
worker-7
隊列 #7
默認情況下,負責調試代碼處理(即在 Web 界面直接運行函數) 需要支持更多用户同時開發腳本時擴容
worker-8-9
隊列 #8、#9
默認情況下,負責函數異步調用處理,如:
1. 異步執行的函數 API
2. 定時任務
需要提高定時任務、異步執行的函數 API處理併發數時擴容
beat 定時任務的觸發器 不得擴容,保證全局單副本
mysql 數據庫 不需要擴容,有更高需求可選擇自建或雲服務
redis 緩存 / 函數執行任務隊列 不需要擴容,有更高需求可選擇自建或雲服務

示例:當需要增強定時任務的處理能力時...

由上文可知,定時任務位於「隊列 #8」,「隊列 #8」對應「服務 worker-8」,因此擴容「服務 worker-8」即可

估算擴容量

以常見的 worker-8 為例:

worker-8 在數據平台附屬版中主要負責執行監控器任務。假設一次檢測任務需要 T 毫秒,那麼 1 分鐘可以執行 60 × 1,000 ÷ T 次檢測。默認情況下,worker-8 每個 Pod 開啓 5 進程。

即單個 worker-8 Pod 的檢測能力為 5 × (60 × 1,000 ÷ T) 個監控器。

公式

Text Only
1
2
A = 5 × (60 × 1,000 ÷ T)
  = 300,000 ÷ T

A:檢測能力

T:檢測任務執行耗時(毫秒)

根據監控器每次執行時長不同,可以列出下面的表格:

單次檢測耗時 單個 Pod 檢測能力 相較於基準
300 1,000 167%
500 600 基準
800 375 63%
1,000 300 50%
2,000 150 25%
3,000 100 17%

反過來,假設一致監控器總數為 M,那麼,所需的 Pod 數量則可以根據 M ÷ (5 × (60 × 1,000 ÷ T)) 得出。

公式

Text Only
1
2
P = M ÷ (300,000 ÷ T)
  = M × T ÷ 300,000

P:所需 Pod 數量

M: 監控器數量

T:檢測任務執行耗時(毫秒)

根據監控器數量、每次執行時長不同,可以列出下面的表格:

監控器數量 單次檢測耗時 所需 Pod 數量 相較於基準
1,000 300 1 50%
1,000 500 2 基準
1,000 800 3 150%
1,000 1,000 4 200%
1,000 2,000 7 350%
1,000 3,000 10 500%
監控器數量 單次檢測耗時 所需 Pod 數量 相較於基準
5,000 300 5 56%
5,000 500 9 基準
5,000 800 14 156%
5,000 1,000 17 189%
5,000 2,000 34 378%
5,000 3,000 50 556%
監控器數量 單次檢測耗時 所需 Pod 數量 相較於基準
10,000 300 10 59%
10,000 500 17 基準
10,000 800 27 159%
10,000 1,000 34 200%
10,000 2,000 67 394%
10,000 3,000 100 588%

操作方法

單機部署的 DataFlux Func 可以通過修改配置({安裝目錄}/docker-stack.yaml),增加對應服務的 deploy.replicas 實現擴容。

請參考官方文檔

有關 deploy.replicas 選項的完整信息,請參考 Docker 官方文檔:Docker Documentation / Compose file deploy reference / replicas

以提升 worker-8 處理能力為例,具體修改部分如下:

示例僅為節選

示例僅展示關鍵修改部分,實際操作時請注意配置完整

docker-stack.yaml 關鍵修改部分
1
2
3
4
5
services:
  worker-8:
    deploy:
      # 同時啓動 2 個處理隊列 8 的工作單元
      replicas: 2

3. 限制資源

限制資源需要根據實際業務合理調整

請根據實際業務合理調整資源限制

一味限制資源,可能會導致任務執行變長,或內存不足無法完成代碼的執行

操作方法

單機部署的 DataFlux Func 可以通過修改配置({安裝目錄}/docker-stack.yaml),增加對應服務的 deploy.resources 實現限制資源。

請參考官方文檔

有關 deploy.resources 選項的完整信息,請參考 Docker 官方文檔:Docker Documentation / Compose file deploy reference / resources

默認情況下,每個 worker-N 副本最多會佔滿 5 個 CPU 核心(即每個工作單元中,有 5 個工作進程)。

以限制 worker-8佔用資源為例,具體修改部分如下:

示例僅為節選

示例僅展示關鍵修改部分,實際操作時請注意配置完整

docker-stack.yaml 關鍵修改部分
1
2
3
4
5
6
7
services:
  worker-8:
    deploy:
      resources:
        limits:
          cpus  : '2.50' # 限制 CPU 最多使用 2.5 個核心
          memory: 4G     # 限制內存 最多使用 4 GB

4. 拆分工作單元

新版中所有工作單元已經拆分

在獨立部署 Func 3.2.0 及以後版本中,默認已經拆分了所有非預留的工作單元,用户可以根據需要啓用預留的隊列

在數據平台附屬 Func 1.77.145 及以後版本中,默認已經拆分了所有工作單元,不再需要用户自行拆分

特殊情況下,可以將默認合併的工作單元(如:worker-1-6)進行拆分,實現更細粒度的任務調度,實現對負責特定隊列的工作單元擴容與資源限制。

假設根據業務需求,DataFlux Func 對訂閲處理的性能要求較高,且希望訂閲消息處理不和同步執行的函數 API處理不會相互干擾,那麼可以從 worker-1-6 將拆分為 worker-1-5worker-6

操作方法

單機部署的 DataFlux Func 可以通過修改配置({安裝目錄}/docker-stack.yaml),新增、修改對應服務,並修改 command 中指定的隊列序號,即可實現拆分工作單元。

指定工作單元監聽的隊列,通過 ./run-worker-by-queue.sh 後的參數實現,服務名稱本身主要作為標註使用,建議與實際監聽隊列一致,避免混亂

示例僅為節選

示例僅展示關鍵修改部分,實際操作時請注意配置完整

docker-stack.yaml 關鍵修改部分
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
services:
  # 刪除原先的「worker-1-6」,改為如下內容

  worker-1-5:
    # 指定工作單元處理 1 ~ 5 號工作隊列
    command: ./run-worker-by-queue.sh 1 2 3 4 5

  worker-6:
    # 指定工作單元處理 6 號工作隊列
    command: ./run-worker-by-queue.sh 6