kafka入门:一个开源的、轻量级、高吞吐、高可用的分布式消息系统
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了kafka入门:一个开源的、轻量级、高吞吐、高可用的分布式消息系统相关的知识,希望对你有一定的参考价值。
参考技术A 随着信息技术的快速发展及互联网用户规模的急剧增长,计算机所存储的信息量正呈爆炸式增长,目前数据量已进入大规模和超大规模的海量数据时代, 如何高效地存储、分析、处理和挖掘海量数据 已成为技术研究领域的热点和难点问题。而 如何采集和运营管理、分析这些数据 也是大数据处理中一个至关重要的组成环节,这就需要相应的基础设施对其提供支持。针对这个需求,当前业界已有很多开源的消息系统应运而生,kafka就是一款当然非常流行的消息系统。Kafka是一款开源的、轻量级的、分布式、可分区和具有复制备份的(Replicated)、基于ZooKeeper协调管理的分布式流平台的功能强大的消息系统。作为一个流式处理平台,必须具备以下3个关键特性:
1) 能够允许发布和订阅流数据。
2) 存储流数据时提供相应的容错机制。
3) 当流数据到达时能够被及时处理。
消息流系统kafka的基本结构包括生产者和消费者,以及kafka集群。
生产者负责生产消息,将消息写入Kafka集群;消费者从Kafka集群中拉取消息。
消息是Kafka通信的基本单位 ,由一个 固定长度的消息头 和一个 可变长度的消息体 构成。
Kafka将 一组消息 抽象归纳为一个主题(Topic),也就是说,一个主题是对消息的一个分类。 生产者将消息指定主题发送到kafka集群,消费者订阅主题或主题的某些分区进行消费。
Kafka将一组消息归纳为一个主题,而 每个主题又被分成一个或多个分区(Partition) 。每个分区由一系列有序、不可变的消息组成,是一个有序队列。 每个分区在物理上对应为一个文件夹 ,分区的命名规则为主题名称后接“—”连接符,之后再接分区编号,分区编号从0开始,编号最大值为分区的总数减1。
分区使得Kafka在并发处理上变得更加容易,理论上来说,分区数越多吞吐量越高,但这要根据集群实际环境及业务场景而定。同时,分区也是Kafka保证消息被顺序消费以及对消息进行负载均衡的基础。
疑问和答案 :分区如何保证消息被顺序消费?每个分区内的消息是有序的,但不同分区间如何保证?猜测是分区从存储空间上比较大,分区个数少。顺序消费的主要因素在分区内的消息,分区间的可以忽略。高吞吐率顺序写磁盘估计也是这个原因。
Kafka只能保证一个分区之内消息的有序性,并不能保证跨分区消息的有序性。 每条消息被追加到相应的分区中,是顺序写磁盘,因此效率非常高,这是Kafka高吞吐率的一个重要保证 。同时与传统消息系统不同的是,Kafka并不会立即删除已被消费的消息,由于磁盘的限制消息也不会一直被存储,因此 Kafka提供两种删除老数据的策略 ,一是基于消息已存储的时间长度,二是基于分区的大小。这两种策略都能通过配置文件进行配置。
每个分区又有一至多个副本(Replica),分区的副本分布在集群的不同代理上,以提高可用性。
从存储角度上分析,分区的每个副本在逻辑上抽象为一个日志(Log)对象,即分区的副本与日志对象是一一对应的。每个主题对应的 分区数 可以在Kafka启动时所加载的配置文件中配置,也可以在创建主题时指定。当然,客户端还可以在主题创建后修改主题的分区数。
为什么副本要分Leader和Follower? 如果没有Leader副本,就需要所有的副本都同时负责读/写请求处理,同时还得保证这些副本之间数据的一致性,假设有n个副本则需要有n×n条通路来同步数据,这样数据的一致性和有序性就很难保证。
为解决这个问题,Kafka选择分区的一个副本为Leader,该分区其他副本为Follower,只有 Leader副本 才负责处理客户端 读/写请求 ,Follower副本从Leader副本同步数据。
引入Leader副本后客户端只需与Leader副本进行交互,这样数据一致性及顺序性就有了保证。Follower副本从Leader副本同步消息,对于n个副本只需n-1条通路即可,这样就使得系统更加简单而高效。
副本Follower与Leader的角色并不是固定不变的,如果Leader失效,通过相应的选举算法将从其他Follower副本中选出新的Leader副本。
疑问 :leader副本和follower副本是如何选出来的?通过zookeeper选举的嘛?
Kafka在ZooKeeper中动态维护了一个 ISR(In-sync Replica) ,即保存同步的副本列表,该列表中保存的是与Leader副本保持消息同步的所有副本对应的代理节点id。 如果一个Follower副本宕机或是落后太多 ,则该Follower副本节点将 从ISR列表中移除 。 本书用宕机 来特指某个代理失效的情景,包括但不限于代理被关闭,如代理被人为关闭或是发生物理故障、心跳检测过期、网络延迟、进程崩溃等。
任何发布到分区的消息会被直接追加到日志文件的尾部(分区目录下以“.log”为文件名后缀的数据文件),而每条 消息 在日志文件中的位置都会对应一个按序递增的 偏移量 。偏移量是一个分区下严格有序的 逻辑值 ,它并不表示消息在磁盘上的物理位置。由于Kafka几乎不允许对消息进行随机读写,因此Kafka并没有提供额外索引机制到存储偏移量。
消费者可以通过控制消息偏移量来对消息进行消费 ,如消费者可以指定消费的起始偏移量。 为了保证消息被顺序消费,消费者已消费的消息对应的偏移量也需要保存 。需要说明的是,消费者对消息偏移量的操作并不会影响消息本身的偏移量。旧版消费者将消费偏移量保存到ZooKeeper当中, 而新版消费者是将消费偏移量保存到Kafka内部一个主题当中。 当然,消费者也可以自己在外部系统保存消费偏移量,而无需保存到Kafka中。
推测 :一个主题有多个分区,一个分区有多个副本。一个主题(一类消息)有多个分区(消息被分段),一个分区(每段消息)有多个副本(每段消息的副本数)。消息一旦发给kafka,就会分配一个偏移量,在多个副本中的偏移量是一样的。这样的话,消费者通过偏移量消费时对于多个副本就没有差异性。
Kafka集群由一个或多个Kafka实例构成,每一个Kafka实例称为代理(Broker),通常也称代理为Kafka服务器(KafkaServer)。在生产环境中Kafka集群一般包括一台或多台服务器,我们可以在一台服务器上配置一个或多个代理。 每一个代理都有唯一的标识id,这个id是一个非负整数 。在一个Kafka集群中,每增加一个代理就需要为这个代理配置一个与该集群中其他代理不同的id, id值可以选择任意非负整数即可,只要保证它在整个Kafka集群中唯一,这个id就是代理的名字,也就是在启动代理时配置的broker.id对应的值。
生产者(Producer)负责将消息发送给代理,也就是向Kafka代理发送消息的客户端。
消费者(Comsumer)以拉取(pull)方式拉取数据,它是消费的客户端。在Kafka中 每一个消费者都属于一个特定消费组 (ConsumerGroup),可以为每个消费者指定一个消费组,以groupId代表消费组名称,通过group.id配置设置。 如果不指定消费组 ,则该消费者属于默认消费组test-consumer-group。
每个消费者有一个全局唯一的id ,通过配置项client.id指定, 如果客户端没有指定消费者的id, Kafka会自动为该消费者生成一个全局唯一的id,格式为$groupId-$hostName-$timestamp-$UUID前8位字符。 同一个主题的一条消息只能被同一个消费组下某一个消费者消费 ,但不同消费组的消费者可同时消费该消息。 消费组是Kafka用来实现对一个主题消息进行广播和单播的手段 ,实现消息广播只需指定各消费者均属于不同的消费组,消息单播则只需让各消费者属于同一个消费组。
推论: kafka消息是按照消息类型(主题),在一个消费者组中只能消费一次。也就是一个消费者组只消费一类型的消息。如果某个服务要消费一类消息,必须将自己置为不同的消费者组。
Kafka利用ZooKeeper保存相应元数据信息, Kafka元数据信息包括如代理节点信息、Kafka集群信息、旧版消费者信息及其消费偏移量信息、主题信息、分区状态信息、分区副本分配方案信息、动态配置信息等。 Kafka在启动或运行过程当中会在ZooKeeper上创建相应节点 来保存元数据信息, Kafka通过监听机制在这些节点注册相应监听器来监听节点元数据的变化 ,从而由ZooKeeper负责管理维护Kafka集群,同时通过ZooKeeper我们能够很方便地对Kafka集群进行水平扩展及数据迁移。
Kafka核心技术与实战
Kafka是linkedIn开发并开源的一套分布式的高性能消息引擎服务,后来被越来越多的公司应用在自己的系统中,可以说,Kafka是大数据时代数据管道技术的首选。在设计的时候,它就实现了高可靠、高吞吐、高可用和可伸缩,得益于这些特性,加上活跃的社区,Kafka成为了一个完备的分布式消息引擎解决方案。
历经多年发展,Kafka的功能和特性也在不断迭代,如今的Kafka集消息系统、存储系统和流式处理平台于一身,并作为连接着各种业务前台和数据后台的消息中间件,在线上环境承担了非常重要的作用。
但在Kafka的实际使用过程中,几乎所有人都或多或少会遇到一些问题,比如:
棘手的线上问题难于定位和解决,怎么办?
在Kafka版本的演进过程中,各种新功能层出不穷,导致各种兼容性问题接踵而至,怎么办?
当集群规模扩展到一定程度后,所追求的高性能与有限的资源之间的矛盾又变得日益尖锐起来,怎么办?
如何顺利填补这些“坑”,是摆在每个Kafka学习者面前最亟待解决的问题。
以上是关于kafka入门:一个开源的、轻量级、高吞吐、高可用的分布式消息系统的主要内容,如果未能解决你的问题,请参考以下文章