文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

数据库压缩到底怎么做?

2024-12-02 19:56

关注

redis

redis的压缩是针对key的压缩

只针对string和list的value

所有的压缩最终都会调用lzf_compress/lzf_decompress

需要配置文件配置rdb_compression rdb压缩才会生效

lzf压缩限制长度要大于20,即使是aaaaaaaaaaaaaaaaaaaa也压不了,大于20才能压。原因没有深究

rdb内部的压缩

rdb解析每条数据,都有标识字段,压缩的record自然是单独的类型

  1. ssize_t rdbSaveLzfStringObject(rio *rdb, unsigned char *s, size_t len) { 
  2. ... 
  3.     comprlen = lzf_compress(s, len, out, outlen); 
  4.     if (comprlen == 0) { 
  5.         zfree(out); 
  6.         return 0
  7.     } 
  8.     ssize_t nwritten = rdbSaveLzfBlob(rdb, out, comprlen, len); 
  9. ... 
  10.  
  11. ssize_t rdbSaveLzfBlob(rio *rdb, void *data, size_t compress_len, 
  12.                        size_t original_len) { 
  13. ... 
  14.      
  15.     byte = (RDB_ENCVAL<<6)|RDB_ENC_LZF; 
  16.     if ((n = rdbWriteRaw(rdb,&byte,1)) == -1goto writeerr; 
  17.     nwritten += n; 
  18. ... 

解压缩

  1. void *rdbGenericLoadStringObject(rio *rdb, int flags, size_t *lenptr) { 
  2. ... 
  3.     if (isencoded) { 
  4.         switch(len) { 
  5.         case RDB_ENC_INT8: 
  6.         case RDB_ENC_INT16: 
  7.         case RDB_ENC_INT32: 
  8.             return rdbLoadIntegerObject(rdb,len,flags,lenptr); 
  9.         case RDB_ENC_LZF: 
  10.             return rdbLoadLzfStringObject(rdb,flags,lenptr); 
  11.         default
  12.             rdbReportCorruptRDB("Unknown RDB string encoding type %llu",len); 
  13.             return NULL; 
  14.         } 
  15.     } 
  16.  ... 
  17.   
  18.  void *rdbLoadLzfStringObject(rio *rdb, int flags, size_t *lenptr) { 
  19. ... 
  20.  
  21.      
  22.     if (rioRead(rdb,c,clen) == 0goto err; 
  23.     if (lzf_decompress(c,clen,val,len) != len) { 
  24.         rdbReportCorruptRDB("Invalid LZF compressed string"); 
  25. ... 

接口简单容易定位

所有的类型string/hash具体到底层,都是string,就会走这个压缩的过程rdbSaveRawString,内部来调用rdbSaveLzfStringObject

  1. ssize_t rdbSaveObject(rio *rdb, robj *o, robj *key, int dbid) { 
  2.     ssize_t n = 0, nwritten = 0
  3.  
  4.     if (o->type == OBJ_STRING) { 
  5.          
  6.         if ((n = rdbSaveStringObject(rdb,o)) == -1return -1
  7.         nwritten += n; 
  8.     } else if (o->type == OBJ_LIST) { 
  9.  
  10.                 if (quicklistNodeIsCompressed(node)) { 
  11.                     void *data; 
  12.                     size_t compress_len = quicklistGetLzf(node, &data); 
  13.                     if ((n = rdbSaveLzfBlob(rdb,data,compress_len,node->sz)) == -1return -1
  14.                     nwritten += n; 
  15.                 } else { 
  16.                     if ((n = rdbSaveRawString(rdb,node->zl,node->sz)) == -1return -1
  17.                     nwritten += n; 
  18.                 } 
  19.                 node = node->next; 
  20.             } 
  21.         } else { 
  22.             serverPanic("Unknown list encoding"); 
  23.         } 
  24. 。。。 

quicklist的压缩

链表压缩可以选择深度,quicklist是redis list的底层数据结构

什么时候做压缩?

  1.  
  2. REDIS_STATIC void __quicklistInsertNode(quicklist *quicklist, 
  3.                                         quicklistNode *old_node, 
  4.                                         quicklistNode *new_node, int after) { 
  5.     if (after) { 
  6.         new_node->prev = old_node; 
  7.         if (old_node) { 
  8.             new_node->next = old_node->next; 
  9.             if (old_node->next) 
  10.                 old_node->next->prev = new_node; 
  11.             old_node->next = new_node; 
  12.         } 
  13.         if (quicklist->tail == old_node) 
  14.             quicklist->tail = new_node; 
  15.     } else { 
  16.         new_node->next = old_node; 
  17.         if (old_node) { 
  18.             new_node->prev = old_node->prev; 
  19.             if (old_node->prev) 
  20.                 old_node->prev->next = new_node; 
  21.             old_node->prev = new_node; 
  22.         } 
  23.         if (quicklist->head == old_node) 
  24.             quicklist->head = new_node; 
  25.     } 
  26.      
  27.     if (quicklist->len == 0) { 
  28.         quicklist->head = quicklist->tail = new_node; 
  29.     } 
  30.  
  31.      
  32.     quicklist->len++; 
  33.  
  34.     if (old_node) 
  35.         quicklistCompress(quicklist, old_node); 

也就是说,头尾不会压缩,其他的节点会压缩,在修改的时候同事把旧的节点给压缩了

这里有个问题,这里的节点压缩了,rdb存储的时候还要特别处理一下,判定已经压缩过,走rdbSaveLzfBlob

需要有个record头来记录一个compression的标记

rocksdb

类似redis,还是很好找的,UncompressData/CompressData

针对sst的压缩

调用关系

UncompressBlockContentsForCompressionType -> UncompressData

WriteBlock/BGWorkCompression -> CompressAndVerifyBlock -> CompressBlock -> CompressData

block本身有信息标记是否是压缩

写入的时候才压缩

blobdb

CompressBlobIfNeeded -> CompressData

GetCompressedSlice -> CompressData

总结

 

来源:王很水的博客内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯