DevOPS

Kafka 进阶:Internal & Reliable

2018-07-13  本文已影响143人  63e29c663713

1. Kafka internal

1.1 Request processing

Kafka 的 request 分为:

1.1.1 Metadata request

kafka client 会定期向任意一个 broker(所有的 brokers 都拥有 partition metadata)发起 metadata request 来获取到每个 topic partition leader 的位置,并缓存在本地(有定期的缓存更新机制),从而在需要发送 produce or fetch requests 时正确的定位 broker 的位置。

如果缓存更新延迟,导致错误的 produce request 发到非 leader partition 的 broker 上,该 broker 会直接返回 error,而不是像 ElasticSearch 那样内部转发。

client 收到 produce/fetch response 的 "not a leader" error 后会 refresh metadata。

1.1.2 Produce request

produce request 的过程之前也聊过了,一个重要配置是 acks。

1.1.3 Fetch request

fetch request 由 consumer 或者 follower replicas 发起。

client 发起人request:

consumers 只能 poll 到写入所有 replicas 的 messages,这也是为了尽量保证 consistency。
这就带来一个问题,replication 是有 lag 的,会导致消息无法第一时间到达 consumers。
// todo : This delay is limited to replica.lag.time.max.ms—the amount of time a replica can be delayed in replicating new messages while still being considered in-sync.

broker 会校验 request 的正确性,包括 leader partition, offset。
broker 使用 zero-copy method 将 messages 发送给 client,大大增加了性能。
broker 处理 fetch request 的方式和处理 produce request 非常相似。

1.1.4 OffsetCommitRequest

过去,kafka 使用 zk 维护 consumers 的 offsets。当 consumer 启动时,向 zk 发请求获取要读的 partition 以及 offset。
但是因为频繁的读写 offsets 对 zk 的压力较大,所以推荐通过 Kafka broker 直接管理,现在 kafka 通过创建一个单独的特殊的 __consumer_offsets topic 来维护 offsets。

1.2 Physical Storage

我们会将 partition 在物理层面拆分成 segments。默认情况下,每个 segment 包含 1GB 的数据/一周的数据。当 broker 往 partition 中写数据时,如果当前 segment 的限制到了,会关闭该文件 & 创建一个新的。当前正在使用的 segment 叫做 active segment。每个 segment 会单独存储在 *.log 的物理文件中。

1.2.1 Indexes

由于 Kafka 支持 consumers 从任意可用的 offset 处读取 message,所以需要能快速的定位 message 所在的 segment 位置,Kafka 为每个 partition 创建有 index,index 维护从 offset 到 segment file 及 file 中的位置的映射。

index 也按照 segment 来拆分。

1.2.2 Compact

有一种场景,只保存相同 key 的最新的 message,就用到了 compact,将老旧的 message delete 掉。本质上也是一种 retention policy,技术细节这里不做介绍了。

这部分内容主要整理总结自 《Kafka The Definitive Guide》 Chapter 6: Reliable Data Delivery

2. Reliable

Kafka 的 components 有 producer, broker, consumer,整体服务的 reliable(可靠性) 依赖每一个环节的 reliable,需要 Linux administrators, network and storage administrators, and the application developers 共同努力。

最常为人知的 Reliability Guarantees 是 ACID,它只要用在关系型数据库中。

2.1 Reliability Guarantees

Kafka 提供的基本的 guarantee 包括:

但是这种 guarantee 只能保证基本的 reliable,并不能保证 fully reliable。
系统中存在着 trade-offs,需要在 reliable 和 availability, high throughput, low latency, hardware costs 间做 trade-offs。

2.2 Replication

replication 是 kafka reliability guarantee 的核心。通过做 replication 来对抗 broker 的 crash。

如何判断某个 replica 是处于 in-sync 状态呢:

可以看出:

什么情况下可能导致 replicas out-of-sync 呢:

2.3 Broker Configuration

对于 reliable 的配置,可以配置在 broker level,也可以配置在 topic level。

2.3.1 Replication Factor

replication.factor 即副本个数,这个参数在 topic 创建后,也可以手动修改的。
replication.factor 越大,会有越高的 reliability,但是会带来更大的备份延迟时间。

不同的 replicas 建议在不同的 brokers 上,而存有 partition replicas 的 broker 尽量在不同的 rack 上。

topic level 的配置是 replication.factor
broker level 的配置是 default.replication.factor(针对自动创建的 topic)

2.3.2 Unclean Leader Election

clean leader election 是指当 leader unavailable 时,kafka 会自动从 in-sync 的 replicas 中选举一个作为新 leader。所有 committed data(committed 是指 message 已经备份到所有 in-sync 的 replicas 中) 都不会丢失。

但是,当 leader unavailable 时,完全没有 in-sync replicas 存在时,该怎么办?参数 unclean.leader.election.enable 决定了这种情况发生时的处理办法,默认配置为 true。

假设存在 3 个 replicas,如果 2 个 followers 全变为 unavailable,leader 会继续接受 write request, followers 变为 out-of-sync。现在 leader unavailable,之前 unavailable 的 out-of-sync 的 followers 恢复后,系统如何抉择:

可以看出,这也是在 consistencyavailability之间做选择,符合 CAP 理论。默认为 true,说明 Kafka 倾向于选择 AP & weak consistency

Kafka 的数据同步模式很像 Master / Slave Async。

2.3.3 Minimum In-Sync Replicas

min.insync.replicas 这个参数的意思有些晦涩,我读了两三遍才算理解。它是指 replicas 中,至少有几个 replicas 处于 in-sync 状态,leader 才会执行写请求,否则拒绝写。而不是 message 至少写入了几个 replicas。

假设有 3 个 replicas(leader 包含在内),如果 min.insync.replicas = 2,则当 producer 写 messages 时,至少要有两个 replicas 处于 in-sync 状态,leader 才会执行写入操作,否则返回 producer NotEnoughReplicasException。

所以该参数配置的越高,则 messages 越可能成功写入到更多的副本。如果该参数设置为 1,则 leader 不会关心其他 replicas 是否处于及时更新数据的状态,只要 leader 自身写没问题,就写入了,而其他 replicas 可能过很长时间才能同步到数据,这就增加了 leader unavailable 时,数据丢失的风险。

2.4 Using Producers in a Reliable System

上面说完了如何配置 broker 来尽量保证 reliable,但是如果 producer 配置不当,也会导致丢数据的情况发生。

2.4.1 ACK

考虑如下场景,partition 有 3 个 replicas:

单独 acks 的配置不能完全保证数据的成功存储。对于 producer 来说,为了保证 reliable,需要:

2.4.2 Retries

当有 error 发生时,需要进行 handle。error 分为两种:

retry 也有风险:

这些处理方式都需要根据业务需求,做出恰当的选择。

2.5 Using Consumers in a Reliable System

由于 Kafka broker 内部已经保证了返回给 consumer 的都是 committed data(保存到全部 in-sync replicas 中),所以 consumer 需要处理的事情就简单多了。但是 consumer 还需要能够正确的处理跟踪消息 offset & 处理消息,保证每次获取到的 message 的正确性,既不重复,也不缺失。

consumer 中有 4 个参数可以影响 reliable:

2.5.1 Consumer retry

有时,当 consumer poll 到 messages 后,处理 messages 时会发生错误,如短暂的写入 db 失败,但是又不想丢失消息,这时可以:

上一篇 下一篇

猜你喜欢

热点阅读