redis入门指南(四)—— redis如何节省空间
写在前面
学习《redis入门指南》笔记,结合实践,只记录重要,明确,属于新知的相关内容。
节省空间
1、redis对于它所支持的五种数据类型,每种都提供了两种及以上的编码方式去存储(具体对应的编码方式可以百度)。因为基于内存的缘故,所以为了平衡时间与空间的使用效率在元素数量较多或较少时采用不同的策略,当然对于使用者这是透明的。
2、查看redis键值的内部编码方式
OBJECT ENCODING key
3、对于每一个键,都会有一个结构提存储它的数据类型,编码格式,数据地址等信息。
typedef struct redisObject
{
unsigned type:; // 这种语法叫做位字段
unsigned notused:;
unsigned encoding:;
unsigned lru:;
int refcount;
void *ptr;
}
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参数,将不会预先存储这些共享对象。
struct shshdr // 仅仅是示意结构
{
int len;
int free;
char buf[];
}
5、对于散列类型,当字段个数小于hash-max-ziplist-entries(配置文件参数,默认512)并且每个字段值长度小于hash-max-ziplist-value(配置文件参数,默认64)时,采用REDIS_ENCODING_ZIPLIST(示意结构如下)编码,否则采用REDIS_ENCODING_HT(真正的散列表);对于redis的键值对存储也是用散列表,但并不使用redisObject结构,所以数字键名不会比字符串名节省空间。
zlbytes // uint32 整个结构占用的空间
zltail // uint32 末尾元素偏移
zllen // unit16 元素数量 ————————————————————
元素1 ----------------------> | 前一个元素大小 |
元素2 | 当前元素的编码类型 |
元素3 | 当前元素大小 |
...... | 当前元素内容 |
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,此时即便将非数字元素删除,编码也不会回转。
typedef struct intset
{
uint32_t encoding;
uint32_t length;
int8_t contents[];
} 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的分数”的顺序排列,并且分数是有序的。
redis入门指南(四)—— redis如何节省空间的更多相关文章
- redis入门指南-安装redis
纸上得来终觉浅 绝知此事要躬行 Redis官方不支持window.微软发布了可在redis的分支.不建议使用 但我确实用了. win7 redis2.8.4 php5.6 apache2.4 ht ...
- Redis入门指南之一(简介)
1. 简介 Redis是一个开源的.高性能的.基于键值对的缓存与存储系统,通过提供多种键值数据类型来适应不同的场景下的缓存与存储需求.同时Redis的诸多高级功能使其可以胜任消息队列.任务队列等不同的 ...
- redis入门指南(七)—— 安全、协议、管理工具及命令属性
写在前面 学习<redis入门指南>笔记,结合实践,只记录重要,明确,属于新知的相关内容. 安全 1.可以使用bind参数绑定一个地址,使redis只接受这个地址的连接. 2.使用requ ...
- Redis入门指南之三(入门)
本节主要介绍Redis的5种数据类型,同时使用Python API来操作Redis,其中python版本为3.5, redis版本为4.0.2. redis-py 的API的使用可以分类为: (1)连 ...
- Redis入门指南之二(安装及配置)
本节主要内容 1. 前言2. redis安装3. 启动和停止Redis 1. 前言 安装Redis需要知道自己需要哪个版本,有针对性的安装,比如如果需要redis GEO这个地理集合的特性,那么red ...
- redis入门指南(二)—— 数据操作相关命令
写在前面 以下绝大部分内容取材于<redis入门指南>,部分结合个人知识,实践后得出. 只记录重要,明确,属于新知的相关内容,杜绝冗余和重复. 字符串 1.字符串类型是redis中最常见的 ...
- redis入门指南(三)—— 事务、过期时间、SORT命令、消息通知与管道
写在前面 学习<redis入门指南>笔记,结合实践,只记录重要,明确,属于新知的相关内容. 事务 1.redis中的事务由一组命令的集合组成,要么都执行,要么都不执行,同时redis的事务 ...
- redis入门指南(五)—— 复制与哨兵
写在前面 学习<redis入门指南>笔记,结合实践,只记录重要,明确,属于新知的相关内容. 一.复制 1.在复制中,数据库分为两类,一类主数据库,一类从数据库,主库用来读写,从库用来读,主 ...
- redis入门指南(六)—— 集群
写在前面 学习<redis入门指南>笔记,结合实践,只记录重要,明确,属于新知的相关内容. 配置集群 1.配置集群,集群解决了单点故障以及单台机器内存上限的问题,使用集群时,只需要将配置文 ...
随机推荐
- TensorFlow从0到1之TensorFlow csv文件读取数据(14)
大多数人了解 Pandas 及其在处理大数据文件方面的实用性.TensorFlow 提供了读取这种文件的方法. 前面章节中,介绍了如何在 TensorFlow 中读取文件,本节将重点介绍如何从 CSV ...
- (七)ExtentReports测试报告的使用
原文链接:https://www.jianshu.com/p/4cd9e92d5edf 1.简介 ExtentReports用于生成测试报告,其不光漂亮而且使用简单,并可以定制相应的样式. 2.使用: ...
- java中Proxy类初探
在java中提供了一个动态代理类,这个类位于java.lang.reflect包中的Proxy类中.什么是动态代理类呢?就是可以在运行时创建一个实现了一组给定接口的新类.听上去有点高深的样子,其实是提 ...
- cb29a_c++_STL_算法_查找算法_(2)search_n
cb29a_c++_STL_算法_查找算法_(2)search_n//比如:连续查找连续的n个8search_n(b,e,c,v),迭代器b,begin(),e,end().连续的c个vpos=sea ...
- powershell代码混淆绕过
目前大多数攻击者已经将PowerShell 利用在了各种攻击场景中,如内网渗透,APT攻击甚至包括现在流行的勒索软件中.powershell的功能强大且调用方式十分灵活,灵活使用powershell可 ...
- 31_栈的分类.swf
栈的分类: 栈可以分为静态栈和动态栈 静态栈:要删除先删除4才能删除3,以数组为数据结构 动态栈:以链表作为数据结构,在实际中使用动态栈比较多
- matlab批量处理数据的方法
问题描述: 有多个.mat格式数据(本文数据名称:‘buf_026.mat’),要抽取其中的数据进行运算,结果返回到数组/xlsx等 关键字:num2str/ xlsxwrite/ eval/ 元胞数 ...
- js语法基础入门(5.1)
5.流程控制 5.1.选择结构 程序流程图 图例: 椭圆: 开始/结束 矩形: 操作 菱形: 判断 连接线: 走向 可以根据程序流程图,理清楚程序执行的流程 5.2.1.if语句 //if语句语法结构 ...
- Ticket Game【博弈】
题目 Monocarp and Bicarp live in Berland, where every bus ticket consists of n digits (n is an even nu ...
- 不就是语法和长难句吗—笔记总结Day1
CONTENTS 第一课 简单句 第二课 并列句 第三课 名词(短语)和名词性从句 第四课 定语和定语从句 第五课 状语和状语从句 第六课 英语的特殊结构 第一课 奋斗的开始——简单句 一.什么是英语 ...