Kafka 的集群复制设计 已翻译 100%

oschina 投递于 2013/07/31 08:13 (共 13 段, 翻译完成于 08-05)
阅读 6376
收藏 10
2
加载中
目录:

Kafka副本协议总体设计

在Kafka中添加副本的目的是更强的持久性和更高的可用性。我们想要保证成功发布的消息不会丢失而且可以被使用,即使在某些服务器发生故障的时候。这些故障可以是由机器错误、程序错误,或者更普遍的软件升级引起的。我们有下述总体的目标:

  1. 可配置的持久性保证:例如,带有关键数据的应用可以选择较强的持久性,这样会增加写操作的延迟,另外某个生成大量软状态数据(soft-state date)的应用可以选择较弱的的持久性,这样具有更快的响应时间。
  2. 自动的副本管理:我们想要简化副本到代理服务器(broker servers)的分配,使得可以增量地扩展集群。

在这里我们主要想解决两个问题:

  1. 如何将一个分区的副本均匀的分配给代理服务器?
  2. 对于一个给定的分区,如何将每个消息传播给所有副本?
袁不语
袁不语
翻译于 2013/07/31 14:55
1

副本位置

初始位置

(仅仅新建主题,基于当前运行着的代理服务器做决定(手工新建主题命令);重新分配命令(基于新集群拓扑重新计算分配,移动每个分区)进行迁移)
首先我们使用管理api新建初始代理服务器(brokers)集合:

create cluster with brokers broker-0, broker-1, broker2

然后我们使用另外一个管理api新建一个主题(topic):

create topic topicX with100partitions

在此之后,下述信息将会注册到zookeeper中:

  1. 一个代理服务器列表;
  2. 一个主题列表,对于每个主题具有一个分区(partitions)列表。

为了更好的负载均衡,我们想要过度划分主题。通常会有比服务器更多的分区。对于每个主题,我们想要在所有服务器均匀地划分分区。我们对代理服务器列表和分区列表进行排序。如果有n个代理服务器,我们将第i个分区分配给第i mod n个代理服务器。该分区的第一个副本将会放置在该分配的代理服务器上,并且做为该分区的优先副本。如果一台代理服务器发生故障,我们想要以同样的方式放置其它副本,这样故障服务器负载将会均匀地转移到所有存活的代理服务器上,而不是转移到某一台上。为了实现该目标,假设有m个分区分给了代理服务器i。分区k的第j个副本将会放置在代理服务器(i+j+k)mod n上。 The following figure illustrates the replica assignments for partitions p0 to p14 on brokers broker-0 to broker-4. In this example, if broker-0 goes down, partitions p0, p1, and p2 can be served from all remaining 4 brokers. We store the information about the replica assignment for ach partition in Zookeeper.【译者注:没有图,所以就不翻译了】

袁不语
袁不语
翻译于 2013/07/31 15:06
1

增量添加在线代理服务器

我们可以用下述管理命令增量地扩展代理服务器集合。

alter cluster add brokers broker-3, broker-4

当添加新的代理服务器后,将会自动地将某些分区迁移到新的代理服务器。我们的目标是使迁移的数据最小化,同时维护均衡的负载。我们使用一个独立的协调进程实现再均衡,后面给出了算法。

袁不语
袁不语
翻译于 2013/07/31 15:19
1

代理服务器下线

我们也可以使用下述管理命令通过使部分代理服务器下线而缩小集群。

alter cluster remove brokers broker-1

这将会在broker-1上启动一个重新分配分区的进程。一旦完成,broker-1将会下线。该命令也会删除broker-1的状态改变路径。

袁不语
袁不语
翻译于 2013/07/31 15:20
1

数据复制

我们想让客户端来选择异步或同步复制. 对于异步的情况, 当发布的消息数量达到1的时候就进行复制. 对于同步复制, 当消息达到一定的数量时才进行最大能力的复制. 当一个客户端试图发布一条消息给主题的一个分区时, 我们必须把这条消息传送给所有的副本. 我们必须决定:

  1. 如何传递这条消息;
  2. 多少个副本接收这条消息;
  3. 副本接收完成后如何处理;
  4. 当一个副本复制失败后如何处理.

我们将在2.1节介绍目前的复制策略. 然后在2.2和2.3节分别介绍同步和异步复制.

-V-
-V-
翻译于 2013/08/01 10:51
1

相关的工作

保持同步复制有两个常见的策略:主备复制和仲裁复制。在这两种情况下,指定一个复制者为领导者,其余的复制者称作追随者。所有的写请求都是通过领导者来进行的,然后领导者把这样的写传递给追随者。

在主备复制里,领导者向客户端确认之前要等到同一组中的每个复制者的写都完成。如果其中的一个复制者无法进行,那么领导者就从当前组中删除这个复制者,然后继续写剩余复制者。如果一个失效的复制者恢复,那么允许它重新加入到这个组,并紧紧追随领导者。假若有f个复制者的话,主备复制可以容忍f-1个失效者。

几点人
几点人
翻译于 2013/08/04 11:25
1

在仲裁复制里,领导者等到大多数复制者的写完成时为止。辅助组的大小不能更改,甚至在一些复制者无法写的情况下。如果有2f+1个复制者,那么仲裁复制可以容忍f个失效者。如果领导者失效了,那么至少需要f+1个复制者推选出新的领导者。

两种复制方式的比较:

  1. 仲裁复制比主备复制有更少的写延迟。后者的任意一个复制的延迟(例如,较长时间的垃圾回收)都会增加写延迟,而前者不会这样。
  2. 给定相同数目的复制者,主备复制可容忍更多的并发失效。
  3. 两个复制者使用主备复制运行良好。而在仲裁复制里,需要大于两个的复制者才能使系统可用。
在kafka里我们选择主备复制,因为它能容忍更多的失效,并且两个复制者也运行良好。当一个复制下线或者变得很慢的时候,短暂的失效就可能发生。不过这是相当稀少的事情,可以通过调整不同的超时参数来缩短短暂失效的时间。

几点人
几点人
翻译于 2013/08/04 11:44
1

同步复制

我们的同步复制遵循典型的主备复制方法。每个分区有n个复制者且可以容忍n-1个复制者失效。选一个复制者做为领导者,其余的复制者为追随者。领导者维护一组同步复制者(ISR):这组复制者完全跟随领导者。在每个分区里,我们把当前的领导者和当前的同步复制组存储在Zookeeper里。

每个复制者都在本地日志里存储消息,并且维护在这个日志里维护着几个重要的偏移位置(如图1所描述)。日志最终偏移(LEO)表示日志的结尾。高水位(HW)表示的最近一次提交消息的偏移位置。每个日志都定期地同步到磁盘。重写偏移量之前的数据确保已经永久的保存在磁盘上。 正如我们将看到的,重写的偏移可能在HW之前后者之后。

几点人
几点人
翻译于 2013/08/04 12:08
1

要发布消息到分区上,客户端首先要从Zookeeper里找到分区的领导者,然后发送消息给领导者。领导者写消息到自己的本地日志。每个追随者使用一个单独的套接字通道不断地从领导者哪儿拉取新消息。这样,追随者按照领导者里写入的同样的顺序接收所有消息。追随者把接收到的咩歌消息写到自己的日志,然后给领导者回复确认。一旦领导者接收到了同步复制组(ISR)里所有复制者的确认,这个消息才算提交了。领导者向前挪动HW,然后发送确认给客户端。为了得到更好的性能,每个追随者在消息写入内存之后就发送确认。因此,对于每个已经提交的消息来说,我们要确保消息已经存储在多个复制者的内存里了。不过,仍然不能确保任何一个复制者都永久地把提交的消息保存在磁盘。假设关联的失效相对稀少,那么这种方式就给我们在响应时间和持久性之间一个很好的平衡。未来,我们可能考虑增加提供更强有力保证的选项。领导者还可以定期地广播HW给所有的追随者。广播消息可以装载在追随者获取请求的返回值里。每个复制者时不时的检查它磁盘的HW。
几点人
几点人
翻译于 2013/08/04 12:42
1

为了简化起见,读总是由领导者来执行。呈现给读取者的消息最多达HW处。

失效的场景

追随者失效
经过了配置的超时时长之后,领导者从它的同步复制组(ISR)里删除失效的追随者,然后继续向同步复制组(ISR)剩余的复制者里写。如果复制者恢复,那么它首先清除自己的日志到最后一次检查的HW处。然后开始从领导者抓取自己HW之后的所有消息。当追随者完全抓取完成这之后,领导者才把它加回到当前的同步复制组(ISR)里。
几点人
几点人
翻译于 2013/08/04 12:43
1
本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接。
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。
加载中

评论(3)

qwfys
qwfys
~~
散关清渭
散关清渭
https://cwiki.apache.org/confluence/display/KAFKA/Kafka+Replication
g
good-luck
翻译的真棒!
返回顶部
顶部