虽然内部数据结构非常强大,但是创建一系列完整的数据结构本身也是一件相当耗费内存的工作,当一个对象包含的元素数量并不多,或者元素本身的体积并不大时,使用代价高昂的内部数据结构并不是最好的办法。

为了解决这一问题,Redis在条件允许的情况下,会使用内存映射数据结构来代替内部数据结构。

内存映射数据结构可以为用户节省大量的内存。不过,因为内存映射数据结构的编码和操作方式要比内部数据结构要复杂得多,所以内存映射数据结构所占用的CPU 时间会比作用类似的内部数据结构要多。

这一部分将对Redis目前正在使用的两种内存映射数据结构进行介绍。

整数集合

整数集合(intset)用于有序、无重复地保存多个整数值,它会根据元素的值,自动选择该用什么长度的整数类型来保存元素。

Intset是集合键的底层实现之一,如果一个集合:

1. 只保存着整数元素;

2. 元素的数量不多;

那么Redis就会使用intset来保存集合元素。

根据需要,intset可以自动从int16_t 升级到int32_t 或int64_t ,或者从int32_t 升级到int64_t 。

typedefstructintset {

// 保存元素所使用的类型的长度

uint32_tencoding;

// 元素个数

uint32_tlength;

// 保存元素的数组

int8_tcontents[];

} intset;

实例

现在,我们要要将一个长度为int32_t 的值65535 加入到集合中,intset需要执行以下步骤:

1. 将encoding 属性设置为INTSET_ENC_INT32 。

2. 根据encoding 属性的值,对contents 数组进行内存重分配。

3. 因为原来的3 个int16_t 值还“挤在”contents 前面的48 个位里,所以程序需要对它们进行移动和类型转换,从而让它们适应集合的新编码方式。

4. 最后,将新值65535 添加到数组:

•Intset用于有序、无重复地保存多个整数值,它会根据元素的值,自动选择该用什么长度的整数类型来保存元素。

•当一个位长度更长的整数值添加到intset时,需要对intset进行升级,新intset中每个元素的位长度都等于新添加值的位长度,但原有元素的值不变。

•升级会引起整个intset进行内存重分配,并移动集合中的所有元素,这个操作的复杂度为O(N) 。

•Intset只支持升级,不支持降级。

•Intset是有序的,程序使用二分查找算法来实现查找操作,复杂度为O(lgN) 。

压缩列表

Ziplist是由一系列特殊编码的内存块构成的列表,一个ziplist可以包含多个节点(entry),每个节点可以保存一个长度受限的字符数组(不以\0 结尾的char 数组)或者整数。

•字符数组

长度小于等于63 (26

redisbook笔记——redis内存映射数据结构的更多相关文章

  1. redis学习笔记——内存映射数据结构

    内存映射数据结构 解决问题:当一个对象包含的元素数量并不多,或者元素本身的体积并不大时,使用代价高昂的内部数据结构并不是最好的办法. 内存映射数据结构是一系列经过特殊编码的字节序列,创建它们所消耗的内 ...

  2. redis底层设计(二)——内存映射数据结构

    我们继续接着上一篇博客,今天来看看内存映射数据结构. 上篇我们讲了内部数据结构,虽然内部数据结构非常强大,但是创建一系列完整的数据结构本身也是一件相当耗费时间的工作,当一个对象包含的元素数量并不多,或 ...

  3. redisbook笔记——redis内部数据结构

    在Redis的内部,数据结构类型值由高效的数据结构和算法进行支持,并且在Redis自身的构建当中,也大量用到了这些数据结构. 这一部分将对Redis内存所使用的数据结构和算法进行介绍. 动态字符串 S ...

  4. 【转载】linux内核笔记之高端内存映射

    原文:linux内核笔记之高端内存映射 在32位的系统上,内核使用第3GB~第4GB的线性地址空间,共1GB大小.内核将其中的前896MB与物理内存的0~896MB进行直接映射,即线性映射,将剩余的1 ...

  5. Redis学习笔记(一):基础数据结构

    一. 引言 <Redis设计与实现>一书主要分为四个部分,其中第一个部分主要讲的是Redis的底层数据结构与对象的相关知识. Redis是一种基于C语言编写的非关系型数据库,它的五种基本对 ...

  6. 《Java核心技术卷二》笔记(二)文件操作和内存映射文件

    文件操作 上一篇已经总结了流操作,其中也包括文件的读写.文件系统除了读写以为还有很多其他的操作,如复制.移动.删除.目录浏览.属性读写等.在Java7之前,一直使用File类用于文件的操作.Java7 ...

  7. 笔记:I/O流-内存映射文件

    内存映射文件时利用虚拟内存实现来将一个文件或者文件的一部分映射到内存中,然后整个文件就可以当作数组一样的访问,这个比传统的文件操作要快得多,Java 使用内存映射文件首先需要从文件中获取一个chann ...

  8. Redis深入学习笔记(六)Redis内存分配

    Redis的高效可以说是轻量级的epoll模型和基于内存的读写共同组成的,关于epoll对于以前的select或者poll的性能优势这里不做介绍,本篇主要介绍领一个重点,Redis的内存分配原理. 获 ...

  9. Redis 5种数据结构使用及注意事项

    1优缺点 非常非常的快,有测评说比Memcached还快(当大家都是单CPU的时候),而且是无短板的快,读写都一般的快,所有API都差不多快,也没有MySQL Cluster.MongoDB那样更新同 ...

随机推荐

  1. JSP HTML区别

    1.最简单的区别就是,HTML能直接打开,jsp只能发布到Tomact等服务器上才能打开2.定义上HTML页面是静态页面可以直接运行,JSP页面是动态页它运行时需要转换成servlet.3.他们的表头 ...

  2. House Of Hello恶搞包为什么如此受热捧!

    凤凰时尚    在大多数人的心中,奢侈品都是昂贵的,摆在精美的橱窗中,动辄上万的价格,高贵而冷艳,也让很多人望而却步.然而,最近在很多时尚年轻一族中却流传着这样一句话“昂贵不等于奢侈,奢侈是一种生活态 ...

  3. C#中&与&&的区别

    刚刚翻书发现这个问题,在网上找了一下,我的理解吧. 他俩的区别就是“&”和“|”不执行短路计算,而&&和||执行了短路计算. &不执行短路计算 ——————表达式A&a ...

  4. Android 安装过程中的问题

    Android  安装过程中的问题 上一篇我说到配置android环境,但是在具体的安装过程中,因为下载的软件或者方法不同,导致没有正确的结果,如果有一些错误的时候,可以试一试关闭eclipse软件, ...

  5. Record Locks

    Record Locks 记录锁: 记录锁是一个锁在一个Index记录上,比如 SELECT c1 FOR UPDATE FROM t WHERE c1 = 10; 阻止任何其他事务inserting ...

  6. weblogic启动报错之Unrecognized option: -jrockit

    报错如下: $ ./startWebLogic.sh . . JAVA Memory arguments: -Xms512m -Xmx512m . WLS Start Mode=Production ...

  7. Delphi NativeXML 乱码的问题

    我遇到 NativeXML 在它的一个节点的属性上面写入属性,但是当读出的值中包含汉字的时候出现了乱码.检查代码如下 NativeXml := TNativeXml.Create; try Nativ ...

  8. cf602A Two Bases

    A. Two Bases time limit per test 1 second memory limit per test 256 megabytes input standard input o ...

  9. vijosP1603迷宫

    vijosP1603迷宫 链接:https://vijos.org/p/1603 [思路] 参考Matrix67的文章: [代码] #include<cstdio> #include< ...

  10. poj3294 Life Forms(后缀数组)

    [题目链接] http://poj.org/problem?id=3294 [题意] 多个字符串求出现超过R次的最长公共子串. [思路] 二分+划分height,判定一个组中是否包含不小于R个不同字符 ...