Kafka特性介绍与基础架构、消息队列
1. Kafka定义
Kafka是一个分布式
的基于发布/订阅模式
的消息队列
(Message Queue),主要应用于大数据实时处理领域。
Kafka设计之初就旨在提供3个方面的功能特性:
- 为生产者和消费者提供一套简单的API
- 降低网络传输和磁盘存储开销
- 具有高伸缩性架构
2. 消息队列
2.1 消息队列应用场景
使用消息队列的好处:
- 解耦
允许独立的扩展或修改两边的处理过程,只要确保他们遵守同样的接口约束。 - 可恢复性
系统的一部分组件失效时,不会影响到整个系统。消息队列降低了进程间的耦合度,所以即使一个处理消息的进程挂掉,加入队列中的消息仍然可以在系统恢复后被处理。 - 缓冲
有助于控制和优化数据流经系统的速度,解决生产消息和消费速度不一致的情况。(更多的生产大于消费) - 灵活性 & 峰值处理能力 & 削峰
在访问量剧增的情况下,应用仍然需要继续发挥作用,但是这样的突发流量并不常见。如果能以处理这类峰值访问为标准来投入资源无疑是巨大的浪费。使用消息队列能够使关键组件顶住突发的访问压力,而不会因为突发的超负荷的请求而完全崩溃。 - 异步通信
很多时候,用户不想也不需要立即处理消息。消息队列提供了异步处理机制,允许用户把一个消息放入队列,但并不立即处理它。想向队列中放入多小消息就放发多少,然后再需要的时候再去处理它们。
总的来说,消息队列提供的都是 解耦、异步、削峰扩展出来的特性。
2.2 消息队列的两种模式
- 点对点模式 (
一对一
,消费者主动拉取数据,消息收到后消息清除)
消息生产者生产消息发送到Queue中,然后消息消费者从Queue中取出消息并且消费消息。消息被消费以后,queue中不在有存储,所以消息消费者不可能消费到已经被消费的消息。 - 发布/订阅模式 (
一对多
,消费者消费数据之后不会清除消息)(Kafka)
消息生产者(发布)将消息发布到topic中,同时有多个消息消费者(订阅)消费该消息。和点对点的方式不同,发布到topic的消息会被所有的订阅者消息。
3. Kafka的设计概要
Kafka的设计初衷是为了解决互联网公司超大量级数据的实时传输。为了实现这个目标,Kafka在设计之初就需要考虑一下4个问题。
- 吞吐量/延时
- 消息持久化
- 负载均衡和故障转移
- 伸缩性
3.1 吞吐量/延时
吞吐量是某种处理能力的最大值。对于Kafka而言,它的吞吐量就是每秒能够处理的消息数或者每秒能够处理的字节数。吞吐量越大越好。
延时衡量的是一段时间间隔,可能是发出某个操作与接收到操作响应(response)之间的时间,或者是系统中导致某些物理变更的起始时刻与变更正式生效时刻之间的间隔。对于Kafka而言,延时可以表示客户端发起请求与服务端处理请求并发送响应给客户端之间的这段时间。延时间隔越短越好。
Kafka依靠一下4点达到高吞吐量、低延时的设计目标的。
- 大量使用
操作系统页缓存
,内存操作速度快且命中率高。 - Kafka不直接参与物理I/O操作,而是交由最擅长此事的操作系统来完成。
- 采用
追加写入方式
,摒弃了缓慢的磁盘随机读/写操作。 - 使用以
sendfile
为代表的零拷贝技术
加强网络间的数据传输效率。
3.2 消息持久化
Kafka是要持久化消息的,而且要把消息持久化到磁盘上。这样做的好处如下:
- 解耦消息发送与消息消费
通过消息持久化使生产者方不再需要消费者方耦合,只是简单的把消息生产出来并交由Kafka服务器保存即可,因此提升了整体的吞吐量。 - 实现灵活的消息处理
很多Kafka的下游子系统(接收Kafka消息的系统)都有这样的需求——对于已经处理过的消息可能在未来某个时间点重新消费一次,即所谓的消息重演
(message replay)。消息持久化可以很方便的实现这样的需求。
3.3 负载均衡和故障转移
负载均衡
,就是让系统的负载根据一定的规则均衡的分配给所有参与工作的服务器上,从而最大限度地提升系统整体的运行效率。
默认情况下,Kafka的每台服务器都有均等机会为Kafka的客户提供服务,可以把负载分散到所有集群中的机器上,避免出现“耗尽某台服务器”的情况发生。Kafka实现负载均衡是通过智能化的分区领导者选举
(partition leader election)来实现的。
故障转移
,是指当服务器意外终止时,整个集群可以快速检测到该失效(failure),并立即经该服务器上的应用或服务自动转移到其他服务器上。故障转移通常以“心跳”
或“会话”
的机制来实现,即只要主服务器与备份服务器之间的心跳无法维持或者主服务器注册到服务中心的会话超时过期,那么就认为主服务器已无法正常运行,集群会自动启动某个被封服务器来代替主服务器工作。
Kafka服务器支持故障转移的方式就是使用会话机制。每台Kafka服务器启动后会以会话
的形式把自己注册到Zookeeper服务器上,一旦该服务器运转出现问题,与Zookeeper的会话便不能维持从而超时失效,此时Kafka集群会选举另一台服务器来完全代替这台服务器继续提供服务。
3.4 伸缩性
伸缩性
表示向分布式系统中增加额外的计算资源(比如CPU、内存、存储和带宽)时吞吐量提升的能力。
如果服务器的状态和管理同一交于专门的协调服务来做(如ZooKeeper),那么整个集群的服务器之间就无须繁重的状态共享,这极大的降低了维护复杂度。倘若要扩容集群节点,只需要简单的启动新的节点机器进行自动负载均衡即可。
Kafka正式采用这种思想——每台Kafka服务器上的状态同一交由ZooKeeper保管。扩展Kafka集群也只需要一步:启动新的Kafka服务器即可。在Kafka服务器上并不是所有的状态都不保存,它只保存很轻量级的内部状态,因此在整个集群间维护状态一致性的代价是很低的。
4. Kafaka基础架构
- Producer: 消息生产者,就是向kafka broker 发消息的客户端。
- Consumer: 消息消费者,向kafka broker 取消息的客户端。
- Consumer Group(CG): 消费者组,由多个consumer组成。消费者组内每个消费者负责消费不同分区的数据,一个分区只能由一个组内消费者消费;消费者组之间互不影响。所有的消费者都属于某个消费者组,即消费者组是逻辑上的一个订阅者。
- Broker: 一台kafka服务器就是一个broker。一个集群由多个broker组成。一个broker可以容纳多个topic。
- Topic(主题): 可以理解为一个队列,生产者和消费者都是面向一个topic。
- Partition(分区): 为了实现扩展性,一个非常大的topic可以分布到多个broker(即服务器)上,一个topic可以划分为多个partition,每个partition是一个有序的队列。
- Replica: 副本(Replication),为了保证集群中的某个节点发生故障时,该节点的partition数据不丢失,且kafka仍然能够继续工作,kafka提供了副本机制,一个topic的每个分区都有若干个副本,一个leader和若干个follower。
- Leader: 每个分区多个副本的“主”,生产者发送数据的对象,以及消费者消费数据的对象都是leader。
- Follower: 每个分区多个副本的“从”,实时从leader中同步数据,保持和leader数据的同步。Leader发生故障时,某个follower会称为新的leader。和传统的主备系统(Master-Slave)不同的是,在这类leader-follower系统中通常只有leader对外提供服务,follower只是被动的追随leader,保持与leader同步。Follower唯一从在的价值就是充当leader的候补:一旦leader挂掉立即就会有一个追随者被选举成为新的leader来接替他的工作。
5. Kafka的使用场景
- 消息传输
- 网站行为日志跟踪
- 审计数据收集
- 日志收集
- Event Sourcing
Event Sourcing 实际上是领域驱动设计(Domain-Driven Design, DDD)的名词,它使用事件序列表示状态变更。 - 流式处理