存储压缩
背景
数据压缩存在于各种场景,视频传输(VR),视频压缩编码–>VR 球形数据的压缩,模型压缩(剪枝) 还存在于各种中间件中,
数据量增加,解决方式通过扩容,或者通过压缩数据,扩容的成本高于压缩,
huffman
高频的字母使用短的信号来编码
信息熵
行式存储和列式存储
行式存储 把原来行的样子原封不动地存储到磁盘上 列式存储 把一列数据挨着放到一起存储,称之为列式存储 空间局部性
列式存储相对于行式存储需要多做的是行转列和列转行
列式存储:(1)相同类型数据在一起,能产生更高的压缩率(2)对列值过滤操作简单,组合不同列结果集更容易(3)在列上做预计算更方便max/min
无损压缩和有损压缩
数据压缩
LZ4 通用二进制压缩
BLOCK数据块–>一层压缩(timestamp,int float,bool等专有压缩)–>二层压缩(通用二进制压缩LZ4)–>存储 timestamp时间列压缩delta-of-delta int类型压缩 zig-zag + simple8b 小整数上效果较好 bool类型列压缩: 1/0二值,bit pack 1bit 浮点类型列压缩: 无损压缩(Google Gorilla)有损压缩 SZ
LZF(redis)
snappy(redis)
ZStd
apache
redis压缩列表
hash-max-ziplist-entries: 使用压缩列表保存时哈希集合中的最大元素个数 hash-max-ziplist-value: 使用压缩列表保存时hash集合中单个元素的最大长度 hash对象保存的键值对数量小于512个,所有的键值对的键和值字符串长度都小于等于64byte时,使用ziplist,否则使用hashtable 一旦从压缩列表转为哈希表,hash类型就会一直用哈希表进行保存而不会再转回压缩列表,在节省内存空间方面哈希表没有压缩列表高效了 压缩列表内存利用率高原因在于连续内存,当一个hash对象只包含少量键值对,并且每个键值对的键和值为小整数或短字符串时,使用压缩列表实现 ziplist是一个经过特殊编码的双向链表,不存储指向前一个链表节点prev和指向下一个链表节点的指针next,而是存储上一个节点长度和当前节点的长度
hive中的数据压缩
ES中的数据压缩
mysql升级同步的数据压缩
MyISAM/InnoDB 都提供compressed data mysql支持压缩的几种方式:
- 传输压缩 客户端和服务器端之间的数据传输,方式:客户端连接服务时加的–compress选项即可(军),要求cpu性能,网络带宽足够,没必要开启压缩
- 单表压缩 在创建表的时候指定表的存储为压缩方式 方式:create 或 alter表时指定ROW_FORMAT=COMPRESSED 同时可以指定压缩块的大小KEY_BLOCK_SIZE=(1 2 4 8 16)
- 单列压缩 调用MYSQL引擎提供的COMPRESS(列名)UNCOMPRESS(列名) 类似于函数 insert into t value(COMPRESS(c1)…) select UNCOMPRESS(c1) from t …
mysql典型的行式存储结构
InnoDB逻辑存储结构,多级存储结构
物理存储结构: 1、ibd 2、frm 3、日志文件组
时序数据库,TDengine 列式存储
总结
专用压缩-压缩侠(模板文件压缩)
存储解压缩
压缩打开对查询和写的性能影响比较大
参考:
apache commons-compress: https://github.com/apache/commons-compress?tab=readme-ov-file redis: ziplist/listpack : hive: