Redis通用數據類型
redis最常用的數據類型主要包括以下五種:
線
混雜
目錄
設置
分類集合
在詳細描述這些數據類型之前,我們先通過壹張圖了解壹下如何描述redis內存管理中的這些不同數據類型:
首先,redis使用壹個redisobject對象來表示所有的鍵和值。Redisobject的主要信息如上圖所示:type代表壹個。
什麽數據類型是值對象?編碼是不同數據類型在redis中的存儲方式。例如,type=string表示值存儲。
壹個普通的字符串,那麽對應的編碼可以是raw或int。如果是int,則意味著實際的redis根據數字類型存儲和表示該字符串。當然,
前提是字符串本身可以用數值表示,比如“123”。
類似“456”的字符串。
這裏需要解釋壹下vm字段。只有打開redis的虛擬內存功能,該字段才會真正分配內存。該功能默認關閉,稍後將詳細介紹該功能。及格
在上圖中,我們可以發現redis使用redisobject表示所有鍵/值數據是壹種內存浪費。當然,這些內存管理成本主要是為了
Redis為不同的數據類型提供了統壹的管理接口,實際作者也提供了各種方法來幫助我們盡可能地節省內存,我們將在後面詳細討論。
讓我們逐壹分析這五種數據類型的使用和內部實現:
線
常用命令:
設置、獲取、減少、增加、管理等
應用場景:
String是最常用的數據類型,普通的key/value存儲都可以歸入這壹類,這裏就不解釋了。
實施模式:
存儲在redis中的字符串默認是壹個字符串,它被redisobject引用。當遇到incr、decr等運算時,會轉換為數值型進行計算。此時,redisobject的編碼字段為int。
混雜
常用命令:
Hget、hset、hgetall等。
應用場景:
我們舉壹個簡單的例子來描述hash的應用場景。例如,我們想存儲壹個用戶信息對象數據,其中包含以下信息:
用戶id是要搜索的關鍵字,存儲值用戶對象包含姓名、年齡、生日等信息。如果它存儲在通用的鍵/值結構中,則有兩種主要的存儲方法:
第壹種方法將用戶id作為搜索關鍵字,並將其他信息封裝到壹個對象中並以序列化的方式存儲。這種方法的缺點是增加了序列化/反序列化的成本,當其中壹個信息需要修改時,需要檢索整個對象,並且修改操作需要保護並發性並引入cas等復雜問題。
第二種方法是將用戶信息對象存儲為與成員壹樣多的鍵值對,並使用用戶id+相應屬性的名稱作為唯壹標識符來獲取相應屬性的值。雖然消除了序列化開銷和並發問題,但用戶id被重復存儲,如果有大量這樣的數據,內存浪費仍然非常可觀。
那麽redis提供的hash就很好地解決了這個問題。redis的hash實際上是內部存儲的值是壹個hashmap,它提供了壹個直接訪問這個map成員的接口,如下圖所示:
也就是說,密鑰仍然是用戶id,
Value是壹個映射,這個映射的鍵是成員的屬性名,value是屬性值,這樣就可以通過其內部映射的鍵直接修改和訪問數據(內部映射的鍵在Redis中稱為field)。
也就是通過key(用戶id)+field(屬性標簽)。
您可以操作相應的屬性數據,這不需要重復存儲數據,也不會帶來序列化和並發修改控制的問題。它很好地解決了這個問題。
同時需要註意的是,redis提供了壹個接口(hgetall),可以直接獲取所有屬性數據,但如果內部映射的成員很多,就涉及到遍歷整個內部映射。
操作,由於redis單線程模型,這種遍歷操作可能很耗時,而其他客戶端的請求完全沒有響應,這需要特別註意。
實施模式:
關於redis已經說過了
對應於哈希值的值實際上是壹個哈希表。實際上,這裏有兩種不同的實現。當hash的成員數量較少時,redis將使用類似於壹維數組的方式將其緊湊存儲,而不是使用真正的hashmap結構和相應的值。
redisobject的編碼是zipmap,當成員數量增加時,它會自動變成壹個真正的hashmap,編碼是ht。
目錄
常用命令:
Lpush、rpush、lpop、rpop、lrange等。
應用場景:
雷迪斯
List有很多應用場景,也是redis最重要的數據結構之壹。例如twitter的關註列表和粉絲列表都可以通過redis的列表結構來實現,這很容易理解,這裏不再贅述。
實施模式:
雷迪斯
list的實現是壹個雙向鏈表,它可以支持反向搜索和遍歷,使其更容易操作,但它帶來了壹些額外的內存開銷。redis內部的許多實現(包括發送緩沖隊列)也使用這種數據結構。
設置
常用命令:
Sadd、spop、sembers、sunion等。
應用場景:
雷迪斯
set提供的功能與list類似,但特殊之處在於set可以自動復制。當您需要存儲數據列表並且不想要重復數據時,set是壹個很好的選擇,並且set提供了壹個重要的接口來判斷成員是否在set集合中,這是list無法提供的。
實施模式:
set的內部實現是壹個。
值始終為null的Hashmap實際上是通過計算hash來快速排序的,這就是為什麽set可以提供壹種判斷成員是否在集合中的方法。
分類集合
常用命令:
紮德、zrange、zrem、zcard等。
使用場景:
redis排序集的使用場景與set類似,只是set不會自動排序,並進行排序。
Set可以通過提供壹個額外的參數score對成員進行排序,它是按順序插入的,即自動排序。當您需要有序且不重復的收藏列表時,可以選擇“已排序”。
設置數據結構,如twitter的public。