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

为了解决这一问题,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. 一个小知识,shell如何输出换行符号

    一般来说如果在echo里直接写上\n,他不会被转义,必须加上-e参数 echo "hello\n morning" # 输出为 hello\n morning echo -e &q ...

  2. python MySQLdb segmentation fault

    import MySQLdb conn = MySQLdb.connect(host=_host,user=_user,passwd=_passwd,db=_db,charset=_charset,p ...

  3. 连接各种数据库神器———DbVisualizer

    作为开发人员,经常会遇到在不同的数据库环境中进行开发或者调试,所以针对每种数据库都要安装对应的客户端,不但要占用硬盘控件而且还要经常切换,无可厚非这是一项头疼并且麻烦的事情.有了DbVisualize ...

  4. AlgorithmsI Programming Assignment 1: PercolationStats.java

    import edu.princeton.cs.algs4.StdOut; import edu.princeton.cs.algs4.StdRandom; import edu.princeton. ...

  5. BZOJ 1053 [HAOI2007]反素数ant

    1053: [HAOI2007]反素数ant Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1948  Solved: 1094[Submit][St ...

  6. POJ-3189-Steady Cow Assignment(最大流+枚举)

    题意 此题题意不太好懂.现有n头牛和b个牛棚,每个牛棚可以养的牛的数目都有一个限制c[i],表示该牛棚最多只能关c[i]头牛,每头牛对每一个牛棚都有一个喜爱值,用1到b来表示,现在要安排这些牛,使得牛 ...

  7. 数据结构(主席树,Bit):XTU 1247/COGS 2344. pair-pair

    pair-pair 输入文件:pair-pair.in   输出文件:pair-pair.out   简单对比 时间限制:7 s   内存限制:64 MB Time Limit : 7000 MS M ...

  8. 【模拟】Codeforces 671A Recycling Bottles

    题目链接: http://codeforces.com/problemset/problem/671/A 题目大意: A和B在一张二维平面上,平面上有N个垃圾,垃圾桶只有一个在T,问把所有垃圾全扔进垃 ...

  9. HDU-2087 剪花布条

    http://acm.hdu.edu.cn/showproblem.php?pid=2087 剪花布条 Time Limit: 1000/1000 MS (Java/Others)    Memory ...

  10. Node.js真的有高并发优势吗?看看Node.js和Tomcat的并发测试结果

    同一套业务逻辑,实现一个webservice中间接口,中间涉及memcached和mogodb的一些操作.分别在Node.js和JAVA平台实现,java代码部署在Tomcat 7.0上,用Apach ...