你真的懂了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命令允許從內部察看給定 <tt class="docutils literal" style="box-sizing: border-box;">key</tt> 的 Redis 對象。

它通常用在除錯(debugging)或者瞭解爲了節省空間而對 <tt class="docutils literal" style="box-sizing: border-box;">key</tt> 使用特殊編碼的情況。

當將Redis用作緩存程序時,你也可以通過它命令中的信息,決定 <tt class="docutils literal" style="box-sizing: border-box;">key</tt> 的驅逐策略(eviction policies)。

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. 可以複習一下數據結構及其實現
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章