写在前面

节省空间

1、redis对于它所支持的五种数据类型,每种都提供了两种及以上的编码方式去存储(具体对应的编码方式可以百度)。因为基于内存的缘故,所以为了平衡时间与空间的使用效率在元素数量较多或较少时采用不同的策略,当然对于使用者这是透明的。

2、查看redis键值的内部编码方式

OBJECT ENCODING key

3、对于每一个键,都会有一个结构去存储它的数据类型,编码格式,数据地址等信息。

1 typedef structredisObject2 {3 unsigned type:4; //这种语法叫做位字段

4 unsigned notused:2;5 unsigned encoding:4;6 unsigned lru:22;7 intrefcount;8 void *ptr;9 }

4、对于字符串类型(示意结构如下),键值可以用一个64位整数表示时,就会使用数据指针表示数据内容(REDIS_ENCODING_INT编码方式),以节省空间;redis3.0引入了REDIS_ENCODING_EMBSTR编码方式,在键值长度小于39时,字符串本身就会跟在redisObject结构之后,减少申请释放内存次数;当对REDIS_ENCODING_EMBSTR编码方式的字符串做任何修改后,都会改为REDIS_ENCODING_RAW编码方式;redis启动后,会预先建立10000个从0~9999这些数字的redisObject结构,当我们set这些值时会直接引用向它们,并自增refcount这个引用,但如果在配置文件参数中设置了maxmemory参数,将不会预先存储这些共享对象。

1 struct shshdr //仅仅是示意结构

2 {3 intlen;4 int free;5 charbuf[];6 }

5、对于散列类型,当字段个数小于hash-max-ziplist-entries(配置文件参数,默认512)并且每个字段值长度小于hash-max-ziplist-value(配置文件参数,默认64)时,采用REDIS_ENCODING_ZIPLIST(示意结构如下)编码,否则采用REDIS_ENCODING_HT(真正的散列表);对于redis的键值对存储也是用散列表,但并不使用redisObject结构,所以数字键名不会比字符串名节省空间。

1 zlbytes //uint32 整个结构占用的空间

2 zltail //uint32 末尾元素偏移

3 zllen //unit16 元素数量 ————————————————————

4 元素1 ----------------------> | 前一个元素大小 |

5 元素2 | 当前元素的编码类型 |

6 元素3 | 当前元素大小 |

7 ...... | 当前元素内容 |

8 zlend //结尾标识,永远为255 ————————————————————

REDIS_ENCODING_ZIPLIST中的每个元素由四部分构成。

第一部分存储前一个元素大小,用于倒序查找,当前一个元素小于254字节时,第一部分占用一个字节,否则占用5个字节;

第二、三部分为元素编码类型和大小,当元素长度不大于63字节时,编码为ZIP_STR_06B(即0<<6),同时第三部分用6个二进制位记录长度,此时二、三部分占用一个字节;当元素长度大于63且小于16383字节时,二、三部分占用2字节,大于16383时占用5字节;

第四部分如果元素内容可以转为数字的话会用相应数字存储,并用二、三部分来表示元素数字的类型(int16_t,int32_t等)。

使用REDIS_ENCODING_ZIPLIST存储散列类型时,元素1存储字段1,元素2存储字段1值;插入,删除,查找(一跳一跳查找,跳过字段值)时都将移动后面的元素或遍历,因此上文的两个参数不能过大。

6、对于列表类型,有REDIS_ENCODING_LINKEDLIST 和REDIS_ENCODING_ZIPLIST两种编码,也有list-max-ziplist-entries和list-max-ziplist-value两个参数控制变换编码的时机;REDIS_ENCODING_LINKEDLIST即双向链表,优化方式与字符串类型的键值相同;较新版本的redis增加了REDIS_ENCODING_QUICKLIST编码方式,它将一个长列表分成若干个以链表形式组织的ziplist,在减少空间占用的同时,提示REDIS_ENCODING_ZIPLIST编码的性能。

7、对于集合类型,有REDIS_ENCODING_HT和REDIS_ENCODING_INTSET(结构如下),当元素都为整数且元素个数小于set-max-intset-entries(配置文件参数,默认512)时,采用REDIS_ENCODING_INTSET;intset默认的encoding是INTSET_ENC_INT16(即2字节),当无法满足时会升级为INTSET_ENC_INT32或INTSET_ENC_INT64,同时调整之前的元素;intset按序存储,采用二分查找,插入和删除效率较低;当初先非数字元素时,编码立刻变为REDIS_ENCODING_HT,此时即便将非数字元素删除,编码也不会回转。

1 typedef structintset2 {3 uint32_t encoding;4 uint32_t length;5 int8_t contents[];6 } intset;

8、对于有序集合类型,有REDIS_ENCODING_SKIPLIST和REDIS_ENCODING_ZIPLIST,同样有两个参数zset-max-ziplist-entries和zset-max-ziplist-value去控制何时变换编码为跳跃表REDIS_ENCODING_SKIPLIST;在这种编码方式下使用两种数据结构来存储有序集合类型键值,散列表用来存储元素值与元素分数的映射关系以实现O(1)时间复杂度的命令,跳跃表存储元素分数及到元素的映射用以实现排序功能;这里的跳跃表允许分数相同的元素存在,并且增加了指向前一个元素的指针以实现倒序查找;此时元素值是用redisObject结构存储的,与字符串类型键值优化方式相同,分数按照double存储;采用REDIS_ENCODING_ZIPLIST时,按照“元素1的值,元素1的分数”的顺序排列,并且分数是有序的。

php redis入门指南,redis入门指南(四)—— redis如何节省空间相关推荐

  1. Redis入门指南 第1章 简介 Redis的几项特性

    Redis入门指南 第1章 简介 Redis的几项特性 之前在做爬虫相关的demo时接触到了Redis,它基于键值对的存储系统吸引了我.它的操作十分方便,而且性能也高.趁着假期,系统地自学一下Redi ...

  2. Redis指南——03入门(上)

    第3章 入门 学会了如何安装和运行Redis,并了解了Redis的基础知识后,本章将详细介绍Redis的五种数据类型及相应的命令,真正进入Redis的世界.在学习的时候,手边打开一个redis-cli ...

  3. 【Redis集群专题】「集群技术三部曲」介绍一下常用的Redis集群机制方案的原理和指南(入门篇)

    集群化的方案 Redis的Sentinel解决了主从复制故障不能自动迁移的问题,但是主节点的写性能和存储能力依然是受到了Redis单机容量有限的限制,所以使用Redis集群去解决这个问题,将Redis ...

  4. Redis指南——03入门(下)

    3.4 列表类型 场景: 正当小白踌躇满志地写着文章列表页的代码时,一个很重要的问题阻碍了他的开发. 原来小白是使用如下流程获得文章列表的: (1)读取posts:count键获得博客中最大的文章ID ...

  5. 大数据学习指南从入门到精通

    目录 大数据学习指南从入门到精通 前言 一.大数据基础 二.大数据必学Java基础 三.ZooKeeper 四.大数据环境搭建 五.Hadoop 六.Hive 七.HBase 八.Kafka 九.Sc ...

  6. Java学习指南从入门到入土

    Java学习指南从入门到入土 本身其实只是刚刚入门,只是经历了两年时间的风吹雨打,经历了各种bug的折磨和学习各种框架的辛酸,才有得现有的 刚刚入门.有句老话说的好叫做 从入门到放弃,人生不易要及时放 ...

  7. VR 终极选购指南:入门、进阶与高端

    若你重回上世纪 90 年代读读 VR,你会发现这个词意涵颇广:从电影<天才割草人>的虚拟空间刺激系统,到电脑屏幕上的3D模型,什么都有.然而发展到今天,VR 简单明了:除某些特定情况,它等 ...

  8. 【数据可视化从入门到精通】指南-发展史-数据可视化应用场景-发展前景-技术选型①

    实战「外卖实战」数据大屏 基于 Vue 3.0 + EChart 4.0 开发 前置学习 具备javascript.html.css的基础 具备Vue的使用基础 了解npm和webpack的基本概念 ...

  9. Redis一篇从入门到实战

    Redis 入门 1.NoSQL概述 什么是NoSQL,NoSQL = Not Only SQL(不仅仅是 SQL)泛指非关系型的数据库 NoSQL 的特点: 方便扩展(数据之间没有关系,很好扩展) ...

  10. 蓝牙BLE(BlueTooth BLE)入门及爬坑指南

    前言 最近比较忙,两三周没有更新简书了,公司正好在做蓝牙BLE的项目,本来觉得挺简单的东西从网上找了个框架,就咔咔地开始搞,搞完以后才发现里面还有不少坑呢,故而写一篇蓝牙BLE入门及爬坑指南,旨在帮助 ...

最新文章

  1. CTFshow php特性 web108
  2. 机器学习:论相关(二)
  3. JAVA模拟某信网登录信息采集
  4. PID控制方法及C语言其实现
  5. 微信支付 - 支付中心回调通知
  6. mysql 导出表数据到另一张表_yz-Mysql数据库中一个表中的数据导出来到另外一个数据库的表格...
  7. silverlight 学习笔记 (五): MVVM Light Toolkits 之 RealCommand
  8. stat函数_使用Python的stat函数有效地获得所有者,组和其他权限
  9. Spark Streaming保存到HDFS目录中案例
  10. 155.PHP中“==”运算符的安全问题
  11. Android app 开发环境搭建
  12. 如何用MATLAB编写FIR维纳滤波器,Fir维纳滤波器的Matlab仿真
  13. matlab矩阵的白化,白化原理及Matlab实现
  14. [喷嚏]区块链已落地30个场景 商用时代正在加速来临
  15. NPOI编辑WORD文档
  16. 社交电商海外崛起:小程序助力打造超级App
  17. Nginx的http_access_module模块
  18. Java:Java和C有什么区别?
  19. 黑苹果重置NVRAM方法,无法进入系统,丢失引导
  20. 当int类型超出了[-2147483648,2147483647]会发生什么?

热门文章

  1. MATLAB中常用的基本数学函数和三角函数
  2. 分析 AlphaGo 算法原理的本质
  3. winhttp API 获取服务器文件大小(更新时间)等
  4. PHP8.0环境详细安装教程
  5. 一键清理系统垃圾文件.BAT
  6. Java视频教程免费分享
  7. 兆骑科创创新创业赛事活动承办,科创企业,企业孵化器
  8. python生成3d人体模型_无限想象空间,用Python就能玩的3D人体姿态估计
  9. VMware安装CentOs7并配置静态IP地址
  10. ppap文件过程流程图制作_PPAP提交范本---过程流程图