Redis數據類型及實現

先列舉:java

五大類型:String、List、Hash、Set、Sorted Set、redis

其它: pubsub(應該算獨立功能吧?)、HyperLogLog(2.8.9+)、Geo(3.2+)、Stream(redis5+)數據庫

* * * redisObject * * *

redis中實現了不少自定義數據結構,但redis並無直接使用這些結構來構建k-v系統,而是使用這些結構建立了一個對象系統;這個對象系統包含了上面咱們列舉的字符串對象、列表對象、哈希對象、集合對象等等;服務器

注:本文假定閱讀者對於redis底層數據結構及實現有必定了解數據結構

注:底層數據結構包括: 簡單動態字符串SDS、鏈表linkedlist、跳躍表skiplist、壓縮列表ziplist、整數集合等等函數

使用對象的優勢性能

  • 執行命令前,方便根據對象類型判斷一個對象是否可執行給定的命令;
  • 針對不一樣的使用場景,爲對象設置多種不一樣的數據結構實現,以優化性能;
  • redis的對象系統還實現了基於引用計數技術的內存回收機制;
  • 經過引用計數,還實現了對象共享機制;
  • redis的對象帶有訪問時間記錄信息,可用於計算數據庫鍵的空轉時長,以輔助實現maxmemory;

redisObject學習

  • type:類型
    • REDIS_STRING: string
    • REDIS_LIST: list
    • REDIS_HASH: hash
    • REDIS_SET: set
    • REDIS_ZSET: zset
  • encoding:編碼,即底層數據結構的類型;
    • REDIS_ENCODING_INT:int = long型整數
    • REDIS_ENCODING_EMBSTR:embstr = embstr編碼的SDS
    • REDIS_ENCODING_RAW:raw = SDS
    • REDIS_ENCODING_HT:hashtable = 字典(哈希表)
    • REDIS_ENCODING_LINKEDLIST:linkedlist = 鏈表
    • REDIS_ENCODING_ZIPLIST:ziplist = 壓縮列表
    • REDIS_ENCODING_INTSET:intset = 整數集合
    • REDIS_ENCODING_SKIPLIST:skiplist = 跳躍表
  • ptr:指向底層數據結構實現的指針;

說明: redis是一個鍵值對系統,它的鍵老是字符串對象,值爲上述類型中聲明的對象類型(新版本有擴充),使用type命令可查看數據庫鍵的類型,實際就是數據庫鍵對應的值的類型;優化


-------- 快樂的分割線-------下面介紹五大類型 ----------------ui


String 字符串

redisObject的type爲REDIS_STRING,用type命令查詢,顯示string,編碼表示底層數據結構:

  • int: 若是一個字符串對像保存的是整數值,且該值可用long類型來表示,那麼該對象會將整數值保存在ptr屬性中(void*轉換爲long),並將encoding設置爲int
  • raw:字符串值(含浮點型),且長度大於32Byte(默認),那字符串對象將使用一個SDS來保存這個值,並將encoding設置爲raw
  • embstr:字符串值(含浮點型),且長度小於等於32字節,則使用embstr編碼的方式來保存

注1:embstr是一種專門保存短字符串的優化編碼,與raw同樣使用redisObject+sdshdr結構,區別是,raw調用兩次內存分配函數來分別建立redisObject結構和sdshdr結構,而embstr則調用一次內存分配函數來分配一塊連續的內存空間,該空間依次包含這兩種結構

注2:浮點型數據,在redis也是作爲字符串對象保存的,保存或者計算時會有一個類型轉換的過程

List 列表

能夠用ziplistlinkedlist表示,後來用quicklist(3.2+)

  • ziplist: 知足如下條件時使用壓縮列表作爲list的底層實現:
    • 全部元素字符串長度都小於64Byte(默認值)
    • 元素數量小於512
  • linkedlist: 不知足使用ziplist的條件時,使用linkedlist
  • quicklist: redis3.2開始支持的數據結構,是一個由ziplist組成的雙端列表,鏈表的每個節點都是一個ziplist,貌似3.2以後,list只用quicklist結構實現

list-max-ziplist-size:每一個ziplist(即quicklist的節點)大小,默認-2,此值可正可負,其中正數表示每一個壓縮列表中存放的最大元素個數,若是是負數,表示按字節數來限定元素個數:

  • -1 每一個節點的ziplist字節大小不能超過4kb
  • -2 每一個節點的ziplist字節大小不能超過8kb(默認值)
  • -3 每一個節點的ziplist字節大小不能超過16kb
  • -4 每一個節點的ziplist字節大小不能超過32kb
  • -5 每一個節點的ziplist字節大小不能超過64kb

Hash 哈希

編碼爲ziplisthashtable

  • ziplist 用兩個ziplist節點分別表示鍵和值,添加鍵值對時,先將鍵節點推入到表尾,再將值節點推入到表尾,所以鍵值對老是緊挨着且先加入的在表頭方向; 知足以下條件時使用ziplist作底層實現:
    • 全部鍵值對的鍵和值字符串的長度所有小於64Byte(默認值,配置項:hash-max-ziplist-value
    • 鍵值對數量小於512(默認值,配置項:hash-max-ziplist-entries
  • hashtable 不知足使用ziplist的條件時,將使用hashtable作爲底層結構

Set 集合

集合對象的編碼能夠是intset或者hashtable

  • intset 知足如下條件時用做集合的底層實現:
    • 集合對象保存的全部元素值都是整數值
    • 元素數量不超過512(默認值,配置項:set-max-intset-entries
  • hashtable 不適用intset時,使用hashtable作爲底層實現,使用hashtable時,只使用鍵,值爲Null,相似於java的HashSet

Sorted Set 有序集合

有序集合的編碼能夠是ziplistskiplist

  • ziplist:使用ziplist實現時,每一個有序集合元素使用挨在一塊兒的兩個ziplistNode表示,第一個表示元素成員member,第二個表示分值score;ziplist中的集合元素按分值從小到大排列,小的靠近表頭方向,大的靠近表尾方向;知足以下條件時使用:
    • 元素數量小於128(默認值,配置項:zset-max-ziplist-entries
    • 全部元素成員的長度小於64(默認值,配置項:zset-max-ziplist-value
  • skiplist 使用zset結構作爲底層實現,每一個zset同時包含一個字典dict和一個跳躍表skiplist:
    • skiplist :按分值從小到大保存了有序集合的元素,保證有序,提升範圍型操做性能
    • dict :字典則是爲每一個元素建立了成員到分值的映射,提供快速查找性能

:編碼爲skiplist時,跳躍表和字典會共享成員及分值,內存中只佔一分,由於不存在內存浪費;


----- 快樂的分割線 -------- 下面其它類型,還沒好好研究完---------


pubsub 發佈/訂閱

發佈/訂閱彷佛是一項獨立功能,不能算一種數據類型,不過從使用上差很少,估且也算在這兒吧;

redis的發佈/訂閱功能分爲兩類:頻道的發佈/訂閱及模式的發佈/訂閱;redis的服務器在redis內部用redisServer結構表示,而發佈訂閱的實現,依賴於redisServer中的兩個屬性:

  • 頻道(channel) pubsub_channels字典,字典的鍵表示被訂閱的頻道,而值是一個鏈表,存儲了全部訂閱該頻道的客戶端;
    • 訂閱:定位到頻道的訂閱鏈表,在表尾添加一個含訂閱客戶端的節點
    • 退訂:定位到頻道的訂閱鏈表,遍歷,找到含退訂客戶端的節點,刪除
    • 發佈:定位到頻道的訂閱鏈表,遍歷,依次發消息
  • 模式(patter) pubsub_patterns 鏈表,每一個節點都包含一個pubsubPattern結構,該結構中存儲了訂閱模式的客戶端和訂閱的模式;
    • 訂閱:建立一個pubsubPattern結構,添加到pubsub_patterns 鏈表尾
    • 退訂:遍歷pubsub_patterns,找到含要退訂的模式和客戶端的節點,刪除
    • 發佈:遍歷pubsub_patterns,向模式匹配的客戶發消息

注:訂閱將阻塞線程,應該在獨立線程獨立客戶端中使用;

HyperLogLog

使用type查詢一個HyperLogLog類型的值,是string,彷佛,是基於string結構實現的HyperLogLog功能?待探究

Geo

Stream

還沒有研究,且目前5.0版本中,做者不建議在生產環境中使用stream,因此學習後再補充


-------- 快樂的分割線------- 知識擴展 ----------------

相關文章
相關標籤/搜索