Kafka中的设计-复制与日志压缩

讲解了Kafka的副本复制以及节点容灾的各种机制,同时介绍了Kafka的日志压缩技术和配额功能

复制

Kafka通过在多台服务器上复制每个主题分区的日志来实现故障容错。这些副本可以自动接管故障服务器的角色,确保消息在出现故障时仍然可用。

复制

  • 每个主题分区在非故障情况下都有一个领导者和零个或多个追随者,构成复制因子。
    • 所有写入操作都发送到领导者,而读取可以发送到领导者或追随者。
    • 追随者从领导者那里获取消息并应用到自己的日志中。
  • 使用特殊节点“控制器”来管理集群中的代理注册,确保活跃性条件得到满足。
    • 只要至少有一个同步副本处于活动状态,已提交的消息就不会丢失。
    • 负责管理broker的注册,当探测到代理发生故障时负责选举ISR的剩余成员之一作为新的领导者。这可以批量处理大量分区的领导者变更通知,从而提高效率和速度。
  • 提供了故障转移和高可用性功能,但在网络分区情况下可能无法保持可用。
    ISR
  • 各个节点满足与控制器保持活动会话,如果是flower复制leader的消息不能落后太多,这样的节点称为“同步”,以避免“活动”或“失败”的模糊性
  • leader维持一组“同步”副本成为ISR,如果一旦有一个节点不满足上述的其中一点,则会被踢出

复制日志:仲裁、ISR 和状态机

  • 复制日志的核心原理:复制日志是分布式系统中的基本原语,通过模拟达成共识的过程来确保数据一致性。
  • 领导者和追随者:领导者选择值的顺序,追随者复制领导者的值。当领导者失败时需要选举新的领导者,确保数据的完整性和一致性。
  • 多数投票:常用的选举领导者和提交决策的方法,确保系统的高可用性和容错性。
  • Kafka 的 ISR 模型:使用动态维护的同步副本集选择leader,确保面对故障时能够容忍和高可用。
  • 设计差异:不要求节点恢复时数据完好无损,采用 ISR 模型和较低的复制因子来提高性能和减少磁盘空间需求。
如果所有的ISR节点都G了怎么办?

一般来说只有两种选择,保证可用或者保证一致

  • 等待 ISR 中的副本恢复并选择该副本作为领导者(希望它仍然拥有所有数据)。
    • 这种就是保持一致,但是只要这些副本关闭,我们就将保持不可用状态。
  • 选择第一个作为领导者复活的副本(不一定在 ISR 中)。
    • 不在ISR中选择,而是直接选择一个没有死亡的节点,但是由于其已经被踢出ISR说明数据与leader不一致,并且其成为新的leader就会把数据同步到其他节点,那么就会造成数据永久丢失,但是至少保证了可以使用
可用和耐用的保证

kafka通过ack=all来保证所有的ISR副本节点都将新的消息写入

  • 禁用不干净的领导者选举 - 如果所有副本都不可用,则分区将保持不可用,直到最近的领导者再次可用。
    • 这实际上更倾向于不可用而不是消息丢失的风险。
  • 指定最小 ISR 大小 - 仅当 ISR 大小高于某个最小值时,分区才会接受写入
    • 以防止仅写入单个副本的消息丢失,该副本随后变得不可用。
副本管理
  • 多个分区的管理:Kafka集群管理数百/数千个分区,通过循环方式平衡分区分布,避免节点承载过多分区。
  • 领导力的平衡:努力确保每个节点都能领导其分区的一定比例,以实现领导力的均衡分配。
  • 优化领导选举流程:领导者选举是关键窗口,需要进行优化以提高效率。

日志压缩

日志压缩-实际上指的是一种数据保留机制,而不是传统意义上的压缩算法或技术

  • 是一种更细粒度的保留机制,会保留每个主键对应的最后一次更新(保留关键信息),类似于Redis将AOF进行优化压缩的机制,把不需要保留的日志删除(节约资源),可以提高重启后快速重建。
  • 应用场景:
    • 数据库变更订阅:通过保留关键信息、实时同步数据以及节约资源等方式,有效支持数据库变更订阅功能,订阅者能够及时获取最新的数据变更情况
    • 事件溯源:将更改日志作为应用程序的主要存储,有利于数据的快速构建,并且可以追溯到每个主键的最终状态。
    • 高可用性的日志记录:通过记录本地状态的更改来实现容错,以便在失败时能够快速重新加载并继续执行。

日志压缩提供的保证

  1. 参数控制消息写入和压缩时间限制:
    1. 主题中的min.compaction.lag.ms参数规定了消息写入后必须经过的最短时间长度才能被压缩
    2. 而max.compaction.lag.ms参数则规定了消息写入和消息适合压缩的时间之间的最大延迟。
    3. 这样可以确保消息在一定时间内被正确地压缩和删除。
  2. 消息顺序和偏移量保持不变: 日志压缩不会重新排序消息,只是删除一些消息,因此消息的顺序永远保持不变。
    1. 此外,消息的偏移量也永远不会改变,它是日志中某个位置的永久标识符。
  3. 消费者获取消息保证: 任何从日志开始进行的消费者都将按照写入顺序看到所有记录的最终状态。
    1. 如果消费者在到达日志头部的时间小于delete.retention.ms参数所设置的时间段内,将看到已删除记录的所有删除标记。
    2. 消费者需要注意,在delete.retention.ms时间段后会错过已删除记录的删除标记。

日志压缩详细信息

通过一个后台线程池构建的日志清理器,重新复制日志段文件,删除其键出现在日志头部的记录
工作原理

  1. 它选择具有最高日志头与日志尾比的日志
  2. 它为日志头部的每个键创建最后一个偏移量的简洁摘要
  3. 它从头到尾重新复制日志,删除日志中稍后出现的键。新的、干净的段会立即交换到日志中,因此所需的额外磁盘空间只是一个额外的日志段(而不是日志的完整副本)。
  4. 日志头的摘要本质上只是一个空间紧凑的哈希表。每个条目正好使用 24 个字节。因此,使用 8GB 的​​清理缓冲区,一次清理迭代可以清理大约 366GB 的日志头(假设有 1k 条消息)。

配额

Kafka 集群能够对请求强制实施配额,以控制客户端使用的代理资源。Kafka 代理可以为共享配额的每组客户端强制执行两种类型的客户端配额:

  1. 网络带宽配额定义字节率阈值(自 0.9 起)
  2. 请求率配额将 CPU 利用率阈值定义为网络和 I/O 线程的百分比(自 0.11 起)

为什么需要配额

  • 生产者和消费者有可能产生/消耗非常大量的数据或以非常高的速率生成请求,从而垄断代理资源,导致网络饱和,并且通常会 DOS 其他客户端和代理本身。
  • 拥有配额可以防止这些问题,并且在大型多租户集群中尤为重要,其中一小部分行为不良的客户端可能会降低行为良好客户端的用户体验。
  • 事实上,当将 Kafka 作为服务运行时,这甚至可以根据商定的合同强制实施 API 限制。

客户群体

Kafka 客户端的身份是用户主体,它代表安全集群中经过身份验证的用户。在支持未经身份验证的客户端的集群中,用户主体是代理使用可配置的PrincipalBuilder. Client-id 是客户端的逻辑分组,具有由客户端应用程序选择的有意义的名称。元组(用户、客户端 ID)定义共享用户主体和客户端 ID 的安全逻辑客户端组。

配额可以应用于(用户、客户端 ID)、用户或客户端 ID 组。对于给定连接,将应用与该连接匹配的最具体的配额。配额组的所有连接共享为该组配置的配额。例如,如果 (user=“test-user”, client-id=“test-client”) 的生产配额为 10MB/秒,则该配额将在用户“test-user”的所有生产者实例与客户端之间共享id“测试客户端”。

具体配置

4.9

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值