消息队列分类
点对点
消息生产者生产消息发送到queue中,而后消息消费者从queue中取出而且消费消息。这里要注意:缓存
- 消息被消费之后,queue中再也不有存储,因此消息消费者不可能消费到已经被消费的消息。
- Queue支持存在多个消费者,可是对一个消息而言,只会有一个消费者能够消费。
发布/订阅
消息生产者(发布)将消息发布到topic中,同时有多个消息消费者(订阅)消费该消息。和点对点方式不一样,发布到topic的消息会被全部订阅者消费。服务器
kafka介绍
kafka是一个分布式的、分区的、多副本的、多订阅者的日志系统(分布式消息队列)。可同时支持点对点模式的消息队列和发布/订阅模式的消息队列。网络
kafka架构说明

kafka角色术语:架构
- Broker:一台kafka服务器就是一个broker。一个集群由多个broker组成
- Topic:消息队列,不一样的消息会被发送至不一样的队列当中
- Producer:消息生产者,就是向kafka broker发消息的客户端
- Consumer:消息消费者,从kafka broker取消息的客户端
- Consumer Group(CG):这是kafka用于实现一个topic消息广播(发给全部的consumer)和单播(发给某一个consumer)的手段。一个topic能够有多个CG,topic的每一条消息都会发送给每一个CG,但CG只会把消息发送给该CG中的一个consumer。若是须要实现广播,只要将每一个consumer配置一个独立的CG便可。而要实现单播则只要将全部的consumer放至同一个CG便可。用CG还能够将consumer进行自由的分组而不须要producer屡次发送消息到不一样的topic
- Partition:Partition是物理上的概念。为了实现扩展性,一个很是大的topic能够分布到多个broker上,一个topic能够分为多个partition,每一个partition是一个有序的队列。partition中的每条消息都会被分配一个有序的id(offset)。kafka只保证按一个partition的顺序将消息发给consumer,不保证一个topic的总体顺序
- Offset:kafka的存储文件都是按照offset.kafka来命名,用offset作名字的好处是方便查找。例如你想找2049的位置,只要找到2048.kafka文件便可。第一个位置为00000000000.kafka
kafka特性:并发
- 提供数据持久化,消息顺序写入磁盘,提高机械盘的读写性能
- 高吞吐量:即便是很是普通的硬件kafka也能够支持每秒数十万的消息
- 经过多副本的方式防止消息丢失
- 支持消息的同步和异步发送
- 消费状态保存在客户端
- 数据迁移、扩容对用户透明
- 按期删除机制,支持设定partitions的segment file保留时间。
kafka支持消息持久化存储,持久化数据保存在kafka的日志文件中,在生产者生产消息后,kafka不会直接把消息传递给消费者,而是先要在broker中进行存储,为了减小磁盘的写入次数,broker会将消息暂时缓存起来,当消息的个数或尺寸、大小达到必定阈值时,再统一写到磁盘上。经过这种方式以提升kafka的执行效率,并减小磁盘IO的调用次数。kafka中的每条消息写到partition中,是顺序写入磁盘的,这可进一步保证写入效率。异步
Topic与Partition的关系
Kafka中的topic是以partition的形式存放的,每一个topic均可以设置它的partition数量,推荐partition的数量要大于同时运行的consumer的数量,也建议partition的数量大于集群broker的数量,这样消息数据就能够均匀的分布在各个broker中。分布式
在存储结构上,每一个partition在物理上对应一个文件夹,该文件夹下存储这个partition的全部消息和索引文件。parition命名规则为topic名称+序号,每个partition序号从0开始,序号最大值为partitions数量减1。性能
每一个partition中有多个大小相等的segment数据文件,每一个segment的大小是相同的,但每一个消息的大小可能不一样,所以segment数据文件中消息的数量可能不相等。segement数据文件有两部分组成,分别为index file和data file,此两个文件是一一对应,对成出现,后缀分别为".index"和".log"。日志
每一个patition有本身的replica,每一个replica分布在不一样的broker节点上,多个partition须要选举出leader partition,leader负责读写,并由zk负责fil over。
一个Topic配置多个patition能够将消息内容分散存放到多个broker上,这样就能够避免文件尺寸达到单机磁盘的上限,同时还能够保证消息存储、消费的效率,由于更多的patitions能够容纳更多的consumer,可有效提高kafka的吞吐率。
partition复制机制
- 在kafka中,复制策略是基于partition,而不是topic。kafka将每一个partition数据复制到多个server上,任何一个partition有一个leader和0到多个follower,副本的数量能够经过broker配置文件定义。
- leader处理全部的读写请求,follower须要与leader保持同步。Follower就像一个consumer,消费消息并保存至本地日志中。leader负责跟踪全部的follower状态,若是follower落后太多或者失效,leader将会把它从同步列表中删除。它会继续从leader从获取数据,直至数据足够新,而后再次加入到同步列表当中。
- kafka不会更换replicas宿主,由于同步列表中的replicas须要足够快,才能保证producer发布消息时接受到ACK的延迟较小。
- 当全部follower都将一条消息保存成功,此消息才被认为是"committed",那么此时consumer才能消费它,这种同步策略要求follower和leader之间必须具备良好的网络环境。
- 即便只有一个replica实例存活,仍然能够保证消息的正常发送和接收,只要zk存活便可(这一点相较于其它分布式存储要求多数存活的方式不一样)。
- 当leader失效时,须要在follower当中选取新的leader。kafka中leader的选举并无采用多数投票的算法。由于这种算法对于网络稳定性、投票者的数量等条件有要求。对于kafka而言,每一个partition中全部的replicas信息均可以在zk中得到,所以选取leader对它来说是一件很容易的事情。
Consumer与Topic的关系
kafka做为分布式的消息系统支持多个producer和多个consumer,producer能够将消息分布到集群中不一样节点的不一样patition上,consumer也能够消费多个节点上的多个patition。在写消息时容许多个producer写到同一个partition中,可是读消息时,一个partition只容许被一个consumer group中的一个consumer所消费。而一个consumer能够消费多个patition。也就是说同一个consumer group下的consumer对partition是互斥的,而不一样consumer group之间则是共享的。
一般状况下,一个group中会包含多个consumer,这样不只能够提升topic中消息的并发消费能力,并且还能提升"故障容错"性,若是group中的某个consumer失效,那么其消费的partitions将会有其余consumer自动接管。而对于一个topic,同一个group中不能有多于partitions个数的consumer同时消费,不然将意味着某些consumer将没法获得消息