以下内容基于阅读kafaka中文文档
磁盘优化
kafka进行了消息持久化,持久化就离不开磁盘,磁盘的性能比较低,kafka在这方面使用顺序io代替随机io,这极大的提高了磁盘的读写性能。现代操作系统在越来越注重使用内存对磁盘进行 cache。现代操作系统主动将所有空闲内存用作 disk caching,代价是在内存回收时性能会有所降低。所有对磁盘的读写操作都会通过这个统一的 cache。如果不使用直接I/O,该功能不能轻易关闭。因此即使进程维护了 in-process cache,该数据也可能会被复制到操作系统的 pagecache 中,事实上所有内容都被存储了两份。
Kafka 建立在 JVM 之上,jvm有如下特点:
- 对象的内存开销非常高,通常是所存储的数据的两倍(甚至更多)。
- 随着堆中数据的增加,Java 的垃圾回收变得越来越复杂和缓慢。
使用文件系统和 pagecache 可以将缓存的容量翻倍(不需要java对象的元数据信息),服务重启后缓存依旧可用(注意是服务不是服务器),如果是基于jvm的进程缓存 而不是操作系统的pagecache,服务重启之后还要经历cold cache(在服务刚启动的时候性能会非常糟糕)。所有保持 cache 和文件系统之间一致性的逻辑现在都被放到了 OS 中,这样做比一次性的进程内缓存更准确、更高效。
在常量时间内读写
kafka的持久化使用了类似日志系统的解决方案,不断的项文件末尾追加,这种架构读写的时间复杂度都是O(1),读操作不会阻塞写。
在不产生任何性能损失的情况下能够访问几乎无限的硬盘空间,这意味着我们可以提供一些其它消息系统不常见的特性。例如:在 Kafka 中,我们可以让消息保留相对较长的一段时间(比如一周),而不是试图在被消费后立即删除。正如我们后面将要提到的,这给消费者带来了很大的灵活性。
批处理优化
kafka基于上文的优化解决了磁盘的io瓶颈问题,接下来就要解决大量的小型io操作。
小型的 I/O 操作发生在客户端和服务端之间以及服务端自身的持久化操作中。
为避免这种情况,kafka创建了一个自己的协议,这个协议是建立在一个 “消息块” 的抽象基础上,合理将消息分组。 这使得网络请求将多个消息打包成一组,而不是每次发送一条消息,