介绍
kafka是一个分布式、可分区可复制的消息系统,它将消息以topic为单位进行了归纳
使用Scala语言(面向函数)编写的
发布消息的程序---producers
消费消息的程序---consumers
kafka集群可以由一个或者多个服务组成,每个服务称为一个broker
producers将消息通过网络发送的kafka集群中,kafka集群再向消费者(consumers)提供消息
客户端通过tcp协议与服务端通信,并且kafka提供的java的客户端,支持多种语言
kafka集群依赖zookeeper来保证系统的可用性
kafka特点:1.高吞吐(生产 25W消息/s,消费 55W/s)
2.数据落地(将消息持久化到磁盘,可批量消费,顺序存储,并且数据不易丢失)
3.易扩展(分布式系统,无需停机即可扩展)
4.客户端维护
topics
对于每个topic,Kafka对其日志进行分区,如下图
每个分区都是由一系列有序不可变的消息组成,消息被不断的追加到分区中,在分区中的每一个消息都有一个连续唯一的offset,用来在分区中标识这个消息。
在一段时间中,kafka集群会保留所有发布的消息,无论消息是否被消费。当时间一到,这些信息才会被删除,释放空间。kafka的性能和数据量是没有关系的,kafka的性能与磁盘读写效率有关。
分区在kafka集群中都是有副本的,拥有副本的服务(broker)可以共同处理数据和请求,副本数量可设置。kafka具有容错能力。kafka中的分区是负载均衡和失败恢复分布式数据存储的基本单位。
每个分区都由一个服务器作为“leader”,零或若干服务器作为“followers”,leader负责处理消息的读和写,followers则去复制leader.如果leader down了,followers中的一台则会自动成为leader。集群中的每个服务器都会同时扮演两个角色:作为它所持有的一部分分区的leader,同时作为其他分区的followers,这样集群就会据有较好的负载均衡。
Producers
Producer将消息发布到它指定的topic中,并负责决定发布到哪个分区。通常简单的由负载均衡机制随机选择分区,但也可以通过特定的分区函数选择分区。使用的更多的是第二种。
Consumers
实际上每个consumer唯一需要维护的数据是消息在日志中的位置,也就是offset.这个offset由consumer来维护:一般情况下随着consumer不断的读取消息,这offset的值不断增加,但其实consumer可以以任意的顺序读取消息,比如它可以将offset设置成为一个旧的值来重读之前的消息。
以上特点的结合,使Kafka consumers非常的轻量级:它们可以在不对集群和其他consumer造成影响的情况下读取消息。你可以使用命令行来"tail"消息而不会对其他正在消费消息的consumer造成影响。
消费消息通常有两种模式:队列模式(queuing)和发布-订阅模式(publish-subscribe)。
(1)队列模式
队列模式中,多个consumers可以同时从服务端读取消息,每个消息只被其中一个consumer读到;
(2)发布订阅模式
发布-订阅模式中消息被广播到所有的consumer中。
(3)Consumers可以加入一个consumer group
组内的Consumer是一个竞争的关系,共同竞争一个topic内的消息,topic中的消息将被分发到组中的一个成员中,同一条消息只发往其中的一个消费者。同一组中的consumer可以在不同的程序中,也可以在不同的机器上。而如果有多个Consumer group来消费相同的Topic中的消息,则组和组之间是一个共享数据的状态,每一个组都可以获取到这个主题中的所有消息。
如果所有的consumer都在一个组中,这就成为了传统的队列模式,在各consumer中实现负载均衡。
如果所有的consumer都不在不同的组中,这就成为了发布-订阅模式,所有的消息都被分发到所有的consumer中。
更常见的是,每个topic都有若干数量的consumer组来消费,每个组都是一个逻辑上的“订阅者”,为了容错和更好的稳定性,每个组都由若干consumer组成,在组内竞争实现负载均衡。实现了组内竞争负载均衡,组间共享互不影响,这其实就是一个发布-订阅模式,只不过订阅者是个组而不是单个consumer