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中添加 ...
随机推荐
- Phoenix 使用教程
引言 hbase 提供很方便的 shell 脚本,可以对数据表进行 CURD 操作,但是毕竟是有一定的学习成本的,基本上对于开发来讲,sql 语句都是看家本领,那么,有没有一种方法可以把 sql 语句 ...
- STM32的三种启动方式
- 10.2-3 ifup&ifdown:激活与禁用网络接口
ifup:激活网络接口 ifup 和 ifdown 命令用于激活指定的网络接口.ifup命令其实是一个Shel脚本,有Shel基础的读者可以使用which命令来找到这个脚本并读一读.命令可读取 ...
- 火币HBAI量化币圈唯一免费量化炒币机器人
量化交易是一种投资方法.以先进的数学模型替代人为的主观判断,利用计算机技术从庞大的历史数据中海选能带来超额收益的多种"大概率"事件以制定策略,极大地减少了投资者情绪波动的影响,避免 ...
- MongoDB学习笔记:文档Crud Shell
MongoDB学习笔记:文档Crud Shell 文档插入 一.插入语法 db.collection.insertOne() 将单个文档插入到集合中.db.collection.insertMan ...
- bat脚本总结
1.修改密码 @echo off set /p b=请输入新密码: net user %username% %b% echo 密码修改成功 %b% 请牢记你的密码 pause 2.删除hosts文件并 ...
- 开源项目核心商城(CoreShop)
帮小伙伴推一下他的开源项目作者是@大灰灰 核心商城(CoreShop)Beta 支持可视化布局的.Net小程序商城 [![star](https://gitee.com/CoreUnion/CoreS ...
- ResNet网络的训练和预测
ResNet网络的训练和预测 简介 Introduction 图像分类与CNN 图像分类 是指将图像信息中所反映的不同特征,把不同类别的目标区分开来的图像处理方法,是计算机视觉中其他任务,比如目标检测 ...
- 神经网络AI加速器技术
神经网络AI加速器技术 能够直接加速卷积神经网络,还能够直接运行常见的网络框架,如TensorFlow.Caffe.PyTorch,DarkNet等,支持用户定制化的网络和计算类型. 功能特点: ● ...
- Springboot中以配置类方式自定义Mybatis的配置规则(如开启驼峰映射等)
什么是自定义Mybatis的配置规则? 答:即原来在mybatis配置文件中中我们配置到<settings>标签中的内容,如下第6-10行内容: 1 <?xml version=&q ...