String、Hash、List、Set和Zset。
等同於java中的, Map<String,String> string 是redis裏面的最基本的數據類型,壹個key對應壹個value。
應用場景 :String是最常用的壹種數據類型,普通的key/value存儲都可以歸為此類,如用戶信息,登錄信息和配置信息等;
實現方式 :String在redis內部存儲默認就是壹個字符串,被redisObject所引用,當遇到incr、decr等操作(自增自減等原子操作)時會轉成數值型進行計算,此時redisObject的encoding字段為int。
Redis雖然是用C語言寫的,但卻沒有直接用C語言的字符串,而是自己實現了壹套字符串。目的就是為了提升速度,提升性能。 Redis構建了壹個叫做簡單動態字符串(Simple Dynamic String),簡稱SDS。
Redis的字符串也會遵守C語言的字符串的實現規則,即 最後壹個字符為空字符。然而這個空字符不會被計算在len裏頭。
Redis動態擴展步驟:
Redis字符串的性能優勢
常用命令 :set/get/decr/incr/mget等,具體如下;
ps:計數器(字符串的內容為整數的時候可以使用),如 set number 1。
補充:
等同於java中的: Map<String,Map<String,String>> ,redis的hash是壹個string類型的field和value的映射表, 特別適合存儲對象。 在redis中,hash因為是壹個集合,所以有兩層。第壹層是key:hash集合value,第二層是hashkey:string value。所以判斷是否采用hash的時候可以參照有兩層key的設計來做參考。並且註意的是, 設置過期時間只能在第壹層的key上面設置。
應用場景 :我們要存儲壹個用戶信息對象數據,其中包括用戶ID、用戶姓名、年齡和生日,通過用戶ID我們希望獲取該用戶的姓名或者年齡或者生日;
實現方式 :Redis的Hash實際是內部存儲的Value為壹個HashMap,並提供了直接存取這個Map成員的接口。如,Key是用戶ID, value是壹個Map。 這個Map的key是成員的屬性名,value是屬性值 。這樣對數據的修改和存取都可以直接通過其內部Map的Key(Redis裏稱內部Map的key為field), 也就是通過 key(用戶ID) + field(屬性標簽) 就可以操作對應屬性數據。 當前HashMap的實現有兩種方式 :當HashMap的成員比較少時Redis為了節省內存會采用類似壹維數組的方式來緊湊存儲,而不會采用真正的HashMap結構,這時對應的value的redisObject的encoding為zipmap,當成員數量增大時會自動轉成真正的HashMap,此時redisObject的encoding字段為int。
常用命令 :hget/hset/hgetall等,具體如下:
等同於java中的 Map<String,List<String>> ,list 底層是壹個鏈表,在redis中,插入list中的值,只需要找到list的key即可,而不需要像hash壹樣插入兩層的key。 list是壹種有序的、可重復的集合。
應用場景 :Redis list的應用場景非常多,也是Redis最重要的數據結構之壹,比如twitter的關註列表,粉絲列表等都可以用Redis的list結構來實現;
實現方式 :Redis list的實現為壹個 雙向鏈表 ,即可以支持反向查找和遍歷,更方便操作,不過帶來了部分額外的內存開銷,Redis內部的很多實現,包括 發送緩沖隊列 等也都是用的這個數據結構。
常用命令 :lpush/rpush/lpop/rpop/lrange等,具體如下:
性能總結 :
它是壹個字符串鏈表,left、right都可以插入添加。
等同於java中的 Map<String,Set<String>> ,Set 是壹種無序的,不能重復的集合。並且在redis中,只有壹個key它的底層由hashTable實現的,天生去重。
應用場景 :Redis set對外提供的功能與list類似是壹個列表的功能,特殊之處在於set是可以自動去重的,當妳需要存儲壹個列表數據,又不希望出現重復數據時,set是壹個很好的選擇,並且 set提供了判斷某個成員是否在壹個set集合內的重要接口 ,這個也是list所不能提供的;如保存壹些標簽的名字。標簽的名字不可以重復,順序是可以無序的。
實現方式 :set 的內部實現是壹個 value永遠為null的HashMap,實際就是通過計算hash的方式來快速排重的,這也是set能提供判斷壹個成員是否在集合內的原因。
常用命令 :sadd/spop/smembers/sunion等,具體如下:
ZSet(Sorted Set:有序集合) 每個元素都會關聯壹個double類型的分數score,分數允許重復,集合元素按照score排序( 當score相同的時候,會按照被插入的鍵的字典順序進行排序 ),還可以通過 score 的範圍來獲取元素的列表。
應用場景 :Redis sorted set的使用場景與set類似,區別是set不是自動有序的,而sorted set可以 通過用戶額外提供壹個優先級(score)的參數來為成員排序,並且是插入有序的,即自動排序。 當妳需要壹個有序的並且不重復的集合列表,那麽可以選擇sorted set數據結構,比如twitter 的public timeline可以以發表時間作為score來存儲,這樣獲取時就是自動按時間排好序的。
底層實現 : zset 是 Redis 提供的壹個非常特別的數據結構,常用作排行榜等功能,以用戶 id 為 value ,關註時間或者分數作為 score 進行排序。實現機制分別是 zipList 和 skipList 。規則如下:
zipList:滿足以下兩個條件
skipList:不滿足以上兩個條件時使用跳表、組合了hash和skipList
為什麽用skiplist不用平衡樹?
主要從內存占用、對範圍查找的支持和實現難易程度這三方面總結的原因。
拓展:mysql為什麽不用跳表?
常用命令 :zadd/zrange/zrem/zcard等;
官網地址: /order/3685.html
壹般我們使用Hyperloglog做基數統計。
什麽是基數?就是壹個集合中不重復的數的個數。
集合A:{1,3,5,7,9,7}
集合B:{1,3,5,7,9}
AB集合的基數都是5
應用:統計網站的訪問量(壹個人訪問網站很多次仍然算作壹次)。
優點:占用的內存是固定的,找2^64次方個數的基數,只需要12KB內存。
缺點:有0.81%的錯誤率,可以忽略不計
概述: bitmap 存儲的是連續的二進制數字(0 和 1),通過 bitmap, 只需要壹個 bit 位來表示某個元素對應的值或者狀態,key 就是對應元素本身 。 我們知道 8 個 bit 可以組成壹個 byte,所以 bitmap 本身會極大的節省儲存空間。
應用場景: 適合需要保存狀態信息(比如是否簽到、是否登錄...)並需要進壹步對這些信息進行分析的場景。比如用戶簽到情況、活躍用戶情況、用戶行為統計(比如是否點贊過某個視頻)。
針對上面提到的壹些場景,這裏進行進壹步說明。
使用場景壹:用戶行為分析 很多網站為了分析妳的喜好,需要研究妳點贊過的內容。
使用場景二:統計活躍用戶
使用時間作為 key,然後用戶 ID 為 offset,如果當日活躍過就設置為 1
那麽我該如果計算某幾天/月/年的活躍用戶呢(暫且約定,統計時間內只有有壹天在線就稱為活躍),有請下壹個 redis 的命令
使用場景三:用戶在線狀態
對於獲取或者統計用戶在線狀態,使用 bitmap 是壹個節約空間效率又高的壹種方法。
只需要壹個 key,然後用戶 ID 為 offset,如果在線就設置為 1,不在線就設置為 0。
補充 :
巨人的肩膀:
blogs.com/Small-sunshine/p/11687809.html
/s/CMu7oXVIKp2s-PXTdMlimA