卡夫卡的分区设计

  1. 生产者写作的并行性受分区数量的限制。
  2. 消费者消费并行度也受到消费分区数量的限制。假设分区数为20,则最大并发消费消费者数为20。
  3. 每个主题由固定数量的分区组成。分区编号确定单个代理可能具有的最大主题数,而不会显着影响性能。

更多细节请参考这里

为什么Kafka不能支持更多分区

  1. 每个分区都存储整个消息数据。尽管每个分区都按顺序写入磁盘,但随着并发写入分区数量的增加,从操作系统的角度来看,写入变得随机。
  2. 由于分散的数据文件,很难使用Linux IO组提交机制。

如何在RocketMQ中支持更多分区?

截图

  1. 所有消息数据都存储在提交日志文件中。所有写入都是完全顺序的,而读取是随机的。
  2. ConsumeQueue存储实际的用户消费位置信息,这些信息也以顺序方式刷新到磁盘。

优点:

  1. 每个使用队列都是轻量级的,并且包含有限数量的元数据。
  2. 对磁盘的访问是完全顺序的,这可以避免磁盘锁争用,并且在创建大量队列时不会导致高磁盘IO等待。

缺点:

  1. 消息消耗将首先读取消耗队列,然后提交日志。在最坏的情况下,该过程会带来一定的成本。
  2. 提交日志和使用队列需要在逻辑上保持一致,这为编程模型带来了额外的复杂性。

设计动机:

  1. 随机阅读。尽可能多地读取以提高页面缓存命中率,并减少读取IO操作。如此大的内存仍然是可取的。如果累积大量消息,读取性能是否会严重降低?答案是否定的,原因如下:
    • 即使消息的大小仅为1KB,系统也会提前读取更多数据,请参阅PAGECACHE预取以供参考。这意味着对于续集数据读取,它将访问将执行的主存储器而不是慢速磁盘IO读取。
    • 从磁盘随机访问CommitLog。如果在SSD的情况下将I / O调度程序设置为NOOP,则读取qps将大大加速,因此比其他电梯调度程序算法快得多。
  2. 鉴于ConsumeQueue仅存储固定大小的元数据,主要用于记录消费进度,因此可以很好地支持随机读取。利用页面缓存预取,访问ConsumeQueue与访问主内存一样快,即使是在大量消息累积的情况下也是如此。因此,ConsumeQueue不会对读取性能带来明显的损失。
  3. CommitLog几乎存储所有信息,包括消息数据。与关系数据库的重做日志类似,只要提交日志存在,就可以完全恢复消耗队列,消息密钥索引和所有其他所需数据。
posted on 2017-04-10 11:34  风又奈何  阅读(5822)  评论(0编辑  收藏  举报