1 Kafka
1.1 Kafka简介
Kafka是一种分布式的,基于发布/订阅的消息系统。原本开发自LinkedIn,用于将用户的行为、网站的活动(网页游览,搜索或其他用户的操作信息)发布记录到不同的话题中心,这些消息数据可实时处理,实时监测,也可加载到Hadoop或离线处理数据仓库供后续大数据发掘。
Kafka主要设计目标如下:
1) 以时间复杂度为O(1)的方式提供消息持久化能力,即使对TB级以上数据也能保证常数时间复杂度的访问性能。
2) 高吞吐率。即使在非常廉价的商用机器上也能做到单机支持每秒100K条以上消息的传输。
3) 支持Kafka Server间的消息分区,及分布式消费,同时保证每个Partition内的消息顺序传输。
4) 支持离线数据处理和实时数据处理。
5) Scale out:支持在线水平扩展。
1.2 Kafka架构
1.2.1 Broker
Kafka集群包含一个或多个服务器,这种服务器被称为broker。
1.2.2 Topic
每条发布到Kafka集群的消息都有一个类别,这个类别被称为Topic。(物理上不同Topic的消息分开存储,逻辑上一个Topic的消息虽然保存于一个或多个broker上但用户只需指定消息的Topic即可生产或消费数据而不必关心数据存储位置)
1.2.3 Partition
Parition是物理上的概念,每个Topic包含一个或多个Partition.
1.2.4 Producer
负责发布消息到Kafka broker。
1.2.5 Consumer
消息消费者,向Kafka broker读取消息的客户端。
1.2.6 Consumer Group
每个Consumer属于一个特定的Consumer Group(可为每个Consumer指定group name,若不指定group name则属于默认的group)。
1.3 Kafka消息队列和消息主题实现
Kafka约定 同一Topic的一条消息只能被同一个Consumer Group内的一个Consumer消费,但多个Consumer Group可同时消费这一消息。
这是Kafka用来实现一个Topic消息的广播(发给所有的Consumer)和单播(发给某一个Consumer)的手段。一个Topic可以对应多个Consumer Group。如果需要实现广播(消息主题),只要每个Consumer有一个独立的Group就可以了。要实现单播(消息队列)只要所有的Consumer在同一个Group里。用Consumer Group还可以将Consumer进行自由的分组而不需要多次发送消息到不同的Topic。
实际上,Kafka的设计理念之一就是同时提供离线处理和实时处理。根据这一特性,可以使用Storm这种实时流处理系统对消息进行实时在线处理,同时使用Hadoop这种批处理系统进行离线处理,还可以同时将数据实时备份到另一个数据中心,只需要保证这三个操作所使用的Consumer属于不同的Consumer Group即可。
2 常用MQ组件
2.1 ActiveMQ
ActiveMQ是Apache所提供的一个开源的消息系统,完全采用Java来实现,因此,它能很好地支持J2EE提出的JMS(Java Message Service,即Java消息服务)规范。JMS是一组Java应用程序接口,它提供消息的创建、发送、读取等一系列服务。JMS提供了一组公共应用程序接口和响应的语法,类似于Java数据库的统一访问接口JDBC,它是一种与厂商无关的API,使得Java程序能够与不同厂商的消息组件很好地进行通信。
JMS支持两种消息发送和接收模型。一种称为P2P(Ponit to Point)模型,即采用点对点的方式发送消息。P2P模型是基于队列的,消息生产者发送消息到队列,消息消费者从队列中接收消息,队列的存在使得消息的异步传输称为可能,P2P模型在点对点的情况下进行消息传递时采用。
另一种称为Pub/Sub(Publish/Subscribe,即发布-订阅)模型,发布-订阅模型定义了如何向一个内容节点发布和订阅消息,这个内容节点称为topic(主题)。主题可以认为是消息传递的中介,消息发布这将消息发布到某个主题,而消息订阅者则从主题订阅消息。主题使得消息的订阅者与消息的发布者互相保持独立,不需要进行接触即可保证消息的传递,发布-订阅模型在消息的一对多广播时采用。
3 Kafka和常规MQ技术比对
Kafka通过zookeeper、raft等实现了分布式一致性,可用来构建可分布式扩展的消息系统,其具有非常高的数据吞吐量,这是其他传统MQ所无法比拟的。当项目应用场景数据量吞吐量较大、低延迟时,可采用Kafka;反之,当数据量吞吐量较小时,可采用诸如ActiveMQ等传统消息中间件。
4 Push vs Poll 技术比对
作为一个消息系统,Kafka遵循了传统的方式,选择由Producer向broker push消息并由Consumer从broker pull消息。而传统的MQ消息中间件如AMQ等,采用了Push模式。事实上,push模式和pull模式各有优劣。
push模式很难适应消费速率不同的消费者,因为消息发送速率是由broker决定的。push模式的目标是尽可能以最快速度传递消息,但是这样很容易造成Consumer来不及处理消息,典型的表现就是拒绝服务以及网络拥塞。而pull模式则可以根据Consumer的消费能力以适当的速率消费消息。
对于Kafka而言,pull模式更合适。pull模式可简化broker的设计,Consumer可自主控制消费消息的速率,同时Consumer可以自己控制消费方式——即可批量消费也可逐条消费,同时还能选择不同的提交方式从而实现不同的传输语义。