主题与分区
1、Kafka 分区数可以增加或减少吗?为什么?
目前Kafka只支持增加分区数而不支持减少分区数。
为什么不支持减少分区?
- 按照Kafka现有的代码逻辑而言,此功能完全可以实现,不过也会使得代码的复杂度急剧增大。
- 实现此功能需要考虑的因素很多,比如删除掉的分区中的消息该作何处理?如果随着分区一起消失则消息的可靠性得不到保障;如果需要保留则又需要考虑如何保留。直接存储到现有分区的尾部,消息的时间戳就不会递增。如果分散插入到现有的分区中,那么在消息量很大的时候,内部的数据复制会占用很大的资源,而且在复制期间,此主题的可用性又如何得到保障?
- 虽然分区数不可以减少,但是分区对应的副本数是可以减少的。
2、 kafka中每个分区的消息是有序的吗?每个主题呢?
每个消息在被追加到分区日志文件的时候都会分配一个特定的偏移量(offset)。
offset 是消息在分区中的唯一标识,Kafka 通过它来保证消息在分区内的顺序性,不过 offset 并不跨越分区,也就是说,Kafka 保证的是分区有序而不是主题有序。
其他
1、Kafka如何实现高性能IO?
1、使用批量处理的方式来提升系统吞吐能力。
- Kafka 的客户端 SDK( 软件开发工具包 ) 在实现消息发送逻辑的时候,采用了异步批量发送的机制。
- 无论是同步发送还是异步发送,Kafka 都不会立即就把这条消息发送出去。它会先把这条消息,存放在内存中缓存起来,然后选择合适的时机把缓存中的所有消息组成一批,一次性发给 Broker。
- Broker 整个处理流程中,无论是写入磁盘、从磁盘读出来、还是复制到其他副本这些流程中,批消息都不会被解开,一直是作为一条“批消息”来进行处理的。
- 在消费时,消息同样是以批为单位进行传递的,Consumer 从 Broker 拉到一批消息后,在客户端把批消息解开,再一条一条交给用户代码处理。
2、基于磁盘文件高性能顺序读写的特性来设计的存储结构。
- 对于磁盘来说,它有一个特性,就是顺序读写的性能要远远好于随机读写。 因为顺序读写相比随机读写省去了大部分的寻址时间,它只要寻址一次,就可以连续地读写下去,所以说,性能要比随机读写要好很多。
- Kafka 存储设计非常简单,对于每个分区,它把从 Producer 收到的消息,顺序地写入对应的 log 文件中,一个文件写满了,就开启一个新的文件这样顺序写下去。消费的时候,也是从某个全局的位置开始,也就是某一个 log 文件中的某个位置开始,顺序地把消息读出来。
- Kafka充分利用了顺序读写这个特性,极大提升了 Kafka 在使用磁盘时的 IO 性能。
3、利用操作系统的 PageCache 来缓存数据,减少 IO 并提升读性能。
- PageCache 是现代操作系统都具有的一项基本特性,相当于操作系统在内存中给磁盘上的文件建立的缓存。
- Kafka 在读写消息文件的时候,充分利用了 PageCache 的特性。一般来说,消息刚刚写入到服务端就会被消费,按照 LRU 的“优先清除最近最少使用的页”这种策略,读取的时候,对于这种刚刚写入的 PageCache,命中的几率会非常高。
- 大部分情况下,消费读消息都会命中 PageCache,带来的好处有两个:一个是读取的速度会非常快,另外一个是,给写入消息让出磁盘的 IO 资源,间接也提升了写入的性能。
4、使用零拷贝技术加速消费流程。
ZeroCopy:零拷贝技术:
我们知道,在服务端,处理消费的大致逻辑是这样的:
- 首先,从文件中找到消息数据,读到内存中;
- 然后,把消息通过网络发给客户端。
这个过程中,数据实际上做了 2 次或者 3 次复制:
- 从文件复制数据到 PageCache 中,如果命中 PageCache,这一步可以省掉;
- 从 PageCache 复制到应用程序的内存空间中,也就是我们可以操作的对象所在的内存;
- 从应用程序的内存空间复制到 Socket 的缓冲区,这个过程就是我们调用网络应用框架的 API 发送数据的过程。
Kafka 使用零拷贝技术可以把这个复制次数减少一次,上面的 2、3 步骤两次复制合并成一次复制。直接从 PageCache 中把数据复制到 Socket 缓冲区中,这样不仅减少一次数据复制,更重要的是,由于不用把数据复制到用户内存空间,DMA 控制器可以直接完成数据复制,不需要 CPU 参与,速度更快。
2、Kafka如何保证一致性?
一致性指的是什么?
不论是旧的 Leader 还是新选举的 Leader,Consumer 都能读到一样的数据。
如何解决?
Kafka引入了High Watermark 机制,当我们将隔离级别isolation.level设置为:read_committed时,Kafka会保证所有消费者所消费的消息都是在High Water Mark之下。
所谓High Watermark ,俗称高水位,它标识了一个特定的消息偏移量(offset),消费者只能拉取到这个 offset 之前的消息。