概述
Kafka是一个分布式流平台,它源自于日志聚合案例,它不须要过高的并发性.在阿里巴巴的一些大型案例中,发现原来的模式已经不能知足的实际需求。所以,开发了一个名为rocketmq的消息中间件,它能够处理普遍的场景,从传统的发布/订阅场景到要求高容量、不容许消息丢失的实时事务系统等。算法
Kafka的分区设计
- 生产者并行写的性能受到分区数量的限制。
- 消费者并行消费的程度受消费的分区数限制。假设消费者分区的数量是20,那么并发消费的最大数量是20.
- 每一个主题由固定数量的分区组成,分区数量决定单个代理在不会显著影响性能的状况下,可能拥有的主题最大数量。
如何选择Kafka集群中Topic分区数量数据库
为何Kafka不能支持更多的分区
- 每一个分区存储整个消息数据。虽然每一个分区都是有序地写入磁盘的,可是随着并发写入分区的增长,从操做系统的角度来看,写入变得随机。
- 因为数据文件分散,很难使用Linux IO组提交机制。
RocketMQ 中是如何支持更多的分区的?
- 全部消息数据都存储在提交日志文件中,全部写入都是彻底连续的,而读取是随机的。
- ConsumeQueue存储用户实际消费的位置信息,这些信息也按顺序刷新到磁盘。
优点:编程
- 每一个消费队列都变得轻量化,而且包含有限数量的元数据(数据量变少)。
- 对磁盘的访问是彻底连续的,这样能够避免磁盘锁争夺,而且在建立大量队列时不会致使高磁盘IO等待。
劣势:缓存
- 消费消息将首先读取消费队列,而后提交日志,在最坏的状况下,过程会带来必定的成本。
- 提交日志和使用队列须要逻辑一致,这会给编程模型带来额外的复杂性。
设计的动机
- 随机读:尽量多地读取以增长页面缓存命中率,并减小读取IO操做。因此在大内存状况下是仍然是适合的。若是积压了大量的消息,读取的性能会严重降低吗?答案是否认的。
缘由以下:并发
- 即便消息大小只有1KB,系统也会提早读取更的数据(缓存数据预取:参考PAGECACHE prefetch ),这意味着对于后续数据读取,将执行对主内存的访问,而不是慢速磁盘IO读取。
- 从磁盘随机访问CommitLog,若是在SSD的状况下将I/O调度器设置为NOOP,那么读取qps的速度将大大加快,比其余操做系统调度算法快得多。
-
因为ConsumeQueue只存储固定大小的元数据,主要用于记录消费过程,所以支持随机读取。利用页面缓存预取,即便是在大量消息积累的状况下,访问ConsumeQueue的速度与访问主内存同样快。所以,ConsumeQueue不会带来明显的读取性能影响。分布式
-
CommitLog几乎存储全部信息,包括消息数据。与关系数据库的重作日志相似,只要存在提交日志,就能够彻底恢复使用队列、消息键索引和全部其余所需数据。性能