Kafka权威指南 读书笔记之(八)跨集群数据镜像

不同的集群之间相互依赖,管理员需要不停地在集群间制数据。大部分数据库都支持复制 ( replication ),也就是持续地在数据库服务器之间复制数据
为前面已经使用过“复制”这个词来描述在同个集群的节点间移动数据,所以我们把群间的数据复制叫作镜像 ( mirroring )。 Kafka 内置的跨集群复制工具叫作 MirrorMaker

我们将讨论跨集群的数据镜像,它们既可以镜像所有数据,也可以镜像部分数据;

然后介绍这些场景所使用的构模式,以及这些架构模式各自的优缺点 ;

接下来会介绍 MirrorMaker 以及如何使用它, 部署和性能调优时要注意的项;

最后对 MirrorMaker 的些替代方案进行比较

跨集群镜像的使用场景

区域集群和中心集群
  有多个数据中心,它们分布在不同的地理区域。这些数据中心都有自己的 Kafka 集群。有些应用程序只需要与本地的 Kafka 集群通信,
而有些则需要访问多个数据中心的数据(否则就没必要考虑跨数据中心的复制方案了)。一个典型的场景。该公司在每个城市都有一个数据中心,它们收集所在城市的供需信息,
并调整商品价格。这些信息将会被镜像到一个中心集群上,业务分析员就可以在上面生成整个公司的收益报告。

冗余( DR)
  一个 Kafka 集群足以支撑所有的应用程序,不过你可能会担心集群因某些原因变得不可用,所以你希望有第个 Kafka 集群,它与第一个集群有相同的数据,如果发生了紧急
情况,可以将应用程序重定向到第二个集群上。

云迁移
  有很多公司将它们的业务同时部署在本地数据中心和云端。为了实现冗余,应用程序通常会运行在云供应商的多个服务区域里,或者使用多个云服务。本地和每个云
服务区域都会有个 Kafka 集群。本地数据中心和云服务区域里的应用程序使用自己的Kafka 集群,当然也会在数据中心之间传输数据。例如,如果云端部署了一个新的应用
程序,它需要访问本地的数据。本地的应用程序负责更新数据,并把它们保存在本地的数据库里。我们可以使用 Connect 捕获这些数据库变更,并把它们保存到本地的 Kafka
集群里,然后再镜像到云端的 Kafka 集群上。这样有助于控制跨数据中心的流量成本,同时也有助于改进流量的监管和安全性。

 

多集群架构
  以下是在进行跨数据中心通信时需要考虑的些问题。

高延迟
  Kafka 集群之间的通信延迟随着集群间距离的增长而增加。虽然光缆的速度是恒定的,但集群间的网络跳转所带来的缓冲和堵塞会增加通信延迟。

有限的带宽
  单个数据中心的广域网带宽远比我们想象的要低得多,而且可用的带宽时刻在发生变化。另外,高延迟让如何利用这些带宽变得更加困难。

高成本
  不管你是在本地还是在云端运行 Kafka,集群之间的通信需要更高的成本。部分原因是因为带宽有限,而增加带宽是很昂贵的。

  Kafka 服务器和客户端是按照单个数据中心进行设计、开发、测试和调优的。假设服务器和客户端之间具有很低的延迟和很高的带宽,在使用默认的超时时间和缓冲区大小时
也是基于这个前提。因此,不建议跨多个数据中心安装 Kafka 服务器

  大多数情况下,要避免向远程的数据中心生成数据,但如果这么做了,那么就要忍受高延迟 ,并且需要通过增加重试次数( Linkedln 曾经为跨集群镜像设置了 32 000 多次重试
次数)和增大缓冲区来解决潜在的网络分区问题(生产者和服务器之间临时断开连接 )。

  果有了跨集群复制的需求,同时又禁用了从 broker 到 broker 之间的通信以及从生产者到broker 之间的通信,允许从 broker 到消费者之间的通信。
事实上,这是最安全的跨集群通信方式。在发生网络分区时,消费者无需从 Kafka 读取数据,数据会驻留在Kafka 里 , 到通信恢复正常。因 此,网 络分区不会造成任何数据丢失。
因为带宽有限,如果个数据中心的多个应用程序需要从另个数据中心的 Kafka 服务器上读取数据,倾向于为每个数据中心安装个 Kafka 集群,并在这些集群间复制数据,而不
是让不同的应用程序通过广域网访问数据。

些架构原则 :
• 每个数据中心至少需要个集群。
每两个数据中心之间的数据复制要做到每个事件仅复制次(除非出现错误需要重试)
• 量从远程数据中读取数据 ,而不是向远程数据中心写入数据。


Hub和 Spoke架构
这种架构适用于个中心 Kafka 集群对应多个本地 Kafka 集群的情况,如 示。

构有个简单的变种,如果只有个本地集群领和个跟随者,如图 所示。

   使用这种架构,它访问到局的数据集。这构的好处在于 ,数据只在本地的数据中生成,而且每个数据中的数据只会被像到中央数据中心次 。 
只处理单个数据中心数据的应用程序可以被部署在本地数据中心里, 而需要处理多个数据中心数据的应用程序需要被部署在中央数据中 里。
因为据复制是单向的,而且消费者总是从同个集群读取数据,所以这种架构易于部署、配置和监控

  这种架构的简单性也导致了些不足。一个数据中的应用程序无法访问另个数据中心的数据 。 家银行在不同的城市有多家分行。每个城市的 Kafka 集群上保存了用户的信和账号历史数据。
把各个城市的数据复制到个中集群上 这样银行就可以利用这些数据进行业务分析。 在用户访问银行网站或去他们所属的分行办理业务时,他们的请求被路由到本地集群上,
同时从本地集群读取数据。假设个用户去另个城市的分行办理务 ,因为他的信息不在这个城市,所以这个分行需要与远程集群发生交互(不建议这么做),
则根本没有办法访问到这个用户的信息(很尴尬) ,这种架构模式在数据访问方面有所局限,因为区域数据中之间的数据是完全独立的。

  采用这种架构时,每个区域数据中心的数据都要被镜像到中央数据中心上。镜像进程会读取每个区域数据中心的数据,并将它重新生成到 中心集群上。 果多个数据中心
出现了重名的题,那这些题的数据可以被到中心集群的单个题上 ,也可以被到多个主题上


双活架构
有两个或个数据中心要共数据并且每个数据中心都可以生产和读取数据时 可以使用双活( Active-Active )架构,如图 所示

 

  这种架构的主要好处在于,它可以为就近的用户提供服务,具有性能上的优势,而且不会因为数据的可用性问题(在 Hub 和 Spoke 架构中就有这种问题)在功能方面作出牺牲。第
个好处是冗余和弹性。因为每个数据中心具备完整的功能, 个数据中心发生失效,就可以把用户重定向到另一个数据中心。这种重定向完全是网络的重定向,因此
种最简单、最透明的失效备援方案。

  这种架构的主要问题在于,如何在进行多个位置的数据异步读取和异步更新时避免冲突。比如镜像技术方面的问题一一如何确保同个数据不会被无止境地来回镜像?而数据
性方面的问题则更为关键。下面是可能遇到的问题。

•  如果用户向个数据中心发送数据,同时从第个数据中心读取数据,那么在用户读数据之前,他发送的数据有可能还没有被镜像到第个数据中心。对于用户来说, 这就
 好比把本书加入到购物车,但是在他点开购物车时,书却不在里面。因此,在使用种架构时,开发人员经常会将用户“粘”在同个数据中心上,以确保用户在大多数
 况下使用的是同个数据中心的数据(除非他们从远程进行连接或者数据中心不可用)

•  一个用户在个数据中心订购了书 A ,而第个数据中心几乎在同时间收到了该用户订购书 B 的订单,在经过数据镜像之后,每个数据中心都包含了这两个事件。两个
    数据中心的应用程序需要知道如何处理这种情况。我们是否应该从中挑选个作为“确”的事件?如果是这样,我们需要在两个数据中心之间定义致的规则,用于确
    哪个事件才是正确的。又或者把两个都看成是正确的事件,将两本书都发给用 户,然后设立个部门专门来处理退货问题? Amazon 就是使用这种方式来处理冲突的,但
    对于股票交易部门来说,这种方案是行不通的。如何最小化冲突以及如何处理冲突要视具体情况而定。总之要记住,如果使用了这种架构,必然会遇到冲突问题,还要想
    办注解决它们。

  如果能够很好地处理在从多个位置异步读取数据和异步更新数据时发生的冲突问题,那我们强烈建议使用这种架构。这种架构是我们所知道的最具伸缩性、弹性、灵活性和成
优势的解决方案。所以,它值得我们投入精力去寻找些办法,用于避免循环复制、把同用户的请求粘在同个数据中心,以及在发生冲突时解决冲突。
双活镜像(特别是当数据中心的数量超过两个)的挑战之处在于,每两个数据中心之间需要进行镜像,而且是双向 的。如果有 5 个数据中心 ,那么就需要维护至少 20 个镜像进
程,还有可能达到 40 个,因为为了高可用,每个进程都需要冗余

  另外,我们还要避免循环镜像,相同的事件不能无止境地来回镜像。对于每个“逻辑题”,我们可以在每个数据中心里为它创建个单独的主题,并确保不要从远程数据中
制同名的主题。例如,对于逻辑主题“users”,我们在个数据中心为其创建“SF.users”主题,在另 个数据中心为其创建“ NYC.users”主题。镜像进程将 SF 的“ SF.
users”镜像到 NYC ,同时将 NYC 的" NYC.users”镜像到 SF。这样来,每个事件只被镜像次,不过在经过镜像之后,每个数据中心同时拥有了 SF.users 和 NYC.users 这
两个主题,也就是说,每个数据中心都拥有相同的用户数据。消费者如果要读取所有的用数据,就需要以“* .users”的方式订阅主题。我们也可以把这种方式理解为数据中心的
命名空间,比如在这个例子里, NYC 和 SF 就是命名空间

  在不久的将来, Kafka 将会增加记录头部信息。头部信息里可以包含源数据中心的信息,们可以使用这些信息来避免循环镜像,也可以用它们来单独处理来自不同数据中心的数
据。当然,你也可以通过使用结构化的数据格式(比如 Avro )来实现这一特性,并用它在数据里添加标签和头部信息 不过在进行镜像时,需要做些额外的工作,因为现成的镜
像工具并不支持自定义的头部信息格式。

主备架构
  有时候,使用多个集群只是为了达到灾备的目的。你可能在同个数据中心安装了两个集群 ,它们包相同的数据,平常只使用其中的主备( Active-Standby )架构示
意图如图 所示。

  这种架构的好处是易于实现,而且可以被用于任何种场景。你可以安装第个集群,然使用镜像进程将第个集群的数据完整镜像到第个集群上,不需要担心数据的访问和
冲突问题,也不需要担心它会带来像其他架构那样的复杂性。

  这种架构的不足在于,它浪费了个集群。 Kafka 集群间的失效备援比我们想象的要难得多。 从目前的情况来看,要实现不丢失数据或无重复数据的 Kafka 集群失效备援是不可能
的。我们只能尽量减少这些问题的发生,但无法完全避免。

  让个集群什么事也不做,只是等待灾难的发生,这明显就是对资源的浪费。有些组织尝试减小灾备集群的规模,让它远小于生产环境的集群规模。
这种做法具有定的风险,因为无法保证这种小规模的集群能够在紧急情况下发挥应有的作用 。有些组织则倾向于让灾备集群在平常也能发挥作用,他们把些只读的工作负载定向到灾备集群上,
也就说,实际上运行的是 Hub 和 Spoke 架构的个简化版本,因为架构里只有个 Spoke。那么问题来了 : 如何实现 Kafka 集群的失效备援?
不管选择哪种失效备援方案, SRE(网站可靠性工程)团队都必须随时待命每季度进行次失效备援是最低限度的要求, 个高效的 SRE 团队会更频繁地进行失效备援。 


1. 数据丢失和不一致性
  Kafka 的各种镜像解决方案都是异步的,所以备集群总是无法及时地获取主集群的最新数据。我们要时刻注意灾备集群与主集群之间
拉开了多少距离,并保证不要出现太大的差距。个繁忙的系统可以允许灾备群与主集群之间有几百个甚至几千个消息的延迟。
在进行计划内的失效备援时,可以先停止主集群,等待镜像进程将剩余的数据镜像完毕,然后切换到灾备集群,这样可以避免数据丢失。在发生非计划内的失效备援时,可能
丢失数千个消息。目前 Kafka 还不支持事务, 就是说,如果多个主题的数据(比如销售数据和产品数据)之间有相关性,那么在失效备援过程中, 些数据可以及时到达灾
备集群,而有些则不能。那么在切换到灾备集群之后,应用程序需要知道该如何处理没有相关销售信息的产品数据。

2. 失效备援之后的起始偏移量
  在切换到灾备集群的过程中,最具挑战性的事情莫过于如何让应用程序知道该从什么地方开始继续处理数据。下面将介绍一些常用的方法,其中有些很简单,但有可能会造成
额外的数据丢失或数据重复:有些则比较复杂,但可以最小化丢失数据和出现重复数据的可能性。

偏移量自动重置
  Kafka 消费者有个配置选项,用于指定在没有上个提交偏移的情况下该作何理。消费者要么从分区的起始位置开始读取数据,要么从分区的末尾开始读取数据

   如果重复处理数据或者丢失一些数据不会造成太大问题 ,那么重置偏移量是最为简单的方案。不过直接从主题的末尾开始读取数据这种方式或许更为常

复制偏移量主题
  如果使用新的 Kafka 消费者( 0.9 或以上版本),消费者会把偏移量提交到一个 __consumer_offsets 的主题上。如果对这个主题进行了镜像,那么当消费者开始读
  取灾备集群的数据时,它们就可以从原先的偏移量位置开始处理数据。这个看起来很简单,不过仍然有很多需要注意的事项。

    首先, 我们并不能保证主集群里的偏移量与灾备集群里的偏移量是完全匹配。假设主集群里的数据只保留 3 天,而你在一个星期之后才开始镜像,那么在这种情况下,主集群里
  第个可用的偏移量可能是 57 000 000 (前 4 天的旧数据已经被除了),而灾备集群里的个偏移量是 0,那么当消费者尝试从 57 000 003 处(因为这是它要读的下个数据)
  开始读取数据时,就会失败。
    其次,就算在主题创建之后立即开始镜像,让主集群和灾备集群的主题偏移量都从 0 始,生产者在后续进行重试时仍然会造成偏移量的偏离。简而言之,目前的 Kafka 镜像解
  决方案无法为主集群和灾备集群保留偏移量。
    最后,就算偏移量被完美地保留下来,因为主集群和灾备集群之间的延迟Kafka 缺乏对事务的支持,消费者提交的偏移量有可能会在记录之前或者记录之后到达。在发生失效
  备援之后,消费者可能会发现偏移量与记录不匹配,或者灾备集群里最新偏移量主集群里的最新偏移量小。如图 所示。

    在这些情况下,我们需要接受一定程度的重复数据。如果灾备集群最新的偏移量主集群的最新偏移量小,或者因为生产者进行重试导致灾备集群的记录偏移量主集群的记录偏
  移量大,都会造成数据重复。你还需要知道该怎么处理最新偏移量与记录不匹配的问题,

  此时要从主题的起始位置开始读取还是从末尾开始读取?
    复制偏移量主题的方式可以用于减少数据重复或数据丢失,而且实现起来很简单,只要及时地从 0 开始镜像数据,并持续地镜像偏移量题就可以了 。不过一定要注意上述的
  几个问题。

基于时间的失效备援
    如果使用的是新版本( 0.10.0 及以上版本)的 Kafka 消费者, 个消息里都包含了时间戳,这个时间戳指明了消息发送给 Kafka 的时间。 在更新版本的 Kafka (0.10.1.0
  及以上版本)里, broker 提供了个索引和个 API ,用于根据时间戳找偏移量。于是,假设你正在进行失效备援 , 并且知道失效事件发生在凌4:05 ,那么就可以让消费
  者从 4:03 的位置开始处理数据。在两分钟的时间差里会存在些重复数据,不过这种方式仍然比其他方案要好得多,而且也很容易向其他人解释一一 “我们将从凌晨 4:03
  的位置开始处理数据”这样的解释要比“我们从个不知道是不是最新的位置开始处理数据”要好得多 所以,这是种更好的折中 。问题是,如何让消费者凌晨 4:03 的
  位置开始处理数据呢?
    可以让应用程序来完成这件事情。 我们为用户提供个配置参数 ,用于指定从什么时间点开始处理数据。如果用户指定了时间,应用程序可以通过新的 API 获取指定时间的
  偏移量,然后从这个位置开始处理数据如果应用程序在开始就是这么设计的,那么使用这种方案就再好不过了。但果应用程序在开始不是这么设计的呢?开发个这样的小工具也并不难一一接收个时间
  戳,使用新的 API 获取相应的偏移,然后提交偏移量。 我们希望在未来的 Kafka 版里添加这样的工具,不过你也可以自己写一。在运行这个工具,应该先关闭消费者
  群组 在工具完成任务之后再启动它们。该方案适用于那些使用了新版 Kafka、对失效备援有明确要求并且喜欢自己开发工具的人

偏移量外部映射
    镜像偏移量主题的个最大问题在于主集群和灾备集群的偏移量会发生偏差。因此, 些组织选择使用外部数据存储(比如 Apache Cassandra ) 来保存集群之间
  的偏移量映射。他们自己开发镜像工具,在个数据被镜像到灾备集群之后,主集群和灾备集群的偏移量被保存到外部数据存储上。或者只有当两边的偏移量差值发生变
  化时,才保存这两个偏移量。 比如, 主集群的偏移495 被映射到灾备集群的偏移量500 ,在外部存储上记录为( 495,500 )。如果之后因为消息重复导差值发生变 化,
  移量 596 被映射为 600,那么就保留新的映射( 569,600 ) 他们没有必要保留 495 596 之间的所有偏移映射,他们假设差值都是样的,所以主集群的偏移量 550 会映
  射到灾备集群的偏移555。那么在发生失效备援时,他们将主集群的偏移量与灾备集群的偏移量映射起来,而不是在时间戳(通常会有点不准确)和偏移量之间做映射。他
  们通过上述技术手段之来强制消费者使用映射中的偏移量。 些在数据记录之前达到的偏移量或者没有及时被镜像到灾备集群的偏移量来说,仍然会有问题一一不过
  这至少已经满足了部分场景的求。
  
3 . 在失效备援之后
  假设失效备援进行得很顺利,灾备集群也运行得很正常,现在需要对主集群做些改动,比如把它变成灾备集群。
如果能够通过简单地改变镜像进程的方向,让它将数据从新的主集群镜像到旧的主集群上情就完美了 !不过,这里还存在两个问题。
•   怎么知道该从哪里开始镜像?我们同样需要解决与镜像程序里的消费者相关的问题。而且不要忘了,所有的解决方案都有可能出现重复数据或者丢失数据,或者两者兼有。
•   之前讨论过,旧的主集群可能会有些数据没有被镜像到灾备集群上,如果在这个时把新的数据镜像回来,那么历史遗留数据还会继续存在,两个集群的数据就会出现
基于上述的考虑,最简单的解决方案是清理旧的主集群,删掉所有的数据和偏移量,然后从新主集群上把数据镜像回来,这样可以保证两个集群的数据是致的

4 . 关于集群发现
  在设计灾备集群时,需要考虑个很重要的问题,就是在发生失效备援之后,应用程序需要知道如何与灾备集群发起通信。不建议把主集群的主机地址硬编码在生产者和消费
者的配置属性文件里大多数组织为此创建了 DNS 别名,将其指向主集群,一旦发生紧急情况 ,可以将其指向灾备集群。有些组织则使用服务发现工具,比如 Zookkeeper、 Etcd
或 Consul。这些服务发现工具(DNS 或其他)没有必要将所有 broker 的信息都包含在内,Kafka 客户端只需要连接到其中的一个 broker ,就可以获取到整个集群的元数据,并发现
集群里的其他 broker。 般提供 3 个 broker 的信息就可以了。除了服务发现之外,在大多数情况下,需要重启消费者应用程序,这样它们才能找到新的可用偏移量,然后继续读取
数据。


延展集群
  在主备架构里, Kafka 集群发生失效时,可以将应用程序重定向到另个集群上,以保证业务的正常运行。而在整个数据中心发生故障时,可以使用延展集群( stretch cluster)
来避免 Kafka 集群失效。延展集群就是跨多个数据中心安装的单个 Kafka 集群。

  延展集群与其他类型的集群有本质上的区别。首先,延展集群并非多个集群,而是单个集群,因此不需要对延展集群进行镜像。延展集群使用 Kafka 内置的复制机制在集群的broker 之间同步数据。
我们可以通过配置打开延展集群的同步复制功能,生产者会在消息成功写入到其他数据中心之后收到确认。同步复制功能要求使用机架信息,确保每个分区
在其他数据中心都存在副本,还需要配置 min. isr和 acks=all ,确保每次写入消息时都可以收到至少两个数据中心的确认。

  同步复制是这种架构的最大优势。有些类型的业务要求灾备站点与主站点保持 100% 的同 步,这是种合规性需求,可以应用在公司的任何个数据存储上,包括 Kafka 本身。这
种架构的另个好处是,数据中心及所有 broker 都发挥了作用,不存在像备架构那样的资源浪费。

  这种架构的不足之处在于,它所能应对的灾难类型很有限,只能对数据中心的故法应对应用程序或者 Kafka 故障。运维的复杂性是它的另个不足之处,它所要的物
基础设施并不是所有公司都能够承担得起的。

  如果能够在至少 3 个具有高带宽和低延迟的数据中心上安装 Kafka (包括 Zookeeper),那么就可以使用这种架构。如果你的公司有 3 栋大楼处于同个街区,或者你的应商在
个地区有 3 个可用的区域,那么就可以考虑使用这种方案。

  为什么是 3 个数据中心? 要是因为 Zookeeper。 Zookeeper 要求集群里的节个数是奇数,而且只有当大多数节点可用时,整个集群才可用。如果只有两个数据中心和奇数个节
点,那么其中的个数据中心将包含大多数节点,也就是说,如果这个数据中心不可用,那么 Zookeeper 和 Kafka 也不可用。如果有 3 个数据中心,那么在分配节点时,可以做
每个数据中心都不会包含大多数点。如果其中的个数据中心不可用, 他两个数据中心包含了大多数节点,此时 Zookeeper 和 Kafka 仍然可用
  从理论上说,在两个数据中心运行 Zookeeper 和 Kafka 是可能的,只要将 Zookeeper 的组配置成允许手动进行失效备援 不过在实际应用 中,这种做法并不常见

Kafka的 MirrorMaker
  Kafka 提供了 个简单的工具,用于在两个数据中心之间镜像数据 这个 工具 MirrorMaker,它包含了 组消费者(因为历史原因,它们在 MirrorMaker 文档里被称
),这些消费者属于同个群组,并从主题上读取数据。每个 MirrorMaker 进程都有单独的生产者。

镜像过程很简单: MirrorMaker 为每个消费者分配个线程,消费源集群的主题和分区上读取数据,然后通过公共生产者将数据发送到目标集群上。
默认情况下,消费者每 60 秒通知生产者发送所有的数据到 Kafka,并待 Kafka 的确认 后消费者再通知源集群提交这些事件相应的偏移量。
这样可以保证不失数据(源集群提交偏之前, Kafka 对消息进行了确认),而且如果 MirrorMaker  进程发生崩溃,最多只会出现 60 秒的重复数据。见图 

如何配置
  MirrorMaker 是高度可配置它使用了个生产者和多个消费者,生产者和消费者的相关配置参数都可以用于配置 MirrorMaker。另外, MirrorMaker 本身也有一些配
置参数,这些配置参数之间有时候会有比较复杂的依赖关系。下面将举一些例子,并着重说明些重要的配置参数。

接下来分别说明 MirrorMaker 的基本命令行参数。
consuMer.config
  该参数用于指定消费者的配置文件。所有的消费者将共用这个配置,也就是说,只能配置个源集群和个 group.id。所有的消费者属于同 个消费者群组,这正好与我们
  的要求不谋而合。配置文件里有两个必选的参数 : bootstrap.servers (源集群的服务器地址)和 group.id。除了这两个参数外,还可以为消费者指定其他任意的配置参数。
  autocommit.enable 参数 般不需要修改,用默认值 false 就行。 MirrorMaker 会在消息安全到达目标集群之后提交偏移量,所以不能使用自动提交。如果修改了这个参数,
  可能会导致数据丢失。 auto.offset.reset 参数一般需要进行修改,默认值是 latest,也就是说, MirrorMaker 只对那些在 MirrorMaker 启动之后到达源集群的数据进行镜像。
  如果想要镜像之前的数据,需要把该参数设为 earliest

producer.config
  该参数用于指定生产者的配置文件。配置文件里唯一必选的参数是 bootstrap.servers(目标集群的服务器地址)。

new.consumer
  MirrorMaker 只能使用 0.8 版本或者 0.9 版本的消费者。建议使用 0.9 版本的消费者,因为它更加稳定。

num.streams
   个流就是个消费者。所有的消费者共用个生产者, MirrorMaker将会使用这些流来填充同个生产者。如果需要额外的吞吐量,就需要创建另MirrorMaker 进程。
whitelist
  这是个正则表达式,代表了需要进行镜像的主题名字。所有与表达式匹配的题都将被镜像。

 

在生产环境部署 MirrorMaker

  在生产环境, MirrorMaker 作为后台服务运行的,而且是以 nohup 的方式运行,并将控制台的输出重定向到个日
文件里。这个工具有个- deamon 命令行参数。理论上,只要使用这个参数就能后台运行,不需要再做其他任何事情,但在实际当中,最近发布的些版本不能如我们所
望的那样。

  大部分使用 MirrorMaker  的公司都有自己的启动脚本,他们使用部署系 Ansible 、 Puppet 、 Chef 和 Salt )实现自动化的部署和配置管理。

  在 Docker 容器里运行 MirrorMaker 变得越来越流行 MirrorMaker 是完全 状态的,也不需要磁盘存储(所有的数据和状态都保存在 Kafka 上) 将 MirrorMaker
装在 Docker 里,就可以实现在单台主机上运行多个 MirrorMaker 因为 单个MirrorMaker 实例的吞吐量受限于单个生产者,所以为了提升要运行多个
MirrorMaker 实例,而 Docker 简化了这 过程。 Docker 也让 MirrorMaker 的伸 缩变得更加容易,在流量高峰时,可以通过增加更多的容器来提升
则减少容器。如果在云端运行 MirrorMaker ,根据吞吐实际情况, 以通过增加额外的服务器来运行 Docker 容器。

  如果有可能,尽量让 MirrorMaker 运行在目标数据中心里 也就是说,如要将 NYC 数据发送到 SF, MirrorMaker 应该运行在 SF 的数据中心里 因为长距离的外部网
据中心的内部网络更加不可靠,如果发生了网络分区,数据中心之间的断开了连接, 那么个无法连接到集群的消费者要比个无法连接到集群的生产者要安多。 如果消费
者无法连接到集群,最多也就是无法读取数据,数据仍然在 Kafka 集群里保留很长的一段时间,不会有丢失的风险。相反,在发生网络分区时,如MirrorMaker 已经读取
了数据,但无法将数据生成到目标集群上,就会造成数据丢失。 所以说, 远程读取比程生成更加安全。

  那么,什么情况下需要在本地读取消息并将其生成到远程数据中心呢?如果需要密传输数据,但又不想在数据中心进行加密,就可以使用这种方式。 消费者通过 SSL 连接
到 Kafka 对性能有定的影响,这个比生产者要严重得多,而且这种性能问题也会影响broker。如果跨数据中心流量需要加密,那么最好把 MirrorMaker 放在源数据中心, 让它
读取本地的非加密数据,然后通过 SSL 连接将数据生成到远程的数据中心 这个时候, 使用 SSL 连接的是生产者,所以性能问题就不那么明显了。在使用这种方式时, 要确
MirrorMaker 在收到目标 broker 副本的有效确认之前不要提交偏移,并在重试次数超出
限制或者生产者缓冲区植出的情况下立即停止镜像。

  如 希望减小源集群和目标集群之间的延迟,可以在不同的机器上运行至少两个MirrorMaker 实例,而且它们要使用相同的消费者群组。也就是说,如果关掉其中台服务
另一个 MirrorMaker 实例能够继续镜像数据。


在将 MirrorMaker 部署到生产环境时,最好要对以下几项内容进行监控。

迟监控
  我们绝对有必要知道目标集群是否落后于源集群。延迟体现在源集群最新偏移量和目标群最新偏移的差异上。见图  。

源集群的最后个偏移量是 7 ,而目标集群的最后一个偏移量是 5 ,所以它间有两个消息的延迟。

两种方式可用于跟踪延迟,不过它们都不是完美的解决方案。
•  检查 MirrorMaker 提交到拥集群的最新偏移量。可以使用 kafka-consumer-groups 工具检查 MirrorMaker 读取的每个分区,查看分区的最新偏移量,也就是 MirrorMaker 提交
 的最新偏移量。不过这个偏移量并不会 100% 的准确,因为 MirrorMaker 不会每时每刻都提交偏移,默认情况下,它会每分钟提交

•  检查 MirrorMaker 读取的最新偏移量(即使还未提交 。消费者通过 JMX 发布关键性度指标,其中有个指标是指消费者的最大延迟(基于它所读取的所有分区计算得出的)。
 这个延迟也不是 100% 的准确,因为它只反映了消费者读取的数据,并没有考虑生产者否成功地将数据发送到目标集群上。

度量指标监控
  MirrorMaker 内嵌了生产者和消费者,它们都有很多可用的度量指标,所以建议对它们进行监控。 Kafka 文档列出了所有可用的度量指标。下面列出了几个已经被证明能够
  升 MirrorMaker 性能的度量指标。
  消费者

生产者

同时适用于两者

canary
  如果对所有东西都进行了监控,那么 canaη 就不是必需的,不过对于多层监控来说,can町可能还是有必要的。我们可以每分钟往拥集群的某个特定主题上发送事件,
  然后尝试从目标集群读取这个事件。如果这个事件在给定的时间之后才到达,那么就出告警,说明 MirrorMaker 出现了延迟或者已经不正常了。

MirrorMaker调优

  MirrorMaker 集群的大小取决于对吞吐量的需求和对延迟的接受程度。如果不允许有任何延迟,那么 MirrorMaker 集群的容量需要能够支撑吞吐量的上限。如果可以容忍些延迟
那么可以在 95%~99% 的时间里只使用 75%-80% 的容量。在吞吐量高峰时可以允许一些延迟,高峰期结束时,因为 MirrorMaker 些空余容量,可以很容易地消除延迟。
  
你可能想要分离比较敏感的主题,它们要求很低的延迟,所以其镜像必须尽可能地接近源集群和 MirrorMaker 集群。这样可以避免主题过于臃肿,或者避免出现失控的生产

者拖慢数据管道。


如果 MirrorMaker 是跨数据中心运行的,可以在 Linux 上对网络进行优化。

 

  要注意,在 Linux 上进行网络调优包含了太多复杂的内容。为了了解更多参数和细节,建议阅读相关的网络调优指南。 例如,由 Sandra K.Johnson 等人合著的 Peiformance tuning
for Linux servers 。

  除此以外,你可能还想对 MirrorMaker 里的生产者和消费者进行调优。首先,你想知道生产者或消费者是不是瓶颈所在一一生产者是否在等待消费者提更多的数,或者其他的
什么?通过查看生产者和消费者的度量指标就可以知道问题所在了 ,如果其中的个进程而另外个很忙,那么就知道该对哪个进行调优了。另外种办怯是查看线程转储
(thread dump ),可以使用 jstack 获得线程转储。如果 MirrorMaker 的大部分时间用在轮那么说明消费者出现了瓶颈,如果大部分时间用在发送上,那么就是生产者出现了瓶颈。
如果需要对生产者进行调优,可以使用下列参数。

max.in.flight.requests.per.connection
  默认情况下, MirrorMaker 只允许存在个处理中的请求。也就是说,生产者在发送下一个消息之前 当前发送的消息必须得到目标集群的确认。这样会对吞吐量造成限
  制,特别是当 broker 在对消息进行确认之前出现了严重的延迟。 MirrorMaker 之所以要限定请求的数量,是因为有些消息在得到成功确认之前需要进行重试,而这是唯一能
  够保证消息次序的方法。如果不在乎消息的次序,那么可以通过增加 max.in.flight.requests.per.connection 的值来提升吞吐量。

linger.msbatch.size
  如果在进行监控时发现生产者总是发送未填满的批次(比如,度量指标 batch-size-avgbatch-size - max 的值总是比 batch.size 低,那么就可以通过增一些延迟来提升吞
  吐量。通过增加 latency.ms 可以让生产者在发送批次之前等待几毫秒,让批次填充更多的数据。如果发送的数据都是搞批次的,同时还有空余的内存,那么可以配置更大的
  batch.size ,以便发送更大的批次

下面的配置用于提升消费者的吞吐量。
•  range 。 MirrorMaker 默认使用 range 策略(用于确定将哪些分区分配给哪个消费者的算法)进行分区分配。 range 策略有一定的优势
  不过range 策略会导致不公平现象。对于 MirrorMaker 来说,最好可以略改为round robin ,特别是在镜像大量的主题和分区的时候将策略改为round robin 算法,
  需要在消费者配置属性文件里加上 partition.assignment.strategy=org.apache.kafka.clients.consumer.RoundRobinAssignor
•  fetch.max.bytes 。如果度盘指标显示 fetch-size - avg 和 fetch - size-max 的数值与 fetch.max.bytes 很接近,说明消费者读取的数据已经接近上限。如果有更多的可用内存,可
  以配置更大的 fetch.max.bytes ,消费者就可以在每个请求里读取更多的数据
•  fetch.min.bytes 和 fetch.max.wait。如果度量指标 fetch - rate 的值很高,说明消费者发送的请求太多了,而且获取不到足够的数据。这个时候可以配置更大的 fetch.min.bytes 和 fetch.max.wait
 这样消费者的每个请求就可以获取到更多的数据, broker 等到有足够多的可用数据时才将响应返回。


其他跨集群镜像方案(略)

posted @ 2018-10-10 13:09  青青子衿J  阅读(1586)  评论(0编辑  收藏  举报