temporal集群部署测试
目标
尝试部署三节点temporal集群
关于temporal数据库支持:https://docs.temporal.io/cluster-deployment-guide#supported-databases
由于maraidb数据库temporal不兼容,而官方文档上描述Cassandra将在1.21后弃用(visibility store)。 mysql、sqlite不考虑,只能postgresql、elastcisearch二选一。 elasticsearch是近实时搜索引擎,由于索引需要刷新(间隔一定时间自动flush缓冲数据到底层,间隔时间可以修改牡,但是间隔越短,带来的性能开销就越大)才能查询到数据,可能不适合作为后端存储。 temporal的docekr-compose项目中存在Cockroach DB相关使用内容,后续尝试使用Cockroach DB。 Cockroach DB是个云原生的分布式数据库,基于分布式kv构建sql引擎,使用postgresql接口标准,意味着可以使用postgresql的驱动来访问Cockroach DB。
准备
需要用到的服务或者镜像:
- temporal server
- temporal admin-tools
- temporal ui
初始化数据库的命令,以MySQL为例:
# 启动admin-tools
docker run -d --network=serviceb --name temporal-admin-tools 172.20.16.139:5000/temporal-admin-tools:1.20.0
docker exec -it temporal-admin-tools bash
# 以下命令中的v表示对应的版本,例如./schema/mysql/v8/visibility/versioned表示mysql8
# 初始化数据库temporal
temporal-sql-tool --ep mariadb-247 -u root --pw servicea.mysql.password -p 3306 --pl mysql8 --db temporal --ca tx_isolation='READ-COMMITTED' create
temporal-sql-tool --ep mariadb-247 -u root --pw servicea.mysql.password -p 3306 --pl mysql8 --db temporal --ca tx_isolation='READ-COMMITTED' setup-schema -v 0.0
temporal-sql-tool --ep mariadb-247 -u root --pw servicea.mysql.password -p 3306 --pl mysql8 --db temporal --ca tx_isolation='READ-COMMITTED' update-schema -d ./schema/mysql/v8/temporal/versioned
# 初始化数据库temporal_visibility
temporal-sql-tool --ep mariadb-247 -u root --pw servicea.mysql.password -p 3306 --pl mysql8 --db temporal_visibility --ca tx_isolation='READ-COMMITTED' create
temporal-sql-tool --ep mariadb-247 -u root --pw servicea.mysql.password -p 3306 --pl mysql8 --db temporal_visibilit --ca tx_isolation='READ-COMMITTED' setup-schema -v 0.0
temporal-sql-tool --ep mariadb-247 -u root --pw servicea.mysql.password -p 3306 --pl mysql8 --db temporal_visibilit --ca tx_isolation='READ-COMMITTED' update-schema -d ./schema/mysql/v8/visibility/versioned注:初始化数据库命令需要加上参数--ca tx_isolation='READ-COMMITTED',由于隔离级别变量读取不了。解决参考https://github.com/temporalio/temporal/issues/1004 。
目前已有mariadb 10.6.14的galera cluster三节点数据库集群。 temporal 从1.20开始支持mysql8,但是小于1.20版本的没有mysql8支持。 temporal中对于mysql分两种:mysql(mysql 57)、mysql8(mysql 8)。
对接MariaDB集群手工测试
temporal 1.20.0
按照准备部分中的命令初始化数据库,在初始化visibility数据库过程中更新到最新的版本时命令日志提示失败。无法继续初始化。转而使用mysql v57.可以正常初始化数据库。 使用以下命令运行temporal server,无法正常启动:
# -e DB=mysql表示数据库类型为mysql,受支持的还有mysql8
docker run -d -v /opt/serviceb/tools/temporal/conf/dynamicconfig/:/etc/temporal/config/dynamicconfig/ -e DB=mysql -e DB_PORT=13306 -e MYSQL_USER=root -e MYSQL_PWD=servicea.mysql.password -e MYSQL_SEEDS=172.31.10.247 -e DYNAMIC_CONFIG_FILE_PATH=config/dynamicconfig/development.yaml -e LOG_LEVEL=info -e CA.TX_ISOLATION='READ-COMMITTED' -p 7231-7235:7231-7235 -p 6933-6935:6933-6935 -p 6939:6939 -p 7239:7239 --net=serviceb --name=temporal-server 172.20.16.139:5000/temporal-server:1.20
# OUTPUT LOG:
[Fx] ERROR Failed to initialize custom logger: could not build arguments for function "go.uber.org/fx".(*App).constructCustomLogger.func2
/go/pkg/mod/go.uber.org/[email protected]/app.go:414:
failed to build fxevent.Logger:
could not build arguments for function "go.temporal.io/server/temporal".glob..func8
/home/builder/temporal/temporal/fx.go:1025:
failed to build log.Logger:
received non-nil error from function "go.temporal.io/server/temporal".ServerOptionsProvider
/home/builder/temporal/temporal/fx.go:159:
sql schema version compatibility check failed: Error 1193: Unknown system variable 'transaction_isolation'
Unable to create server. Error: could not build arguments for function "go.uber.org/fx".(*App).constructCustomLogger.func2 (/go/pkg/mod/go.uber.org/[email protected]/app.go:414): failed to build fxevent.Logger: could not build arguments for function "go.temporal.io/server/temporal".glob..func8 (/home/builder/temporal/temporal/fx.go:1025): failed to build log.Logger: received non-nil error from function "go.temporal.io/server/temporal".ServerOptionsProvider (/home/builder/temporal/temporal/fx.go:159): sql schema version compatibility check failed: Error 1193: Unknown system variable 'transaction_isolation'.由于数据库为mariadb,temporal可能不兼容,无法读取系统变量--事务隔离级别transaction_isolation。导致无法正常连接数据库。
尝试了mysql和mysql8,均无法正常使用mariadb集群来作为后端存储持久化的数据源。
temporal 1.19.1
操作同上,但是1.19.1不支持mysql8,所以只有mysql。
同样的错误输出,无法兼容mariadb 10.6.14 galera cluster。
对接Cockroach DB集群
部署CRDB
cockroachdb: v23.1 latest 非安全模式启动,官方推荐生产环境使用ssl证书或者key登录,此次手工实验使用账户密码来测试。 默认情况下为root账户无密码。
docker run -d -p 0.0.0.0:26257:26257 -p 0.0.0.0:9997:9997 -p 0.0.0.0:26357:26357 -v /tmp/cockroach/data/:/cockroach/cockroach-data/ --net=serviceb --hostname=172-20-16-234 --name=cockroachdb-234 172.20.16.139:5000/cockroachdb:latest-v23.1 start --advertise-addr=172.20.16.234:26357 --http-addr=cockroachdb-234:9997 --listen-addr=cockroachdb-234:26357 --sql-addr=cockroachdb-234:26257 --insecure --accept-sql-without-tls --join=172.20.16.147:26357,172.20.16.234:26357,172.20.16.139:26357
docker run -d -p 0.0.0.0:26257:26257 -p 0.0.0.0:9998:9998 -p 0.0.0.0:26357:26357 -v /tmp/cockroach/data/:/cockroach/cockroach-data/ --net=serviceb --hostname=172-20-16-139 --name=cockroachdb-139 172.20.16.139:5000/cockroachdb:latest-v23.1 start --advertise-addr=172.20.16.139:26357 --http-addr=cockroachdb-139:9998 --listen-addr=cockroachdb-139:26357 --sql-addr=cockroachdb-139:26257 --insecure --accept-sql-without-tls --join=172.20.16.147:26357,172.20.16.234:26357,172.20.16.139:26357
docker run -d -p 0.0.0.0:26257:26257 -p 0.0.0.0:9999:9999 -p 0.0.0.0:26357:26357 -v /tmp/cockroach/data/:/cockroach/cockroach-data/ --net=serviceb --hostname=172-20-16-147 --name=cockroachdb-147 172.20.16.139:5000/cockroachdb:latest-v23.1 start --advertise-addr=172.20.16.147:26357 --http-addr=cockroachdb-147:9999 --listen-addr=cockroachdb-147:26357 --sql-addr=cockroachdb-147:26257 --insecure --accept-sql-without-tls --join=172.20.16.147:26357,172.20.16.234:26357,172.20.16.139:26357
# init cluster, output like 'Cluster successfully initialized'
docker exec -it cockroachdb-147 ./cockroach --host=cockroachdb-147:26357 init --insecure
# use sql
docker exec -it cockroachdb-147 ./cockroach sql --host=cockroachdb-147:26257 --insecure浏览器访问任意节点的的http端口(如下图),CRDB的web工具做的还可以,支持查看集群状态、集群监控指标、数据库中数据信息,活动信息、事务信息等,功能看起来挺全面,还自带profile功能,遗憾的是不能编辑设置之类的。
启动Temporal
初始化数据库
# temporal admin tools 1.19.1
docker run -d --net=serviceb -e TEMPORAL_CLI_ADDRESS=temporal-147:7233 --name=temporal-admin-tools 172.20.16.139:5000/temporal-admin-tools:1.19.1
docker exec -it temporal-admin-tools bash
temporal-sql-tool --ep cockroachdb-147 -u root -p 26257 --pl postgres --db temporal create
temporal-sql-tool --ep cockroachdb-147 -u root -p 26257 --pl postgres --db temporal setup-schema -v 0.0
temporal-sql-tool --ep cockroachdb-147 -u root -p 26257 --pl postgres --db temporal update-schema -d ./schema/postgresql/v96/temporal/versioned
temporal-sql-tool --ep cockroachdb-147 -u root -p 26257 --pl postgres --db temporal_visibility create
temporal-sql-tool --ep cockroachdb-147 -u root -p 26257 --pl postgres --db temporal_visibility setup-schema -v 0.0
temporal-sql-tool --ep cockroachdb-147 -u root -p 26257 --pl postgres --db temporal_visibility update-schema -d ./schema/postgresql/v96/visibility/versioned启动temporal
docker run -d -p 7231-7235:7231-7235 -p 6933-6935:6933-6935 -p 6939:6939 -p 7239:7239 -v /tmp/temporal/config/:/etc/temporal/config/ -e DB=postgresql -e DB_PORT=26257 -e POSTGRES_USER=root -e POSTGRES_SEEDS=cockroachdb-147 -e DYNAMIC_CONFIG_FILE_PATH=config/dynamicconfig/development.yaml -e LOG_LEVEL=info -e BIND_ON_IP=0.0.0.0 -e TEMPORAL_BROADCAST_ADDRESS=172.20.16.147 -l kompose.volume.type=configMap --net=serviceb --name=temporal-147 172.20.16.139:5000/temporal-auto-setup:1.19.1
docker run -d -p 7231-7235:7231-7235 -p 6933-6935:6933-6935 -p 6939:6939 -p 7239:7239 -v /tmp/temporal/config/:/etc/temporal/config/ -e DB=postgresql -e DB_PORT=26257 -e POSTGRES_USER=root -e POSTGRES_SEEDS=cockroachdb-139 -e DYNAMIC_CONFIG_FILE_PATH=config/dynamicconfig/development.yaml -e LOG_LEVEL=info -e BIND_ON_IP=0.0.0.0 -e TEMPORAL_BROADCAST_ADDRESS=172.20.16.139 -l kompose.volume.type=configMap --net=serviceb --name=temporal-139 172.20.16.139:5000/temporal-auto-setup:1.19.1
docker run -d -p 7231-7235:7231-7235 -p 6933-6935:6933-6935 -p 6939:6939 -p 7239:7239 -v /tmp/temporal/config/:/etc/temporal/config/ -e DB=postgresql -e DB_PORT=26257 -e POSTGRES_USER=root -e POSTGRES_SEEDS=cockroachdb-234 -e DYNAMIC_CONFIG_FILE_PATH=config/dynamicconfig/development.yaml -e LOG_LEVEL=info -e BIND_ON_IP=0.0.0.0 -e TEMPORAL_BROADCAST_ADDRESS=172.20.16.234 -l kompose.volume.type=configMap --net=serviceb --name=temporal-234 172.20.16.139:5000/temporal-auto-setup:1.19.1temporal官方文档并未找到集群配置内容,无法部署集群,尽管连接到同一个数据库集群
启动temporal ui
docker run -d -p 7230:8080 -e TEMPORAL_ADDRESS=temporal-147:7233 -e TEMPORAL_CORS_ORIGINS=http://localhost:3000 --net=serviceb --name=temporal-ui 172.20.16.139:5000/temporal-ui:2.14.0
docker run -d -p 7230:8080 -e TEMPORAL_ADDRESS=temporal-139:7233 -e TEMPORAL_CORS_ORIGINS=http://localhost:3000 --net=serviceb --name=temporal-ui 172.20.16.139:5000/temporal-ui:2.14.0
docker run -d -p 7230:8080 -e TEMPORAL_ADDRESS=temporal-234:7233 -e TEMPORAL_CORS_ORIGINS=http://localhost:3000 --net=serviceb --name=temporal-ui 172.20.16.139:5000/temporal-ui:2.14.0启动超过两个(包括两个)temporal server后查看workflow详情,页面频繁出现503,貌似是节点问题。
目前将servicec、serviceb-master全都连接到147节点的temporal,此时147节点的temporal可以看到有worker,而其余节点(例如234节点,能看到workflow的数据,因为共用一个数据库,但是没有worker)。 自动运行一晚上再看结果。
运行一晚上后目前结果中存在异常的结果,其余并无异常。 但是此种模式不适合集群部署,因为预期中的三节点部署会部署三个serviceb-master、并且各自连接各自的节点上的maraidb、temporal,此时此种temporal部署模式为3个单独的temporal节点,会导致3个temporal均有worker,任务调度可能会出问题。
以上配置均为未配置temporal环境变量:bind_on_ip和broadcast_address的手工实验。 如果在环境变量中增加这两个配置,部署后,通过temporal-admin-tools执行tctl admin cluster describe命令,可以看到三节点集群的成员信息: 同时将serviceb-master的配置中切换到三节点中的其中一个节点,此时通过temporal ui可以看到workflow中有一个worker,其余节点也能看到有一个worker,这与之前的3节点各自部署独立的temporal不一样,似乎temporal集群部署成功。 再将servicec的workflow配置切换到集群另外一个节点,重启servicec,此时的情况为serviceb-master连接节点234,所有的servicec连接节点147。在serviceb页面上操作存储池缩容,移除数据盘,可以正常完成操作。
目前结论
3节点temporal集群手工部署成功,但是否适配serviceb还有待测试,已经测试的是单节点serviceb-master,集群模式下的3节点serviceb-master的效果还未可知。从理论上来讲,3个serviceb-master连接同一个temporal集群,会注册3个worker,temporal会处理任务调度,把任务交给其中的某个worker执行。
Temporal集群化(最小化改动 base serviceb 5.2.0)
部署要求: 集群必须3节点起, 最好是奇数个节点; 需要增加的内容: cockroachdb v23.1.5 docker image; 以及temporal初始化pg的schema脚本(v12); Docker服务; 需要移除的内容: postgres v9.6; 配置改动:
- temporal 的配置中增加bindOnIp, 值为0.0.0.0;
- temporal 的配置中增加broadcastAddress, 值为当前运行的节点ip; 部署改动:
- 移除安装postgres的部分, 变更为启动CRDB容器的部分,由于CRDB原生支持分布式和docker, 因此可以通过启动命令来配置CRDB集群. 启动完成后init 集群;
- 初始化temporal数据库时, 使用v12的pg脚本, 而不是v9.6版本;
- CRDB单节点和集群启动方式不一样;
- serviceb双管环境结合temporal3节点集群时, 不同的serviceb可以连接不同的temporal节点, 也可以通过nginx作为负载均衡, 将流量转发到其他节点; 需要考虑的点:
- CRDB许可证风险: CRDB使用带限制的BSL许可, 不允许云服务商将其作为对外数据库服务;
- temporal官方不支持CRDB, 没有运行其标准测试, 对于CRDB的支持本质上来自于postgresql, 因为CRDB不完全兼容postgres协议, 换句话来说就是temporal官方不保证CRDB的支持;
- 两个serviceb实例如何访问temporal集群, 直连还是使用nginx负载均衡;
- CRDB对于时间同步要求较高, 节点加入集群时, 与集群内一半的节点的时间偏移不能超过400ms, 否则可能无法加入集群;
- CRDB运行时,如果使用的盘写入太慢, 导致log过久, 服务会down;
- CRDB和temporal集群以及docker运维;
- docker容器在成都的环境上, 貌似存在一些网络问题, 使用bridge模式来部署容器后无法访问容器;
- 存在CRDB运行一段时间后重启容器无法成功, 报错数据库已存在并且不是原始数据库: 暂未找到原因, 删除数据(丢失所有workflow执行记录)后重新部署CRDB; 可能是由于数据存在在/tmp目录下, 系统自动清理其中很久未使用的文件,导致启动时找不到对应的文件(STORAGE_MIN_VERSION), 进而启动失败;
- CRDB出错后相关资料较少;
docker run -d --env COCKROACH_DATABASE=aaa --env COCKROACH_USER=temporal --env COCKROACH_PASSWORD=temporal --name=roach-single --hostname=172-31-10-242 -p 26257:26257 -p 9876:9876 -v /tmp/cockroach/data/:/cockroach/cockroach-data/ --ip=172.17.0.2 172.20.16.139:5000/cockroachdb:latest-v23.1 start-single-node --http-addr=172.31.10.242:9876 --insecure