大数据杂谈之初窥Kafka

随着时代的发展,信息爆炸,大量的数据信息需要捕获、传递、处理,传统的ActiveMQ、Rabbit MQ等消息系统越来越适应不了当前数据信息高吞吐的时代要求。由Linkedin公司设计开发的Kafka,一款基于zookeeper管理的分布式消息系统应运而生。Kafka以其并行处理、高吞吐、易扩展、高容错等特性逐渐应用于各种大数据场景。因其功能的不断完善,整合各种应用场景,Kafka逐步由单一的消息系统向流式处理平台转化,但其基础的消息系统功能属性始终未曾改变。要了解Kafka须先理解什么是消息系统?

在这里相信有许多想要学习大数据的同学,大家可以+下大数据学习裙:957205962,即可免费领取套系统的大数据学习教程

简单来说,消息系统是负责系统层级间进行消息管理、传递的中间介质。消息系统的解耦、消峰、异步等几大特性,使得上下游应用专注数据处理和自身的功能实现。消息系统从实现特点上来看大致分为两类:一是点对点消息系统,二是点对多,即发布/订阅消息系统。

点对点消息系统如下图所示,生产者生成消息并将消息发出存入消息队列,消息的消费者从消息队列中读取消息,消费者可以是一个也可以是多个,但是消息队列中的消息只能一次消费。该类型消息系统主要应用于订单,票务等系统。

点对点

点对多(发布/订阅)消息系统,与点对点消息系统不同,引入了主题(topic)概念,生产者将消息发布并存入消息系统对应的主题中,消息的消费者订阅主题。生产者将消息分类发布到对应的主题中,消费者可以根据订阅的主题进行消息消费,并且可以实现多个消费者订阅共同的主题,即实现生产者发布一条消息,该消息可以被多个不同的消费者所消费。该类型的消息系统主要应用于点对多的场景。具体模型如下。

点对多

根据消息系统的分类可知Kafka是属于点对多(发布/订阅)的消息系统。不同于传统的发布/订阅消息系统的是Kafka是基于zookeeper管理的多producer、多customer的消息系统,而且对于Kafka消息系统本身来说也是逻辑概念,Kafka消息系统其本身物理架构往往是多台物理服务器组合而成的分布式消息系统集群。

 

Zookeeper在Kafka集群中充当集群管家的角色,负责管理集群中所有的元数据信息的存储管理,负责建立生产者和消费者的订阅关系信息实现生产者与消费者的负载均衡,以及一切服务请求任务的调度分配等。由于zookeeper承担了Kafka集群中的大量的信息管理、任务调度等工作,使得集群中其他数据处理服务器能够更专注的进行数据处理,这也是Kafka具备并行数据处理、高吞吐、动态扩展、高可用等特性的基础。

在介绍Kafka的工作原理前先简单介绍几个概念:

消息生产者(producer):发布消息到 Kafka 集群的终端或服务,即Kafka集群上游应用。

消息代理(broker):Kafka集群中包含的服务器,负责消息处理。

主题(topic):每条发布到 Kafka 集群的消息属于的类别,即 Kafka中的消息分类。

分区(partition):partition 是物理上的概念,每个 topic 包含一个或多个 partition。Kafka通过partition实现并行消息处理。

消息消费者(consumer):从 Kafka 集群中消费消息的终端或服务,即Kafka集群下游应用。

消息消费者组(Consumer group):为满足高吞吐设计需求,消息的消费是按照消费组来进行消费的,每个消费组至少存在1个consumer,每个consumer 都属于一个消费组consumer group。

分区备份(replication):partition 的副本,保障 partition 的高可用。

领导者(leader):replication中的一个角色, producer 和 consumer 只跟 leader 交互。

跟随者(follower):replication 中的一个角色,从 leader 中复制数据。

控制器(controller):Kafka 集群中的其中一个服务器,用来进行 leader election 以及各种 failover。

在这里相信有许多想要学习大数据的同学,大家可以+下大数据学习裙:957205962,即可免费领取套系统的大数据学习教程

一般的消息系统基于消息模型进行处理,消息模型根据发起动作不同分为两种:推送(push)模型和拉取(pull)模型。Kafka集群作为消息处理平台负责保证消息完整性并实现高效并发吞吐,不主动处置消息,即采用接收上游应用推送(push)消息,接受下游系统发起的消息(pull)申请。

Kafka集群消息处理分为三步:一是接收producer发布的message数据;二是broker对message数据进行处理;三是consumer订阅消费message数据。

producer 发布消息

消息生产者producer 采用 push 模式将消息发布到指定broker,这里的broker并不是随机选择的,而是zookeeper获取的。如图所示:

producer写入流程说明

1. 消息生产者producer根据zookeeper中存储的Kafka集群元数据信息,获取对应topic的partition对应的leader信息。

2. producer 将消息发送给该 partition leader

3. leader 将消息写入本地 log,leader写入完成之后,向producer发送ack,完成消息写入。

由于每个topic可能存在多个partition,所以一个producer可能同时向不同的broker上的多partition进行数据推送。每条消息采用append的方式追加到partition中去,之所以采用append的方式主要是考虑顺序写磁盘,因顺序写磁盘效率比随机写内存要高,所以选择追加的方式是出于保障 Kafka 吞吐率的考虑。

另外,为保证producer消息写入,Kafka提供三种写保护模式:

At most once:消息最多传输一次,消息可能会丢,但绝不会重复传输。

At least one 消息绝不会丢,但可能会重复传输。

Exactly once 每条消息肯定会被传输一次且仅传输一次。

Kafka根据创建消息主题topic,将消息持久化存储在服务器系统上,物理上把 topic分成一或多个partition,partition个数由配置文件中server.properties 中的num.partitions=3 配置项决定,每个 partition 物理上对应一个文件夹,该文件夹存储该 partition 的所有消息和索引文件。

Kafka通过Partition replication机制来保证实现高可用(HA)性,即通过数据冗余来保证数据高可用。一个 partition 可能会有多个 replication,replication个数由配置文件server.properties 中的default.replication.factor=N配置项决定。没有 replication 的情况下,一旦 broker 宕机,topic的partition数据完整性不能保证,导致其上所有 partition 的数据都不可被消费,与此同时生产者producer也不能继续push数据到partition。引入replication之后,同一个 partition 可能会有多个 replication,而这时需要在这些 replication 之间选出一个 leader,producer 和 consumer 只与这个 leader 交互,其它 replication 作为 follower 从 leader 中复制数据。

Kafka消息直接写入本地文件系统,进行持久化存储,对于Kafka来说逻辑上消息没有失效时限,只有消息保留时限,即消息不会因为被消费而被删除。当然考虑到服务器存储空间以及消息的有效性,消息也不会无限的保留,Kafka旧消息删除策略有两种:

一是基于时间,即消息保留时长。

二是基于消息文件大小,即消息存储文件超过规定大小后删除。

通过设置为配置文件参数log.retention.hours和log.retention.bytes实现。

Consumer根据指定topic进行消息的消费,Kafka的消息分配单位是 partition。因为每个 consumer 都属于一个group,一个partition 只能被同一个group内的一个 consumer所消费(也就保障了一个消息只能被 group 内的一个 consumer 所消费),但是多个 group 可以同时消费这个 partition。

Consumer根据zookeeper存储的topic元数据信息,找到指定的broker,采用pull模式从broker中读取数据。Kafka之所以考虑consumer采用pull模型主要是push模式broker是消息发送的发起方,当存在多个consumergroup同时进行消息消费时,不能做到实质性的高并发,容易造成出现发送瓶颈。且消息发送速率是由 broker决定的,很难适应消费速率不同的消费者。从另外一个角度来说,broker不确定consumer的消费能力,可能造成consumer的等待或堆积的情况。Consumer采用pull 模式则可以根据 consumer 的消费能力以适当的速率消费消息,同时consumer也可以自己控制消费方式(批量或逐条),并且Kafka采用文件系统进行消息持久化存储,机制本身也支持,pull模式也简化了broker功能设计。

对应kafka提供的三种producer消息写入模式:At most once、At least one、Exactly once。Consumer也可以理解为三种消息处理模式,而实现的不同则是由消息读取处理和commit顺序决定的,具体如下:

At most once:读消息后commit再处理,保证每次读取的消息都没有被处理过。即消息最多被处理一次。

At least one:读完消息先处理在commit。如消息处理未提交,再次读取消息会出现同一次消息多次处理情况。

Exactly once:要实现该模式则需要通过consumer同时协调offset和操作的输出结果来保证。

Kafka是一种特殊的消息系统,不仅有传统消息系统的解耦、冗余、消峰,灵活,异步通信等特点,还具备一些传统消息系统所不具备的特性。具体表现在如下几点:

扩展性:Kafka是一个分布式系统,支持不停机扩展。

高并发、高吞吐:通过并发producer、partition以及consumer group实现高吞吐,支持数千个客户端同时读写。

持久、可靠性:消息被持久化存储到本地磁盘,支持数据备份防止数据丢失

容错性:Kafka集群节点失效不影响服务提供,理论上n个replication允许n-1个节点失效。

在线/离线处理:Kafka消息机制即支持消息实时流处理,也支持消息的离线批量处理。

随着广泛应用和自身的特性,Kafka逐渐由消息系统向流平台转变,从 0.9 版本开始,Kafka 的标语已经从“一个高吞吐量,分布式的消息系统”改为"一个分布式流平台"。常用场景如下:

1.日志收集:前端日志收集,Kafka作为日志聚合工具。然后通过统一接口服务的方式开放给各种consumer,例如Hadoop、Hbase、Solr等。

2.消息队列系统:解耦和生产者和消费者、缓存消息等。

3.用户活动跟踪:用户活动收集统计,根据用户不同活动将用户行为进行topic分类,通过不同topic进行汇总分析,做到用户活动实时的监控跟踪,进行在线或离线的用户行为分析。

4.流式处理:保存收集流数据,对接流式计算处理框架,比如spark streaming和storm等。

Kafka应用不仅限于单一场景,只要集群处理能力能够达到,众多场景完全可以部署在同一个集群之上,这也是Kafka称之为分布式流平台原因。

我行各类数据应用持续发展,不断与时俱进,不同数据域中的Kafka集群也逐步从单一功能逐步向组合兼容多种应用场景转变,目前我行运行准实时平台、分析平台、应用开发平台等多套Kafka集群,作为日常日志收集、消息队列传递、应用系统间的数据传递等多个应用场景,例如准实时平台目前几十个应用用户,topic应用达到数百个,每秒传输数据达到数百兆,接收消息几万条/每秒,这是建立在平台5台服务器基础上,尽管如此平台处理毫无压力。

Kafka随着大数据时代应运而生,设计之初为大数据处理中的大数据吞吐难题,在解决吞吐和高可用等方面做出了卓越贡献,这也是Kafka之所以火热的原因,但Kafka不能够保证消息精确处理,消息只能做到局部有序等特点也限制了在相关领域的应用。不可否认的是,因Kafka的架构设计优势和新版本中健全的消费机制,细粒度权限控制,事务支持等功能的不断完善,使得Kafka的应用前景更为值得期待。

猜你喜欢

转载自blog.csdn.net/cqacry2798/article/details/86503646