热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

kafka集群为什么需要三个节点_每天处理千亿级日志量,Kafka是如何做到的?

之前为大家分享了不少Kafka原理解析类的干货,今天咱们一起来看看360基于Kafka千亿级数据量的深度实践!图片来自Pexels本文主要围绕如下内容分享࿱

之前为大家分享了不少 Kafka 原理解析类的干货,今天咱们一起来看看 360 基于 Kafka 千亿级数据量的深度实践!

7b23b1aa96ed1606bf318c610746f138.png

图片来自 Pexels

本文主要围绕如下内容分享:

  • 消息队列选型
  • Kafka 在 360 商业化的现状
  • Kafka Client 框架
  • 数据高可用
  • 负载均衡
  • 鉴权、授权与 ACL 方案
  • Quota 机制
  • 跨 IDC 的数据同步
  • 监控告警
  • 线上问题及解决方案

消息队列选型

当时主要考虑以下几个维度:

  • 社区活跃度
  • 客户端支持
  • 吞吐量

对比几个系统下来,觉得 Kafka 比较符合我们的要求。现在有一个新的开源系统 Pulsar,我觉得也可以尝试一下。

2aabfdc15ce10ce1476b376a5a945e02.png

Kafka 设计上的亮点如下:

baf4a7e6425792450cbbbda3f8434b07.png

Kafka 性能和吞吐都很高,通过 Sendfile 和 Pagecache 来实现 Zero Copy 机制,顺序读写的特性使得用普通磁盘就可以做到很大的吞吐,相对来说性价比比较高。

Kafka 通过 Replica 和 ISR 机制来保证数据的高可用。

Kafka 集群有两个管理角色:

  • Controller 主要是做集群的管理。
  • Coordinator 主要做业务级别的管理。

这两种角色都由 Kafka 里面的某个 Broker 来担任,这样 Failover 就很简单,只需要选一个 Broker 来替代即可。

从这个角度来说 Kafka 有一个去中心化的设计思想在里面, 但 Controller 本身也是一个瓶颈,可以类比于 Hadoop 的 Namenode。

CAP 理论相信大家都有了解过,分布式系统实现要么是 CP,要么是 AP。

Kafka 实现比较灵活,不同业务可以根据自身业务特点来对 Topic 级别做偏 CP 或偏 AP 的配置。

支持业务间独立重复消费,并且可以做回放。

06fb8b9795df0c52d270c26e83389afb.png

这个是 Kafka 的简要架构,主要分为:

  • 生产端
  • Broker 端
  • 消费端

日志有三个层次:

  • 第一个层次 Topic
  • 第二个层次 Partition(每个 Partition 是一个并行度)
  • 第三个层次 Replica(Replica 表示 Partition 的副本数)

Kafka 在 360 商业化的现状

f92a92f78692742ee064fab99d255619.png

目前集群有千亿级数据量,100 多台万兆机器,单 Topic 的最大峰值 60 万 QPS,集群的峰值大概在 500 万 QPS。

c22ffe3b197607bc598794abfe10509e.png

我们的物理机配置 24Core/10G 网卡/128G 内存/4T*12 HDD,值得说一下的是我们采用了万兆网卡加普通磁盘 4T*12 的配置,测下来磁盘吞吐和网络吞吐是能够匹配上的。

再者考虑到我们的数据量比较大,SSD 盘没有特别大的且成本比较高。

磁盘的组织结构我们用的是 JBOD,RAID10 也是很好的方案(磁盘成本会翻倍)。

我们目前的 Kafka 版本是 1.1.1,推荐大家部署 0.11 以上的版本会好一些,这个版本对协议做了很多优化,对于后续的 2.x 版本都是兼容的。

b5b3f7d4b8bccebf886464c4527908ee.png

这个是我们 Kafka 上下游相关的组件,生产端主要是各种 Kafka Clients/实时服务/Flume/Logstash。

消费端分为实时,离线(ETL),监控三部分。实时有 Spark/Flink/Storm 等主流框架, 离线部分我们基于 Flink 自研了一个统一落地框架 Hamal,从 Kafka 消费一遍数据就可以落地到多个下游系统(HDFS、Hbase、Redis等),可以避免重复消费。

还有部分是监控的需求,我们把 ES/InfluxDB 相关的日志打到 Kafka,然后再消费出来通过 Grafana 展示,但目前我们已经切到 Prometheus 上了。

Kafka Client 框架

为什么要做这个框架呢?之前有很多的业务部门用裸 API 自己去实现 Kafka Client 的逻辑。

但是会有很多问题,有一些异常情况会 Catch 不全,我们做这个框架是想把所有的细节屏蔽掉,然后暴露出足够简单的接口。

这样可以减少业务犯错的可能性,我们要确保极端的情况下比如网络或集群异常时的可用性,如果网络或集群不可用,数据会先落到本地,等恢复的时候再从本地磁盘恢复到 Kafka 中。

5f1f1aaabd849298a1503e9b62dcdc5e.png

我们实现了两个框架:

  • LogProducer,支持 at least once。
  • LogConsumer,支持 at least once 和 exactly once 两种语意,其中 exactly once 需要业务去实现 Rollback 接口。
4842b59a84524b993301f390403cdd2f.png

LogProducer 框架的大体思路是通过内存队列将日志发送到 Kafka,当 Kafka 或网络不可用的情况下会写本地磁盘,同时会有一个线程去实时检测 Kafka 或者网络的可用情况,如果恢复就会加载磁盘日志并发送到 Kafka。

我们还支持一种共享内存的策略来代替内存,使用共享内存是为了减少重启过程中日志的丢失数。

85b857dd41585cc99a9f3bd4402b1439.png

LogConsumer 的框架实现,通过 Blocking Queue 将 Consumer 线程和 Worker 线程解耦,因为现实情况是消费逻辑很简单,但是处理逻辑会很复杂。

这样就可以对 Consumer 线程和 Worker 线程做不同的配置,同时通过 Blocking Queue 还可以实现反压机制。

比如 Worker 处理不过来了,这时候 Blocking Queue 就会满,反压到 Consumer 线程会停止消费。

同时我们在 Worker 线程接口里面会提供接口让用户提交到 global offsetmap。

如上图我们提供三个组合接口,如果在业务处理与 Commit 中实现了业务端 Rollback 逻辑, 那么就是 exactly once 语义,默认是 at least once 语义。

数据高可用

之前讲过 Kafka 本身提供 Replica+ISR 的机制来保证数据高可用,但我们觉得这个可能还不够,所以我们还要支持 Rack Aware。

比如 Replica=3 的情况,确保三个副本在不同的物理 Rack 上,这样我们最多能容忍两个物理机架同时出问题而数据仍可用,我们 Rack Aware 方案是与负载均衡方案一起做掉的,具体后面会讲。

3c139bc91a870f14ea91520f40dbf162.png

值得注意的是 Kafka 官方也支持 Rack Aware,通过在 Broker 端配置 broker.rack 参数可实现。

但有一个限制,必须为每个 Rack 分配数量相同的 Brokers,否则会导致 Replica 分配倾斜,实际情况是 IDC 的 Rack 是很多的,分配到的物理机分布也可能很随机。

一个可以参考的解决思路是采用虚拟 Rack Group 的概念,比如维护 3 个虚拟 Rack Group,申请到的物理机加入到这 3 个 Group 中,并确保 Rack Group 间分配的物理机数量一致。

当然 Rack Group 间物理机不应存在有相同物理 Rack 的情况。

负载均衡

Kafka 的负载均衡功能在 Confluent 商业版本才支持,负载均衡本质上来说是 Replica 分配均匀问题。

我们一开始想通过经典一致性 Hash 来解决,如下图:

a20012b60cb5f16a91cc133a285eb1d1.png

然后我们发现经典一次性 Hash 不能满足我们的需求,比如要加一个节点 node5,只能分担节点 node2 的部分负载,不能做全局节点的负载均衡。

7d0020ef822f7537c0d918a6780de2a3.png

于是我们基于虚拟节点的一次性 Hash 的算法实现了一个方案,如图所示:相同的颜色对应同一个物理机,Hash 环上的都是虚拟节点。

这里有四个物理节点,其中 node4 是我们新加的节点。通过虚拟节点可以把物理节点的负载足够均衡地分散出去,所以当我把 node4 加到 Hash 环上的时候,分担了所有物理机的负载。

算法实现的步骤分为两个大的步骤:

①新建 hash circle:通过 vnode_str(比如 hostname-v0)做一个 MD5 的 Hash,得到虚拟节点的 vnode_key,再用 ring 字典来保存虚拟节点到物理节点的映射,同时将 vnode_key 加入到 sorted_keys 的 list 中。

②在 Hash 环中分配 Replica:将(topic_name+partition_num+replica_num)作为 Key 用相同的 MD5 Hash 算法得到 replica_key。

接着二分查找该 replica_key 在 sorted_keys 中的 Position, 最后用 Ring 字典来映射到物理机 Node,至此 Replica 分配完成。

55c40ea533e3f9d2c4347a87ecf9cea6.png

我们基于这个算法解决三个问题:

  • 添加物理节点只需迁移很小一部分数据。
  • 对不同配置的物理机做权重设置,可以支持异构集群的部署。
  • 实现 Replica 的 Rack Aware,物理节点上面会有 Rack 信息,在为 Replica 分配物理节点的时候会记录已经分配的 Rack 信息。

如果有重复的情况,就会把 vnode_key 找到 Position 的位置 +1 找下一个物理节点,我们会确保三个 Replica 的物理 Rack 一定是不一样的(假如 Replica=3)。

Leader Balance:这是一种快速且成本低的负载 Balance 方法,因为 Kafka 只有 Leader 提供读写,所以通过 Leader 切换是可以达到负载切换的效果的,由于只是 Leader 切换不涉及数据同步,因此这个代价是比较小的。

Disk Rebalance:这个 Feature 需要 Kafka1.1.0 版本之后才支持,Kafka 提供了一些脚本和 API 可以做 Balance 操作, 其本质也是生成 Replica Plan 然后做 Reassign。

鉴权、授权和 ACL 方案

如果是新集群比较推荐基于 SASL 的 SCRAM 方案,实施起来比较简单。

如果老集群想中途施行鉴权授权机制会比较困难,需要推各个业务去修改配置,同时切换的过程也很容易出问题。

下面介绍下我们实现的一个白名单机制来解决老集群的问题,首先将老业务加入到白名单中,让新业务通过工单流程来申请 Topics 和 Consumers 两种资源权限并加到白名单里,定期监测非法(没有走工单)Topics,Consumers 资源。

同时将这些资源都 Deny 掉,这样就收紧了 Topics 和 Consumer 读写权限的口子,同时原有业务不会有任何影响。

c30a24ed9915fb08bc122f21c0eb3c02.png

Quota 机制

7ee9aa22b6ef0c7e9f9dbee5c1194aa8.png

Quota 主要是为了解决多个业务间资源抢占问题。Quota 类型有两种:

  • 一种是限制网络带宽。
  • 一种是限制请求速率(限制 CPU)。

我们对业务做了三个优先级设置:高,中,低优先级,高优先级不做限制,中优先级可容忍 lag,低优先级极端情况可停掉,通过工具可以批量限制某个优先级的所有业务,可以确保高优先级业务及集群的安全。

跨 IDC 的数据同步

2655c9746fc7bc8f3f740459eba0dc7a.png

首先我们为什么要做跨 IDC 的数据同步?没做这个同步之前业务可能对数据的读写没有一个 IDC 的概念,所以很容易就会有跨 IDC 的读写,多个业务还可能有重复 Consume 和 Produce。

这就造成跨 IDC 网络的极大浪费, 加上跨 IDC 的网络并不稳定,有时候会有一些异常,业务也不一定能很好处理。

58dc8f094313585f65204d315555bd51.png

为了解决以上问题,我们统一做了跨 IDC 的数据同步服务,首先我们约定业务只能做本 IDC 的读写,不允许做跨 IDC 的读写,如果有跨 IDC 的数据需求,要向我们申请,通过 Mirrormaker 去同步一份过来。

这样做有两个好处:

  • 一是屏蔽了异常对业务的影响。
  • 二是节省了 IDC 之间的带宽(我们通过同步机制能保证这份数据只传输一份)。

我们还基于 Marathon/Mesos 对这个服务做了 Pass 化,提高了服务的 SLA。

75a967a633ad1ff905cc65612619404f.png

监控告警

0b92c7126a9f9e50af03e6d0f5a2e05b.png
35d1456e8ec71308860fa9fea532b456.png

我们的监控警告平台如下:

  • 基于 Jmx exporter+Promehteus+Grafana 来做图表展示,在每个 Broker 上面部署 Jmx exporter,Prometheus 会去 Pull 这些数据,最后通过 Grafana 来展示。
  • 基于 Kafka Manager 做瞬态指标的监控。
  • 基于 Burrow 做 Consumer lag 的监控。
  • 基于 Wonder 来做告警,这个是 360 内部实现的一个组件,类似 Zabbix。
d7e9198944fa748c9305f58c7b82441d.png

线上问题及解决方案

a16136fbc0617f62254557489dd8b4d2.png

磁盘故障:我们通过 Smartctl 来监测,首先状态是要 Passed 的,其次我们会判断 197 Current_Pending_Sector 这个属性值不能大于 100, 如果大于 100 这个磁盘可能有读写性能问题。

bootstrap.servers 性能瓶颈:该参数可以配置多台 Broker,这些 Broker 作为 Proxy 的角色为 Kafka Clients 提供 Lookup 服务。

如果集群规模很大,Clients 很多的情况下,这些 Proxy 角色的 Broker 的负载会很大,为了解决这个问题,我们对 bootstrap.servers 参数做了 VIP 配置。

每个 VIP 可以绑定任意多的 Brokers,这样在客户端不需要修改配置的情况下可以对 Proxy 动态扩缩容。

Consumer 重启不消费:业务反馈消费停止,重启也不能够解决问题,后来定位发现是早于 0.11 之前版本的 Bug:

https://issues.apache.org/jira/browse/KAFKA-5413 

原因是 log cleaner 线程挂了导致 Compact 停止,__consumer_offsets 这个 Topic 的量非常大,broker reload 时间特别长,这段时间是停止服务的。

解决方法有两个:

  • 一是升级到 Kafka 0.11+ 版本
  • 二是将 Offset 迁移到新的 Consumer Group 来解决(规避掉有问题的 Coordinator)。

严锁鹏

85f856261869246ab102cad7885c0be9.png

严锁鹏,奇虎 360 大数据架构运维专家,具有 10 年基础架构与大数据开发经验。2013 年加入 360 商业化团队,负责消息中间件开发与运维,同时涉及大数据架构、微服务架构、实时计算平台、机器学习平台、监控系统等基础设施建设,致力于为商业化团队提供稳定高效的基础服务。



推荐阅读
  • 流处理中的计数挑战与解决方案
    本文探讨了在流处理中进行计数的各种技术和挑战,并基于作者在2016年圣何塞举行的Hadoop World大会上的演讲进行了深入分析。文章不仅介绍了传统批处理和Lambda架构的局限性,还详细探讨了流处理架构的优势及其在现代大数据应用中的重要作用。 ... [详细]
  • Java高级工程师学习路径及面试准备指南
    本文基于一位朋友的PDF面试经验整理,涵盖了Java高级工程师所需掌握的核心知识点,包括数据结构与算法、计算机网络、数据库、操作系统等多个方面,并提供了详细的参考资料和学习建议。 ... [详细]
  • 一家位于长沙的知名网络安全企业,现面向全国诚聘高级后端开发工程师,特别欢迎具有一线城市经验的技术精英回归故乡,共创辉煌。 ... [详细]
  • 本文总结了一次针对大厂Java研发岗位的面试经历,探讨了面试中常见的问题及其背后的原因,并分享了一些实用的面试准备资料。 ... [详细]
  • 本文详细介绍了 Java 网站开发的相关资源和步骤,包括常用网站、开发环境和框架选择。 ... [详细]
  • HDFS数据读写流程详解
    本文详细解析了HDFS(Hadoop分布式文件系统)中的数据读写过程,包括从客户端发起请求到最终完成数据传输的每一个关键步骤。 ... [详细]
  • 本周三大青年学术分享会即将开启
    由雷锋网旗下的AI研习社主办,旨在促进AI领域的知识共享和技术交流。通过邀请来自学术界和工业界的专家进行在线分享,活动致力于搭建一个连接理论与实践的平台。 ... [详细]
  • 入门指南:使用FastRPC技术连接Qualcomm Hexagon DSP
    本文旨在为初学者提供关于如何使用FastRPC技术连接Qualcomm Hexagon DSP的基础知识。FastRPC技术允许开发者在本地客户端实现远程调用,从而简化Hexagon DSP的开发和调试过程。 ... [详细]
  • 本文探讨了有效学习专业技能的方法,包括编程语言、操作系统、软件组件及前沿技术的探索,旨在为初学者提供一套系统的自学指南。 ... [详细]
  • 本文源自Coursera平台吴恩达教授的深度学习课程,重点探讨了卷积神经网络(ConvNets)从二维图像处理向一维信号及三维数据处理的拓展应用。 ... [详细]
  • 本文将深入探讨 Unreal Engine 4 (UE4) 中的距离场技术,包括其原理、实现细节以及在渲染中的应用。距离场技术在现代游戏引擎中用于提高光照和阴影的效果,尤其是在处理复杂几何形状时。文章将结合具体代码示例,帮助读者更好地理解和应用这一技术。 ... [详细]
  • 深入探讨:Actor模型如何解决并发与分布式计算难题
    在现代软件开发中,高并发和分布式系统的设计面临着诸多挑战。本文基于Akka最新文档,详细探讨了Actor模型如何有效地解决这些挑战,并提供了对并发和分布式计算的新视角。 ... [详细]
  • Redis 是一个高性能的开源键值存储系统,支持多种数据结构。本文将详细介绍 Redis 中的六种底层数据结构及其在对象系统中的应用,包括字符串对象、列表对象、哈希对象、集合对象和有序集合对象。通过12张图解,帮助读者全面理解 Redis 的数据结构和对象系统。 ... [详细]
  • 自动驾驶中的9种传感器融合算法
    来源丨AI修炼之路在自动驾驶汽车中,传感器融合是融合来自多个传感器数据的过程。该步骤在机器人技术中是强制性的,因为它提供了更高的可靠性、冗余性以及最终的 ... [详细]
  • 三角测量计算三维坐标的代码_双目三维重建——层次化重建思考
    双目三维重建——层次化重建思考FesianXu2020.7.22atANTFINANCIALintern前言本文是笔者阅读[1]第10章内容的笔记,本文从宏观的角度阐 ... [详细]
author-avatar
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有