Redis類型type與編碼encoding原理及使用示例
摘要
Redis是一款開源的高性能key-value數(shù)據(jù)庫,廣泛應(yīng)用于各種場(chǎng)景。在Redis中,數(shù)據(jù)類型(type)和編碼(encoding) 是非常重要的概念。本篇博客將詳細(xì)介紹Redis支持的數(shù)據(jù)類型以及相應(yīng)的編碼方式和底層實(shí)現(xiàn)原理。
要查看Redis某個(gè)key的內(nèi)部編碼,可以使用Redis命令OBJECT ENCODING key
。其中,key
是你想要查詢的鍵名。例如,如果你想要查詢名為mykey
的鍵的內(nèi)部編碼,可以執(zhí)行以下命令:
127.0.0.1:6379> object encoding mykey // 查看某個(gè)Redis鍵值的編碼
redisObject
在 Redis 中,redisObject 是 Redis 中最基本的數(shù)據(jù)結(jié)構(gòu)之一。redisObject 用于表示 Redis 中的鍵值對(duì)中的值,它可以是字符串、整數(shù)、列表、哈希表等任意一種 Redis 數(shù)據(jù)類型。
redisObject 的定義如下:
typedef struct redisObject { // 類型 unsigned type:4; // 編碼方式 unsigned encoding:4; // 引用計(jì)數(shù) int refcount; // 指向?qū)嶋H值的指針 void *ptr; } robj;
- type:表示 redisObject 的類型。
- encoding:表示 redisObject 的編碼方式。
- refcount:表示當(dāng)前 redisObject 被引用的次數(shù)。
- ptr: ptr字段則是一個(gè)指針,指向?qū)嶋H的 Redis 對(duì)象。
Redis源碼encoding取值有如下幾種:
#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 */
類型與編碼介紹
Redis支持五種主要的數(shù)據(jù)類型:字符串(string)、列表(list)、集合(set)、有序集合(sorted set)和哈希(hash)。每種數(shù)據(jù)類型都有對(duì)應(yīng)的編碼方式。
數(shù)據(jù)類型與編碼方式總覽如下:
數(shù)據(jù)類型 | 編碼方式 |
---|---|
字符串 | int、embstr、raw |
哈希表 | ziplist、hashtable |
列表 | ziplist、linkedlist、quicklist |
集合 | intset、hashtable |
有序集合 | ziplist、skiplist |
字符串
字符串是Redis中最基本的數(shù)據(jù)類型,通常用于存儲(chǔ)文本或二進(jìn)制數(shù)據(jù)。Redis支持兩種編碼方式:
- int:當(dāng)字符串可以表示為整數(shù)時(shí),Redis會(huì)將其轉(zhuǎn)換為整數(shù),并采用int編碼方式存儲(chǔ)。int編碼方式的優(yōu)點(diǎn)是存儲(chǔ)空間小,操作效率高。缺點(diǎn)是只能存儲(chǔ)整數(shù),不支持字符串操作。
- embstr(embstr-encoded string):保存長度小于44字節(jié)的字符串,當(dāng)一個(gè)字符串比較短,采用此編碼方式存儲(chǔ),可以減少內(nèi)存占用。
- raw(raw-encoded string):保存長度大于44字節(jié)的字符串,當(dāng)一個(gè)字符串比較長時(shí),采用此編碼方式存儲(chǔ)。
列表
列表是一系列有序的字符串集合,可以添加、修改和刪除元素。Redis支持三種編碼方式:
- ziplist:在Redis3.2版本之前,當(dāng)List列表中每個(gè)字符串的長度都小于64字節(jié)并且List列表中元素?cái)?shù)量小于512個(gè)時(shí),List對(duì)象使用ziplist編碼,其他情況使用linkedlist編碼。ziplist是一種緊湊的、壓縮的列表結(jié)構(gòu),可以節(jié)省內(nèi)存。適用于小型列表。
- linkedlist:linkedlist是一種鏈表結(jié)構(gòu),支持任意大小的列表。但其內(nèi)存占用會(huì)隨著列表長度的增加而增加。
- quicklist:Redis 3.2版本引入,quicklist是一種由多個(gè)ziplist組成的列表結(jié)構(gòu),既能保證性能,又能節(jié)省內(nèi)存。適用于大型列表。
集合
集合是一系列無序的字符串集合,支持添加、刪除和查詢?cè)?。Redis支持兩種編碼方式:
- intset:當(dāng)集合中的元素都是整數(shù)時(shí),Redis會(huì)采用intset編碼方式存儲(chǔ)。intset編碼方式的優(yōu)點(diǎn)是存儲(chǔ)空間小,操作效率高。
- hashtable:當(dāng)集合中的元素包含字符串時(shí),Redis會(huì)采用hashtable編碼方式存儲(chǔ)。hashtable編碼方式的優(yōu)點(diǎn)是可以存儲(chǔ)任意類型的元素,支持字符串操作。缺點(diǎn)是存儲(chǔ)空間相對(duì)較大,操作效率相對(duì)較低。
有序集合
有序集合是一系列無序的字符串集合,每個(gè)元素關(guān)聯(lián)一個(gè)分?jǐn)?shù),可以根據(jù)分?jǐn)?shù)排序。Redis支持兩種編碼方式:
- ziplist:保存的元素少于128個(gè)并且所有元素大小都小于64字節(jié)使用ziplist編碼,ziplist是一種緊湊的、壓縮的列表結(jié)構(gòu),適用于小型有序集合。
- skiplist:skiplist是一種跳躍表結(jié)構(gòu),支持快速查詢和排序。適用于大型有序集合。
哈希表
哈希表是一系列鍵值對(duì)集合,每個(gè)鍵關(guān)聯(lián)一個(gè)值。Redis支持兩種編碼方式:
- ziplist:哈希對(duì)象保存的所有鍵值的字符串長度小于64字節(jié)并且鍵值對(duì)數(shù)量小于512個(gè),Redis會(huì)采用ziplist編碼方式存儲(chǔ)。ziplist編碼方式的優(yōu)點(diǎn)是存儲(chǔ)空間小,操作效率高。缺點(diǎn)是不支持快速的鍵查找操作。
- hashtable:除上述條件之外,Redis會(huì)采用hashtable編碼方式存儲(chǔ)。hashtable編碼方式的優(yōu)點(diǎn)是支持快速的鍵查找操作。缺點(diǎn)是存儲(chǔ)空間相對(duì)較大,操作效率相對(duì)較低。
類型與編碼底層原理
了解Redis支持的數(shù)據(jù)類型和編碼方式后,我們來看一下它們的底層實(shí)現(xiàn)原理。
編碼轉(zhuǎn)換
Redis中的每個(gè)鍵值對(duì)都有一個(gè)類型標(biāo)識(shí),表示該鍵值對(duì)的數(shù)據(jù)類型。當(dāng)我們對(duì)一個(gè)鍵進(jìn)行操作時(shí),Redis會(huì)根據(jù)該鍵當(dāng)前的編碼方式以及操作所需的編碼方式,對(duì)鍵值對(duì)進(jìn)行編碼轉(zhuǎn)換。
例如,當(dāng)我們向一個(gè)字符串中追加內(nèi)容時(shí),如果該字符串當(dāng)前的編碼方式為raw,但是新的內(nèi)容可以使用embstr編碼方式存儲(chǔ),那么Redis會(huì)將該字符串的編碼方式從raw轉(zhuǎn)換為embstr。
數(shù)據(jù)結(jié)構(gòu)
除了編碼方式外,Redis還使用了許多經(jīng)典的數(shù)據(jù)結(jié)構(gòu)來實(shí)現(xiàn)各種數(shù)據(jù)類型。例如,Redis的列表和哈希表都是采用鏈表結(jié)構(gòu)實(shí)現(xiàn)的。而有序集合則采用了跳躍表(Skip List)這種高效的數(shù)據(jù)結(jié)構(gòu)。
這些數(shù)據(jù)結(jié)構(gòu)都經(jīng)過了精心設(shè)計(jì)和優(yōu)化,以滿足各種場(chǎng)景下的應(yīng)用需求。例如,鏈表結(jié)構(gòu)適合頻繁地添加和刪除元素,而跳躍表結(jié)構(gòu)則適合排序和查找。
總結(jié)
本篇博客介紹了Redis支持的五種主要數(shù)據(jù)類型以及相應(yīng)的編碼方式。Redis的數(shù)據(jù)類型和編碼方式是為了在不同的場(chǎng)景下達(dá)到最佳的性能和內(nèi)存占用。在使用Redis時(shí),需要根據(jù)實(shí)際情況選擇合適的數(shù)據(jù)類型和編碼方式,以達(dá)到最佳的效果。同時(shí),需要注意不同數(shù)據(jù)類型和編碼方式的優(yōu)缺點(diǎn),以便在實(shí)際使用中做出合理的選擇。
以上就是Redis類型type與編碼encoding原理及使用示例詳解的詳細(xì)內(nèi)容,更多關(guān)于Redis類型編碼原理的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Redis如何實(shí)現(xiàn)數(shù)據(jù)庫讀寫分離詳解
Redis的主從架構(gòu),能幫助我們實(shí)現(xiàn)讀多,寫少的情況,下面這篇文章主要給大家介紹了關(guān)于Redis如何實(shí)現(xiàn)數(shù)據(jù)庫讀寫分離的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。2018-03-03redis緩存一致性延時(shí)雙刪代碼實(shí)現(xiàn)方式
這篇文章主要介紹了redis緩存一致性延時(shí)雙刪代碼實(shí)現(xiàn)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-08-08Redis分布式鎖方案設(shè)計(jì)之防止訂單重復(fù)提交或支付
這篇文章主要為大家介紹了Redis分布式鎖之防止訂單重復(fù)提交或支付方案設(shè)計(jì)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-09-09Redis延遲隊(duì)列和分布式延遲隊(duì)列的簡(jiǎn)答實(shí)現(xiàn)
在我們的工作中,很多地方使用延遲隊(duì)列,比如訂單到期沒有付款取消訂單,制訂一個(gè)提醒的任務(wù)等都需要延遲隊(duì)列,那么我們需要實(shí)現(xiàn)延遲隊(duì)列,本文就來介紹一下如何實(shí)現(xiàn),感興趣的可以了解一下2021-05-05如何利用Redis分布式鎖實(shí)現(xiàn)控制并發(fā)操作
這篇文章主要介紹了如何利用Redis分布式鎖實(shí)現(xiàn)控制并發(fā)操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-09-09K8S部署Redis(單機(jī)、集群)的超詳細(xì)步驟
redis是一款基于BSD協(xié)議,開源的非關(guān)系型數(shù)據(jù)庫(nosql數(shù)據(jù)庫)這篇文章主要給大家介紹了關(guān)于K8S部署Redis(單機(jī)、集群)的超詳細(xì)步驟,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下2024-05-05Redis做數(shù)據(jù)持久化的解決方案及底層原理
Redis有兩種方式來實(shí)現(xiàn)數(shù)據(jù)的持久化,分別是RDB(Redis Database)和AOF(Append Only File),今天通過本文給大家聊一聊Redis做數(shù)據(jù)持久化的解決方案及底層原理,感興趣的朋友一起看看吧2021-07-07redis實(shí)現(xiàn)好友關(guān)注&消息推送的方法示例
Redis作為一款開源的內(nèi)存數(shù)據(jù)庫,具有可靠性、速度快、易用性等優(yōu)點(diǎn),已經(jīng)被廣泛應(yīng)用于開發(fā)實(shí)際項(xiàng)目中,本文主要介紹了redis實(shí)現(xiàn)好友關(guān)注&消息推送的方法示例,感興趣的可以了解一下2023-10-10