Redis类型(Type)与编码(Encoding)

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Tair(兼容Redis),内存型 2GB
简介: Redis是一款开源的高性能key-value数据库,广泛应用于各种场景。在Redis中, 数据类型(Type)和编码(Encoding) 是非常重要的概念。本篇博客将详细介绍Redis支持的数据类型以及相应的编码方式和底层实现原理。

本文已收录至GitHub,推荐阅读 👉 Java随想录

微信公众号:Java随想录

原创不易,注重版权。转载请注明原作者和原文链接

Redis是一款开源的高性能key-value数据库,广泛应用于各种场景。在Redis中, 数据类型(Type)和编码(Encoding) 是非常重要的概念。本篇博客将详细介绍Redis支持的数据类型以及相应的编码方式和底层实现原理。

要查看Redis某个key的内部编码,可以使用Redis自带的命令OBJECT ENCODING key

其中,key是你想要查询的键名。例如,如果你想要查询名为mykey的键的内部编码,可以执行以下命令:

127.0.0.1:6379> object encoding mykey  // 查看某个Redis键值的编码

redisObject

在Redis中,redisObject 是一个非常重要的数据结构,它用于保存字符串、列表、集合、哈希表和有序集合等类型的值。以下是关于 redisObject 结构体的定义:

typedef struct redisObject {
   
    unsigned type:4;
    unsigned encoding:4;
    unsigned lru:24; /* lru time (relative to server.lruclock) */
    int refcount;
    void *ptr;
} robj;

各个属性解析如下:

  • type:用于标识对象所属的类型,分别是 REDIS_STRINGREDIS_LISTREDIS_SETREDIS_ZSETREDIS_HASH 等。
  • encoding: 用于标识对象内部的编码方式, 如 REDIS_ENCODING_INTREDIS_ENCODING_HTREDIS_ENCODING_ZIPMAP 等。
  • lru:这个字段记录了对象被命令调用的时间, 它是缓存淘汰策略(LRU)的一部分。
  • refcount:引用计数,当 refcount 减少到0时,对象就可以被清理并回收内存。
  • ptr:一个指针,根据对象的类型和编码方式的不同,这个指针可能会指向各种不同的类型,比如整数、动态字符串、链表、字典等。

其中,redisObject的encoding取值有如下几种:

#define OBJ_ENCODING_RAW 0        //简单动态字符串,用于保存键值对的键和配置文件中的参数。
#define OBJ_ENCODING_INT 1        //整型值,用于优化小整数的内存使用。
#define OBJ_ENCODING_HT 2         //哈希表,用于存储普通哈希对象的字段和值。
#define OBJ_ENCODING_ZIPMAP 3     //缩字典,这是一种特殊类型的哈希表,用于优化小哈希对象的内存使用。
#define OBJ_ENCODING_LINKEDLIST 4 //双端链表,用于存储列表键。
#define OBJ_ENCODING_ZIPLIST 5    //压缩列表,用于优化小列表或者小哈希对象的内存使用。
#define OBJ_ENCODING_INTSET 6     //整数集合,用于优化只包含整数元素的集合的内存使用。
#define OBJ_ENCODING_SKIPLIST 7   //跳跃表和字典,用于存储有序集合键。
#define OBJ_ENCODING_EMBSTR 8     //对于长度小于44字节的字符串,Redis选择使用此特殊的编码方式。
#define OBJ_ENCODING_QUICKLIST 9  //对于列表对象(list object)的一种编码方式。quicklist是ziplist和双向链表的混合体。

Type与Encoding介绍

Redis支持五种主要的数据类型:字符串(String)、列表(List)、集合(Set)、有序集合(Sorted Set)和哈希(Hash)。

每种数据类型都有对应的编码方式,数据类型与编码方式总览如下:

数据类型 编码方式
字符串 int、embstr、raw
哈希表 ziplist、hashtable
列表 ziplist、linkedlist、quicklist
集合 intset、hashtable
有序集合 ziplist、skiplist

字符串

字符串是Redis中最基本的数据类型,通常用于存储文本或二进制数据。字符串在Redis中支持三种编码方式:

  • int:当字符串可以表示为整数时,Redis会将其转换为整数,并采用int编码方式存储。int编码方式的优点是存储空间小,操作效率高。缺点是只能存储整数,不支持字符串操作。
  • embstr(embstr-encoded string) :保存长度小于44字节的字符串,当一个字符串比较短,采用此编码方式存储,可以减少内存占用。
  • raw(raw-encoded string) :保存长度大于44字节的字符串,当一个字符串比较长时,采用此编码方式存储。

列表

列表是一系列有序的字符串集合,可以添加、修改和删除元素。列表在Redis中支持三种编码方式:

  • ziplist:在Redis3.2版本之前,当List列表中每个字符串的长度都「小于64字节」并且List列表中「元素数量小于512个」时,List对象使用ziplist编码,其他情况使用linkedlist编码。ziplist是一种紧凑的、压缩的列表结构,可以节省内存,适用于小型列表。
  • linkedlist:linkedlist是一种链表结构,支持任意大小的列表。但其内存占用会随着列表长度的增加而增加。
  • quicklist:Redis 3.2版本引入,quicklist是一种由多个ziplist组成的列表结构,既能保证性能,又能节省内存,适用于大型列表。

集合

集合是一系列无序的字符串集合,支持添加、删除和查询元素。集合在Redis中支持两种编码方式:

  • intset:当集合中的元素都是整数时,Redis会采用intset编码方式存储。intset编码方式的优点是存储空间小,操作效率高。
  • hashtable:当集合中的元素包含字符串时,Redis会采用hashtable编码方式存储。hashtable编码方式的优点是可以存储任意类型的元素,支持字符串操作。缺点是存储空间相对较大,操作效率相对较低。

有序集合

有序集合是一系列无序的字符串集合,每个元素关联一个分数,可以根据分数排序。有序集合在Redis中支持两种编码方式:

  • ziplist:当集合中元素个数少于128个,并且每个元素的大小小于64字节时,使用此编码方式。这是因为ziplist在处理较小数据时,内存效率更高,性能更优。
  • skiplist:skiplist是一种跳跃表结构,支持快速查询和排序。适用于大型有序集合。

哈希表

哈希表是一系列键值对集合,每个键关联一个值。哈希表在Redis中支持两种编码方式:

  • ziplist:保存的所有键值的字符串长度小于64字节,并且键值对数量小于512个,Redis会采用ziplist编码方式存储。ziplist编码方式的优点是存储空间小,操作效率高。缺点是不支持快速的键查找操作。
  • hashtable:除上述条件之外,Redis会采用hashtable编码方式存储。hashtable编码方式的优点是支持快速的键查找操作,缺点是存储空间相对较大,操作效率相对较低。

Type与Encoding底层原理

了解Redis支持的数据类型和编码方式后,我们来看一下它们的底层实现原理。

编码转换

Redis中的每个键值对都有一个类型标识,表示该键值对的数据类型。当我们对一个键进行操作时,Redis会根据该键当前的编码方式以及操作所需的编码方式,对键值对进行编码转换。

例如,当我们向一个字符串中追加内容时,如果该字符串当前的编码方式为raw,但是新的内容可以使用embstr编码方式存储,那么Redis会将该字符串的编码方式从raw转换为embstr。

数据结构

除了编码方式外,Redis还使用了许多经典的数据结构来实现各种数据类型。例如,Redis的列表和哈希表都是采用链表结构实现的。而有序集合则采用了跳跃表(Skip List)这种高效的数据结构。

这些数据结构都经过了精心设计和优化,以满足各种场景下的应用需求。例如,链表结构适合频繁地添加和删除元素,而跳跃表结构则适合排序和查找。

本篇博客介绍了Redis支持的五种主要数据类型以及相应的编码方式。

Redis的数据类型和编码方式是为了在不同的场景下达到最佳的性能和内存占用。理解这些类型和编码机制,对于深化我们对Redis的认识,优化其性能,以及发挥其最大潜力是至关重要的。

虽然每个项目的需求和应用可能会有所不同,但通过精心选择和使用合适的类型和编码,我们都可以充分利用Redis为我们的应用带来的高效,快速和可靠。

总之,Redis的类型和编码是其核心功能的基石,理解这些可以帮助我们更好地使用Redis,解决实际问题。当你下次面临需要决定使用哪种数据结构或编码方式的时候,希望你可以记住今天的内容,并从中找到答案。感谢您抽出宝贵的时间阅读这篇文章,希望它对您有所帮助!


感谢阅读,如果本篇文章有任何错误和建议,欢迎给我留言指正。

老铁们,关注我的微信公众号「Java 随想录」,专注分享Java技术干货,文章持续更新,可以关注公众号第一时间阅读。

一起交流学习,期待与你共同进步!

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
相关文章
|
2月前
|
负载均衡 NoSQL 算法
一天五道Java面试题----第十天(简述Redis事务实现--------->负载均衡算法、类型)
这篇文章是关于Java面试中Redis相关问题的笔记,包括Redis事务实现、集群方案、主从复制原理、CAP和BASE理论以及负载均衡算法和类型。
一天五道Java面试题----第十天(简述Redis事务实现--------->负载均衡算法、类型)
|
11天前
|
JSON 缓存 NoSQL
redis序列化数据时,如何包含clsss类型信息?
通过配置 `com.fasterxml.jackson.databind.ObjectMapper` 的 `enableDefaultTyping` 方法,可以使序列化后的 JSON 包含类信息。
33 2
|
3月前
|
存储 缓存 NoSQL
Redis 常用五种数据类型编码
Redis 常用五种数据类型编码
34 9
|
4月前
|
NoSQL Redis C语言
[hiredis 的Redis执行语句返回结果类型全说明
[hiredis 的Redis执行语句返回结果类型全说明
33 1
|
4月前
|
存储 NoSQL Redis
蓝易云 - Redis之bitmap类型解读
需要注意的是,虽然bitmap可以高效地存储和计算大量的位,但是它也有一些局限性,例如,它不能直接获取或设置某一范围内的所有位,也不能直接获取或设置多个不连续的位。
22 2
|
3月前
|
Java
Redis19----RedisTemplate操作Hash类型
Redis19----RedisTemplate操作Hash类型
|
3月前
|
NoSQL Redis
Redis11-----Sortedset类型,SortedSet底层是由数据树实现的,SortedSet删除同学,获取Amy同学分数,获取Rose同学排名,查询80分以下的学生,给Amy同学加2分
Redis11-----Sortedset类型,SortedSet底层是由数据树实现的,SortedSet删除同学,获取Amy同学分数,获取Rose同学排名,查询80分以下的学生,给Amy同学加2分
|
3月前
|
存储 NoSQL Java
Redis10------Set类型,存在着无序的特征存储的顺序和插入的顺序是无关的,set集合的一大特点是不可重复,在redis中支持交集插集等特殊功能,好友列表,共同关注等等
Redis10------Set类型,存在着无序的特征存储的顺序和插入的顺序是无关的,set集合的一大特点是不可重复,在redis中支持交集插集等特殊功能,好友列表,共同关注等等
|
3月前
|
NoSQL Java Redis
Redis09-----List类型,有序,元素可以重复,插入和删除快,查询速度一般,一般保存一些有顺序的数据,如朋友圈点赞列表,评论列表等,LPUSH user 1 2 3可以一个一个推
Redis09-----List类型,有序,元素可以重复,插入和删除快,查询速度一般,一般保存一些有顺序的数据,如朋友圈点赞列表,评论列表等,LPUSH user 1 2 3可以一个一个推
|
3月前
|
存储 Java
Redis08命令-Hash类型,也叫散列,其中value是一个无序字典,类似于java的HashMap结构,Hash结构可以将对象中的每个字段独立存储,可以针对每字段做CRUD
Redis08命令-Hash类型,也叫散列,其中value是一个无序字典,类似于java的HashMap结构,Hash结构可以将对象中的每个字段独立存储,可以针对每字段做CRUD
下一篇
无影云桌面