部署和维护 / 架构、扩容与限制资源
本文主要介绍 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. 授权链接处理 2. 订阅消息处理 |
需要提高授权链接、订阅消息处理并发数时可扩容 |
worker-7 队列 #7 |
默认情况下,负责调试代码处理(即在 Web 界面直接运行函数) | 需要支持更多用户同时开发脚本时扩容 |
worker-8-9 队列 #8、#9 |
默认情况下,负责函数异步调用处理,如: 1. 自动触发处理 2. 批处理 |
需要提高自动触发、批处理处理并发数时扩容 |
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:检测能力
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:所需 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 |
|
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 |
|
4. 拆分工作单元
新版中所有工作单元已经拆分
在独立部署 Func 3.2.0 及以后版本中,默认已经拆分了所有非预留的工作单元,用户可以根据需要启用预留的队列
在观测云附属 Func 1.77.145 及以后版本中,默认已经拆分了所有工作单元,不再需要用户自行拆分
特殊情况下,可以将默认合并的工作单元(如:worker-1-6
)进行拆分,实现更细粒度的任务调度,实现对负责特定队列的工作单元扩容与资源限制。
假设根据业务需求,DataFlux Func 对订阅处理的性能要求较高,且希望订阅消息处理不和同步 API(旧版:授权链接)处理不会相互干扰,那么可以从 worker-1-6
将拆分为 worker-1-5
和 worker-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 |
|