redisbook笔记——redis内存映射数据结构
虽然内部数据结构非常强大,但是创建一系列完整的数据结构本身也是一件相当耗费内存的工作,当一个对象包含的元素数量并不多,或者元素本身的体积并不大时,使用代价高昂的内部数据结构并不是最好的办法。
为了解决这一问题,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
内存映射数据结构 解决问题:当一个对象包含的元素数量并不多,或者元素本身的体积并不大时,使用代价高昂的内部数据结构并不是最好的办法. 内存映射数据结构是一系列经过特殊编码的字节序列,创建它们所消耗的内 ... 我们继续接着上一篇博客,今天来看看内存映射数据结构. 上篇我们讲了内部数据结构,虽然内部数据结构非常强大,但是创建一系列完整的数据结构本身也是一件相当耗费时间的工作,当一个对象包含的元素数量并不多,或 ... 在Redis的内部,数据结构类型值由高效的数据结构和算法进行支持,并且在Redis自身的构建当中,也大量用到了这些数据结构. 这一部分将对Redis内存所使用的数据结构和算法进行介绍. 动态字符串 S ... 原文:linux内核笔记之高端内存映射 在32位的系统上,内核使用第3GB~第4GB的线性地址空间,共1GB大小.内核将其中的前896MB与物理内存的0~896MB进行直接映射,即线性映射,将剩余的1 ... 一. 引言 <Redis设计与实现>一书主要分为四个部分,其中第一个部分主要讲的是Redis的底层数据结构与对象的相关知识. Redis是一种基于C语言编写的非关系型数据库,它的五种基本对 ... 文件操作 上一篇已经总结了流操作,其中也包括文件的读写.文件系统除了读写以为还有很多其他的操作,如复制.移动.删除.目录浏览.属性读写等.在Java7之前,一直使用File类用于文件的操作.Java7 ... 内存映射文件时利用虚拟内存实现来将一个文件或者文件的一部分映射到内存中,然后整个文件就可以当作数组一样的访问,这个比传统的文件操作要快得多,Java 使用内存映射文件首先需要从文件中获取一个chann ... Redis的高效可以说是轻量级的epoll模型和基于内存的读写共同组成的,关于epoll对于以前的select或者poll的性能优势这里不做介绍,本篇主要介绍领一个重点,Redis的内存分配原理. 获 ... 1优缺点 非常非常的快,有测评说比Memcached还快(当大家都是单CPU的时候),而且是无短板的快,读写都一般的快,所有API都差不多快,也没有MySQL Cluster.MongoDB那样更新同 ... 如何按ESC关闭窗口? 在InitializeComponent();下面增加KeyDown事件,如: public ModifyPrice() { InitializeComponent(); th ... 题目链接:BZOJ - 1875 题目分析: 这道题如果去掉“不会立刻沿着刚刚走来的路走回”的限制,直接用邻接矩阵跑矩阵乘法就可以了.然而现在加了这个限制,建图的方式就要做一些改变.如果我们把每一条边 ... http://www.jdon.com/artichect/scalable5.html http://www.dedecms.com/knowledge/data-base/nosql/2012/0 ... 嗯...老生常谈的话题, 不过系统的总结了一下, 找了个相对简单的实现方式, 可以方便的发送任何文字 参考另一片文章: http://www.cnblogs.com/-clq/archive/2011 ... 1. 正则表达式特殊符号.[:alnum:]:代表英文大小写字符及数字:[:alpha:]:代表英文大小写字符:[:blank:]:代表空格键与[Tab]键:[:cntrl:]:代表键盘上的控制键,即 ... road 难度级别: A: 编程语言:不限:运行时间限制:1000ms: 运行空间限制:131072KB: 代码长度限制:102400B 试题描述 某国有N个城市,这N个城市由M条双向道路连接.现 ... 题目大意: 给你一个base 进制的数字,把这个数字的每一位进行全排列,问有多少个数字是可以整除k的. 题目解析: #include<cstdio> #include<cstring ... 题目链接: http://codeforces.com/gym/100526 http://acm.hunnu.edu.cn/online/?action=problem&type=show& ... 1.c的格式化输入输出: printf()和scanf()函数可以较好实现格式化输入输出,例子如下: printf("%3d",3); //结果为__3 (_为空格) pri ... http://acm.hdu.edu.cn/showproblem.php?pid=1016 #include <iostream> using namespace std; int a[ ...redisbook笔记——redis内存映射数据结构的更多相关文章
随机推荐