序言:
Kafka是一个依赖磁盘来存储和缓存消息,一般对于磁盘的读写我们认为它的速度很慢的(实际上对于磁盘的读写速度也是根据我们的使用方式来决定它的快慢,例如如果我们进行顺序读写那么它的速度和随机内存访问相差无几,但若我们进行随机读写时,该效率与内存相差千倍),关于服务器中各存储介质的读写速度可参考以下图。
从上述我们可以看出磁盘处于一个底层的位置,而缓存(内存)处于金字塔位置。那么Kafka为何不向Rabbitmq那样采用内存作为默认的存储介质,使用磁盘作为备用(使用磁盘作为消息的持久化,避免内存丢失)来以此实现高吞吐和低延迟的特性 。这与Kafka的设计有一定关系,Kafka在创立之初就是作为日志系统采集的中间件而使用,对于日志文件每日可产生海量的数据,而且这些数据可能被进行落地存储一定日期,对于这些数据我们如果的存储在内存中,很显然第一成本很大,第二不一定有那么大的内存硬件供我们使用(kafka也会使用到内存,只不过不会非常依赖(当然内存大在数据体量大的时候也会有好处,后文叙述),这也是我们在大数据场景中可以看到kafka的原因-内存比磁盘贵)。而Rabbitmq它的设计模式是为了更快的将数据push给消费者,并且当消费者进行ack时,该条消息就会标记删除,后续会有其它线程进行del。 第二也是最重要的一点Kafka通过设计了存储的数据结构,读写的使用方式来规避了磁盘的缺点,放大磁盘的优点,最终达到高吞吐和低延迟的特性,对比Rabbitmq来说,吞吐量比Rabbitmq高而延迟相对于Rabbitmq的ns Kafka的ms也是可以接受。
1:顺序读写
Kafka对于数据写入磁盘文件,都以文件追加的形式,不会存在对之前数据的修改,(只有当满足一定条件会进行segment分段存储,即将最后文件置为可读,并创建新的log,及索引文件,并设置为读写,最后的offset作为文件名。这些条件有以下四种:
- 当log文件的体量超过超过broker设置的阈值(log.segment.bytes=1073741824-1G内存)
- 当index文件的体量超过来broker设置的阈值(log.index.size