消息队列面试解析系列(七)- 数据压缩(下)

简介: 消息队列面试解析系列(七)- 数据压缩

4 压缩分段选型



大部分压缩算法区别主要是,对数据进行编码的算法,压缩的流程和压缩包的结构大致一样。

而在压缩过程中,你最需要了解的就是如何选择合适的压缩分段。


压缩时,给定的被压缩数据它必须有确定长度,或是有头有尾的,不能是个无限数据流,若要对流数据压缩,必须把流数据划分成多帧,一帧帧分段压缩。


主要因为压缩算法在压缩前,一般都需对被压缩数据从头到尾扫描:确定如何对数据划分和编码。


  • 一般原则:
    重复次数多、占用空间大的内容,使用尽量短的编码,这样压缩率会更高。


被压缩数据长度越大,重码率更高,压缩比也越高。

比如这篇文章,可能出现几十次“压缩”,将整篇文章压缩,这词重复率几十次,但按照每个自然段来压缩,每段中这词重复率只有二三次。显然全文压缩压缩率高于分段压缩。


分段并非越大越好,超过一定长度后,再增加长度对压缩率贡献不大了。

过大的分段长度在解压时,还有更多解压浪费。

比如,一个1MB大小的压缩文件,即使你只是需要读其中很短的几个字节,也不得不把整个文件全部解压缩,造成很大的解压浪费。


所以要根据业务,选择合适压缩分段,在压缩率、压缩速度、解压浪费间找到平衡点。


确定数据划分和压缩算法后,就可压缩了,压缩过程就是用编码替换原始数据。

压缩后的压缩包是由这编码字典和用编码替换后的数据组成。


这就是数据压缩过程。解压时,先读取编码字典,然后按字典把压缩编码还原成原始数据即可。


5 Kafka 消息压缩流程


首先可以配置Kafka是否开启压缩,支持配置使用哪种压缩算法。

因为不同场景是否需要开启压缩,选择哪种压缩算法都不能一概而论。

所以Kafka将选择权交给使用者。


在开启压缩时,Kafka选择一批消息一起压缩,每一个批消息就是一个压缩分段。使用者也可以通过参数来控制每批消息的大小。


在Kafka中,生产者生成一个批消息发给服务端,在服务端中是不会拆分批消息的。那按批压缩,意味在服务端也不用对这批消息进行解压,可整批直接存储,然后整批发给消费者。最后,批消息由消费者解压。

在服务端不用解压,就不会耗费服务端CPU,同时还能获得压缩后,占用传输带宽小,占用存储空间小。

使用Kafka时,如果生产者和消费者的CPU不是特别吃紧,开启压缩后,可节省网络带宽和服务端的存储空间,提升总体的吞吐量,一般都是个不错的选择。


Kafka在生产者上,对每批消息进行压缩,批消息在服务端不解压,消费者在收到消息之后再进行解压。Kafka的压缩和解压都是在客户端完成的。



6 RocketMQ 消息压缩源码


默认压缩大于4K的消息(可配置)

image.png


压缩算法是zip,默认级别5(可配置)


image.png


也是客户端做解压缩工作,服务端只存储。


    private boolean tryToCompressMessage(final Message msg) {
        if (msg instanceof MessageBatch) {
            // 当前不支持批量消息的压缩
            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;
    }


DefaultLitePullConsumerImpl#pullSyncImpl会调用PullAPIWrapper#processPullResult,会为压缩消息进行解压缩。

RocketMQ的压缩机制也是Producer压缩,Broker传输,Consumer解压缩,

不同的是kaffka的压缩是基于一批批消息,对于CPU空闲较多的场景下会有更大的吞吐提


7 总结

一直以来,常见算法都是空间换时间,但在MQ和一些IO密集型应用中还有CPU计资源换网络带宽/磁盘IO。

数据压缩本质是CPU资源换存储资源,或用压缩解压的时间换取存储的空间。


在选择压缩算法的时候,需综合考虑压缩时间和压缩率两个因素,被压缩数据的内容也是影响压缩时间和压缩率的重要因素。

必要时可先用业务数据做一个压缩测试,这样有助于选择最合适的压缩算法。


另外影响压缩率的重要因素是压缩分段,需根据业务情况选择一个合适分段,在保证压缩率前提下,尽量减少解压浪费。


image.pngimage.png

image.png

目录
相关文章
|
6天前
|
监控 Java 应用服务中间件
高级java面试---spring.factories文件的解析源码API机制
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置、起步依赖和内嵌服务器等特性,极大地简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是spring.factories文件的解析源码API机制。
20 2
|
6天前
|
存储 网络协议 安全
30 道初级网络工程师面试题,涵盖 OSI 模型、TCP/IP 协议栈、IP 地址、子网掩码、VLAN、STP、DHCP、DNS、防火墙、NAT、VPN 等基础知识和技术,帮助小白们充分准备面试,顺利踏入职场
本文精选了 30 道初级网络工程师面试题,涵盖 OSI 模型、TCP/IP 协议栈、IP 地址、子网掩码、VLAN、STP、DHCP、DNS、防火墙、NAT、VPN 等基础知识和技术,帮助小白们充分准备面试,顺利踏入职场。
19 2
|
26天前
|
存储 缓存 关系型数据库
滴滴面试:单表可以存200亿数据吗?单表真的只能存2000W,为什么?
40岁老架构师尼恩在其读者交流群中分享了一系列关于InnoDB B+树索引的面试题及解答。这些问题包括B+树的高度、存储容量、千万级大表的优化、单表数据量限制等。尼恩详细解释了InnoDB的存储结构、B+树的磁盘文件格式、索引数据结构、磁盘I/O次数和耗时,以及Buffer Pool缓存机制对性能的影响。他还提供了实际操作步骤,帮助读者通过元数据找到B+树的高度。尼恩强调,通过系统化的学习和准备,可以大幅提升面试表现,实现“offer直提”。相关资料和PDF可在其公众号【技术自由圈】获取。
|
17天前
|
存储 NoSQL MongoDB
MongoDB面试专题33道解析
大家好,我是 V 哥。今天为大家整理了 MongoDB 面试题,涵盖 NoSQL 数据库基础、MongoDB 的核心概念、集群与分片、备份恢复、性能优化等内容。这些题目和解答不仅适合面试准备,也是日常工作中深入理解 MongoDB 的宝贵资料。希望对大家有所帮助!
|
22天前
|
缓存 前端开发 JavaScript
"面试通关秘籍:深度解析浏览器面试必考问题,从重绘回流到事件委托,让你一举拿下前端 Offer!"
【10月更文挑战第23天】在前端开发面试中,浏览器相关知识是必考内容。本文总结了四个常见问题:浏览器渲染机制、重绘与回流、性能优化及事件委托。通过具体示例和对比分析,帮助求职者更好地理解和准备面试。掌握这些知识点,有助于提升面试表现和实际工作能力。
58 1
|
1月前
|
监控 Java easyexcel
面试官:POI大量数据读取内存溢出?如何解决?
【10月更文挑战第14天】 在处理大量数据时,使用Apache POI库读取Excel文件可能会导致内存溢出的问题。这是因为POI在读取Excel文件时,会将整个文档加载到内存中,如果文件过大,就会消耗大量内存。以下是一些解决这一问题的策略:
73 1
|
21天前
|
存储 NoSQL Redis
Redis常见面试题:ZSet底层数据结构,SDS、压缩列表ZipList、跳表SkipList
String类型底层数据结构,List类型全面解析,ZSet底层数据结构;简单动态字符串SDS、压缩列表ZipList、哈希表、跳表SkipList、整数数组IntSet
|
1月前
|
存储 关系型数据库 MySQL
面试官:MySQL一次到底插入多少条数据合适啊?
本文探讨了数据库插入操作的基础知识、批量插入的优势与挑战,以及如何确定合适的插入数据量。通过面试对话的形式,详细解析了单条插入与批量插入的区别,磁盘I/O、内存使用、事务大小和锁策略等关键因素。最后,结合MyBatis框架,提供了实际应用中的批量插入策略和优化建议。希望读者不仅能掌握技术细节,还能理解背后的原理,从而更好地优化数据库性能。
|
1月前
|
存储 大数据 数据库
Android经典面试题之Intent传递数据大小为什么限制是1M?
在 Android 中,使用 Intent 传递数据时存在约 1MB 的大小限制,这是由于 Binder 机制的事务缓冲区限制、Intent 的设计初衷以及内存消耗和性能问题所致。推荐使用文件存储、SharedPreferences、数据库存储或 ContentProvider 等方式传递大数据。
62 0
|
1月前
|
缓存 Java 程序员
Map - LinkedHashSet&Map源码解析
Map - LinkedHashSet&Map源码解析
67 0

推荐镜像

更多