最近在逛ElasticJob官方社区时发现很多小伙伴都在头疼这个ElasticJob上云的问题,ElasticJob本就号称分布式弹性任务调度框架,怎么在云原生环境就有了问题了呢,这就要从Kubenertes和ElasticJob的一些状态化说起。
有意思的状态
“状态是人或事物表现出来的形态。是指现实(或虚拟)事物处于生成、生存、发展、消亡时期或各转化临界点时的形态或事物态势。”
-
可以包括情绪、思想、行为和生理状态等方面,比如某某人最近的状态不好。
-
比如系统的温度、压力、体积、物态、物质的量、相、各种能量等等一定时,我们就说系统处于一个状态(state)。
-
-
-
-
再到云原生Kubernetes中提及的无状态服务(Stateless Service)和普通有状态服务(Stateful Service)等等。
在Kubernetes中, 无状态 和 有状态 指的是应用在容器中运行时的数据持久化需求。
指的是应用在容器中运行时不会在容器中持久化存储数据,应用容器可以随意创建、销毁。对于无状态应用,请求转发给任何一个容器实例都可以正确运行。例如,web应用就是一种无状态应用。
则指应用在容器中运行时需要稳定的持久化存储、稳定的网络标识、固定的pod启动和停止次序。这些应用需要在不同的节点之间保持数据同步,并且需要在节点故障时能够快速恢复。例如,数据库、缓存等都是有状态应用。
无状态下的容器
可以看到对于大部分 计算型 (业务型) ,非存储型的应用更推荐使用 无状态 的模式,这样就可以实现随意创建(扩容),销毁(缩容)操作了,既然大部分业务系统使用了这种无状态容器就意味着容器的网络,存储等总是在每一次的销毁,创建的发布周期中发生变更。简单的说就是容器的IP在每次发布时 总是会创建一个新的IP。
容器IP是如何在每次创建时产生一个新的IP的,这个原理可以去研究下Kubernetes的虚拟IP的产生,这里重点说下这个IP变更带来的问题,在传统的物理机和虚拟机下部署的服务的IP往往是由运维统一管控分配的,也就是说同一个应用使用哪些IP相对固定往往不会出现大规模的变更,但是云原生环境下无状态容器快速频繁的扩缩容时哪个服务使用哪个IP往往并不会固定每一次变更总会有一个新的IP的使用。
每次IP变更是无状态的一种模式本身并没有什么问题,但是有问题的是目前现有的很多框架或者中间件由于产生很早,开发阶段时还未遇到或者考虑到这种IP频繁变更的场景,经常会借助IP进行了有状态处理,比如Dubbo2中的接口级服务配置,ShardingSphere-ElasticJob 的有状态Server IP节点等等,这种对IP做了有状态操作的框架或者中间件在云原生环境频繁变更IP的场景下很容易产生大量无意义的脏数据存储,对注册中心或者存储都带来了无意义的压力。
ElasticJob中的有状态IP
ShardingSphere-ElasticJob是一个分布式任务调度框架,它由当当网基于Quartz二次开发,功能丰富强大,采用Zookeeper实现分布式协调,可实现任务高可用以及分片。ShardingSphere-ElasticJob已于2020年5月28日成为Apache ShardingSphere的子项目。
具体如何使用可以查阅官网,相关原理也可以查阅《中间件源码》公众号中对ShardingSphere-ElasticJob分析的文章。
在ShardingSphere-ElasticJob中默认注册中心使用的是分布式协调中间件Zookeeper,对IP的处理有两个位置:
-
instance目录: 一个位置是位于注册中心instance目录下的临时节点,这个节点包含了IP+进程信息,借助此目录下的节点可以有效的实现分片逻辑。节点存在意味着进程存在,节点不存在意味着进程不存在。
-
server目录: 另外一个位置是位于注册中心server目录下的持久IP节点,这个IP节点是用来存储当前IP实例的状态的,比如当前实例是否处于禁用状态, 有问题的就是这个持久的,有状态的节点,在无状态的容器环境下随着容器发布次数增多这个IP节点也会越来越多,注册中心无意义的脏数据也会越来越多,对注册中心的压力也会呈线性增长,这就是社区用户遇到的头疼的问题。
解决方案
既然ShardingSphere-ElasticJob要上容器支持云原生环境下的无状态的业务,那我们就把ShardingSphere-ElasticJob有状态的IP变成无状态,比较优雅且彻底的方式就是废弃掉持久化IP这个有状态的功能让ShardingSphere-ElasticJob彻底变成无状态的定时调度,但是考虑到部署在物理机或者虚拟机环境下现存的分布式定时调度业务可能已经使用到了此状态功能,对于已经使用到此状态IP的节点暂不做处理直接跳过,针对已经下线的IP节点则直接删除即可。
感兴趣的小伙伴可以查看如下代码和PR进行测试试用,当然有问题也可以继续反馈。
https://github.com/apache/shardingsphere-elasticjob/pull/2251