redis--hash的实现
Redis数据结构---字典,哈希表,dict 或java中的map,数据使用key -> value的形式存储,整个redis数据库就是基于字典实现,api见hash
REDIS的hash实现原理和java的HashMap十分相似,可参考阅读
理解redis的hash实现,就要先理解一下三个结构 dictEntry, ditht, dict
哈希表节点 dictEntry {
void *key //键值
union{void *val; uint64_tu64; int64_ts64} v //值 可以是指针,可以是uint_64_t整数 或者int64_t整数
struct dictEntry *next; //指向下一个哈希节点,形成链表的结构(同java hashmap中的entry)
}
哈希表 dictht{
dictEntry **table; //一个元素为dictEntry 的数组
long size; // 哈希表的大小
long sizemask; // 哈希表大小掩码,用于计算存储时所在的数组下标 大小总是等于size-1
long used; //当前哈希表已有的节点数量
}
哈希表有个负载因子 的概念,load_factor = used/size 即已使用 除以总数size的结果
而提供api给我们开发者,即直接使用的dict实现如下
字典 dict{
dictType *type //指针,特定类型的函数 redis中有定义,指向了一族函数,用以实现针对键值对的操作,这同list的dup free match一样,也是多太的一种,是dict可以存不同类型的键值对
void *privdata //私有数据 用以使用dictType中定义的特定函数时传入的可选参数
dictht ht[2] //元素为哈希表的数组,长度为2,即保存着2个哈希表
in trehashidx // rehash索引,当不在进行rehash时为-1
}
当向一个dict中set一个键值A对时,会先使用hash算法根据键值计算出一个数字,即哈希表中数组的下标,该键值对就存放在此位置上,
如果再有一个键值B对被set存放进入此dict时,hash算法根据键值计算出的数字同上,即为键冲突,也叫哈希冲突,这时hash表会使用头插法,将B的dictEntry的next设置为A,形成链表的数据结构
随着dict的操作,键值对会有增多和减少,为了是负载因子在合理范围内,会产生rehash,其步骤简单如下:
当没有rehash的普通情况下,dict中的ht[2] 数组总是使用ht[0] 对应的哈希表来保存数据,当需要扩容或缩减时,会为ht[1]分配对应的存储空间,其大小算法是
扩容时,大小是第一个大于ht[0]的size的 2的n次方,缩小时,是第一个小于ht[0]长度的2的n次方(可参考java的Hashmap中的tablesizefor算法)
当ht[1]分配好空间后,会把ht[0]上的所有数据复制到ht[1]上,之后ht[0]变为空表,是否,把ht[1]移到ht[0]上继续使用
如果redis在执行BGSAVE或BAREWRITEAOF命令操作,会在当前redis服务现场中创建子进程,使用的是写时复制技术优化子进程的使用效率!
当没有子进程存在时,负载因子大于等于1时就会进行rehash,当存在子进程时,负载因子需要大于等于5才会进行rehash
当负载因子小于0.1时,也会进行收缩操作的rehash!
这样设计的目的就是尽量的使子进程工作期间,不要有rehash操作的产生,避免不必要的内存浪费
rehash使用的是渐进式rehash
它不会一次性的吧所有的ht[0] 中的数据一下子复制到ht[1]中,而是在增删改查操作发生时,每发生一次就复制一个值过去,同时对rehashidx做+1,避免了集中的大量的运算而导致redis夯死,值得注意的是,每次新增操作会把新增的值放入ht[1]中,同时复制一个ht[0]中数据到ht[1]中!同时,因为完整数据存在于2个hash表中,所有查询时是先查ht[0],再查ht[1]!循序渐进的复制,最终复制完成
redis--hash的实现的更多相关文章
- python处理json和redis hash的坑
1.使用MySQLdb读取出来的数据是unicode字符串,如果要写入redis的hash中会变成 "{u'eth0_outFlow': 2.5, u'eth1_inFlow': 3.44} ...
- redis学习(二) Redis Hash
Redis hash 是一个string类型的field和value的映射表,hash特别适合用于存储对象. Redis 中每个 hash 可以存储 232 - 1 键值对(40多亿). redis ...
- redis hash map
redis hash的使用详见文章:http://www.miaoyueyue.com/archives/235.html hash操作命令如下: hset(key, field, value):向名 ...
- ***Redis hash是一个string类型的field和value的映射表.它的添加、删除操作都是O(1)(平均)。hash特别适合用于存储对象
http://redis.readthedocs.org/en/latest/hash/hset.html HSET HSET key field value (存一个对象的时候key存) 将哈希 ...
- Redis hash数据类型操作
Redis hash是一个string类型的field和value的映射表.一个key可对应多个field,一个field对应一个value.将一个对象存储 为hash类型,较于每个字段都存储成str ...
- Redis hash 类型及操作
原文:http://blog.sina.com.cn/s/blog_5f044a4d0102v01k.html Redis hash是一个string类型的field和value的映射表.它的添加.删 ...
- Redis学习第三课:Redis Hash类型及操作
Redis hash是一个string类型的field和value的映射表.它的添加.删除操作都是O(1)(平均).hash特别适用于存储对象.相较于对象的每个字段存在单个string类型.将一个对象 ...
- Python --Redis Hash操作
一.Redis Hash操作 Redis 数据库hash数据类型是一个string类型的key和value的映射表,适用于存储对象.Redis 中每个 hash 可以存储 232 - 1 键值对(40 ...
- C#操作Redis Hash数据表
/// <summary> /// Redis Hash /// </summary> public static void Redis_Hash() { RedisClien ...
- Redis hash(哈希)
Redis hash可储存多个键值对,适合储存对象的属性. 1.hset key fieldName fileValue //hset即hash set,set这里是设置的意思.往hash中添加 ...
随机推荐
- 配置文件修改java安全级别和站点信息
配置文件修改java安全级别和站点信息原创Green_1001 最后发布于2015-04-22 23:00:09 阅读数 516 收藏展开 通过配置文件修改java安全级别 配置文件名称为deploy ...
- 052.Python前端Django框架路由层和视图层
一.路由层(URLconf) 1.1 路由层简单配置 URL配置(URLconf)就像Django 所支撑网站的目录.它的本质是URL与要为该URL调用的视图函数之间的映射表:你就是以这种方式告诉Dj ...
- shell应用之cobbler批量部署
如果使用的是原始源,可直接使用该脚本,如果是用的其它源且有cobbler安装包的可删除脚本中的配置yum源步骤.批量部署使用的软件有:cobbler dhcp httpd tftp-server xi ...
- Arduino+AS608指纹锁避坑记
Arduino+AS608指纹锁避坑记 .title { text-align: center; margin-bottom: 0.2em } .subtitle { text-align: cent ...
- Step By Step(Lua-C API简介)
Step By Step(Lua-C API简介) Lua是一种嵌入式脚本语言,即Lua不是可以单独运行的程序,在实际应用中,主要存在两种应用形式.第一种形式是,C/C++作为主程序,调用Lua代码, ...
- CVPR2020最新论文扫描盘点(下)
CVPR2020最新论文扫描盘点(下) 最近计算机视觉三大顶会之一CVPR2020接收结果已经公布,一共有1470篇论文被接收,接收率为22%,相比去年降低3个百分点,竞争越来越激烈.这里整理来自Tw ...
- MegEngine亚线性显存优化
MegEngine亚线性显存优化 MegEngine经过工程扩展和优化,发展出一套行之有效的加强版亚线性显存优化技术,既可在计算存储资源受限的条件下,轻松训练更深的模型,又可使用更大batch siz ...
- Python神经网络集成技术Guide指南
Python神经网络集成技术Guide指南 本指南将介绍如何加载一个神经网络集成系统并从Python运行推断. 提示 所有框架的神经网络集成系统运行时接口都是相同的,因此本指南适用于所有受支持框架(包 ...
- gradle 混合编程java、scala、kotlin、groovy
众所周知,java是基于JVM的开发语言,但能够在JVM上运行的开发语言不仅仅有java,目前还有很热门的kotlin(kotlin不仅仅只能开发Android).scala.groovy等等.目前国 ...
- 8, java数据结构和算法: 从阶乘来看递归的调用
直接上代码 public class RecursionDemo { //从阶乘看 递归的调用机制 public static void main(String[] args) { System.ou ...