原創轉載請注明出處: https://www.cnblogs.com/agilestyle/p/11532375.html
String: 一般做一些復雜的計數功能的緩存
List: 做簡單的消息隊列的功能
Hash: 單點登錄
Set: 做全局去重的功能
SortedSet: 做排行榜應用,取TopN操作;延時任務;做范圍查找
類型 | 簡介 | 特性 | 場景 |
---|---|---|---|
String (字符串) |
Redis的字符串是動態字符串,是可以修改的字符串,它的內部表示就是一個字符數組, 內部結構的實現類似於Java的ArrayList 它的內部結構是一個帶長度信息的字節數組 |
可以包含任何數據,比如jpg圖片或者序列化的對象,規定字符串的長度不得超過512MB。 Redis的字符串有兩種存儲方式,在長度特別短時,使用embstr形勢存儲,而長度超過44字節時候,使用raw形勢存儲 |
1、訪問量統計:每次訪問博客和文章使用 INCR 命令進行遞增 2、將數據以二進制序列化的方式進行存儲 |
Hash (字典) |
Redis的字典相當於Java語言里面的HashMap 字典結構內部包含了兩個Hashtable,通常情況下只有一個Hashtable是有值的, 但是在字典擴容縮容時候,需要重新分配新的Hashtable,然后進行漸進式搬遷,這時候兩個Hashtable存儲的分別是舊的Hashtable和新的Hashtable;待搬遷結束后,舊的Hashtable被刪除,新的Hashtable取而代之 |
適合存儲對象,並且可以像數據庫中update一個屬性一樣只修改某一項屬性值(Memcached中需要取出整個字符串反序列化成對象修改完再序列化存回去)。 大字典的擴容是比較耗時的,需要重新申請新的數組,然后將舊字典所有鏈表中的元素重新掛接到新的數組下面,這是一個O(n)級別的操作,作為單線程的Redis很難承受這樣耗時的過程,所以Redis使用漸進式rehash小步搬遷雖然慢一點,但是肯定可以搬完。 |
1、存儲、讀取、修改對象屬性,比如:用戶(姓名、性別、愛好),文章(標題、發布時間、作者、內容) |
List (列表) |
Redis的列表相當於Java的LinkedList List的結構底層實現不是一個簡單的LinkedList,而是快速鏈表(quicklist)。 首先在列表元素較少的情況下,會使用一塊連續的內存存儲,這個結構是ziplist,即壓縮列表。它將所有的元素彼此緊挨着一起存儲,分配的是一塊連續的內存;當數據量比較多的時候才會改成quicklist。 |
增刪快,提供了操作某一段元素的API 普通的鏈表需要的附加指針空間太大,會浪費空間,加重內存的碎片化。Redis將鏈表和ziplist結合起來組成了quicklist,也就是將多個ziplist使用雙向指針串聯起來使用,既滿足了快速的插入刪除性能,又不會出現太大的空間冗余 |
1、最新消息排行等功能(比如朋友圈的時間線) 2、消息隊列 |
Set (集合) |
Redis的集合相當於Java語言里面的HashSet,內部的鍵值對是無須的、唯一的 Set的結構底層實現是字典,只不過所有的value都是NULL,其他的特性和字典一摸一樣。 |
1、添加、刪除、查找的復雜度都是O(1) 2、為集合提供了求交集、並集、差集等操作 當set集合容納的元素都是整數並且元素個數較少時,Redis會使用intset來存儲集合元素。intset是緊湊的數組結構,同時支持16位,32位和64位整數 |
1、共同好友 2、利用唯一性,統計訪問網站的所有獨立ip 3、好友推薦時,根據tag求交集,大於某個閾值就可以推薦 |
Sorted Set (有序集合) |
Redis有序列表類似於Java的SortedSet和HashMap的結合體, 一方面是一個set,保證內部value的唯一性,另一方面可以給每個value賦予一個score,代表這個value的排序權重。 它的內部實現是一個Hash字典 + 一個跳表。 |
數據插入集合時,已經進行天然排序 Redis的跳表共有64層,能容納2的64次方個元素。 Redis之所以用跳表來實現有序集合 1. 插入、刪除、查找以及迭代輸出有序序列這幾個操作,紅黑樹都能完成,時間復雜度跟跳表是一樣的。但是按照區間來查找數據,紅黑樹的效率就沒有跳表高 2. 跳表更容易代碼實現,比起紅黑樹來說還是好懂、好寫很多,可讀性好,不容易出錯 3. 跳表更加靈活,可以通過改變索引構建策略,有效平衡執行效率和內存消耗 |
1、排行榜,取TopN操作 2、帶權重的消息隊列 |
Note:
可以使用debug object key_name來查看內部結構
string內部結構,在長度特別短時,使用embstr形勢存儲(embeded),而當長度超過44字節時,使用raw形勢存儲
set內部結構,當set放進去了非整數值時,存儲形勢立即從intset轉變成了hashtable
Redis為了節約內存空間使用,zset和hash容器對象在元素個數較少的時候,采用壓縮列表(ziplist)進行存儲。壓縮列表是一塊連續的存儲內存空間,元素之間緊挨存儲,沒有任何冗余空隙。
list內部結構,注意觀察encoding的值,quicklist是ziplist和linkedlist的混合體,它將linkedlist按段切分,每一段使用ziplist讓存儲緊湊,多個ziplist之間使用雙向指針串接起來。
Reference
https://www.redis.net.cn/order/