redis内部数据结构和外部数据结构揭秘
Redis有哪些数据结构?
字符串String、字典Hash、列表List、集合Set、有序集合SortedSet。
很多人面试时都遇到过这种场景吧?
其实除了上面的几种常见数据结构,还需要加上数据结构HyperLogLog、Geo。
可是很多人不知道redis 不仅有上面的几种数据结构,还内藏了内部的数据结构。即redis可以分为外部数据结构和内部数据结构。
1. 如何查看redis的数据结构?
1.1 如何查看redis的外部数据结构?
可以使用type命令,返回key的类型,如string, list, set, zset, hash 和stream,实例如下:

redis> SET key1 "value"
"OK"
redis> LPUSH key2 "value"
(integer) 1
redis> SADD key3 "value"
(integer) 1
redis> TYPE key1
"string"
redis> TYPE key2
"list"
redis> TYPE key3
"set"
redis>

1.2 如何查看redis的内部数据结构
可以通过Object命令来查看。object命令允许从内部察看给定 key 的 Redis 对象。
2.redis数据结构的定义redisObject
内部数据类型server.h

typedef struct redisObject {
unsigned type:4;
unsigned encoding:4;
unsigned lru:LRU_BITS; /* LRU time (relative to global lru_clock) or
* LFU data (least significant 8 bits frequency
* and most significant 16 bits access time). */
int refcount;
void *ptr;
} robj;

其中,type为redis的外部数据结构,encoding为redis的内部数据结构实现
type的值如下:

/*-----------------------------------------------------------------------------
* Data types
*----------------------------------------------------------------------------*/ /* A redis object, that is a type able to hold a string / list / set */ /* The actual Redis Object */
#define OBJ_STRING 0 /* String object. */
#define OBJ_LIST 1 /* List object. */
#define OBJ_SET 2 /* Set object. */
#define OBJ_ZSET 3 /* Sorted set object. */
#define OBJ_HASH 4 /* Hash object. */ /* The "module" object type is a special one that signals that the object
* is one directly managed by a Redis module. In this case the value points
* to a moduleValue struct, which contains the object value (which is only
* handled by the module itself) and the RedisModuleType struct which lists
* function pointers in order to serialize, deserialize, AOF-rewrite and
* free the object.
*
* Inside the RDB file, module types are encoded as OBJ_MODULE followed
* by a 64 bit module type ID, which has a 54 bits module-specific signature
* in order to dispatch the loading to the right module, plus a 10 bits
* encoding version. */
#define OBJ_MODULE 5 /* Module object. */
#define OBJ_STREAM 6 /* Stream object. */

encoding的值如下:server.h

/* Objects encoding. Some kind of objects like Strings and Hashes can be
* internally represented in multiple ways. The 'encoding' field of the object
* is set to one of this fields for this object. */
#define OBJ_ENCODING_RAW 0 /* Raw representation */
#define OBJ_ENCODING_INT 1 /* Encoded as integer */
#define OBJ_ENCODING_HT 2 /* Encoded as hash table */
#define OBJ_ENCODING_ZIPMAP 3 /* Encoded as zipmap */
#define OBJ_ENCODING_LINKEDLIST 4 /* No longer used: old list encoding. */
#define OBJ_ENCODING_ZIPLIST 5 /* Encoded as ziplist */
#define OBJ_ENCODING_INTSET 6 /* Encoded as intset */
#define OBJ_ENCODING_SKIPLIST 7 /* Encoded as skiplist */
#define OBJ_ENCODING_EMBSTR 8 /* Embedded sds string encoding */
#define OBJ_ENCODING_QUICKLIST 9 /* Encoded as linked list of ziplists */
#define OBJ_ENCODING_STREAM 10 /* Encoded as a radix tree of listpacks */

内部类型总结

3.数据结构的限制server.h

/* Zipped structures related defaults */
#define OBJ_HASH_MAX_ZIPLIST_ENTRIES 512
#define OBJ_HASH_MAX_ZIPLIST_VALUE 64
#define OBJ_SET_MAX_INTSET_ENTRIES 512
#define OBJ_ZSET_MAX_ZIPLIST_ENTRIES 128
#define OBJ_ZSET_MAX_ZIPLIST_VALUE 64
#define OBJ_STREAM_NODE_MAX_BYTES 4096
#define OBJ_STREAM_NODE_MAX_ENTRIES 100
/* HyperLogLog defines */
#define CONFIG_DEFAULT_HLL_SPARSE_MAX_BYTES 3000

4.实例
4.1 字符串String
int :8个字节的长整型
embstr:小于44个字节的字符串(目前),3.0以前的版本为39
raw:大于39个字节小于512MB的字符串
object.c

/* Create a string object with EMBSTR encoding if it is smaller than
* OBJ_ENCODING_EMBSTR_SIZE_LIMIT, otherwise the RAW encoding is
* used.
*
* The current limit of 44 is chosen so that the biggest string object
* we allocate as EMBSTR will still fit into the 64 byte arena of jemalloc. */
#define OBJ_ENCODING_EMBSTR_SIZE_LIMIT 44

验证一下:

Connected.
local:0>object encoding test1
"int" local:0>object encoding test2
"embstr" local:0>object encoding test3
"raw" local:0>get test1
"10000" local:0>get test2
"hello world!" local:0>get test3
"Redis is not a plain key-value store, it is actually a data structures server, supporting different kinds of values. What this means is that, while in traditional key-value stores you associated string keys to string values, in Redis the value is not limited to a simple string, but can also hold more complex data structures. The following is the list of all the data structures supported by Redis, which will be covered separately in this tutorial:" local:0>

4.2 哈希hash
当filed的个数少于512,且没有value大于64字节时,内部编码为ziplist
当filed的个数大于512,或者value大于64字节时,内部编码为hashtable

Connected.
local:0>hmset hashtest1 field1 value1 field2 value2 field3 value3
"OK" local:0>object encoding hashtest1
"ziplist" local:0>hset hashtest2 field1 "Redis modules can access Redis built-in data structures both at high level, by calling Redis commands, and at low level, by manipulating the data structures directly."
"1" local:0>object encoding hashtest2
"hashtable" local:0>

4.3 列表list
redis 3.2 之前
当列表list中的元素个数少于512,且没有value大于64字节时,内部编码为ziplist
当列表list中的元素个数大于512,或者value大于64字节时,内部编码为linkedlist
redis 3.2 之后
都使用quicklist

Connected.
local:0>rpush listtest1 value1 value2 value3 value4 value5
"5" local:0>object encoding listtest1
"quicklist" local:0>rpush listtest2 "Redis modules can access Redis built-in data structures both at high level, by calling Redis commands, and at low level, by manipulating the data structures directly."
"1" local:0>object encoding listtest2
"quicklist" local:0>

4.4 集合set
当集合set中的元素都是整数且元素个数小于512(默认时)使用intset
其它条件使用hashtable

local:0>sadd settest1 1 2 3
"3" local:0>object encoding settest1
"intset" local:0>sadd settest2 "hello world!"
"1" local:0>object encoding settest2
"hashtable" local:0>

4.5 有序集合zset
当有序集合zse中的元素个数少于128(默认),且没有value大于64字节时,内部编码为ziplist
当有序集合zse中的元素个数大于128(默认),或者value大于64字节时,内部编码为skiplist

Connected.
local:0>zadd zsettest1 10 value1 20 value2 30 value3
"3" local:0>object encoding zsettest1
"ziplist" local:0>zadd zsettest2 60 "Redis modules can access Redis built-in data structures both at high level, by calling Redis commands, and at low level, by manipulating the data structures directly."
"1" local:0>object encoding zsettest2
"skiplist" local:0>

4.6 Geo

Connected.
local:0>GEOADD Sicily 13.361389 38.115556 "Palermo" 15.087269 37.502669 "Catania"
"2" local:0>object encoding Sicily
"ziplist" local:0

4.7 HyperLogLog

Connected.
local:0>PFADD hll a b c d e f g
"1" local:0>object encoding h11
null local:0>object encoding hll
"raw" local:0>

5 总结
1. 外部数据结构类型可以通过type来查看
2.内部数据结构类型可以通过object来查看
3. 理解内部数据结构的实现有助于我们深入理解redis
4. 可以复习一下数据结构及其实现
redis内部数据结构和外部数据结构揭秘的更多相关文章
- 你真的懂redis的数据结构了吗?redis内部数据结构和外部数据结构揭秘
Redis有哪些数据结构? 字符串String.字典Hash.列表List.集合Set.有序集合SortedSet. 很多人面试时都遇到过这种场景吧? 其实除了上面的几种常见数据结构,还需要加上数据结 ...
- 你真的懂了redis的数据结构吗?redis内部数据结构和外部数据结构揭秘
原文链接:https://mp.weixin.qq.com/s/hKpAxPE-9HJgV6GEdV4WoA Redis有哪些数据结构? 字符串String.字典Hash.列表List.集合Set.有 ...
- 探索Redis设计与实现6:Redis内部数据结构详解——skiplist
本文转自互联网 本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 https://github.com/h2pl/Java-Tutorial ...
- 探索Redis设计与实现2:Redis内部数据结构详解——dict
本文转自互联网 本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 https://github.com/h2pl/Java-Tutorial ...
- 【转】Redis内部数据结构详解 -- skiplist
本文是<Redis内部数据结构详解>系列的第六篇.在本文中,我们围绕一个Redis的内部数据结构--skiplist展开讨论. Redis里面使用skiplist是为了实现sorted s ...
- redisbook笔记——redis内部数据结构
在Redis的内部,数据结构类型值由高效的数据结构和算法进行支持,并且在Redis自身的构建当中,也大量用到了这些数据结构. 这一部分将对Redis内存所使用的数据结构和算法进行介绍. 动态字符串 S ...
- 关于redis内部的数据结构
最大感受,无论从设计还是源码,Redis都尽量做到简单,其中运用到的原理也通俗易懂.特别是源码,简洁易读,真正做到clean and clear, 这篇文章以unstable分支的源码为基准,先从大体 ...
- [转]Redis内部数据结构详解-sds
本文是<Redis内部数据结构详解>系列的第二篇,讲述Redis中使用最多的一个基础数据结构:sds. 不管在哪门编程语言当中,字符串都几乎是使用最多的数据结构.sds正是在Redis中被 ...
- redis内部数据结构深入浅出
最大感受,无论从设计还是源码,Redis都尽量做到简单,其中运用到的原理也通俗易懂.特别是源码,简洁易读,真正做到clean and clear, 这篇文章以unstable分支的源码为基准,先从大体 ...
随机推荐
- ALGO-115_蓝桥杯_算法训练_和为T(枚举)
问题描述 从一个大小为n的整数集中选取一些元素,使得它们的和等于给定的值T.每个元素限选一次,不能一个都不选. 输入格式 第一行一个正整数n,表示整数集内元素的个数. 第二行n个整数,用空格隔开. 第 ...
- 一个简单的springmvc例子 入门(1)
一直是从事棋牌游戏,平常用的东西 大多数只是使用一些javase的一些 api对spring 这方面 用到的比较少,每次学了都忘,始终记不住.为了 更轻松学习springboot,从新学习了sprin ...
- HTML-Ronoob-基础教程:HTML 字符实体
ylbtech-HTML-Ronoob-基础教程:HTML 字符实体 1.返回顶部 1. HTML 中的预留字符必须被替换为字符实体. HTML 实体 在 HTML 中,某些字符是预留的. 在 HTM ...
- 数据迁移_老集群RAC迁移数据恢复到新集群RAC
数据迁移_老集群RAC迁移数据恢复到新集群RAC 作者:Eric 微信:loveoracle11g 1.把老集群RAC备份的数据远程拷贝到新集群RAC [root@old-rac-node1 ~]# ...
- Change default network name (ens33) to old “eth0” on Ubuntu 18.04 / Ubuntu 16.04
Change default network name (ens33) to old “eth0” on Ubuntu 18.04 / Ubuntu 16.04 By Raj Last updated ...
- URL传值乱码
JS端: &value=encodeURIComponent("value") C端: HttpUtility.UrlDecode(Request.Params[" ...
- sqoop1.4.7 导入数据到hive2.3.4 jackson版本问题
今天用sqoop往hive导入数据的时候,执行报错,错误信息为: java.lang.NoSuchMethodError:com.fasterxml.jackson.databind.ObjectMa ...
- 好习惯: 用controller as 语法和$inject数组注入
angular好习惯1: 用controller as 语法和$inject数组注入 1) 像普通的JS类一样实现controller,摆脱$scope 2) 用.$inject数组注入相关模块,便于 ...
- flex布局 (引用阮一峰老师的flex布局-语法篇)
一.Flex 布局是什么? Flex 是 Flexible Box 的缩写,意为"弹性布局",用来为盒状模型提供最大的灵活性. 任何一个容器都可以指定为 Flex 布局. .box ...
- Ddr2,ddr3,ddr4内存条的读写速率
理论极限值是可以计算的:1333MHz * 64bit(单通道,双通道则128bit) / 8(位到字节单位转换) = 10.664GB/s.这只是理论,实际发挥还要看内存控制器,实际上1333单条跑 ...