在容器云环境中设计高可用的Kafka集群,需要从存储,网络的高可用来方面考虑:
网络层面需要关注Kafka如何二次寻址向Broker发送消息以及如何在容器云环境中实Rebalance,可以通过容器云CNI扩展方案支持静态PodIP固定加Underlay组网方案实现或者通过LoadBalancer方案实现。为了更好的理解网络高可用的必要性,先下Kafka客户端建立连接和Rebalance的原理,
Kafka客户端连接到Kafka集群的流程:
1)获取Broker元数据:客户端首先需要从Kafka集群获取Broker元数据,以了解可用的Broker和分区分配信息。Kafka客户端会向Kafka集群中的一个Broker发送一个元数据请求,获取可用的Broker列表和分区分配信息。这个元数据请求可以被任何一个Broker处理。
2)连接Broker:客户端会从可用的Broker列表中选择一个Broker进行连接。连接可以是TCP连接或SSL连接,取决于Kafka集群的配置。
3)发送请求:客户端连接到Broker后,可以发送请求来获取、生产或消费消息。请求包括请求类型、主题、分区、消息等信息。
4)处理请求:Broker接收到请求后,会根据请求类型进行处理,例如读取或写入消息。
5)返回响应:Broker处理完请求后,会向客户端返回响应。响应包括响应状态、主题、分区、消息等信息。
6)断开连接:客户端可以选择断开连接或者保持连接。如果客户端断开连接,则需要重新执行上述步骤重新连接到Broker。
在Kafka Broker宕机恢复后, Kafka 客户端会自动触发重平衡(rebalancing)流程,以重新分配消费者实例和分区之间的关系 :
1)Kafka 客户端会检测到 broker 宕机新拉起节点并刷新Borker元数据 。
2)Kafka 客户端会向 Kafka 集群协调器发送心跳,以确保它仍然是一个活跃的消费者组成员。如果协调器在一定的时间内没有收到心跳,则会将该消费者标记为失效,并将其分区重新分配给其他消费者。
3) Kafka 客户端会向协调器请求重新分配消费者实例和分区的关系。协调器会根据消费者组的配置和现有的消费者实例列表,重新计算分区的分配结果。
4)协调器会将新的分区分配方案发送给消费者组中的所有消费者实例。消费者实例会根据新的分配方案,重新分配自己负责的分区。
5)消费者实例会根据新的分配方案,重新分配自己负责的分区,并在重新分配完成后重新开始消费消息。
可以看到Kafka客户端和Server端建立连接都是通过Kakfa Broker元数据进行二次连接,需要通过broker 的 bootstrap 地址是通过 listeners
配置参数来指定的,它可以设置一个或多个监听器,每个监听器可以有一个或多个地址。 以下是一个示例配置文件:
broker:
id: 0
rack: dc1
listeners:
INTERNAL://:9092
EXTERNAL://:9093
CLIENT://:9094
advertised.listeners:
INTERNAL://kafka1.internal:9092
EXTERNAL://kafka1.example.com:9093
CLIENT://kafka1.example.com:9094
在容器云环境中需要将 EXTERNAL 地址配置为静态PodIP地址或LoadBalancer地址,来确保Kafka Broker可以正常寻址:
1)基于静态PodIP可以通过环境变量注入,然后启动时通过环境变量渲染broker配置即可达到效果,以下例子可参考注入POD_IP:
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
- name: my-container
image: my-image
env:
- name: POD_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
2) 基于LoadBalancer方案则更为复杂,通常需要通过开发单独的Kafka Operator服务来管理Kafka在容器云上的生命周期,当然该方案也是各类中间件服务容器云上的推荐方案,从可用性、兼容性、可移植性上均会更好,Kafka社区也开源了Operator,可以参考https://github.com/strimzi/strimzi-kafka-operator直接使用,也可以根据各容器云平台特点开发Kafka Operator服务。
当然Kafka在容器云上的高可用性还有很多地方可以考虑,比如基于集群联邦或Kafka MirrorMaker2 实现Kafka的机房级别容灾、Kafka容灾场景下的可观测性等,也可以参考近期信通院发布的《云原生能力成熟度模型-第5部分:中间件》行业标准进行比对。
收起1,常见套路就是要么应用层自己做,就是Kafka的一主多从能力,要么容器平台体系支撑,就是靠容器平台自身的漂移能力解决可靠性和恢复能力。
2,两种方案各有优劣,一主多从结合本地盘,就是当前的常规套路,但是有几个问题,服务器自身的可靠性,3年寿命的周期替换,数据迁移;RAID卡的抖动问题,本地盘的可靠性,一旦盘失效,重构的缓慢与性能波动;无法弹性扩容,容量用满又需要迁移;计算存储资源不匹配,混在一起无法按需扩展;存储自身几块盘现网也出现很多使用不均的问题;为了可靠性通常需要三副本配置,同城容灾需要更多副本支持;同类应用如果都采用一主多从,有类似七八种组件,管理运维上对中小金融机构的压力也比较大
3,以实测结果看,用容器平台自身的可靠性能力,失效后自动漂移,可以形成统一的平台化方案。同时,采用外置企业NAS存储,确实更适合容器平台的租户管理,业务隔离,优先级配置,资源共享。尤其是如果只配置单副本的情况下,明显性能优于一主多从模式,再结合企业存储自身的可靠性底蕴,整体方案实现了诸多好处。
1)计算存储分离,无论计算扩还是存储扩,互不影响,按需扩展
2)容器云平台一般都带有租户属性或者业务隔离属性,配合企业NAS的租户能力,更容易实现端到端的资源隔离,认证鉴权,安全管理,读写控制,优先级设定,以及整体资源的合理管控,如按照租户设定容量上限。
3)配合Kafka,依托企业存储的高可靠,可以配置单主模式,性能最佳,甚至是2倍以上本地盘一主多从的模式,同时结合容器平台自身的漂移能力,可以解决计算侧故障的恢复问题。
4)平台化体系搭建,从目前看,类似Kafka的分布式核心组件有很多,比如redis,elastic search,nigix,mysql等等,常规操作都是各自为战的一主多从,多个集群不只是浪费资源,甚至是消耗大量管理运维的精力。如果均可以利用容器平台的自身漂移解决可靠性问题,无疑会大大降低客户维护多个单集群主从模式的运维难度。
5)存储自身扩容,完全无感知,不影响业务;同时,单盘失效,重构也没有任何影响,也不涉及RAID卡抖动这些常规问题;可靠性远高于普通服务器。而且,存储使用周期长,一般五年起步,多则七到八年,服务器到期更换,无需数据迁移。
在银行行业中,Kafka集群是非常重要的组件,因此设计容器云环境的高可用Kafka集群是非常关键的。以下是一些设计建议:
总之,设计容器云环境的高可用Kafka集群需要考虑多个方面,包括节点数量、协调器、自动化部署、持久化存储和监控工具等。通过综合考虑这些因素,可以确保Kafka集群在容器云环境中具有高可用性和可扩展性。