一文回顧Reids五大對象(數據類型)

Redis 是一個高性能的分散式記憶體型資料庫,在中國外各大互聯網公司中都有著廣泛的使用,即使是一些非互聯網公司中也有著非常重要的適用場景,所以對 Redis 的掌握也成為後端工程師必備的基礎技能,在面試中,Redis早已成為老生常談的話題,而在實際工作中,我們更是每時每刻都需要和 Redis 打交道。因此熟練的掌握Redis技術棧的各種武功秘籍至關重要!

Redis提供了五種主要的對象(數據類型)供開發者使用,它提供了強大且實用的功能。然而實際開發中有大多數的開發者僅簡單會用Redis String的Get與Set。這就好比降龍十八掌,你只學會了一掌。在真正實戰對敵之時不免略顯單薄!這篇文章我們將回顧Redis這五大對象,以便於我們能夠在實戰中真正做到遊刃有餘。

一、字元串(終究是我扛下了所有)

字元串類型是Redis最基礎的數據結構,其他幾種數據結構都是在字元串類型基礎上構建的。字元串類型的值是字元串(簡單的字元串、複雜的字元串(例如JSON、XML))、數字(整數、浮點數),甚至是二進位(圖片、音頻、影片)等

字元串對象的內部編碼有3種 :intrawembstr。Redis會根據當前值的類型和長度來決定使用哪種編碼來實現。

  • int:如果一個字元串對象保存的是整數值,並且這個整數值可以用long類型來表示
  • raw:如果字元串對象保存的是一個字元串值,並且這個字元串值的長度大於32位元組
  • embstr:如果字元串對象保存的是一個字元串值,並且這個字元申值的長度小於等於32位元組

 reids字元串的使用場景是最為廣泛的,甚至有些對redis其它幾種對象不太熟悉的人,基本所有場景都會使用字元串(序列化一下直接扔進去),這讓本身很單純的字元串承受了它這個年紀本不該承受的重量。其實Redis的主要使用場景主要有以下幾種:

  1. 作為快取層,快取熱點數據
  2. Redis字元串可以自增自減的特性可以用來做計數器、限速器、自增ID生成等
  3. 分散式系統的Session共享
  4. 二進位數據的存儲

有關Redis字元串的更詳細的介紹,可以查看我的這篇文章。

Redis對象——字元串(String)

二、哈希(存儲對象我也行)

哈希對象用來存儲一組數據對。每個數據對又包含鍵值兩部分。

Redis-Hash

哈希對象也有兩種實現方式。ziplist(壓縮列表),hashtable(哈希表)

同樣,只有當存儲的數據量比較小的情況下,Redis 才使用壓縮列表來實現哈希對象。具體需要滿足兩個條件:

  • 字典中保存的鍵和值的大小都要小於 64 位元組;
  • 字典中鍵值對的個數要小於 512 個。

當不能同時滿足上面兩個條件的時候,Redis 就使用哈希表來實現哈希對象。

當存儲的內容是對象的時候,Redis 字元串對象的很多功能使用Redis 哈希對象也可以實現。如快取用戶資訊的時候,使用Redis哈希對象存儲,簡單直觀,如果使用合理可以減少記憶體空間的使用。但也有其缺點,就是要要控制哈希在ziplist和hashtable兩種內部編碼的轉換,hashtable會消耗更多記憶體。

此外,Redis 哈希對象還可以實現購物車、計數器等功能。

有關Redis哈希對象的更詳細的介紹,可以查看我的這篇文章。

Redis對象——哈希(Hash)

三、列表(棧和隊列我都行)

列表這種對象支援存儲一組有序的、不重複的數據。因為其有序性,它可以獲取指定範圍的元素列表、可以在O(1)的時間複雜度獲取指定索引下標的元素等。

在Redis3.2版本以前列表類型的內部編碼有兩種。當滿足下面兩個條件的時候,Redis 列表對象使用ziplist(壓縮列表)來實現。

  • 當列表的元素個數小於list-max-ziplist-entries配置(默認512個)

  • 當列表中每個元素的值都小於list-max-ziplist-value配置時(默認64位元組)

當列表類型無法滿足ziplist的條件時,Redis會使用linkedlist作為列表的內部實現。

而在Redis3.2版本開始對列表數據結構進行了改造,使用 quicklist 代替了 ziplist 和 linkedlist.

由於列表對象的有序且不可重複的特性,它比較適合用來做文章、商品等列表的存儲。

列表類型可以 lpush (左側push),同時又可以使用 rpop (右側彈出)(查詢並刪除)第一個元素,所以列表類型具有先進先出的特性,可以用來實現消息隊列。也可以lpush(左側push)->lpop(左側彈出),具有後進先出的特性,因此開發中需要使用棧的時候,我們也可以藉助列表對象來實現。
有關Redis列表對象的更詳細的介紹,可以查看我的這篇文章。

Redis對象——列表(List)

四、集合(標籤系統我在行)

集合對象 (Set) 是一個無序並唯一的鍵值集合。它的存儲順序不會按照插入的先後順序進行存儲。與列表所不同的是它存儲的數據是無序且不重複的。

集合對象的內部編碼也有兩種:intset(整數集合)與hashtable(哈希表)。當滿足下面兩個條件的時候集合對象使用intset來實現。

  • 集合中的元素都是整數
  • 集合中的元素個數小於set-maxintset-entries配置(默認512個)

不滿足上面兩個條件時集合對象使用hashtable來實現。

集合對象的主要幾個特性就是,無序、不可重複、支援並交差,因此可以用來做標籤系統。

而集合的 SPOP(隨機移除並返回集合中一個或多個元素)SRANDMEMBER(隨機返回集合中一個或多個元素) 命令可以幫助我們實現一個抽獎系統。

有關Redis集合對象的更詳細的介紹,可以查看我的這篇文章。

Redis對象——集合(Set)

五、有序集合(排起名來我最棒)

有序集合類型 (Sorted Set或ZSet) 相比於集合類型多了一個排序屬性 score(分值),對於有序集合 ZSet 來說,每個存儲元素相當於有兩個值組成的,一個是有序結合的元素值,一個是排序值。有序集合保留了集合不能有重複成員的特性(分值可以重複),但不同的是,有序集合中的元素可以排序。

有序集合是由 ziplist (壓縮列表)skiplist (跳躍表) 組成的。

當數據比較少時,有序集合使用的是 ziplist 存儲的,有序集合使用 ziplist 格式存儲必須滿足以下兩個條件:

  • 有序集合保存的元素個數要小於 128 個;
  • 有序集合保存的所有元素成員的長度都必須小於 64 位元組。

如果不能滿足以上兩個條件中的任意一個,有序集合將會使用 skiplist 結構進行存儲。

有序集合比較典型的使用場景就是排行榜系統例如學生成績的排名。某影片(部落格等)網站的用戶點贊、播放排名、電商系統中商品的銷量排名等

有關Redis有序集合對象的更詳細的介紹,可以查看我的這篇文章。

Redis對象——有序集合(ZSet)

小結

Redis提供了五種最基礎也是最常用的對象(數據類型):String、Hash、List、Set、ZSet。了解這五種對象的有助於我們更好的在日常開發中對Redis進行使用。而通過這篇文章我們可以看到每種對象都是通過多種數據結構來實現的,大家可以思考一下為什麼。

—–END—–

Tags: