跳至主要內容

消息队列-⑤高性能篇

holic-x...大约 25 分钟消息队列消息队列

消息队列-⑤高性能篇

学习核心

消息队列-高性能篇

  • 基于Kafka框架作为学习沉淀
    • Kafka 高性能 核心
      • 多层次
      • 顺序写
      • 页缓存
      • 零拷贝
      • 批量操作
      • 数据压缩
    • Kafka 高性能常见题型

学习资料

高性能总结

​ 从“存储设计”(多层次)、“读写”(顺序写、Page Cache)、“传输”(零拷贝)、“应用层”(批量操作、数据压缩)等方面提供了性能优化支持

  • 多层次(分治+查询优化)
    • Topic 划分多Partition(分治)、Partition 拆分多文件(查询优化)
  • 顺序写(写入优化)
    • “顺序写入磁盘”:Kafka根据自身定位和需求选择“顺序写磁盘”(其性能既接近普通内存写,又降低了数据丢失风险),顺序写入减少了磁盘寻道时间,使得磁盘IO操作更加高效,能够持续高速写入数据,从而实现高吞吐量
  • 页缓存(读写优化)
    • “顺序写入内存”:引入操作的系统的Page Cache进行读写优化,通过合理配置参数来充分利用Page Cache提高消息的读写性能
      • 写入:消息先写入Page Cache,然后由操作系统进行异步刷盘(整个过程中可能存在消息丢失风险)
      • 读取:先从Page Cache读取,如果命中则直接返回,如果没有命中则从磁盘读取然后回写Page Cache再响应
  • 零拷贝(传输优化)
    • 零拷贝技术可以优化数据发送效率,Kafka则充分利用了Linux的这个特性来提升性能
    • Kafka底层传输是通过调用sendfile()系统调用函数,进而减少【上下文切换】、【数据拷贝】带来的损耗
      • 【上下文切换】:sendfile() 替换了原有的read()、wirte()(传统:2次=》零拷贝:1次)
      • 【数据拷贝】:数据直接在核心态传输,只需要拷贝2次(传统:4次=》零拷贝:2次)
  • 批量操作(应用层)
    • 批量发送:通过“批量发送”(“发送缓冲”:将数据在缓冲中聚集起来,然后再统一发送给Broker)减少IO、网络性能消耗
    • 批量消费:一次性拉取多条消息进行消费,节约网络开销和带宽
  • 数据压缩(应用层)
    • 可通过压缩消息来提升kafka性能,压缩算法的选择结合实际业务场景配置
    • kafka压缩的环节:producer端进行消息压缩(享受发送环节的性能增长)、broker端进行消息压缩(享受更高磁盘利用率)
    • kafka支持的压缩算法:gzip、snappy、lz4、zstd

多层次(分治+查询优化)

​ Kafka 本质是数组,数组的优势在于存储连续、方便索引,如果顺序写入性能会很高。但是如果光是一个数组,随着数据越积越多,单一磁盘存放越来越吃力,造成I/O压力过大。所以Kafka不仅仅是一个数组,实际上,Kafka充分利用分治的思想,将这一个抽象的大数组,划分为很多个小数组。

1.Kafka 多层划分核心

多层划分概念

  • Topic 划分多Partition(分治):一个Topic划分多个Partition,分布在不同的Broker =》可以理解为一个大数组被划分为多个小数组,分别存放在不同的Broker
  • Partition 拆分多文件(查询优化):Kafka对Partition做了进一步拆分,每个Partition对应多个不同的文件(这些文件是分离开来的:.index.log.timeindex
    • .log:记录数据(即消息本身)
    • .index:时间索引(通过时间对.log文件做索引查询)
    • .timeindex:偏移量索引(通过偏移量对.log文件做索引查询)

顺序写(写入优化)

1.Kafka 写入机制

​ 基于前面的学习可知,Kafka 写入数据实际最终就是添加到每个Partition 末端(写入对应的磁盘文件中)。这种设计手段简单高效、且非常巧妙

数据落地思路 =》顺序写磁盘

​ 为了实现数据可靠,一般有两种思路:

  • 【方式1】直接写入磁盘:直接写磁盘很容易实现了数据可靠,缺点是性能很差;
  • 【方式2】先写入程序内存,后续再寻求持久化:这种思路写入之后需要有完善复杂的机制同步到磁盘,增加了很高的复杂性;

​ 上述两种方式的选择取决于“低复杂度”和“高性能”的取舍,其实可以有两者兼顾的手段:顺序写磁盘

2.顺序写入磁盘

顺序写入磁盘概念核心

一般情况下内存写入通常远快于磁盘写入,但例外的是,当磁盘顺序写入的话,其性能和内存的差距并不会太大,所以落盘场景是可以考虑磁盘顺序写的,

​ Kafka的写入模式专门设计成了顺序写入磁盘(此处写磁盘也不一定是直接刷盘,而是交由操作系统控制,也会存在丢失数据的风险),相对于“先写内存后刷盘”的方式来说其减少了一个消息可能遗失的环节。

顺序写的优势

  • 高效的磁盘利用:
    • 磁盘的顺序写入性能通常远远高于随机写入性能,这使得 Kafka 能够实现高吞吐量
  • 简单的存储管理
    • 顺序写入简化了日志段的管理和消息的追加操作
    • 日志文件按顺序组织,便于快速查找和读取消息
  • 可靠性和一致性
    • 顺序写入有助于确保消息的可靠性,因为消息一旦写入日志文件,不会被修改
    • 消费者可以通过偏移量准确地读取消息,确保消息处理的顺序和一致性

顺序写入为什么快?

磁盘写入的核心步骤是寻址、数据传输,而寻址这一过程是主要耗时点,顺序写入磁盘则是通过减少寻址时间(主要耗时的步骤得到优化)进而提升写入性能

​ 一般而言写磁盘的性能会远远低于操作内存,但是顺序写入则不一样,顺序写入的性能通常而言可以高出随机写入3个以上的数量级,甚至接近内存写入。

​ 首先先理解写入磁盘具体是做什么?可以简单一点把写入磁盘分为两步:1.寻址;2.数据传输,寻址需要磁头转动,是机械操作、是主要耗时的地方,而随机写入,就得每一次都去寻址,这就意味着每一次都需要机械活动,自然就非常慢,所以从磁盘的视角来看,它是很讨厌随机写入的。

​ 如果想更深入一点理解,可以把磁盘写入拆得更细致:

  • (1)磁头沿着半径机械移动,最终移动到数据所在的磁柱
  • (2)盘片旋转,是磁盘对齐数据所在扇区
  • (3)数据传输,也就是写入数据

​ (1)、(2)可以看作寻址,(3)是数据传输,在随机读写情况下,写100000次数据,就需要100000次磁头移动时间、100000次盘面旋转时间,而顺序写入情况下,只需要1次磁头移动和1次盘面旋转,即一次寻址,然后最后都是写100000次数据,但是大的耗时被缩减了,所以顺序写入的性能自然就上来了

image-20240823153357903

页缓存(读写优化)

1.顺序写入内存

​ 基于上述“顺序写”概念,顺序写入磁盘的速度已经很快了,如果能实现“顺序写入内存”速度会更快。Kafka 利用操作系统自带的Page Cache来实现一定程度顺序读写内存

​ Page Cache可以简单看作热点磁盘数据的内存缓存,其读写优化体现分析如下:

  • 写入优化:当消息写入时,先写入Page Cache,后面由操作系统异步将其刷入磁盘,进而提升性能
  • 读取优化:当读取消息时,先从Page Cache中读取,如果命中则直接返回;如果没有命中则再去磁盘中读取随后回写Page Cache、返回数据

image-20240823155058668

​ 值得一提的是,Kafka是生产消费者模式,即生产了消息,在无积压情况下,这个消息很快就会被消费,也就是说生产消费时写入了Page Cache,而很快就有消费者来触发Kafka应用程序读取对应数据,而这个时间间隔很短,PageCache命中的可能性会很高

2.Page Cache数据和磁盘同步

​ 数据写入Page Cache之后,是需要和磁盘同步的。此时如果电脑断电或者重启,这部分数据就会丢失。数据同步有几个时机:

  • (1)当空间内存不够用了,也就是说低于某个阈值时,此时将Page Cache刷入并释放Page Cache

  • (2)当脏页在内存驻留时间超过一个阈值时

    • 写入数据之后,Page Cache 会标记为脏页,即内存数据页跟磁盘数据页内容不一致
  • (3)用户主动调用刷脏系统,调用sync()和fsync()(理解概念即可)

    • sync系统调用:实际是将所有修改过的缓冲区排入写队列,不等待磁盘操作结束
    • fsync系统调用:需要传入一个文件描述符fd为参数,fsync会确保写磁盘结束才返回,安全性高

3.Page Cache 相关参数

​ 为了充分利用 Page Cache,可以关注Kafka 一些文件相关的配置和优化策略

操作系统配置(linux下)

(1)vm.dirty_background_ratio

vm.dirty_background_ratio参数用于控制内存中脏页的比例,确保系统及时将脏页写入磁盘,避免过多的脏页占用 Page Cache。这个值通常默认在 5% 或 10%,具体和系统型号版本有关系,Linux下具体默认值可通过 cat /proc/sys/vm/dirty_background_ratio命令查看

​ 对于磁盘性能比较差的服务器,应该把这个值设置的小一点,这样可以把一个比较重的IO操作,拆解为多个小的IO操作,减少单次压力:

  • 较低的vm.dirty_background_ratio参数值可以确保脏页及时写回磁盘,避免在短时间内大量脏页写回磁盘造成的IO突发
  • 较高的vm.dirty_background_ratio参数值可能会导致较大的IO负载
(2)vm.dirty_ratio

vm.dirty_ratio参数用于控制内存中脏页的比例,确保系统及时将脏页写入磁盘,避免过多的脏页占用 Page Cache。它控制的是脏页占总内存的最大比例。当脏页达到这个比例时,所有后续写操作会被阻塞,直到部分脏页被写回磁盘。默认值一般为20%,具体和系统型号版本有关系,Linux下的默认配置可通过cat /proc/sys/vm/dirty_ratio命令查看。

​ 需注意,这是一个前台操作,影响用户进程的性能,所以尽量不要达到这个阈值,如果写压力比较大,建议适当调大这个值

日志文件清除参数

​ 如果业务不是说数据非要一直保留,是可以开启清除策略的,这样也可以减少不必要的数据占用 PageCache,从而提高读写性能,以下是清除相关的参数:

(1)log.retention.bytes

log.retention.bytes参数定义了每个主题在磁盘上可以占用的最大字节数。当日志文件的大小达到这个阈值时,Kafka将开始删除旧的日志文件以腾出空间。log.retention.bytes默认是-1,表示没有上限,也就是不删除,具体可以根据业务情况灵活设置这个参数,不过这个值对于业务开发者可能会比较难以设定,所以更多的是使用下面的log.retention.ms参数

(2)log.retention.ms

log.retention.ms参数定义了日志文件保留的最长时间。当日志文件的创建时间超过这个阈值时DKafka 将删除这些过期的日志文件。这个配置单位是以毫秒为单位,默认为可以配置成整数表示的毫秒数604800000,表示7天(7天*24小时*60分钟*60秒*1000毫秒)

(3)配置场景参考

组合使用log.retention.byteslog.retention.ms可以组合使用,Kafka 会在任意一个条件满足时删除日志文件。例如,如果日志文件超过 10 GB 或者超过7天,Kafka 就会删除旧的日志文件

独立使用:如果只设置了 log.retention.ms 而没有设置 log.retention.bytes ,日志文件将只会根据时间进行清理。反之亦然。

零拷贝(传输优化)

1.“传输”分析

常规传输为何低效?

问题分析

​ 消息是存储在Kafka服务器,消费者消费消息时,数据要从Kafka服务端传递给消费者。具体分析流程即当有Consumer订阅王题,数据需要从磁盘读取并将数据写入网络套接字,然后在网络中进行传输,这个操作看似不复杂,但如果不很好的设计传输流程,它的效率会非常低

常规传输为何低效?

常规的数据传输方式简单又传统,但存在冗余的上文切换和数据拷贝,在高并发系统里是非常糟糕的,多了很多不必要的开销,会严重影响系统性能

​ 如果应用程序要从磁盘读取数据发送到网络,那么会经历下图的流程:可以从系统调用数据拷贝两个角度分析

image-20240823162442635

2次系统调用

​ 一次是 read(),一次是 write(),每次系统调用都得先从用户态切换到内核态,等内核完成任务后,再从内核态切换回用户态,所以共发生了4次用户态与内核态的上下文切换。且上下文切换的成本并不小,一次切换需要耗时几十纳秒到几微秒,虽然时间看上去很短,但是在高并发的场景下,这类时间容易被累积和放大,从而影响系统的性能

4次数据拷贝:其中两次是 DMA 的拷贝,另外两次则是通过 CPU拷贝的

  • 第1次拷贝:把磁盘上的数据拷贝到操作系统内核的缓冲区里(一些资料称之为Read Buffer),这个拷贝的过程是通过 DMA 搬运的
  • 第2次拷贝:把内核缓冲区的数据拷贝到用户的缓冲区里,干是我们应用程序就可以使用这部分数据了,这个拷贝到过程是由 CPU 完成的
  • 第3次拷贝:把刚才拷贝到用户的缓冲区里的数据,再拷贝到内核的socket 的缓冲区里,这个过程依然还是由CPU 搬运的
  • 第4次拷贝:把内核的 socket 缓冲区里的数据,拷贝到网卡的缓冲区里,这个过程又是由 DMA 搬运的

​ 基于上述分析,本来是搬运一份数据,结果内部却搬运了4次,过多的数据拷贝无疑会消耗 CPU资源,大大降低了系统性能

​ DMA(Direct Memory Access),即直接内存访问,核心就是CPU 不再参与「将数据从磁盘控制器缓冲区搬运到内核空间」的工作,这部分工作全程由 DMA 完成。但是 CPU 在这个过程中也是必不可少的,因为传输什么数据,从哪里传输到哪里,都需要 CPU 来告诉 DMA 控制器。早期 DMA 只存在在主板上,如今由于IO设备越来越多,数据传输的需求也不尽相同,所以每个IO设备里面都有自己的 DMA 控制器

优化思路分析

​ 基于上述分析,结合传统传输方式下的低效问题分析,可以从“系统调用”和“数据拷贝”这两方面进行切入

(1)减少系统调用次数

​ 读取磁盘数据的时候,之所以要发生上下文切换,这是因为用户空间没有权限操作磁盘或网卡,内核的权限最高,这些操作设备的过程都需要交由操作系统内核来完成,所以一般要通过内核去完成某些任务的时候,就需要使用操作系统提供的系统调用函数。

​ 而一次系统调用必然会发生2次上下文切换:首先从用户态切换到内核态,当内核执行完任务后,再切换回用户态交由进程代码执行。

​ 所以,要想减少上下文切换的次数,就要减少系统调用的次数

(2)减少数据拷贝次数

​ 传统的文件传输方式会历经4次数据拷贝,其中的「从内核的读缓冲区拷贝到用户的缓冲区里,再从用户的缓冲区里拷贝到 socket 的缓冲区里」这个过程是没有必要的。因为文件传输的应用场景中,在用户空间并不会对数据「再加工」,所以数据实际上可以不用搬运到用户空间,因此用户的缓冲区是没有必要存在的。

​ 那么有没有一种技术,可以是实现数据之间在核心态进行传输,而不需要将数据在核心态和用户态之间来回复制,最终发送给接收端呢?=》零拷贝技术

2.“零拷贝”

​ 所谓的零拷贝是指将数据在内核空间直接从磁盘文件复制到网卡中,而不需要经由用户态的应用程序之手。这样既可以提高数据读取的性能,也能减少核心态和用户态之间的上下文切换,提高数据传输效率。

image-20240823163609568

具体流程如下:

(1)sendfile开启流程(sendfile是代替了read和write),相当于只有一次系统调用 =》减少上下文切换性能损耗

(2)操作系统将数据从磁盘通过DMA加载到内核空间的缓存区

(3)操作系统将数据的描述符拷贝到Socket 缓冲区中(Socket 缓冲区仅仅会拷贝一个描述符过去,不会拷贝数据)

(4)操作系统直接将数据从内核空间的缓存区传输到网卡中,并通过网卡将数据发送给接收方(本质是通过DMA来做的,此处DMA叫SG-DMA,理解为增强版DMA)

​ SG-DMA是一种强大的 DMA技术,特别适用于处理复杂的数据传输需求。在现代计算和通信系统中,SG-DMA提供了高效的数据传输解决方案,显著提高了系统性能和资源利用率。通过合理使用SG-DMA,系统可以在高性能数据处理和低功耗设计中找到平衡

基于上述流程分析,使用零拷贝之后,系统调用次数从2次变成了1次(减少上下文切换性能损耗),拷贝次数从4次变成了2次(减少数据拷贝次数),显著减少了数据传输的损耗,提升性能

3.kafka哪里使用的零拷贝

​ Kafka 充分利用零拷贝技术,大幅提升I/O的吞吐率,这也是为什么Kafka在处理海量数据时这么快的原因之一。可以通过追溯kafka文件传输的代码,其最终是调用了Java NIO库的transferTo方法,如果linux系统支持调用sendfile系统调用,则transferTo最后实际会使用到sendfile()系统调用函数

批量操作

​ 除却利用底层的技术,kafka 还在应用程序层面提供了一些手段来提升性能,例如批量操作(批量生产、批量消费)。

​ 实际上,批量操作并不是Kafka特有的技术支持,它是后端领域中非常常见的优化手段

1.批量生产

​ Kafka默认是消息来了就发送到Kafka服务端,试想下如果有5个线程来发送消息,那么并发度就只有5。但很多时候其实也不会去追求瞬时发送,所以这里有一个潜在的优化方向就是批量发送。即在向Kafka写入数据时,可以启用批次写入,这样可以避免在网络上频繁传输单个消息带来的延迟和带宽开销。假设网络带宽为10MB/S,一次性传输10MB的消息比传输1KB的消息10000万次显然要快得多。

配置参数(影响批量发送的核心参数)

高吞吐配置推荐:linger.ms:20s、batch.size:32kb、buffer.memory:32MB

linger.ms在发送一个批次消息前等待多少ms(默认是0,即不等待,即来即发),如果想增大单个批次的消息数的话可以增加linger.ms(例如3s,5s,10s,20s等)。

batch.size数据量累计到多大就发送(默认为16KB),即使没有达到linger.ms,只要批次字节数达到batch.size阈值也会立刻发送。可以将批量大小增加到32KB或64KB以提高请求的吞吐量。每个分区的批次是独立计算的,所以不要将batch.size设置为太高的数字,否则可能会遇到高内存使用率

buffer.memory控制生产者用于缓存消息的总内存大小。如果生产者发送消息的速度超过了Kafka 接收的速度,这个缓冲区会被填满,在批量场景要额外注意,比如希望批量发送64KB的消息,但是buffer.memory配置只有12KB,这显然是会阻塞生产者写入流程的,所以buffer.memory需要配置得大一些,默认值是32MB,还是很稳的。

​ 场景类比理解:可以理解为类似有很多件快递,一件一件发出去、运输肯定成本高,但是一批快递发在一个集装箱里,发到目的城市,那效率自然会有所提升。而这些参数可以分别对应场景中的设定

  • linger.ms:一批快递等待发车的时间,超出这个时间阈值就发车
  • batch.size:“装车累计量”,当装车达到这个阈值就发车(如果超过阈值但发车时间还没到也是直接发车)
  • buffer.memory:“车总容量”,例如一辆车最多放1000个快递,但是批量预期希望单批塞2000个快递,这明显是会出错的。因此在批量场景下,一般都会将这个值配置大一点

注意事项

​ 凡事有取舍,批量操作在带来性能优化的同时,也会付出一定的代价。在使用聚合发送需要下面几个问题:

  • 吞吐量 vs 延迟:增大 batch.sizelinger.ms 可以提高吞吐量,但也会增加消息的延迟,需要根据应用需求进行权衡
  • 内存使用:增大 buffer.memory 可以提高批量发送的效率,但会占用更多的内存
  • 可靠性:在批量发送消息时,要注意可能的数据丢失风险(聚合发送数据一丢就是一批)。如果对消息有很高的可靠性要求,需要确保配置了适当的 acks 参数,例如 acks=all ,以确保消息的可靠交付

2.批量消费

​ 批量消费是指一次性拉多条消息进行消费,这样可以节约网络开销和带宽

配置参数(影响批量消费的核心参数)

max.poll.records:每次调用 poll()方法时返回的最大记录数,用于设置单次轮询获取的最大记录条数

fetch.min.bytes:消费者在一次拉取请求中希望接收的最小数据量(以字节为单位),消费者会等待单批数据大小达到阈值时再返回

fetch.max.wait.ms:如果指定了 fetch.min.bytes ,则该参数控制消费者等待服务器返回数据的最大时间,即使在此时间内数据量没有达到 fetch.min.bytes,也会返回当前可用的数据

消费者示例配置:

  • linger.ms:500 // 每次poll最多拉取500条记录
  • batch.size:1024 // 最小拉取1024字节的数据
  • buffer.memory:500 // 最长等待500ms

注意事项

处理效率:批量消费消息可以显著提高处理效率,但需要确保处理逻辑能够快速处理这些消息,否则可能会导致消息堆积

偏移量提交:默认情况下,消费者会定期自动提交偏移量。可以通过配置 enable.auto.commit 参数来控制自动提交的行为,或者手动提交偏移量以确保消息处理的可靠性

资源管理:在批量消费时,要注意内存和 CPU 的使用情况,避免资源耗尽导致系统不稳定

数据压缩

​ 生产者通常发送基于文本的数据,例如JSON 数据。在这种情况下,对生产者应用压缩非常重要。默认情况下,生产者消息以未压缩的方式发送。Kafka支持两种类型的压缩(producer端和broker端) 通过启用压缩,可以减少网络利用率和存储,这通常是向Kafka 发送消息时的瓶颈

​ 压缩批次具有以下优点:

  • 生产者请求的大小要小得多,通常压缩之后的数据比压缩前小3倍以上
  • 因为数据变小了,通过网络传输数据的速度更快,即延迟更短,同时也拥有了更好的吞吐量
  • 因为数据变小了,那么在磁盘上存储的消息也变小了,Kafka 中的磁盘利用率更高

1.何时需要压缩?

​ 如果是追求高性能的服务,那么正常来说,都是需要开启压缩的,但它也会付出额外的CPU,需要考虑压缩带来的磁盘、带宽节省的收益是大于CPU一定程度的损失的

​ 那怎么判断收益是否大于损失?=》这个得看业务团队的具体情况来分析:

  • 如果团队CPU资源多到用不完,而瓶颈在于带宽或者磁盘存储,那显然需要开启压缩
  • 消息如果比较大,可以考虑压缩
  • 消息自身内容如果重复度高,可以考虑压缩(压缩本质就是针对重复片段用简单代码取代,已实现让数据更小的目的,所以重复度越高,压缩效果肯定是越好的)
  • 多条消息之间内容重复度高,那么可以考虑在批量发送和消息压缩一起开启,效果会很好
  • 其实一般来说,如果追求高性能的服务,那么都会开启压缩的

2.在哪个环节压缩?

producer端进行压缩

​ producer可以选择使用compression.type设置来压缩消息(参数枚举:none、gzip、lz4、snappy、zstd 等压缩算法) (注意: zstd 压缩是在Kafka 2.1之后引入的),考虑测试 snappy 或 lz4 以获得最佳速度/压缩比。

​ 为了进一步提高性能,可以搭配“批量发送”操作使用,压缩一批数据,达到更好的压缩效果

image-20240823215336521

broker端进行压缩

​ broker也可以进行压缩,即在发送端不进行压缩(则无法享受发送环节的性能增长),但还是可以享受更高磁盘利用率。Broker压缩是主题级的,也就是说不同主题可以有不同设计,包括用不同的压缩算法。

​ 默认情况下,broker是不开启压缩的,体现在配置上,就是主题压缩定义为compression.type=producer,即直接继承 producer 端所发来消息的压缩方式,即无论是否压缩,无论采用哪种压缩算法,broker 都原样存储消息

Broker端的压缩有规则限制:

  • 如果Broker开启了压缩,而Producer未开启压缩,那么没有歧义,就在Broker执行压缩即可
  • 如果Broker和Producer端同时开启了压缩配置,则遵循如下规则:
    • 如果两者压缩设置相同(例如lz4),则Broker不会进行重复压缩,消息批次将按原样写入日志文件
    • 如果两者压缩设置不同,Broker则解压消息并重新按配置压缩(Broker将解压缩消息并将其重新压缩为其配置的格式)

3.压缩算法对比

​ 目前 Kafka 共支持四种主要的压缩类型:GzipSnappyLz4Zstd

  • Gzip可能是平常工作生活中打交道是最多的,它的缺点在于CPU高、速度又不是很快

  • Snappy是Google的作品,性能非常棒,也没有什么明显的缺点,各方面都还可以

  • Lz4特点在于速度非常快,但是缺点是压缩比率很低,也就是快是快,但是压缩不够到位。Zstd是 Facebook开源的压缩算法,压缩率和压缩速度都还可以,和Snappy一样比较能打,直到 Kafka 的 2.1.0 版本才引入支持

  • zstd其Githubopen in new window也公布了他们的压测对比数据,可以看到Zstd的压缩速度是命令前茅的,同时还可以通过--fast参数控制压缩比,压缩比稍低的时候压缩速度也就更快一些

评论
  • 按正序
  • 按倒序
  • 按热度
Powered by Waline v3.1.3