本文要点:
- 高盛 (Goldman Sachs) 的核心前端办公平台团队在一个虚拟的基础设施上运行了一个基于 Apache Kafka 的集群,这个基础设施每周可以处理 1.5 Tb 的流量。
- 该团队已经投入了大量的资源来防止数据丢失,并且在同一个 (或非常接近) 的城区建立了数据中心,多个中心可以有效地作为灾难恢复和业务连续性 (DRBC) 的独立冗余数据中心。
- 核心的前端办公平台团队在创建工具以支持其基础设施方面投入了大量资金,包括 REST 服务,以提供对 Kafka 集群的调用,同时还创建了一个全面的度量捕获组件。
- 故障有可能会发生,工程师们必须未雨绸缪。GS 采用的方法是将所有业务运行在高可靠性设备上,并且权衡各种情况之后使配置简洁易懂的。
在 2017 年的纽约 QCon 大会上,安东·戈尔什科夫 (Anton Gorshkov) 提出“ 使用 Kafka 避免数据流故障”。他分享了一个大型金融机构平台团队如何设计和运营像 Apache Kafka 这样共享的内部消息集群的经验,他还分享了他们未来的计划及解决的一些不可避免的故障问题。
高盛 (Goldman Sachs) 总经理戈尔什科夫 (Gorshkov) 首先介绍了高盛 (Goldman Sachs),并讨论了其部门管理的数据流处理工作量。该公司的投资管理部门管理着 1.4 万亿美元的资产,核心平台团队与许多其他内部团队合作,为 Apache Kafka、数据结构和 Akka 提供平台和基础设施服务。该团队在一个虚拟的基础设施上运行了一个基于 Apache Kafka 的集群,这个基础设施每周可以处理 1.5 Tb 的流量。尽管消息计数相对较低——按每周数百万计——在高峰时期 Kafka 上每秒产生 1500 条消息。
Apache Kafka 集群的部署目标是:
- 没有数据丢失,即使是在数据中心中断的情况下 ;
- 没有主 / 备份之分 ;
- 没有故障转移场景 ;
- 停机时间降到最低。
高盛团队已经投入了大量的资源来防止基本数据丢失,包括提供磁带备份、夜间批量复制、异步复制和同步复制 (例如,使用 Symmetrix 远程数据工具进行同步磁盘级复制)。Gorshkov 提醒观众每个程序员都知道的数据延迟问题,并指出光速决定了从纽约到旧金山的最理想网络往返行程需要花费60 毫秒,弗吉尼亚到俄亥俄州需要12 毫秒,而纽约到新泽西则需要4 毫秒。由于数据中心位于相同的城市区或其他比较靠近的地方,多个中心可以被有效地作为灾难恢复和业务连续性的独立冗余数据中心。这与AWS 这样的现代云供应商所采用的方法非常相似,基础设施按地理区域划分,而区域又进一步划分为可用性区域。
允许将多个数据中心做为一个Apache Kafka 集群部署的策略,如下图所示,其中一个概念集群跨越多个物理数据中心。
Gorshkov 碰到过一系列故障场景,首先是研究在独立虚拟机 (VM) 主机连接数据中心失败的情况下将发生的情况。这种情况每年发生一到五次,但对 Kafka 的生产者和消费者没有影响,因为该系统仍然能够满足至少三个副本所需的最小同步需求。在这种情况下,除了替换主机之外,没有手动恢复途径。如果存在底层基础设施或管理程序故障,两个主机同时出现故障的情况每年就会发生一次甚至更多。如果出现这种故障模式,一些 Kafka 相关的的进程将停止。短期修复方式是为受影响的分区添加副本,并最终替换坏主机。高盛计算机基础设施允许无缝的 VM 替换,并且不需要更新 DNS aliases 配置或 Kafka 配置。
如果数据中心内的三个主机同时出现故障,那么集群任务就会立即停止,因为这个配置不再能满足跨集群的同步复制所需的数量。值得庆幸的是,这种情况每隔几年才会发生一次。修复方法是尽快替换主机。如果数据中心出现故障或出现网络分割,据 Gorshkov 测算这将是“一个 20 年一遇的事件”,那么短期解决方案是在没有受到影响的数据中心部分添加额外的主机。对恢复时间的最大影响是需要多长时间提供新主机,因为数据中心通常只保持一定的空闲容量。
核心平台团队在创建工具以支持其基础设施方面投入了大量资金,包括REST 服务和相关的web 应用程序,以提供对Kafka 集群的调用支持。提供REST 服务的端点可允许查看各种状况的信息,以及诸如消费者延迟和获得的同步复制的数量等核心指标。还可以获得关于ZooKeeper 配置、簇首选举过程和运行时代理指标的信息。平台团队还创建了一个组件,该组件可以从应用程序、JVM 和基础设施级别的集群操作中记录大量指标。度量指标会被发送到一个时间序列数据库,并被转发到一个集中管理的高盛警报结构中。在这里,警报可以被发送给待命的工程师。
典型的示例部署包括一个上游服务(例如,一个贸易订单服务),它充当消息源,并根据内部状态变化发送事件(这同时也会在服务的数据存储中被捕获) 到Apache Kafka 集群。 Kafka Connect API 是用来连接 Kafka 集群内部消息的,下游目标通常包括直接输入消息到内存中的 RDBMS,以维护用于故障诊断表格版本的所有消息, Spark 流作业将结果输出到内存中的 RDBMS,由最终用户通过查询相关的 Vert.x 或 REST api,最终批量的 ETL 作业会将所有事件持久化到一个数据池中以进行检查管理。
如果发生了严重的中断,并且需要对消息进行重发时,由于上游服务给每条消息添加了全局惟一标识符,所以可以很容易地实现重播,并且不会导致重复播报消息,也不会破坏消息的幂等性保证。如果上游系统没有生成惟一的标识符,那么Gorshkov 建议探索使用Confluent 团队引入Apache Kafka 的一次性处理语义的方法,并研究下Kafka 改进建议(KIP)“ KIP-98——一次性交付和事务性消息传递”。
在演讲的最后一部分,Gorshkov 说,故障一定会发生的,工程师必须准备好处理这些问题。他的团队所采用的方法是做好多重防护。基本上,在建立弹性系统时遇到的许多权衡都涉及吞吐量和可靠性 (相对于成本)。Apache Kafka 有许多配置选项——可能太多了——最好将一些开关隐藏起来。关于配置 Kafka 使其有效运行的更多细节,Gorshkov 推荐了 Confluent online talk 系列, Gwen Shapira 的“ Apache Kafka 的最佳实践”。他的观点是,必须用一种易懂的方法来实现弹性,因为这是工程师们在系统中获得信心的唯一方式。
Gorshkov 在 QCon NY talk 上的演讲视频“使用Kafka 避免数据流故障”可以在InfoQ 上找到。
关于作者
Daniel Bryant 正在引领组织和技术领域的变革。他目前的工作包括通过引入更好的需求收集和计划技术、关注敏捷开发中架构的相关性以及促进持续集成 / 交付,从而在组织内部实现敏捷开发。Daniel 目前的技术专长是“DevOps”工具、云 / 容器平台和微服务实现。他也是伦敦 Java 社区 (LJC) 的领导者,为几个开源项目贡献了自己的力量,为著名的技术网站如 InfoQ、DZone 和 Voxxed 撰稿,并定期在 QCon、JavaOne 和 Devoxx 等国际会议上发表文章。
英文原文链接: When Streams Fail: Implementing a Resilient Apache Kafka Cluster at Goldman Sachs
评论