万字长文| 在 Kubernetes 上设计和测试高可用的 Kafka 集群

f1449906f8c29afd864ab8b8da708b0c.gif

新钛云服已为您服务1491

9d0252d26a8270010a3388d14a75fd85.gif

01a32e0efdb01a66fb601ff1a795690c.png

在本文中,我们将了解 Kafka 的架构以及它如何通过复制分区支持高可用性。然后,我们也可以自己实现一个 Kafka 集群以使用标准 Kubernetes 资源实现高可用性,并了解它是如何做到高可用的,从而避免单点故障问题

在最简单的基础环境中,Kafka 的架构由单个 Broker 服务器及其作为客户端的生产者和消费者组成。

· 生产者创建记录并将它们发布到 Kafka 代理。

4cfdbe80f7d166e8f7523d30881b7a78.png

· 消费者从broker节点消费记录。

44c535f87bd6f0309b0d40be8477d786.png

虽然这个 Kafka 集群可以支持典型的 Kafka 用例,但对于大多数实际情况来说它还是过于简单了。

首先,让我们解释一下常见的相关专业术语。

· Broker:消息中间件处理节点;每个Kafka服务节点称之为一个Broker,一个Kafka集群由一个或多个Broker组成。

· Topic:一类特定数据集合的统称;可类比DB中Table的概念;逻辑概念。

· Producer:消息的生产者,向Broker发送消息的客户端。

· Consumer:消息的消费者,向Broker读取消息的客户端。

· Consumer Group:每一个Consumer隶属于一个特定的Consumer Group,一条消息可以被不同Group中的Consumer消费,但同一Group内的消息只能被一个Consumer消费。

· Partition:是对Topic中所包含数据集的物理分区;物理概念。

· Replication:副本集;是Kafka高可用的一种保障机制。

Kafka 通常作为一个由三个或更多brokers代理组成的集群运行,这些brokers可以跨越多个数据中心或云区域。

fae5941bcde3d833dac53c710f10d831.png

这种集群架构支持对可扩展性、一致性、可用性、分区容错性和性能的需求。

在本文中,我们的学习目标是探索 Kafka 在 Kubernetes 上的可用性

在此,特别说明,我们将独立设计一个 高可用的基于kubernetes的Kafka 集群:

1、优先考虑用性而不是一致性,这是大家可能希望为实时指标收集等用例做出的权衡,在这种情况下,如果发生故障,写入新数据的可用性比丢失一些历史数据点更重要。(https://en.wikipedia.org/wiki/CAP_theorem)

2、优先选择简单而不是其他非功能性需求(例如安全性、性能、效率等),从而更专注于 Kafka 和 Kubernetes。

3、本文也假设维护服务的计划外中断比基础设施故障更有可能发生

考虑到这些因素,让我们首先讨论一个典型的高可用性 Kafka 集群——运行于主机上而非运行于Kubernetes集群中。

Kafka partitions 与 replication-factor

在 Kafka 中,消息被分类为topics,在集群中,每个topic都有一个唯一的名称。

例如,如果您构建一个聊天应用程序,您可能会为每个聊天室设置一个topic(例如“dave-tom-chat”)。

但是当消息的数量超过broker限制的大小时会发生什么?

Topic被分解成多个分区,每个分区都可以存在于 Kafka 集群中的一个单独节点上。

换句话说,来自单个topic的所有消息可以存储在不同的broker中,但来自单个分区的所有消息只能在同一个节点上找到。

· 如果一个topic包含所有消息,当设备上没有空间时它是如何工作的?

d1b75fbd33672d4853f499d36d64a217.png

· Kafka 使用分区将记录分发给多个broker。

da11f23c0b48977059e96eec8be1fb83.png

· 每个topic可以有不同数量的分区。来自单个分区的所有记录始终一起存储在节点上。

bb042a6bdfaf1408869a54618ef9b009.png

这种设计选择支持topic的并行化、可扩展性和高消息吞吐量。

下面还有更多内容,让我们继续往下看。

Topic配置了一个replication factor,它决定了每个分区的副本数。

如果一个集群只有一个topic和一个分区,则replication factor为 3 意味着存在三个分区:每个分区一个副本。

9a1a1fcf88f1fadacbacda5c3014566d.png

分区的所有副本都存在于不同的broker上,因此您不能配置比集群中的节点多的分区副本。

在前面的示例中,replication factor为 3,您应该期望 Kafka 集群中至少有三个节点。

但是 Kafka 如何让这些副本保持同步呢?

分区被区分成leader和follower角色,其中分区leader处理所有写入和读取,follower纯粹用于故障转移。

follower可以与leader同步(包含所有分区leader的消息,除了缓冲区窗口中的消息)或不同步。

64c13aa9f3246bd6631f5206fb12ac70.png

所有同步副本的集合称为 ISR(in-sync replicas)。

这些是 Kafka 和replications的基础;让我们看看故障时会发生什么。


了解brokers故障

假设 Kafka 集群有 3 个broker,replication factor为 1。

集群中只有一个topic和一个分区。

当 broker 不可用时,分区也不可用,集群无法为消费者或生产者提供服务。

6c81387803856c977d59c9cf65827289.png

让我们通过将replication factor设置为 3 来改变它。

在这种情况下,每个broker都有一个分区的副本。

当broker不可用时会发生什么?

77fe1a58be928ad4878658d7dc096e2a.png

如果分区有额外的同步副本,其中一个将成为临时分区leader。

集群可以照常运行,消费者或生产者没有停机时间。

一个所有分区同步的 Kafka 集群丢失了一个broker。

ecfa0cf171e70443d93fa0c8e7d17bd7.png

两个分区中的一个将被提升为leader,集群将继续照常运行。

f65ebbe46bf59b1b8a3967da6ea86e0d.png

当有分区副本但它们不同步时怎么办?

在这种情况下,有两种选择:

  1. 选择等待分区leader重新上线——牺牲可用性。

  2. 允许不同步的副本成为临时分区leader——牺牲一致性。

分区不同步的 Kafka 集群失去了一个broker。

0f63a9aafc9314e79643e15d9e539ac4.png

集群可以将其中一个不同步的副本提升为leader。但是,您可能会丢失一些消息。

1043d229dba52977d1e6e71fd0649443.png

或者,您可以等待broker恢复,但是,这样影响您服务的可用性。

06f70a5a9a07bbfeab5c95f167270088.png

上面我们已经讨论了一些失败场景,下面让我们看看如何处理它们。


如何解决或者减轻常见故障

您可能注意到一个分区应该有一个额外的同步副本 (ISR) 可用以在分区leader丢失后幸存下来。

因此,一个简单的集群大小至少得有两个最小同步副本大小为 2 的broker。

然而,这还不够。

如果你只有两个副本,然后失去了一个broker,同步副本大小会减少到 1,生产者和消费者都无法工作(即最小同步副本为 2)。

因此,broker的数量应该大于最小同步副本大小(即至少 3 个)。

您可以设置一个只有两个broker且最小同步副本大小为 2 的 Kafka 集群。

22190b8a6d040e1f3eff08602b78ae35.png

但是,当broker丢失时,集群将变得不可用,因为单个副本处于同步状态。

4084443f7200f9136cb990e1379b2b19.png

您应该配置一个 Kafka 集群,该集群的broker数量大于同步副本的大小。

66e2d74a152d00a6e1f644829aa25819.png

在这种情况下,如果一个 broker 丢失,Kafka 集群仍然可以继续运行。

11e3f05650346c3ec4b48d88e58535d6.png

那你又该如何规划broker的位置了?

考虑到大都使用云服务托管的 Kafka 集群,因此最好在故障域(例如区域、区域、节点等)之间分布broker节点。

因此,如果您希望设计一个可以容忍一次计划内和一次计划外故障的 Kafka 集群,您至少应该考虑以下要求:

· 最少 2 个同步副本。

· topic的replication factor为 3。

· 至少 3 个 Kafka broker,每个broker运行在不同的节点上。

· 节点分布在三个可用区。

在本文的剩余部分,您将在 Kubernetes 上构建和故障测试 Kafka 集群以验证这些假设。


在 Kubernetes 上部署 3 节点 Kafka 集群

让我们创建一个跨三个可用区的三节点集群:

$ k3d cluster create kube-cluster \
  --agents 3 \
  --k3s-node-label topology.kubernetes.io/zone=zone-a@agent:0 \
  --k3s-node-label topology.kubernetes.io/zone=zone-b@agent:1 \
  --k3s-node-label topology.kubernetes.io/zone=zone-c@agent:2
INFO[0000] Created network 'k3d-kube-cluster'
INFO[0000] Created image volume k3d-kube-cluster-imagesINFO[0000] Starting new tools node...INFO[0001] Creating node 'k3d-kube-cluster-server-0'
INFO[0003] Starting Node 'k3d-kube-cluster-tools'
INFO[0012] Creating node 'k3d-kube-cluster-agent-0'
INFO[0012] Creating node 'k3d-kube-cluster-agent-1'
INFO[0012] Creating node 'k3d-kube-cluster-agent-2'
INFO[0012] Creating LoadBalancer 'k3d-kube-cluster-serverlb'
INFO[0017] Starting new tools node...INFO[0017] Starting Node 'k3d-kube-cluster-tools'
INFO[0018] Starting cluster 'kube-cluster'
INFO[0018] Starting servers...INFO[0018] Starting Node 'k3d-kube-cluster-server-0'
INFO[0022] Starting agents...INFO[0022] Starting Node 'k3d-kube-cluster-agent-1'
INFO[0022] Starting Node 'k3d-kube-cluster-agent-0'
INFO[0022] Starting Node 'k3d-kube-cluster-agent-2'
INFO[0032] Starting helpers...INFO[0032] Starting Node 'k3d-kube-cluster-serverlb'
INFO[0041] Cluster 'kube-cluster' created successfully!

您可以通过以下方式验证集群是否已准备就绪:

$ kubectl get nodes
NAME                        STATUS   ROLES                  VERSION
k3d-kube-cluster-server-0   Ready    control-plane,master   v1.22.7+k3s1
k3d-kube-cluster-agent-1    Ready    <none>                 v1.22.7+k3s1
k3d-kube-cluster-agent-0    Ready    <none>                 v1.22.7+k3s1
k3d-kube-cluster-agent-2    Ready    <none>                 v1.22.7+k3s1

接下来,让我们将 Kafka 集群部署为 Kubernetes StatefulSet。

这是一个 YAML 清单,kafka.yaml定义了创建简单 Kafka 集群所需的资源:

apiVersion: v1
kind: Service
metadata:
  name: kafka-svc
  labels:
    app: kafka-app
spec:
  clusterIP: None
  ports:
    - name: '9092'
      port: 9092
      protocol: TCP
      targetPort: 9092
  selector:
    app: kafka-app
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: kafka
  labels:
    app: kafka-app
spec:
  serviceName: kafka-svc
  replicas: 3
  selector:
    matchLabels:
      app: kafka-app
  template:
    metadata:
      labels:
        app: kafka-app
    spec:
      containers:
        - name: kafka-container
          image: doughgle/kafka-kraft
          ports:
            - containerPort: 9092
            - containerPort: 9093
          env:
            - name: REPLICAS
              value: '3'
            - name: SERVICE
       
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Python图像处理是一项非常有趣的技能,这项技能可以使您能够更好地理解计算机视觉、数字信号处理、深度学习和其他各种应用程序。学习Python图像处理的第一步是掌握基本的Python语言和编程知识,例如变量、循环、条件语句和函数等。 学习Python图像处理工具包也是非常重要的,这些工具包包括 Pillow、OpenCV、SciPy、scikit-image等。这些工具包提供了一系列函数和方法,使您可以方便地操作图像、从图像中提取特征和执行模式识别。Pillow是Python Imaging Library的升级版,支持在Python 3.x版本的平台上使用。OpenCV是一个强大的计算机视觉库,提供各种算法和函数来处理图像和视频件。SciPy提供了广泛的科学计算功能,包括图像处理。Scikit-image是一个基于Python的用于图像处理和计算机视觉的库。 Python图像处理的学习过程需要不断地进行实践,应该尝试不同的图像处理技术、算法和工具包来理解每个技术的优势和劣势。还应该尽量积累有关图像处理的知识(例如神经网络、模式识别和计算机视觉的数学原理)。可以使用在线编程环境或者自己安装Python和相关工具包来进行实践。实践的过程中,一定要保持耐心、自信和专注,因为Python图像处理涉及到很多细节和不同的实现方式。 另外,可以通过阅读相关的书籍、参加培训班和参与Python图像处理社区等方式,来了解更多Python图像处理的知识和技术。阅读书籍可以从入门到进阶的学习,培训班可以有专业人士教授,Python图像处理社区可以互相交流学习。 学习Python图像处理需要不断地实践和努力,但是通过掌握基本的Python语言和编程知识、了解Python图像处理工具包和积累相关的知识,您一定可以成为Python图像处理的专家。加油!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值