Kafka基础知识

Kafka保证数据的有序消费

Kafka does it better. By having a notion of parallelism—the partition—within the topics, Kafka is able to provide both ordering guarantees and load balancing over a pool of consumer processes. This is achieved by assigning the partitions in the topic to the consumers in the consumer group so that each partition is consumed by exactly one consumer in the group. By doing this we ensure that the consumer is the only reader of that partition and consumes the data in order. Since there are many partitions this still balances the load over many consumer instances. Note however that there cannot be more consumer instances in a consumer group than partitions.

上面说的很清除了,在一个partition内的数据,是可以保证有序的,但是跨partition的是不可以的。

非常好的Kafka文章: Kafka介绍

程序上要保证消费消息的幂等性,保证不要重复消费。这样Kafka发送的消息就不必在意是否重复发了。

我认为zk在Kafka中就是保证协调,调度kafka集群的作用,维持kafka集群的高可用,当有机器宕机时,要及时摘除,并重新选择Leader,保证正常的replication。

zookeeper 存储集群的元数据信息,对节点进行心跳检测验活,controller选主。

很多传统的Message Queue都会在消息被消费完后将消息删除,一方面避免重复消费,另一方面可以保证Queue的长度比较短,提高效率。而如上文所述,Kafka并不删除已消费的消息,为了实现传统Message Queue消息只被消费一次的语义,Kafka保证每条消息在同一个Consumer Group里只会被某一个Consumer消费。

Kafka对消息的分配是以Partition为单位分配的,而非以每一条消息作为分配单元

公司目前在用的时talos,是基于Kafka二次开发的,主要优点:

1、使用HDFS存储;

2、解决消息重复发送问题:

公司用的talos中,解决消息幂等消费是从生产者和消费者两端入手的。

生产者端提交去重:每次生产一条消息,分配一个唯一的sequenceNumber序列号,这样即使生产者提交信息后,由于接收不到talos提交信息反馈导致重传了,talos也会根据sequenceNumber进行去重处理。

消费者端去重:先根据接收到消息的sequenceNumber进行去缓存里(set数据结构)查,不存在则代表没有处理过该消息,业务逻辑处理该条消息,处理完后将sequenceNumber存入redis的set中;存在代表消费过,那么就不处理。redis相当于一个去重缓存。

  • kafka
    优点:有维护支持,较为稳定,高吞吐,消息回溯
    缺点:迁移成本高,且不支持定时消息和重试
    迁移过程:需在生产和消费两端适配现有接口
  • nsq
    优点:轻量级消息队列,支持定时消息和重试
    缺点:需要单独运维,迁移成本较

再说说Kafka的高吞吐量,每秒可达到百万级。总结主要有以下几点:

1、顺序读写;

2、零拷贝;

3、分区并发写入;

4、压缩;

5、内存映射 mmap

顺序读写

虽然Kafka不像Redis那样直接操作内存,而是写入磁盘文件。但是其性能并不差,而这完全归功于Kafka实现的顺序写入和读取。每次写入都是追加到本地磁盘文件的末尾,并不是随机写入。

Kakfa做过试验展示了顺序读写提升的性能

  1. Sequence I/O: 600MB/s (实验室)

  2. Sequence I/O: 400MB-500MB/s (工作场景)

  3. Random I/O: 100KB/s

零拷贝

Kafka通过使用零拷贝提升了处理速度,其调用的是sendfile,关于零拷贝的介绍可以参考我之前写的文章: Linux之零拷贝技术

分区

消息可以根据某种策略(比如hash key 取模)分配到不同的partation中,然后可以并行执行。

压缩

Producer在发送消息前会将数据进行压缩,减少传输时间。

内存映射

就是mmap技术,Memory Mapped Files。就是将磁盘文件映射到内核缓冲区,这使得操作磁盘文件就像操作内存一样。Kafka可以选择同步刷磁盘,也可选择异步刷盘。

文件存储

Kafka的文件存储。之前也说过,虽然Kafka是将数据写入磁盘文件,但由于其采用顺序写入,因此性能很强悍。

对于同一个topic,可以有多个分区partition,命名方式就是topic名称+分区序号。如: testtopic-0。

在一个partition下,文件会按照段segment存储,而segment的大小可以设置,通过segment分段,可以更快速的寻找数据,类似二分查找。而对于每一个segment都会存在三种类型的文件,.index,.log,.timeindex 如下:

.log是存储实际的数据;

.index存储的是位移索引,索引指的是对应数据文件消息的物理偏移地址。主要存储了offset和position

Dumping /home/work/logs/kafka-logs/testtopic-0/00000000000000000000.index
offset: 387 position: 5928
offset: 403 position: 13520
offset: 1000 position: 31678

offset表示在这个文件的相对位置,positon表示消息在这个文件的实际物理地址,需要通过指针移动到目标地址。

.timeindex存储的是时间戳和消息的位移值,这个主要是方便通过时间戳查询。

参考资料:

Kafka为什么吞吐量大、速度快?

Kafka史上最详细原理总结

Kafka日志存储详解

Kafka文件存储机制那些事

--------EOF---------
微信分享/微信扫码阅读