Redis對基礎數據類型進行了封裝,構建出上層的對象系統,這個系統包含:字符串對象、列表對象、哈希對象、集合對象和有序集合對象。
Redis對象結構:
[cce lang=”c”]
typedef struct redisObject {
//類型
unsigned type:4;
//編碼
unsigned encoding:4;
//LRU時間
unsigned lru:REDIS_LRU_BITS; /* lru time (relative to server.lruclock) */
//引用計數
int refcount;
//底層實現數據結構的指針
void *ptr;
} robj;
[/cce]
相關宏定義:
[cce lang=”c”]
#define REDIS_LRU_BITS 24
#define REDIS_LRU_CLOCK_MAX ((1<<REDIS_LRU_BITS)-1) /* Max value of obj->lru */
#define REDIS_LRU_CLOCK_RESOLUTION 1 /* LRU clock resolution in seconds */
[/cce]
Redis對象類型:(使用type命令查看)
[cce lang=”c”]
/* Object types */
#define REDIS_STRING 0
#define REDIS_LIST 1
#define REDIS_SET 2
#define REDIS_ZSET 3
#define REDIS_HASH 4
//對象編碼類型:(使用object encoding命令)
#define REDIS_ENCODING_RAW 0 /* Raw representation */
#define REDIS_ENCODING_INT 1 /* Encoded as integer */
#define REDIS_ENCODING_HT 2 /* Encoded as hash table */
#define REDIS_ENCODING_ZIPMAP 3 /* Encoded as zipmap */
#define REDIS_ENCODING_LINKEDLIST 4 /* Encoded as regular linked list */
#define REDIS_ENCODING_ZIPLIST 5 /* Encoded as ziplist */
#define REDIS_ENCODING_INTSET 6 /* Encoded as intset */
#define REDIS_ENCODING_SKIPLIST 7 /* Encoded as skiplist */
[/cce]
不同類型和編碼的對象:
類型 | 編碼 | 對象 |
REDIS_STRING | REDIS_ENCODING_INT | 使用整數值實現的字符串對象 |
REDIS_STRING | REDIS_ENCODING_EMBSTR | 這貨redis3.0引入的,不管 |
REDIS_STRING | REDIS_ENCODING_RAW | sds實現的字符串對象 |
REDIS_LIST | REDIS_ENCODING_ZIPLIST | 使用壓縮列表實現的列表對象 |
REDIS_LIST | REDIS_ENCODING_LINKEDLIST | 使用雙向鏈表實現的列表對象 |
REDIS_HASH | REDIS_ENCODING_ZIPLIST | 使用壓縮列表實現的哈希對象 |
REDIS_HASH | REDIS_ENCODING_HT | 使用字典實現的哈希對象 |
REDIS_SET | REDIS_ENCODING_INTSET | 使用整數集合實現的集合對象 |
REDIS_SET | REDIS_ENCODING_HT | 使用字典實現的集合對象 |
REDIS_ZSET | REDIS_ENCODING_ZIPLIST | 使用壓縮列表實現的有序集合對象 |
REDIS_ZSET | REDIS_ENCODING_SKIPLIST | 使用跳躍表想和字典實現的有序集合對象 |
字符串對象:
整數(long)被保存為int類型
浮點保存為字符串,浮點運算(INCRYBYFLOAT)redis先轉成浮點,進行運算后再轉回字符串
列表對象:
列表對象同時滿足一下兩個條件時,列表對象使用ziplist編碼
列表對象保存的所有字符串元素的長度都小于64個字節(list-max-ziplist-value)
列表對象保存的元素數量小于512個(list-max-ziplist-entries)
不能滿足條件的都需要使用linkedlist編碼。
哈希對象:
使用壓縮列表,鍵和值分別作為節點按順序放入列表
使用ziplist的條件:
哈希對象保存的所有鍵值對的鍵和值的字符串長度小于64個字節(hash-max-ziplist-value)
哈希對象保存的鍵值對數量小于512個(hash-max-ziplist-entries)
集合對象:
hashtable編碼,字典的每個鍵都是一個字符串對象,字典的值全部設置為NULL
使用intset編碼條件:
集合對象保存的所有元素是整數值
集合對象保存的元素數量不超過512個(set-max-intset-entries)
不滿足條件的集合對象需要使用hashtable編碼
有序集合對象:
ziplist編碼的有序集合,每個集合元素使用兩個緊挨在一起的壓縮節點列表來保存,第一個節點保存元素的成員,第二個節點保存元素的分值。
skiplist編碼的有序集合,采用一個skiplist和一個hashtable實現。
使用ziplist編碼條件:
有序集合保存的元素數量小于128個(zset-max-ziplist-entries)
有序集合保存的所有元素成員的長度都小于64字節(zset-max-ziplist-value)
對象共享:
Redis在初始化時,會創建1w個字符串對象(REDIS_SHARED_INTEGERS),包含整數0~9999,當需要使用這些對象的時候,會使用這些對象的引用(引用計數)而不新創建。
[cce lang=”c”]
if (value >= 0 && value < REDIS_SHARED_INTEGERS) {
incrRefCount(shared.integers[value]);
o = shared.integers[value];
}
[/cce]
轉載自:https://coolex.info/blog/454.html