redis hash设置过期时间 redis给hash设置过期时间_编码格式

一、hash 简介

Redis Hashes are maps between string fields and string values, so they are the perfect data type to represent objects (e.g. A User with a number of fields like name, surname, age, and so forth):

中文译文如下

redis hash 是 字符 filed 和 value 之间的映射表,所以非常适合用于存储对象(比如:一个用户有多个属性字段,如:名称,年龄等等。)

Hash 在存储对象值后的逻辑图如下:


redis hash设置过期时间 redis给hash设置过期时间_redis hash设置过期时间_02


这里是两个用户对象存储的值,左边的是 key ,右边的是 value ,而 value 是以映射的关系来进行存储。Hash 适合存储对象结构,或者数据库表的字段结构。

二、hash 简单命令操作

关于 hash 的操作命令,同样的在 参考文档中都能够获取到,这边演示几个操作命令。

单个属性的设置和获取,以及多个属性到的设值和获取。

Hset 和 Hget 单个属性操作


redis hash设置过期时间 redis给hash设置过期时间_redis hash设置过期时间_03


Hmset 和 Hmget 多个属性操作


redis hash设置过期时间 redis给hash设置过期时间_Redis_04


三、hash 的编码格式

hash 在 redis 内部的编码格式


redis hash设置过期时间 redis给hash设置过期时间_复杂度_05

hash 内部有两种编码格式: ziplisthashtable

3.1、ziplist

翻到 ziplist的c源码文件(ziplist.c),来看一下官方的 doc 描述

redis hash设置过期时间 redis给hash设置过期时间_复杂度_06

中文译文大意如下

ziplist 是一种特殊编码双链表,设计用于提高内存效率,不过内存利用率提高了,相关的查询操作速度自然会降低,因为多了编码解码的操作。可以说是,ziplist 是时间换空间的设计。

所以 ziplist 适用于key-value键值对的个数比较少的时候。

它存储字符串和整数值,其中整数被编码为实际的整数,而不是一系列字符。

push 和 pop 的复杂度是 O(1) 的,其他操作会根据具体使用的内存而使得其他操作的复杂度提升,比如说 HMset 批量操作,操作的属性越多,复杂度也就越高,n个属性,复杂度就是O(n)。

在 doc 文件中能够知道 ziplist 的抽象结构定义

redis hash设置过期时间 redis给hash设置过期时间_复杂度_07

结构定义的抽象图如下

redis hash设置过期时间 redis给hash设置过期时间_redis hash设置过期时间_08

ziplist 是以一种特殊编码进行存储的,所以redis并没有提供一个结构体来保存压缩列表的信息,而是提供了一组宏来定位每个成员,部分宏定义如下:

redis hash设置过期时间 redis给hash设置过期时间_Redis_09

重点关注 ziplist entry 的宏定义,代码和 doc 注释如下

redis hash设置过期时间 redis给hash设置过期时间_复杂度_10

zlentry 结构体是用来管理节点信息的。

ziplist 是一个特殊编码的双向链表,它的特殊性就在于对节点进行了压缩处理。而压缩前后 zlentry 就是 entry 节点信息的一个承载对象,换句话说,在存储前 zilentry 用来表示当前数据的信息,在将数据信息读取解压后也是用的 zlentry 来存储表示。

来看一下从 ziplist 中获取 entry 是相关的解码操作

hset 为入口(t_hash.c),设置单个hash的操作命令处理入口。

下面是一张简单的时序图

redis hash设置过期时间 redis给hash设置过期时间_编码格式_11

hashTypeSet 相关代码如下

redis hash设置过期时间 redis给hash设置过期时间_Redis_12

查看 ziplistFind方法(ziplist.c 中),部分代码如下

redis hash设置过期时间 redis给hash设置过期时间_redis hash设置过期时间_13

查看其中一个解密操作 ZIP_DECODE_LENGTH,代码如下

redis hash设置过期时间 redis给hash设置过期时间_redis hash设置过期时间_14

3.2、hashtable

来看一下 hashtable,hashtable 结构图如下

redis hash设置过期时间 redis给hash设置过期时间_复杂度_15

Redis 中 hash表被称为字典 (dict),Redis的字典使用哈希表作为底层实现,一个哈希表里面可以有多个哈希表节点,而每个哈希表节点保存了字典中的一个键值对

Redis中的哈希采用了典型的挂链解决冲突的方式,当有多个key-value键值对的键名key映射值相同时,系统会将这些键值value以单链表的形式保存,同时为了控制哈希表占用内存大小,Redis采用了双哈希表ht[2]结构,并逐步扩大哈希表容量的策略。

通常情况下只有 h[0] 被使用,当数据量多的时候会进行扩容,在 Redis 中存在扩容阈值 `dict_force_resize_ratio=5`