ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Apache DolphinScheduler 使用 JDBC 作为注册中心:配置指南与源码原理解析

Apache DolphinScheduler 使用 JDBC 作为注册中心:配置指南与源码原理解析 Apache DolphinScheduler 使用 JDBC 作为注册中心配置指南与源码原理解析【免费下载链接】dolphinschedulerApache DolphinScheduler is the modern data orchestration platform. Agile to create high performance workflow with low-code项目地址: https://gitcode.com/GitHub_Trending/dol/dolphinscheduler导读本文介绍 Apache DolphinScheduler 的 JDBC Registry 插件如何用 MySQL / PostgreSQL 数据库替代 ZooKeeper 作为集群注册中心存储 Master、Worker 等服务的元数据并完成服务注册、心跳保活与分布式协调。读完本文你将掌握初始化注册表脚本、在 master/worker/api 中配置registry.type: jdbc、为 Worker 单独配置数据源的全部要点并从源码层面理解心跳刷新、会话超时与临时节点清理的底层实现。为什么需要 JDBC 注册中心在 DolphinScheduler 集群中Master、Worker、Alert 等进程需要共享一份集群元数据谁是存活的 Master、哪些 Worker 注册了哪些任务槽位、分布式锁的持有者是谁。默认实现基于 ZooKeeper见 master 默认配置 中registry.type: zookeeper。JDBC Registry 插件则把注册中心的角色完全交给关系型数据库不依赖任何外部协调组件直接用 MySQL 或 PostgreSQL 存储注册信息。其收益与代价都很明确适合已经强依赖 MySQL / PostgreSQL、希望减少 ZooKeeper 运维成本的集群数据库本身成为集群协调的单点依赖需要保证其可用性与连接池健康。从插件实现看JdbcRegistry实现了统一注册中心接口Registry见 JdbcRegistry.java因此对上层 Master/Worker 完全透明——切换注册中心类型只需修改application.yml。核心机制数据表设计与心跳模型JDBC 注册中心由 4 张表构成初始化脚本位于MySQLmysql_registry_init.sqlPostgreSQLpostgresql_registry_init.sql表名作用关键字段t_ds_jdbc_registry_data注册数据节点类比 ZooKeeper 节点data_key、data_value、data_typeEPHEMERAL/PERSISTENT、client_idt_ds_jdbc_registry_lock分布式锁lock_key、lock_ownerip_processId、client_idt_ds_jdbc_registry_client_heartbeat客户端心跳记录client_nameip_processId、last_heartbeat_time、connection_configt_ds_jdbc_registry_data_change_event数据变更事件ADD/UPDATE/DELETEevent_type、jdbc_registry_data从 JdbcRegistryServer.java 的清理逻辑可以清晰看到心跳模型客户端启动时调用registerClient向t_ds_jdbc_registry_client_heartbeat写入一条心跳记录后台定时线程以heartbeat-refresh-interval为周期批量刷新所有存活客户端的心跳时间refreshClientsHeartbeat另一条定时任务以session-timeout为周期执行purgeInvalidJdbcRegistryMetadata找出心跳超时的死客户端级联删除其注册的临时数据节点EPHEMERAL 类型和持有的锁。这意味着data_type EPHEMERAL的数据随客户端会话存活PERSISTENT数据则长期保留与 ZooKeeper 的临时/持久节点语义一致见 JdbcRegistry.java 中deleteOnDisconnect到DataType的映射。快速上手两步启用 JDBC 注册中心第一步初始化数据库表在目标数据库执行对应初始化脚本两条脚本均包含DROP TABLE IF EXISTS可重复执行# MySQL mysql -uroot -p dolphinscheduler \ dolphinscheduler-registry/dolphinscheduler-registry-plugins/dolphinscheduler-registry-jdbc/src/main/resources/mysql_registry_init.sql # PostgreSQL psql -h localhost -U root -d dolphinscheduler -f \ dolphinscheduler-registry/dolphinscheduler-registry-plugins/dolphinscheduler-registry-jdbc/src/main/resources/postgresql_registry_init.sql注意注册表与业务库共用同一个数据库实例即可如dolphinscheduler无需新建库。若业务库中已存在 DolphinScheduler 的元数据表脚本只会新增这 4 张注册表不会影响既有数据。第二步修改注册中心配置在master / worker / api的application.yml中把注册中心类型切换为 jdbcregistry: type: jdbc该配置通过 Spring Boot 条件装配生效——JdbcRegistryAutoConfiguration 与 JdbcRegistryProperties 都带有ConditionalOnProperty(prefix registry, name type, havingValue jdbc)只有registry.type为jdbc时整个 JDBC 插件才被加载。完成这两步后启动集群Master/Worker 的服务元数据就会写入数据库。可选配置心跳与会话超时JDBC 插件支持两个关键调优参数registry: type: jdbc # 心跳刷新周期默认 3s。后台线程每隔该时间批量刷新一次所有存活客户端的心跳时间 heartbeat-refresh-interval: 3s # 会话超时时间默认 60s。客户端心跳超过该时长未刷新即被判定离线并清理其临时节点与锁 session-timeout: 60s两个参数的默认值与校验规则都能在 JdbcRegistryProperties.java 中找到heartbeatRefreshInterval默认Duration.ofSeconds(3)且必须大于等于 1s否则配置校验直接报错sessionTimeout默认Duration.ofSeconds(60)且必须大于 3 倍的心跳刷新间隔sessionTimeout 3 * heartbeatRefreshInterval这是为了保证至少能容忍两三次心跳丢失后再判定离线避免网络抖动导致误杀。调参建议集群规模小、对故障感知要求高时可适当缩短两者若注册中心数据库负载偏高可适当放宽heartbeat-refresh-interval但务必保持session-timeout 3 * heartbeat-refresh-interval的约束。另外插件启动时会打印本次生效的配置摘要便于排查jdbcRegistryClientName - host:port heartbeatRefreshInterval - PT3S sessionTimeout - PT60S其中jdbcRegistryClientName默认取NetUtils.getHost() : serverPort用于唯一标识注册客户端见 JdbcRegistryProperties.java。Worker 数据源配置关键步骤API 与 Master 进程本身自带数据源可直接复用spring.datasource但 Worker 进程不包含业务数据源因此必须为 Worker 单独配置注册中心使用的 JDBC 数据源Hikari 连接池。这也是使用 JDBC 注册中心最容易遗漏的一步。使用 MySQL 作为注册中心在 Worker 的application.yml中配置registry.hikari-configregistry: type: jdbc heartbeat-refresh-interval: 3s session-timeout: 60s hikari-config: jdbc-url: jdbc:mysql://127.0.0.1:3306/dolphinscheduler username: root password: root maximum-pool-size: 5 connection-timeout: 9000 idle-timeout: 600000使用 PostgreSQL 作为注册中心registry: type: jdbc heartbeat-refresh-interval: 3s session-timeout: 60s hikari-config: jdbc-url: jdbc:postgresql://localhost:5432/dolphinscheduler username: root password: root maximum-pool-size: 5 connection-timeout: 9000 idle-timeout: 600000hikari-config直接映射到 JdbcRegistryAutoConfiguration 中构建的HikariDataSource常用连接池参数含义参数默认值HikariCP说明jdbc-url-注册中心数据库 JDBC 地址必须填写username/password-数据库账号密码必须填写maximum-pool-size10连接池最大连接数示例取 5 以降低 Worker 对数据库的连接占用connection-timeout30000获取连接的超时时间毫秒示例 9000msidle-timeout600000空闲连接回收时间毫秒示例 10 分钟对应地插件的集成测试使用了完全一致的最小配置见 application-mysql.yaml其中还把心跳间隔调至 1s、会话超时调至 3s 用于快速验证。注意事项与常见问题MySQL 驱动需要手动添加JDBC 插件在发行包中不会内置mysql-connector-java.jar。若使用 MySQL必须将驱动 jar 加入 DolphinScheduler 的 classpath如放入 lib 目录否则插件启动时无法建立数据库连接。PostgreSQL 场景则无需额外处理。Master/API 复用业务数据源Master 与 API 自身已有数据源无需也不建议再写hikari-config否则连接池会重复占用数据库连接。临时节点由服务端清理客户端异常退出如进程被 kill -9后其 EPHEMERAL 数据与锁不会立即消失而是要等session-timeout后被清理线程回收。因此该超时时间决定了故障节点元数据的最大残留时长。分布式锁依赖唯一键锁的实现基于t_ds_jdbc_registry_lock.lock_key的唯一索引——插入成功即获锁插入触发DuplicateKeyException则自旋重试见 JdbcRegistryLockManager.java并支持同一客户端可重入计数。初始化脚本中的唯一索引uk_t_ds_jdbc_registry_lockKey不能被删改。连接状态自动恢复当心跳刷新连续失败时服务端状态机从STARTED→SUSPENDED超过session-timeout未恢复则进入DISCONNECTED并通知上层监听器恢复后自动触发onReconnected见 JdbcRegistryServer.java。因此短时数据库抖动不会直接导致服务下线。验证与延伸阅读插件自带 MySQL / PostgreSQL 两套集成测试基类覆盖了数据增删查、子节点枚举、事件订阅等核心行为可作为理解行为边界的参考MysqlJdbcRegistryTestCase.javaPostgresqlJdbcRegistryTestCase.java需要进一步研究的内容还包括注册中心 SPI 的通用接口定义见 dolphinscheduler-registry-api若需对比其他实现如 ZooKeeper、etcd可查看 dolphinscheduler-registry-plugins 目录。切换到 JDBC 注册中心后建议在数据库侧持续监控这 4 张注册表的数据量与last_heartbeat_time的更新频率以判断集群协调是否健康。【免费下载链接】dolphinschedulerApache DolphinScheduler is the modern data orchestration platform. Agile to create high performance workflow with low-code项目地址: https://gitcode.com/GitHub_Trending/dol/dolphinscheduler创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进