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的实现的更多相关文章

  1. python处理json和redis hash的坑

    1.使用MySQLdb读取出来的数据是unicode字符串,如果要写入redis的hash中会变成 "{u'eth0_outFlow': 2.5, u'eth1_inFlow': 3.44} ...

  2. redis学习(二) Redis Hash

    Redis hash 是一个string类型的field和value的映射表,hash特别适合用于存储对象. Redis 中每个 hash 可以存储 232 - 1 键值对(40多亿). redis ...

  3. redis hash map

    redis hash的使用详见文章:http://www.miaoyueyue.com/archives/235.html hash操作命令如下: hset(key, field, value):向名 ...

  4. ***Redis hash是一个string类型的field和value的映射表.它的添加、删除操作都是O(1)(平均)。hash特别适合用于存储对象

    http://redis.readthedocs.org/en/latest/hash/hset.html HSET HSET key field value   (存一个对象的时候key存) 将哈希 ...

  5. Redis hash数据类型操作

    Redis hash是一个string类型的field和value的映射表.一个key可对应多个field,一个field对应一个value.将一个对象存储 为hash类型,较于每个字段都存储成str ...

  6. Redis hash 类型及操作

    原文:http://blog.sina.com.cn/s/blog_5f044a4d0102v01k.html Redis hash是一个string类型的field和value的映射表.它的添加.删 ...

  7. Redis学习第三课:Redis Hash类型及操作

    Redis hash是一个string类型的field和value的映射表.它的添加.删除操作都是O(1)(平均).hash特别适用于存储对象.相较于对象的每个字段存在单个string类型.将一个对象 ...

  8. Python --Redis Hash操作

    一.Redis Hash操作 Redis 数据库hash数据类型是一个string类型的key和value的映射表,适用于存储对象.Redis 中每个 hash 可以存储 232 - 1 键值对(40 ...

  9. C#操作Redis Hash数据表

    /// <summary> /// Redis Hash /// </summary> public static void Redis_Hash() { RedisClien ...

  10. Redis hash(哈希)

    Redis hash可储存多个键值对,适合储存对象的属性. 1.hset key fieldName fileValue    //hset即hash set,set这里是设置的意思.往hash中添加 ...

随机推荐

  1. stm32.cube(一)——系统架构及目录结构

    一.前言 Arm的应用场景往往比51单片机复杂得多,如果一个高级应用的开发需要连底层的结构性代码都要重构,那么在成本和研发周期上就会面临巨大的风险.为了简化编码过程,芯片厂商经常会提供一些板卡级支持的 ...

  2. STM32 库函数 延时函数计算

  3. BXL文件怎样转换为AD LIB文件

    https://jingyan.baidu.com/article/48b558e326e1b17f39c09a57.html

  4. linux Generating /run/initramfs/rdsosreport.txt 问题

    Generating /run/initramfs/rdsosreport.txt 问题 实验室异常断电,导致Centos7重启以后出现 Generating "/run/initramfs ...

  5. MYSQL导入/迁移后事件不执行

    mysql迁移后事件不执行 查看数据库是否开启事件支持 mysql> show variables like 'event_scheduler'; +-----------------+---- ...

  6. iapp后台一本通php源码+iapp源码

    给大家分享一个后台源码,内有后台php源码,还有iapp对接源码,一本通 iapp+ PHP源码 经过一个小时的研究看看,测试了一下, 1.注册登录以修复正常,签到正常 2.所有工具正常 3.接口,i ...

  7. unity ab包打包和加载的简单学习示例

    闲着没事结合项目看了下unity AssetBundle打包和使用,写了一些测试例子,需要的可以拿去,导入一个空项目即可 链接:https://pan.baidu.com/s/1H85dnMNkRoW ...

  8. 1130-host ... is not allowed to connect to this MySql server

    解决方法: 1. 改表法. 可能是你的帐号不允许从远程登陆,只能在localhost.这个时候只要在localhost的那台电脑,登入mysql后,更改 "mysql" 数据库里的 ...

  9. NVIDIA GPU自动调度神经网络

    NVIDIA GPU自动调度神经网络 对特定设备和工作负载进行自动调整对于获得最佳性能至关重要.这是有关如何使用自动调度器为NVIDIA GPU调整整个神经网络. 为了自动调整神经网络,将网络划分为小 ...

  10. NVIDIA DeepStream 5.0构建智能视频分析应用程序

    NVIDIA DeepStream 5.0构建智能视频分析应用程序 无论是要平衡产品分配和优化流量的仓库,工厂流水线检查还是医院管理,要确保员工和护理人员在照顾病人的同时使用个人保护设备(PPE),就 ...