Original URL:https://amazonaws-china.com/cn/blogs/big-data/best-practices-for-running-apache-kafka-on-aws/
注意: 本文的撰写时间早于 Amazon MSK 的上线日期。Amazon MSK 是一项面向 Apache Kafka 的全托管、高可用性、高安全性服务。我们建议您直接使用 Amazon MSK,而非在 EC2 实例中运行您自主管理的 Apache Kafka 集群。当然,如果您需要在 EC2 上运行 Apache Kafka,那么本文提供的最佳实践与指导方针仍然适用。
本文是与 Intuit 公司合作撰写的特约文章,旨在分享在 AWS 上运行 Apache Kafka 集群的经验、最佳实践与建议。感谢 Vaishak Suresh 以及 Intuit 公司各位同事们的贡献与支持。
援引 Intuit 公司的自我评价:Intuit 是一家领先的 AWS 企业客户,为市场提供各类业务与财务管理解决方案。关于 Intuit 公司与 AWS 合作的更多详细信息,请参阅我们之前发布的《在AWS上使用Apache Spark Streaming与Apache Kafka实现实时流处理》博文。Apache Kafka 是一套开源分布式流平台,可帮助用户构建各类实时流式应用程序。
本文中提到的各项最佳实践,基于我们两年多以来在 AWS 上运行及操作大规模 Kafka 集群所积累到的经验心得。本文的目标在于帮助各位正在 AWS 上运行 Kafka 集群、以及正在考虑将本地 Kafka 部署迁移至 AWS 的客户找到更理想的实现途径。
AWS 也提供Amazon Kinesis Data Streams,一项 Kafka 替代性全托管服务。
在 Amazon EC2 上运行 Kafka 部署能够带来一种高性能且可扩展性强的解决方案,高效实现流数据提取。AWS 为 Kafka 部署提供多种不同的实例类型与存储选项组合,因此带来的部署拓扑也会非常的复杂与丰富,用户要找到最符合自身需求的配置也非常困难。
在本文中,我们将从以下几个方面探索在 AWS 上搭建与维护 Kafka 集群的诀窍:
部署注意事项与模式选择
存储选项
实例类型
网络
升级
性能调优
监控
安全性
备份与恢复
注意:在生产环境中部署 Kafka 集群时,大家还需要考虑一系列重要因素,例如消息数量、消息大小、监控、故障处理以及其他运维问题。
部署注意事项与模式选择
在本节中,我们将探讨适用于 AWS 平台的各种 Kafka 部署选项,以及各个选项的优缺点。一套成功的部署方案必须考虑到这些具体选项,并在实际选择时充分考虑到可用性、一致性以及运维成本等因素。
单 AWS 区域、三可用区、全主动模式
一种典型的部署模式(全主动模式)是在单一 AWS 区域之内使用三个可用区。每个可用区内部署一套 Kafka 集群,同时附带 Apache ZooKeeper 与 Kafka 生产/消费实例,具体如下图所示。
在这种模式下,Kafka 集群部署具有以下特征:
Kafka 生产实例与 Kafka 集群部署在同一可用区内。
使用 Elastic Load Balancer 将数据均匀分发至三个 Kafka 集群当中。
Kafka 消费实例将来自三个 Kafka 集群的数据聚合起来。
Kafka 集群的故障转移则通过以下方式实现:
标记所有 Kafka 生产实例。
停止消费实例。
调度并重新堆叠 Kafka。
重启消费实例。
重启 Kafka 生产实例。
下面来看这种模式的优势与缺点。
优势
高可用性
可承受两个可用区发生故障。
故障转移期间不存在消息丢失。
部署难度低。
缺点
运维较高:
所有变更都需要部署三次,每个 Kafka 集群部署一次。
需要对三个 Kafka 集群进行维护与监控。
需要对三个消费集群进行维护与监控。
必须重新启动才能修复并升级 Kafka 集群中的代理。在这种模式下,我们需要对各个集群分别进行滚动升级。
单一区域、三个可用区、主-备模式
另一种典型的部署模式(主-备)是在单一 AWS 区域内部署单一 Kafka 集群,而各 Kafka broker 及 ZooKeeper 则分布在三个可用区之间。另外建立一个类似的 Kafka 集群充当备用集群,详见下图。我们可以通过 MirrorMaker 使用 Kafka 镜像功能,借此在任意两个集群之间复制消息内容。
在这种模式下,Kafka 集群部署将具有以下特征:
Kafka 生产实例将被部署在全部三个可用区内。
只有一个 Kafka 集群跨三个可用区进行部署(主动)。
ZooKeeper 实例将被部署在所有可用区内。
代理均匀分布在全部三个可用区内。
Kafka 消费实例可跨全部三个可用区进行部署。
部署体系内还包含备用 Kafka 生产实例以及一个多可用区 Kafka 集群。
Kafka 集群的故障转移通过以下方式实现:
将流量切换至备用 Kafka 生产集群与 Kafka 集群。
重新启动消费实例以对接备用 Kafka 集群。
下面来看这种模式的优势与缺点。对于 0.10 或更低的 Kafka 版本,我们需要额外分配主题副本,以便将各副本分配给不同可用区上的代理(机架感知)。
优势
与第一种模式相比,运维成本更低。
只需要一套 Kafka 集群即可实现数据的管理与消费。
可以在不激活备用 Kafka 集群的前提下处理单可用区故障。
缺点
由于需要在各 Kafka broker 之间进行跨可用区数据传输,因此延迟将相应增加。
对于 0.10 或更低的 Kafka 版本,我们需要额外分配主题副本,以便将各副本分配给不同可用区上的 broker(机架感知)。
一旦出现网络故障(ZooKeeper 无法识别 Kafka 代理),则集群可用性可能受到影响。
故障转移期间,传输中的消息可能丢失。
Intuit 公司建议在单一 AWS 区域内使用单一 Kafka 集群,并将 broker 分布在三个可用区(即单区域、三可用区模式)当中。这种模式拥有远超其他模式的容错能力,可用区故障亦不会导致 Kafka 停机。
存储选项
我们可以通过以下两种存储选项,在 Amazon EC2 中实现文件存储:
临时存储位于 Amazon EC2 实例之内。这种方式可以根据实例类型提供较高的 IOPS。另一方面,Amazon EBS 存储卷则拥有更高的弹性水平,用户可以根据存储需求对 IOPS 进行单独配置。EBS 存储卷在恢复时间方面也拥有明显的优势。大家选择的存储方案在很大程度上由 Kafka 集群所支持的工作负载类型决定。
Kafka 提供内置容错机制,可跨越多个实例(可配置具体数量)复制数据分区。一旦某个代理发生故障,用户可以从集群当中托管有其他副本的各代理处提取数据并实现恢复。取决于数据传输的实际大小,恢复过程与相关网络流量也有可能存在很大差别。这些反过来,又会最终影响到集群的整体性能。
下表对比了使用实例存储与使用 EBS 存储的具体优势。
实例存储
对于中大型 Kafka 集群,建议大家使用实例存储。这是因为在规模较大的集群当中,读取/写入流量将分布在大量代理当中,因此单一代理丢失所产生的影响较小。但对于规模较小的集群,故障节点的快速恢复则变得非常重要。因此如果使用实例存储,则小型 Kafka 集群中恢复故障代理的时间周期将更长,且会造成更多的网络传输流量。
对于 h1、i3 以及 d2 这样的存储优化型实例,特别适合充当 Kafka 这类分布式应用程序的存储方案。
EBS
在 Kafka 部署中使用 EBS 的主要优势在于,一旦代理发生故障或者因其他原因而需要更换,EBS 能够显著减少数据传输流量。替换用代理可以更快加入集群。
当实例发生故障或终止时,存储在 EBS 上的数据将得到保留。存储在 EBS 存储卷上的代理数据将保持不变,用户能够将该 EBS 存储卷挂载至新的 EC2 实例之上。被替代的代理中的大部分复制数据已经被保存在 EBS 存储卷内,无需通过网络从其他代理处复制。只有初始代理发生故障时,后续变更才需要在网络上传输。这将显著加快代理的恢复速度。
Intuit 公司之所以选择 EBS,是因为其业务经常需要对实例进行重新调整部署,而且 EBS 还能够提供其他一些额外助益。
Kafka 部署中通常使用的复制因子为 3。考虑到 EBS 在其自身存储层也有多副本机制,因此 Intuit 选择的 Kafka 的复制因子为 2(而非 3)。
实例类型
实例类型的选择,通常由 Kafka 集群上流式应用程序所需要的存储类型决定。如果您的应用程序需要临时存储,那么 h1、i3 以及 d2 实例往往是大家的最佳选项。
Intuit 公司使用 r3.xlarge 实例对应代理,r3.large 对应 ZooKeeper,并使用 ST1(吞吐量优化型磁盘驱动器)EBS 匹配 Kafka 集群。
下面来看 Intuit 测试中的基准示例配置:
配置
r3.xlarge
ST1 EBS
12 brokers
代理字节 (MB/s)
12 分区
总计 346.9
如果需要使用 EBS 存储,不妨考虑 AWS 提供的新型 r4 实例。相较于原有 R3 实例,此 r4 实例在以下方面有所提升:
处理器速度更快(Boradwell 架构)。
默认对 EBS 进行优化。
具有基于弹性网络适配器(ENA)的网络功能,能够在较低配置条件下实现 10 Gbps 传输速率。
使用成本比 R3 实例低 20%。
注意:最佳实践建议大家始终检查实例类型的最新变更。
网络
对于 Kafka 这类分布式系统,网络无疑扮演着非常重要的角色。快速可靠的网络将保证各节点之间能够轻松通信,而可用的网络吞吐量上限则控制着 Kafka 能够处理的最大流量。网络吞吐量与磁盘存储通常是决定集群大小的主要因素。
如果大家希望集群能够接收高读取/写入流量,请选择提供 10 Gb/s 传输性能的实例类型。
此外,请通过选项保证代理间的网络流量保持在专用子网之内,这意味着客户端将能够接入各代理。代理与客户端之间的通信将使用相同的网络接口与端口。关于更多详细信息,请参阅EC2实例IP寻址说明文档。
如果大家需要在一个以上的 AWS 区域内部署集群,则可使用跨区域 VPC 对等网络连接位于两个 AWS 区域内的两个 VPC。但请注意,跨可用区部署场景会带来网络传输成本。
升级
Kafka 在发展早期对向下兼容不够重视,但随着项目发展,其向下兼容性也做得越来越好。在 Kafka 升级期间,大家应该确保生产者与消费者客户端的版本等于或低于当前待升级版本。升级完成之后,大家即可开始使用新的协议版本及其支持的一切新功能。目前我们可以通过三种方式进行升级,下面具体展开讨论。
滚动升级或就地升级
在滚动或就地升级场景下,我们每次只对一个 Kafka broker 进行升级。这里推荐大家选择滚动重启方案以避免给最终用户带来停机影响。
停机升级
如果您可以接受停机,则可暂时关闭整个集群,升级各个 Kafka broker 而后重新启动集群。
蓝/绿升级
Intuit 公司选择蓝/绿部署模式处理其工作负载,下面来看更多详细情况。
如果您能够构建起另一个独立的 Kafka 集群并对其进行升级,我们强烈建议您使用蓝/绿升级方案。在这种情况下,推荐大家使用最新 Kafka 版本以使集群保持最新。关于 Kafka 版本升级的更多详细信息,请参阅Kafka升级说明文档。
下图所示,为蓝/绿升级模式的基本架构。
在这种情况下,升级的具体流程为:
在 AWS 上创建一个新的 Kafka 集群。
创建一个新的 Kafka 生产栈并指向新的 Kafka 集群。
在新的 Kafka 集群上创建主题。
端到端测试绿部署(合理性检查)。
使用 Amazon Route 53 将 AWS 上的新 Kafka 生产栈指向之前创建的新绿 Kafka 环境。
回滚的具体流程为:
使用 Amazon Route 53 将 AWS 上的旧 Kafka 生产线指向旧有 Kafka 环境。
关于使用 Kafka 蓝/绿部署架构的更多详细信息,请参阅 re: Invent 大会演示文稿《通过蓝/绿部署架构运用云资源》。
性能调优
大家可以在多个维度上实现 Kafka 的性能调优。下面来看部分性能优化最佳实践。
以下是部分常规性能调优方法:
如果吞吐量低于网络容量,则尝试以下方法:
添加更多线程
添加批次大小
添加更多生产实例
添加更多分区
要提高 acks = -1 时的延迟,请上调 num.replica.fetches 的值。
对于跨可用区数据传输用例,请调整 sockets 与 OS TCP 的缓冲区设置。
保证 num.replica.fetches 值大于 Kafka 专用磁盘的数量。
根据生产者实例数量,消费者实例数量以及复制因子调整 num.network.threads 的值。
您的消息大小也会影响到网络传输带宽。要从 Kafka 集群中获得更高性能,请选择可提供 10 Gb/s 性能的实例类型。
要对 Java 及 JVM 进行性能调优,请尝试以下方法:
使用 Oracle JDK(使用新的 G1 垃圾优先收集器)最大程度减少 GC 暂停。
尝试将 Kafka 堆大小保持在 4 GB 以下。
监控
我们需要随时了解 Kafka 集群在生产环境中是否保持正常运行。有时候我们只需要确保集群已经启动,但有时候还需要对 Kafka 应用程序中的诸多活动部分进行监控。接触过运维工作的朋友可能也有同感,我们往往很难准确分辨需要留意的重要内容与可以暂时搁置起来的内容。对项目的监控范围从总体流量到简单指标、再到生产者、消费者、代理、控制器、ZooKeeper、主题、分区乃至消息等等,可谓无所不包。
为了进行监控,Intuit 公司使用到多种工具,包括 Newrelec、Wavefront、Amazon CloudWatch 以及 AWS CloudTrail。我们建议大家使用以下监控方案。
在系统指标方面,我们建议监控以下几项:
CPU 负载
网络指标
文件句柄使用量
磁盘空间
磁盘 I/O 性能
垃圾收集
ZooKeeper
在生产者方面,我们建议监控以下几项:
Batch-size-avg
Compression-rate-avg
Waiting-threads
Buffer-available-bytes
Record-queue-time-max
Record-send-rate
Records-per-request-avg
在消费者方面,我们建议监控以下几项:
Batch-size-avg
Compression-rate-avg
Waiting-threads
Buffer-available-bytes
Record-queue-time-max
Record-send-rate
Records-per-request-avg
安全性
与大多数分布式系统一样,Kafka 也在各相关组件之间提供较为安全的数据传输机制。根据您的具体设置,安全性要素可能涵盖不同的服务,例如加密、Kerberos、传输层安全(TLS)证书以及高级访问控制列表(ACL)设置等。下文将详细介绍 Intuit 公司采取的方法。关于本节未提及的更多 Kafka 安全详细信息,请参阅Kafka说明文档。
静态加密
对于采用 EBS 的 EC2 实例,大家可以使用启用加密功能的 Amazon EBS 存储卷实现静态数据加密。Amazon EBS 使用AWS Key Management Service (AWS KMS) 实现加密功能。关于更多详细信息,请参阅 EBS 说明文档中的Amazon EBS加密。对于采用实例存储的 EC2 实例,大家可以使用Amazon EC2实例存储加密实现静态数据加密。
传输加密
Kafka 使用 TLS 对各客户端与节点间通信进行加密。
身份验证
由客户端(生产实例与消费实例)指向各代理以及各代理间的连接使用安全套接字层(SSL)或简单身份验证与安全层(SASL)实现身份验证。
Kafka 支持 Kerberos 身份验证。如果您已经拥有 Kerberos 服务器,则可将 Kafka 添加至现有配置当中。
授权
在 Kafka 中,我们可以进行插入式授权,并与外部授权服务进行集成。
备份与恢复
我们在部署中使用的具体存储类型,决定了备份与恢复的实际策略。
在使用实例存储时,备份 Kafka 集群的最佳方法是设置另一个集群并使用 MirrorMaker 进行消息复制。Kafka 的镜像功能可帮助用户轻松为现有 Kafka 集群维护一套副本。根据具体设置及要求,您的备份集群可以与主集群位于同一 AWS 区域之内,也可以位于其他集群当中。
对基于 EBS 的部署,大家可以启用 EBS 存储卷的自动快照功能以实现存储卷备份。我们可以利用这些快照轻松创建新的 EBS 存储卷以进行恢复。我们建议将备份文件存储在 Amazon S3 当中。
关于如何在 Kafka 中实现备份的更多详细信息,请参阅Kafka说明文档。
总结
在本文中,我们将讨论了在 AWS 云中运行 Kafka 的几种常见模式。AWS 还提供另一种托管解决方案,即 Amazon Kinesis Data Streams。该方案无需为服务器的管理或扩展而分神,大家可以在几秒钟之内扩展流式管道规模且无任何停机,跨可用区数据复制将自动执行,以开箱即用的方式享受良好的安全保障,Kinesis Data Stream 与 Lambda、Redshift、Elasticsearch 等多种 AWS 服务以及 Storm、Spark、Flink 等开源框架紧密集成。大家还可以参考kafka-kinesis连接器的相关信息。
如果大家有任何问题或建议,请在评论区中与我们交流。
扩展阅读
如果本文对您有所帮助,也建议大家参阅使用Amazon Kinesis Analytics实现无服务器日志分析以及使用Amazon Kinesis Analytics进行实时点击流异常检测。
核子可乐译
作者介绍:
Prasad Alle 是 AWS 专业服务部的高级大数据顾问。他在领导和构建适合于 AWS 企业和战略客户的可扩展且可靠的大数据、机器学习、人工智能和物联网解决方案上投入了大量时间。他还对各种不同技术非常感兴趣,例如高级边缘计算、在边缘站点的机器学习等。在他的空余时间,他喜欢阅读和与家人在一起。
原文链接:
https://amazonaws-china.com/cn/blogs/china/best-practices-for-running-apache-kafka-on-aws/
评论