消息队列高手课
李玥
京东零售技术架构部资深架构师
立即订阅
8426 人已学习
课程目录
已完结 41 讲
0/4登录后,你可以任选4讲全文学习。
课前必读 (2讲)
开篇词 | 优秀的程序员,你的技术栈中不能只有“增删改查”
免费
预习 | 怎样更好地学习这门课?
基础篇 (8讲)
01 | 为什么需要消息队列?
02 | 该如何选择消息队列?
03 | 消息模型:主题和队列有什么区别?
04 | 如何利用事务消息实现分布式事务?
05 | 如何确保消息不会丢失?
06 | 如何处理消费过程中的重复消息?
07 | 消息积压了该如何处理?
08 | 答疑解惑(一) : 网关如何接收服务端的秒杀结果?
进阶篇 (21讲)
09 | 学习开源代码该如何入手?
10 | 如何使用异步设计提升系统性能?
11 | 如何实现高性能的异步网络传输?
12 | 序列化与反序列化:如何通过网络传输结构化的数据?
13 | 传输协议:应用程序之间对话的语言
14 | 内存管理:如何避免内存溢出和频繁的垃圾回收?
加餐 | JMQ的Broker是如何异步处理消息的?
15 | Kafka如何实现高性能IO?
16 | 缓存策略:如何使用缓存来减少磁盘IO?
17 | 如何正确使用锁保护共享数据,协调异步线程?
18 | 如何用硬件同步原语(CAS)替代锁?
19 | 数据压缩:时间换空间的游戏
20 | RocketMQ Producer源码分析:消息生产的实现过程
21 | Kafka Consumer源码分析:消息消费的实现过程
22 | Kafka和RocketMQ的消息复制实现的差异点在哪?
23 | RocketMQ客户端如何在集群中找到正确的节点?
24 | Kafka的协调服务ZooKeeper:实现分布式系统的“瑞士军刀”
25 | RocketMQ与Kafka中如何实现事务?
26 | MQTT协议:如何支持海量的在线IoT设备?
27 | Pulsar的存储计算分离设计:全新的消息队列设计思路
28 | 答疑解惑(二):我的100元哪儿去了?
案例篇 (7讲)
29 | 流计算与消息(一):通过Flink理解流计算的原理
30 | 流计算与消息(二):在流计算中使用Kafka链接计算任务
31 | 动手实现一个简单的RPC框架(一):原理和程序的结构
32 | 动手实现一个简单的RPC框架(二):通信与序列化
33 | 动手实现一个简单的RPC框架(三):客户端
34 | 动手实现一个简单的RPC框架(四):服务端
35 | 答疑解惑(三):主流消息队列都是如何存储消息的?
测试篇 (2讲)
期中测试丨10个消息队列热点问题自测
免费
期末测试 | 消息队列100分试卷等你来挑战!
结束语 (1讲)
结束语 | 程序员如何构建知识体系?
消息队列高手课
登录|注册

19 | 数据压缩:时间换空间的游戏

李玥 2019-09-05
你好,我是李玥。
这节课我们一起来聊一聊数据压缩。我在前面文章中提到过,我曾经在一台配置比较高的服务器上,对 Kafka 做过一个极限的性能压测,想验证一下 Kafka 到底有多快。我使用的种子消息大小为 1KB,只要是并发数量足够多,不开启压缩时,可以打满万兆网卡的全部带宽,TPS 接近 100 万。开启压缩时,TPS 可以达到 2000 万左右,吞吐量提升了大约 20 倍!
算术好的同学可能会立刻反驳我说,2000 万 TPS 乘以 1KB 的消息大小,再把字节 Byte 转换成比特 bit,换算成网络传输的带宽是 200Gb/s,服务器网卡根本达不到这么大的传输带宽!
我们的测试服务器的网卡就是普通的万兆网卡,极限带宽也就是 10Gb/s,压测时候的实际网络流量大概在 7Gb/s 左右。这里面,最重要的原因就是,我在测试的时候开启了 Kafka 的压缩功能。可以看到,对于 Kafka 来说,使用数据压缩,提升了大概几十倍的吞吐量。当然,在实际生产时,不太可能达到这么高的压缩率,但是合理地使用数据压缩,仍然可以做到提升数倍的吞吐量。
所以,数据压缩不仅能节省存储空间,还可以用于提升网络传输性能。这种使用压缩来提升系统性能的方法,不仅限于在消息队列中使用,我们日常开发的应用程序也可以使用。比如,我们的程序要传输大量的数据,或者要在磁盘、数据库中存储比较大的数据,这些情况下,都可以考虑使用数据压缩来提升性能,还能节省网络带宽和存储空间。
取消
完成
0/1000字
划线
笔记
复制
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
该试读文章来自付费专栏《消息队列高手课》,如需阅读全部文章,
请订阅文章所属专栏。
立即订阅
登录 后留言

精选留言(12)

  • 姜戈
    RocketMq(rockmq-all 4.4.1-SNAPSHOT): 默认压缩大于4K的消息(可配置),压缩算法是zip,默认级别5(可配置),同样也是客户端做解压缩工作,服务端只存储;对于批量消息的压缩,目前并不支持。
    摘取DefaultMQProducerImpl.java 部分源码:
    private boolean tryToCompressMessage(final Message msg) {
            if (msg instanceof MessageBatch) {
                //batch dose not support compressing right now
                return false;
            }
            byte[] body = msg.getBody();
            if (body != null) {
                if (body.length >= this.defaultMQProducer.getCompressMsgBodyOverHowmuch()) {
                    try {
                        byte[] data = UtilAll.compress(body, zipCompressLevel);
                        if (data != null) {
                            msg.setBody(data);
                            return true;
                        }
                    } catch (IOException e) {
                        log.error("tryToCompressMessage exception", e);
                        log.warn(msg.toString());
                    }
                }
            }

            return false;
        }

    作者回复: 👍👍👍

    2019-09-05
    12
  • leslie
    老师提到了压缩:适当扩展一下,这个东西早期数据库备份其实经常会要去使用;个人的感受不是耗资源-是极度耗费资源,压缩比越大CPU越大,服务器做数据库备份压缩时基本上什么事情都做不了,尤其像oracle、sybase这种;sybase的备份策略更人性但是代价的权衡其实当时就、、、、、、
         大多数情况下其实我们在做这种事情时不太可能单独什么事情都不做:可能生产环境还是会去选择Rockmq吧,毕竟中间件不像数据库-单独的服务器,cpu的资源使用上相对宽裕,尤其是对于中小型企业,硬件资源没有那么宽裕,Rockmq是个不错的选择,计算机组成原理的课程还是对于数据备份做了一些比较好的讲解,胡老师的课对kafka的压缩机制有讲解;综合下来我应当会选择Rockmq。
         几门课程同时在跟-确实发现时间上蛮吃力,为了学习天天的业余生活活在闹钟之中:可能很多东西只能等完课了再进一步梳理;只能用刘超老师的学习法-第一遍先粗学了,第一遍还是希望明白是什么回事,什么场景怎么用;老师的消息队列课程与计算机组成原理、操作系统的关系更大些,同时跟这三门就已经挤压不出时间到kafka上了,完课的时候明白选什么,为什么选算是基本达到学习这门功课的基本目标吧,学习过程中为了明白原来而交叉去学习其它两门课所付出的时间代价其实远超与预期。
         感谢老师的分享:期待老师下节课的分享。
    2019-09-05
    12
  • z.l
    Kafka每个压缩过的消息集合在 Broker 端写入时都要发生解压缩操作,目的是为了对消息执行各种验证。
    好像是这样吧?

    作者回复: 只会解压header,消息体不会解压。

    2019-09-17
    1
  • 路途
    kafka压缩后它的offset如何计算,假如刚好要回溯的数据就在压缩包中offset如何计算

    作者回复: 正常情况下,客户端每次拉消息都是整批拉取,不会出现你说的情况。如果是指定消费位置来消费,客户端在拉取整批消息之后,再计算一下批内的偏移量,把正确的消息返回给用户代码。

    2019-09-05
    2
    1
  • DFighting
    一直学习算法都是空间换时间,但是在消息中间件和一些IO密集型的应用中还会有CPU计算资源换网络带宽/磁盘IO,刚刚看了下RocketMQ源码,在DefaultMQPullConsumerlmpl.pullSyncImpl中会调用PullAPIWrapper.processPullResult,在这里会为压缩的消息进行解压缩。Producer端没找到压缩的源码,只是在checkMessage中会对消息体的长度进行限制,超过4K(网上查的)会抛出来MQClientException,猜测应该也是会压缩。也就是RocketMQ的压缩机制也是Producer压缩,Broker传输,Consumer解压缩,不同的是kaffka的压缩是基于一批一批消息的,对于CPU空闲较多的场景下会有更大的吞吐提升。

    作者回复: 👍👍👍

    2019-09-05
    1
  • 一步
    现在系统使用的是rabbitmq,在发送数据时候使用的是protobuffer进行序列化,这时候还有必要开启压缩吗?如果开启了压缩会不会效果更好的?

    作者回复: 这个不能一概而论啊,你需要根据我这节课的讲的那些原则自己衡量一下。一般来说,如果消息体比较大,客户端的CPU不是很忙,开启压缩后都会有一定的性能提升。

    2019-09-05
    1
  • 业余草
    Kafka设计的很精妙,但是使用的场景局限性也很大。压缩是现代网络通信中必不可少的一环,也有不少专栏都写过了。
    2019-09-05
    1
  • godtrue
    压缩——以CPU计算资源换空间,以期减少网络带宽或磁盘存储空间,提高传输速率。老师,讲的20个0的例子很形象,如果夸张点2000个0就更能体会压缩的效果啦😄
    2019-09-24
  • 王莹
    RockerMQ生产者压缩:
    压缩逻辑控制
      DefaultMQProducerImpl#tryToCompressMessage
        批消息,暂不支持
        Message的body byte[] 超过 4K,开启压缩
        压缩level默认5,启动参数-Drocketmq.message.compressLevel可以配置
    压缩数据处理
      UtilAll#compress(final byte[] src, final int level)
        使用JDK的
          java.io.ByteArrayOutputStream
          java.util.zip.Deflater
          java.util.zip.DeflaterOutputStream
    2019-09-09
  • 北冥Master
    如果是批消息,服务端不解压,直接返回给消费者端解压---如果批消息很大,一个批次几百上千呢?也是一次性返回给消费者端吗?这样岂不是影响并发消费,从而影响消费速度?

    作者回复: 在发送端,批的大小是有参数控制的,不会过大。

    2019-09-08
  • 张三
    确实想到了霍夫曼编码,还有位图。
    2019-09-06
  • 青舟
    RocketMQ 在DefaultMQProducerImpl.tryToCompressMessage中判断消息长度大于4Kb就进行压缩,压缩算法是zip(java.util.zip.Deflater)

    我注意到在发送时,会判断如果消息是一个批量消息(MessageBatch),就不开启压缩。这是为什么呢?

    作者回复: 因为批消息还不支持压缩

    2019-09-05
    2
收起评论
12
返回
顶部