Redis 学习 ---- 4.字典
2016-03-17 11:38
501 查看
4.1 字典的实现
哈希表由dict.h/dictht结构定义:
哈希表结点:
Redis中的字典由dict.h/dict结构表示:
type属性和privdata属性是针对不同类型的键值对,为创建多态字典而设置的:
①type属性是一个指向dictType结构的指针,每个dictType结构保存了一簇用于操作特定类型键值对的函数,Redis会为用途不同的字典设置不同的类型特定函数。
②而privdata属性则保存了需要传给哪些类型特定函数的可选参数。
4.2 哈希算法
当字典被用作数据库的底层实现,或者哈希键的底层实现时,Redis使用MurmurHash2算法来计算键的哈希值。
MurmurHash算法最初由Austin Appleby于2008年发现,这种算法的有点在于,即使输入的键是有规律的,算法仍能给出一个很好的随机分布性,并且算法的计算速度也非常快。该算法主页:http://code.google.com/p/smhasher/
4.3 解决键冲突
Redis的哈希表使用链地址法来解决键冲突.
4.4 rehash
扩展和收缩哈希表的工作可以通过执行rehash(重新散列)操作来完成
哈希表的扩展与收缩
当一下条件中的任意一个被满足时,程序会自动开始对哈希表执行扩展操作:
1)服务器目前没有在执行BGSAVE命令或者BGREWRITEAOF命令,并且哈希表的负载银子大于等于1。
2)服务器目前正在执行BGSAVE命令或者BGREWRITEAOF命令,并且哈希表的负载银子大于等于5。
另一方面,当哈希表的负载因子小于0.1时,成灰自动开始对哈希表执行收缩操作
4.5 渐进式rehash
渐进式rehash执行期间,删除,查找,更新等操作会在俩个哈希表上进行。新增保存在ht[1]里
4.7 重点回顾
Ⅰ 字典被广泛用于实现Redis的各种功能,其中包括数据库和哈希键
Ⅱ Redis中的字典使用哈希表作为底层实现,每个字典带有俩个哈希表,一个平时使用,另一个仅在进行rehash时使用
Ⅲ 当字典被用作数据库的底层实现,或者哈希键的底层实现时,Redis使用MurmurHash2算法来计算键的哈希值
Ⅳ 哈希表使用链地址法来解决键冲突,被分配到同一个索引上的多个键值对会联接成一个单向链表
Ⅴ 在对哈希表进行扩展或者收缩操作时,程序需要将现有哈希表包含的所有键值对rehash到新哈希表里面,并且这个rehash过程并不是一次性地完成的,而是渐进式地完成。
哈希表由dict.h/dictht结构定义:
typedef struct dictht{ dictEntry **table; // 哈希表数组 unsigned long size; // 大小 unsigned long sizemask; // 总是等于size-1、哈希表大小掩码,用于计算索引值 unsigned long used; // 该哈希表已有结点的数量 }dictht;
哈希表结点:
typedef struct dictEntry{ void *key; // 键 union{ void *val; uint64_t u64; int64_t s64; }v; struct dictEntry *next; //指向下个哈希表结点,形成链表 }dictEntry;
Redis中的字典由dict.h/dict结构表示:
typedef struct dict{ dictType *type; // 类型特定函数 void *privdata; // 私有数据 dictht ht[2]; // 哈希表 int rehashidx; // rehash索引,当rehash不在进行时,值为-1 }dict;
type属性和privdata属性是针对不同类型的键值对,为创建多态字典而设置的:
①type属性是一个指向dictType结构的指针,每个dictType结构保存了一簇用于操作特定类型键值对的函数,Redis会为用途不同的字典设置不同的类型特定函数。
②而privdata属性则保存了需要传给哪些类型特定函数的可选参数。
typedef struct dictType{ unsigned int (*hashFunction)(const void *key); // 计算哈希值的函数 void *(*keyDup)(void *privdata, const void *key); // 复制键的函数 void *(*valDup)(void * privdata, const void *obj); // 复制值的函数 int (*keyCompare)(void *privdata,const void *key1,const void *key2); // 对比键的函数 void (*keyDestructor)(void *privdata, void *key); // 销毁键的函数 void (*valDestructor)(void *privdata, void *obj); // 销毁值的函数 }dictType;
4.2 哈希算法
当字典被用作数据库的底层实现,或者哈希键的底层实现时,Redis使用MurmurHash2算法来计算键的哈希值。
MurmurHash算法最初由Austin Appleby于2008年发现,这种算法的有点在于,即使输入的键是有规律的,算法仍能给出一个很好的随机分布性,并且算法的计算速度也非常快。该算法主页:http://code.google.com/p/smhasher/
4.3 解决键冲突
Redis的哈希表使用链地址法来解决键冲突.
4.4 rehash
扩展和收缩哈希表的工作可以通过执行rehash(重新散列)操作来完成
哈希表的扩展与收缩
当一下条件中的任意一个被满足时,程序会自动开始对哈希表执行扩展操作:
1)服务器目前没有在执行BGSAVE命令或者BGREWRITEAOF命令,并且哈希表的负载银子大于等于1。
2)服务器目前正在执行BGSAVE命令或者BGREWRITEAOF命令,并且哈希表的负载银子大于等于5。
// 负载因子 = 哈希表已保存结点数量 / 哈希表大小 load_factor = ht[0].used / ht[0].size
另一方面,当哈希表的负载因子小于0.1时,成灰自动开始对哈希表执行收缩操作
4.5 渐进式rehash
渐进式rehash执行期间,删除,查找,更新等操作会在俩个哈希表上进行。新增保存在ht[1]里
4.7 重点回顾
Ⅰ 字典被广泛用于实现Redis的各种功能,其中包括数据库和哈希键
Ⅱ Redis中的字典使用哈希表作为底层实现,每个字典带有俩个哈希表,一个平时使用,另一个仅在进行rehash时使用
Ⅲ 当字典被用作数据库的底层实现,或者哈希键的底层实现时,Redis使用MurmurHash2算法来计算键的哈希值
Ⅳ 哈希表使用链地址法来解决键冲突,被分配到同一个索引上的多个键值对会联接成一个单向链表
Ⅴ 在对哈希表进行扩展或者收缩操作时,程序需要将现有哈希表包含的所有键值对rehash到新哈希表里面,并且这个rehash过程并不是一次性地完成的,而是渐进式地完成。
相关文章推荐
- Redis 集群
- 从Redis缓存服务器获取省市信息
- Redis 学习 ---- 3.链表 Linked List
- 深入理解Redis主键失效原理及实现机制
- Redis安装配置
- Redis 学习 ---- 1.引言
- Redis 主从配置和参数详解
- PHP-redis中文说明
- Redis学习(一)-基础理论、字符串命令、列表结构
- CentOS6.5下redis安装部署配置指南、常用命令、主从同步集群、redis-php学习资料整合详解
- windows下安装redis服务 AND PHP中添加扩展 AND PHP中使用
- redis 在spring boot工程中的应用(四) 图片的读取与缓存 byte string
- redis 在spring boot工程中的应用(三) 问题发现与解决 :反序列化 报错
- 常用的 redis操作
- java(优化12) 15天玩转redis之第六篇
- Redis提供商配置ASP.NET会话状态
- redis学习笔记2--命令返回值
- 重温redis--redis在springmvc下的使用
- redis主从配置
- Redis主从配置