从Kafka在大数据平台的应用场景来看,主要分为以下三类:
第二类是为数据分析提供数据源,各埋点日志会作为数据源,支持并对接公司离线数据、实时数据仓库及分析系统,包括多维查询、实时DruidOLAP、日志明细等。
第三类是为业务方提供数据订阅。除了在大数据平台内部的应用之外,我们还使用Kafka为推荐搜索、大交通、酒店、内容中心等核心业务提供数据订阅服务,如用户实时特征计算、用户实时画像训练及实时推荐、反作弊、业务监控报警等。
主要应用如下图所示:
早期大数据平台之所以引入Kafka作为业务日志的收集处理系统,主要是考虑到它高吞吐低延迟、多重订阅、数据回溯等特点,可以更好地满足大数据场景的需求。但随着业务量的迅速增加,以及在业务使用和系统维护中遇到的问题,例如注册机制、监控机制等的不完善,导致出现问题无法快速定位,以及一些线上实时任务发生故障后没有快速恢复导致消息积压等,使Kafka集群的稳定性和可用性得受到挑战,经历了几次严重的故障。
解决以上问题对我们来说迫切而棘手。针对大数据平台在使用Kafka上存在的一些痛点,我们从集群使用到应用层扩展做了一系列的实践,整体来说包括四个阶段:
第一阶段:版本升级。围绕平台数据生产和消费方面存在的一些瓶颈和问题,我们针对目前的Kafka版本进行技术选型,最终确定使用1.1.1版本。
第二阶段:资源隔离。为了支持业务的快速发展,我们完善了多集群建设以及集群内Topic间的资源隔离。
第三阶段:权限控制和监控告警。
首先在安全方面,早期的Kafka集群处于裸跑状态。由于多产品线共用Kafka,很容易由于误读其他业务的Topic导致数据安全问题。因此我们基于SASL/SCRAM+ACL增加了鉴权的功能。
在监控告警方面,Kafka目前已然成为实时计算中输入数据源的标配,那么其中Lag积压情况、吞吐情况就成为实时任务是否健康的重要指标。因此,大数据平台构建了统一的Kafka监控告警平台并命名「雷达」,多维度监控Kafka集群及使用方情况。
下面围绕几个关键点为大家展开介绍。
之前大数据平台一直使用的是0.8.3这一Kafka早期版本,而截止到当前,Kafka官方最新的Release版本已经到了2.3,于是长期使用0.8版本过程中渐渐遇到的很多瓶颈和问题,我们是能够通过版本升级来解决的。
举例来说,以下是一些之前使用旧版时常见的问题:
同时对一些目标版本的特性进行了选型调研,如:
最终选择1.1版本,则是因为出于Camus与Kafka版本的兼容性及1.1版本已经满足了使用场景中重要新特性的支持的综合考量。这里再简单说一下Camus组件,同样是由Linkedin开源,在我们的大数据平台中主要作为Kafka数据Dump到HDFS的重要方式。
针对以上的问题,在集群改造上做了两方面实践:
(1)集群拆分
按照功能维度拆分多个Kafka物理集群,进行业务隔离,降低运维复杂度。
以目前最重要的埋点数据使用来说,目前拆分为三类集群,各类集群的功能定义如下:
全量订阅集群:该集群Topic中的绝大部分数据是从Log集群实时同步过来的。上面我们提到了Log集群的数据是不对外的,因此全量集群就承担了消费订阅的职责。目前主要是用于平台内部的实时任务中,来对多个业务线的数据分析并提供分析服务。
个性定制集群:之前提到过,我们可以根据业务方需求来拆分、合并数据日志源,同时我们还支持定制化Topic,该集群只需要提供分流后Topic的落地存储。
集群整体架构划分如下图:
(2)资源隔离
Topic的流量大小是集群内部进行资源隔离的重要依据。例如,我们在业务中埋点日志量较大的两个数据源分别是后端埋点数据源server-event和端上的埋点mobile-event数据源,我们要避免存储两个数据的主题分区分配到集群中同一个Broker上的节点。通过在不同Topic进行物理隔离,就可以避免Broker上的流量发生倾斜。
(1)权限控制
开始介绍时我们说过,早期Kafka集群没有设置安全验证处于裸跑状态,因此只要知道Broker的连接地址即可生产消费,存在严重的数据安全性问题。
一般来说,使用SASL的用户多会选择Kerberos,但就平台Kafka集群的使用场景来说,用户系统并不复杂,使用Kerberos就有些大材小用,同时Kerberos相对复杂,存在引发其他问题的风险。另外,在Encryption方面,由于都是运行在内网环境,所以并没有使用SSL加密。
最终平台Kafka集群使用SASL作为鉴权方式,基于SASL/SCRAM+ACL的轻量级组合方式,实现动态创建用户,保障数据安全。
(2)监控告警
之前在集群的使用中我们经常发现,消费应用的性能无缘无故变差了。分析问题的原因,通常是滞后Consumer读取的数据大概率没有命中Page-cache,导致Broker端机器的内核要首先从磁盘读取数据加载到Page-cache中后,才能将结果返还给Consumer,相当于本来可以服务于写操作的磁盘现在要读取数据了,影响了使用方读写同时降低的集群的性能。
这时就需要找出滞后Consumer的应用进行事前的干预从而减少问题发生,因此监控告警无论对平台还是用户都有着重大的意义。下面介绍一下我们的实践思路。
整体方案:
整体方案主要是基于开源组件KafkaJMXMetrics+OpenFalcon+Grafana:
关于监控:
关于告警:
雷达系统:自研监控系统,通过Falcon及Eagle获取Kafka指标,结合设定阈值进行告警。以消费方式举例,Lag是衡量消费情况是否正常的一个重要指标,如果Lag一直增加,必须要对它进行处理。
监控示例:
(1)实时数据订阅平台
核心思想是基于Kafka数据源的身份认证和权限控制,增加数据安全性的同时对Kafka下游应用进行管理。
(2)标准化的申请流程
(3)监控告警
对于平台来说,权限与资源是绑定的,资源可以是用于生产的Topic或消费使用的GroupTopic。一旦权限分配后,对于该部分资源的使用就会自动在我们的雷达监控系统进行注册,用于资源整个生命的周期的监控。
(4)数据重播
出于对数据完整性和准确性的考量,目前Lamda架构已经是大数据的一种常用架构方式。但从另一方面来说,Lamda架构也存在资源的过多使用和开发难度高等问题。
(5)主题管理
为什么提供主题管理?举一些很简单的例子,比如当我们想让一个用户在集群上创建他自己的KafkaTopic,这时显然是不希望让他直接到一个节点上操作的。因此刚才所讲的服务,不管是对用户来讲,还是管理员来讲,我们都需要有一个界面操作它,因为不可能所有人都通过SSH去连服务器。
因此需要一个提供管理功能的服务,创建统一的入口并引入主题管理的服务,包括主题的创建、资源隔离指定、主题元数据管理等。
(6)数据分流
在之前的架构中,使用方消费Kafka数据的粒度都是每个KafkaTopic保存LogSource的全量数据,但在使用中很多消费方只需要消费各LogSource的部分数据,可能也就是某一个应用下几个埋点事件的数据。如果需要下游应用自己写过滤规则,肯定存在资源的浪费及使用便捷性的问题;另外还有一部分场景是需要多个数据源Merge在一起来使用的。
基于上面的两种情况,我人实现了按业务方需求拆分、合并并定制化Topic支持跨数据源的数据合并及appcode和eventcode的任意组个条件的过滤规则。
解决数据重复问题。为了解决目前平台实时流处理中因故障恢复等因素导致数据重复的问题,我们正在尝试用Kafka的事务机制结合Flink的两段提交协议实现端到端的仅一次语义。目前已经在平台上小范围试用,如果通过测试,将会在生产环境下推广。
Consumer限流。在一写多读场景中,如果某一个Consumer操作大量读磁盘,会影响Produce级其他消费者操作的延迟。l因此,通过KafkaQuota机制对Consume限流及支持动态调整阈值也是我们后续的方向
场景扩展。基于Kafka扩展SDK、HTTP等多种消息订阅及生产方式,满足不同语言环境及场景的使用需求。