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

为了解决这一问题,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. Gunicorn快速入门

    Gunicorn (独角兽)是一个高效的Python WSGI Server,通常用它来运行 wsgi application(由我们自己编写遵循WSGI application的编写规范) 或者 w ...

  2. 关于MYSQL优化(持续更新)

    *利用MYSQL数据缓存提高效率,注意事项: 1.应用环境:不经常改变的表及对此表相同的查询 2.不适用于服务器端编写的语句 3.根据数据使用频率,合理分解表 4.合理使用默认条件,提高命中率 5.统 ...

  3. WINDOWS下的SALT-MINION安装流水图

    简单的下一步下一步, 没多少说的,可以在安装的时候设置MASTER和MINION的东东.. 不多说,上图:

  4. H3C S5000和H3C S5500,俺来罗

    S5开头,后面第二位数0-4搂二层交换机.5-9的为三层交换机. 小常识.

  5. Android 中使用MediaRecorder进行录像详解(视频录制)

    在这里给出自己的一个测试DEMO,里面注释很详细.简单的视频录制功能. package com.video; import java.io.IOException; import android.ap ...

  6. github Travis CI 持续集成

    一个项目如何保证代码质量是开发中非常重要的环节,对于开源项目来说更是如此,因为开源项目要面对的是来自不同水平开发者提交的代码.所以围绕开源做持续集成(Continuous Integration)变得 ...

  7. POJ-2774-Long Long Message(后缀数组-最长公共子串)

    题意: 给定两个字符串 A 和 B,求最长公共子串. 分析: 字符串的任何一个子串都是这个字符串的某个后缀的前缀. 求 A 和 B 的最长公共子串等价于求 A 的后缀和 B 的后缀的最长公共前缀的最大 ...

  8. Javascript 面向对象编程(一):封装 by 阮一峰

    <Javascript高级程序设计(第二版)>(Professional JavaScript for Web Developers, 2nd Edition) 它们都是非常优秀的Java ...

  9. Smartdraw世界上最流行的商业绘图软件

    Smartdraw 更多图片(5张) SmartDraw是世界上最流行的商业绘图软件.2006 年获美国政府司法部 (U.S. Department of Justice) 专用软件,2007获美国政 ...

  10. 《A First Course in Probability》-chaper4-离散型随机变量-随机变量函数的期望

    给定一个离散型随机变量X,根据定义我们容易得到期望E[X],但是在具体的问题当中,我们会得到一个关于X的另一个函数关系Y=g(X),那么我们就非常的好奇,根据函数关系Y=g(X)和随机变量X的分布列数 ...