Kafka在设计之初,就考虑了以下几个方面的问题:
另外, Kafka 实现持久化的设计也有新颖之处。普通的系统在实现持久化时可能会先尽量使用内存,当内存资源耗尽时,再一次性地把数据“刷盘”;而 Kafka 则反其道而行之, 所有数据都会立即被写入文件系统的持久化日志中,之后 Kafka 服务器才会返回结果给客户端通知它们消息已被成功写入。这样做既实时保存了数据,又减少了 Kafka 程序对于内存的消耗,从而将节省出的内存留给页缓存使用,更进一步地提升了整体性能 。
总结一下,上面主要讨论了 Kafka 在吞吐量/延时、消息持久化、负载均衡/故障转移和伸缩性这 4 个方面的设计理念。正是得益于这些设计特性, Kafka 才成为了 一个完备的分布式消息引擎解决方案,赢得了广大用户的赞誉 。
Kafka 在消息设计时特意避开了繁重的 Java 堆上内存分配,直接使用紧凑二进制字节数组 ByteBuffer 而不是独立的对象,至少能够访问多一倍的可用内存。
值得一提的是, Kafka 的 Partition 实际上并没有太多的业务含义,它的引入就是单纯地为了提升系统的吞吐量,因此在创建 Kafka Topic 的时候可以根据集群实际配置设置具体的Partition 数,实现整体性能的最大化。
显然,每条消息在某个 Partition 的位移是固定的,但消费该 Partition 的消费者的位移会随着消费进度不断前移,但终究不可能超过该分区最新一条消息的位移 。
综合之前说的 Topic、Partition 和 Offset,我们可以断言 Kafka 中的一条消息其实就是一个<Topic,Partition,Offset>三元组,通过该元组值我们可以在 Kafka 集群中找到唯一对应的那条消息。
Kafka 保证同 一个 Partition 的多个 Replica 一定不会分配在同一台 broker 上 。毕竟如果同一个 broker 上有同一个 Partition 的多个 Replica,那么将无法实现备份冗余的效果。