kafka是领英(Linked-in)开源的,承载着领英万亿级/天的消息数量。
具有如下特点
- 高吞吐量、低延迟:每秒可以处理几十万条消息,它的延迟最低只有几毫秒
- 可扩展性:支持热扩展
- 持久性、可靠性:消息被持久化到本地磁盘,支持数据备份防止数据丢失
- 容错性:允许集群中节点失败(若副本数量为n,则允许n-1个节点失败)
- 高并发:支持数千个客户端同时读写
和大多数消息队列类似,kafka中有这么几个角色:
- Topic:消息存放的目录即主题
- Producer:生产消息到topic的一方
- Consumer:订阅topic消费消息的一方
- Broker:Kafka的服务实例就是一个broker
消息主题(Topic)
每个topic,kafka维护着几个分区日志(Patitioned Log)在存储它的内容,如下图:
这张图中有几个概念:
- Partition:消息的分区,一个topic中,通常会分为几个区(默认3)。消息发送到哪个区,由消息生产者决定,一般通过topic和key取hash来决定分区。
- 顺序消费:在每个区中的消息是顺序的,即同一个topic的消息不是顺序消费的(如果partition个数大于1的话)。
- 消息过期:kafka会将消息保存一段时间,保存的时间可配置。不管消息有没有被消费,到了过期时间消息就会被删除。
消息生产者(Producer)
- Producers直接发送消息到broker上的leader partition,不需要经过任何中介一系列的路由转发。为了实现这个特性,kafka集群中的每个broker都可以响应producer的请求,并返回topic的一些元信息,这些元信息包括哪些机器是存活的,topic的leader partition都在哪,现阶段哪些leader partition是可以直接被访问的。
- Producer客户端自己控制着消息被推送到哪些partition。实现的方式可以是随机分配、实现一类随机负载均衡算法,或者指定一些分区算法。Kafka提供了接口供用户实现自定义的分区,用户可以为每个消息指定一个消息key,通过这个key来实现一些hash分区算法。
- 发送效率。以Batch的方式推送数据可以极大的提高处理效率,kafka Producer 可以将消息在内存中累计到一定数量后作为一个batch发送请求。Batch的数量大小可以通过Producer的参数控制,参数值可以设置为累计的消息的数量(如500条)、累计的时间间隔(如100ms)或者累计的数据大小(64KB)。通过增加batch的大小,可以减少网络请求和磁盘IO的次数,当然具体参数设置需要在效率和时效性方面做一个权衡。
- 发送的可靠性。配置ack参数,producer需要server接收到数据之后发出的确认接收的信号,ack=0:不需要,ack=1:leader成功将数据写入本地log,all:leader需要等待所有备份都成功写入日志。
消息消费者(Consumer)
- 消息的消费由consumer主动pull,这一点不同于其他消息队列。
- 每个consumer都归属于一个组(consumer group),一条消息只能被同一个组中的一个consumer消费。
- 如果所有consumer都有同一个组名,那么kafka就相当于一个队列消息服务,而各个consumer均衡的消费相应partition中的数据。若consumer的组名都不同,那么此时kafka就相当于一个广播服务,会把topic中的所有消息广播到每个consumer。
- 在kafka中,当前读到消息的offset值是由consumer来维护的,因此,consumer可以自己决定如何读取kafka中的数据。比如,consumer可以通过重设offset值来重新消费已消费过的数据。不管有没有被消费,kafka会保存数据一段时间,这个时间周期是可配置的,只有到了过期时间,kafka才会删除这些数据。
- Kafka提供了两套consumer api,分为high-level api和sample-api。Sample-api 是一个底层的API,它维持了一个和单一broker的连接,并且这个API是完全无状态的,每次请求都需要指定offset值,因此,这套API也是最灵活的。High-level API,封装了对集群中一系列broker的访问,可以透明的消费一个topic。它自己维持了已消费消息的状态(zookeeper中保存offset),即每次消费的都是下一个消息。
kafka其他特性
- 消息压缩。压缩可以提高网络传输效率,但会增加CPU负担。主要应用在大数据的处理中,此时网络的传输往往成为性能瓶颈。
- 数据冗余。kafka在0.8版本以后支持了数据冗余,可将一份数据备份在多个其他节点中。一个备份数量为n的集群允许n-1个节点宕机的情况下保证数据不丢失。
- 消息持久化。Kafka高度依赖文件系统来存储和缓存消息,一般的人认为磁盘是缓慢的,其实磁盘的的随机读写非常慢,但顺序写非常快。比如:在一个6x7200rpm SATA RAID-5 的磁盘阵列上线性写的速度大概是600M/秒,但是随机写的速度只有100K/秒,两者相差将近6000倍。