【Redis深度歷險】那些年Redis的數據結構

【Redis深度歷險】那些年Redis的數據結構

Redis端口號6379的來源
Redis的端口號是6379,但這個端口號並不是隨機選擇的,源於"MERZ",這個單詞在手機當中的對應數字就是6379。"MERZ"在Redis作者Antirez的好友圈當中代表愚蠢的意思。

數據結構
Redis的key只能是字符串,value可以是String,Hash,List,Sorted Set(Zset)。

String
Redis的字符串是動態字符串(SDS Simple Dynamic String ),內部結構有點兒類似於java的ArrayList,都是採取預分配來減少內存的頻繁擴容。如圖len是實際字符串的長度,capacity是預分配的空間(數組容量)。創建字符串時,len和capacity一樣長,使用字節數組存放內容。

struct SDS {

T capacity; // 數組容量
T len; // 數組長度
byte flags; // 特殊標識位
byte[] content; // 數組內容

}

如果在1M以內,都是加倍擴充容量
如果超過1M則,每次擴容1M
字符串的最大容量是512M

String的一些基礎操作
普通get set
127.0.0.1:6379> set name amber
OK
127.0.0.1:6379> get name
"amber"
127.0.0.1:6379> exists name
(integer) 1
127.0.0.1:6379> del name
(integer) 1
127.0.0.1:6379> get name
(nil)
127.0.0.1:6379>
批量mset,mget
127.0.0.1:6379> set name amber
OK
127.0.0.1:6379> set name2 nick
OK
127.0.0.1:6379> mget name name2
1) "amber"
2) "nick"
127.0.0.1:6379> mset name3 wade name4 hellen
OK
127.0.0.1:6379> mget name name2 name3 name4
1) "amber"
2) "nick"
3) "wade"
4) "hellen"
127.0.0.1:6379>
設置過期時間
第一種 expire
127.0.0.1:6379> set name amber
OK
127.0.0.1:6379> expire name 5
(integer) 1
127.0.0.1:6379> get name
"amber"
//等待5s
127.0.0.1:6379> get name
(nil)
127.0.0.1:6379>
利用setex
setex name 時間 value
127.0.0.1:6379> setex name 5 amber
OK
127.0.0.1:6379> get name
"amber"
127.0.0.1:6379> get name
(nil)
127.0.0.1:6379>
自增自減
127.0.0.1:6379> set age 18
OK
127.0.0.1:6379> incr age
(integer) 19
127.0.0.1:6379> incrby age 5
(integer) 24
127.0.0.1:6379> incrby age -5
(integer) 19
127.0.0.1:6379> decr age
(integer) 18
127.0.0.1:6379>
List
Redis的list結構有點像Java中的LinkedList,但實際上地產不僅僅是簡單的linkedlist,底層是quicklist(太深入了等待作者以後學習...)

特點
list的插入刪除效率很高,時間複雜度爲O(1),但是索引的定位就很慢,即O(n)

操作
左進右出(隊列)
127.0.0.1:6379> lpush names amber nick wade
(integer) 3
127.0.0.1:6379> rpop names
"amber"
127.0.0.1:6379> rpop names
"nick"
127.0.0.1:6379> rpop names
"wade"
127.0.0.1:6379> rpop names
(nil)
127.0.0.1:6379>
當然你也可以左近左出(棧),可以自己實驗一下。

索引操作
lindex相當於java的get(int index)根據索引取值,但是因爲要遍歷鏈表,如果數據很大,導致開銷增大
ltrim key index1 index2 保留index1和index2之間的數據
127.0.0.1:6379> lpush names amber nick wade
(integer) 3
127.0.0.1:6379> lindex names 0
"wade"
127.0.0.1:6379> lindex names 1
"nick"
127.0.0.1:6379> lindex names 2
"amber"
127.0.0.1:6379> ltrim names 0 1
127.0.0.1:6379> lindex names 0
"wade"
127.0.0.1:6379> lindex names 1
"nick"
127.0.0.1:6379> lindex names 2
(nil)
127.0.0.1:6379>
hash(散列)
Redis的hash類似java中的HashMap

特點
Redis中的Hash進行rehash時區別於java中的HashMap。
在redis進行rehash時會同時保留新舊兩個結構,並在後續的定時任務當中慢慢把舊的數據移動到新數據。

操作
127.0.0.1:6379> hmset person name amber age 18
OK
127.0.0.1:6379> hgetall person
1) "name"
2) "amber"
3) "age"
4) "18"
127.0.0.1:6379> hget person name
"amber"
127.0.0.1:6379> hset person gender 1
(integer) 1
127.0.0.1:6379> hgetall person
1) "name"
2) "amber"
3) "age"
4) "18"
5) "gender"
6) "1"
set
Redis中的set相當於java中的HashSet,內部相當於實現了一個字典

特點
value唯一

操作
127.0.0.1:6379> sadd names amber
(integer) 1
127.0.0.1:6379> sadd names amber
(integer) 0
127.0.0.1:6379> sadd names nick wade
(integer) 2
127.0.0.1:6379> smembers names
1) "amber"
2) "wade"
3) "nick"
zset(sorted set)
Redis中的zset相當於java中sorted set和HashMap的結合。在set的基礎上還可以給value賦予score(排序的權重)

特點
zset因爲有score需要排序,但是採用普通的鏈表查找銷量過低。因此zst採用層級制度。有點類似於國家->省級->市->xxx。最底層的鄉鎮肯帝就是我們的L0層級了,所有的元素都串聯在一起,每個幾個元素就選出市位於L2,同樣的道理每隔幾個L2層級的元素就選出省位於L3層級。當我們插入新的節點的時候,只需要從最頂層開始進行查找定位到相應位置就行了。是不是有點兒像數組的二分查找。

操作
其實還有一些操作,不過這裏就不展示了

127.0.0.1:6379> zadd names 2 amber
(integer) 1
127.0.0.1:6379> zadd names 3 wade
(integer) 1
127.0.0.1:6379> zadd names 1 nick
(integer) 1
127.0.0.1:6379> zrange names 0 2
1) "nick"
2) "amber"
3) "wade"
127.0.0.1:6379>
數據結構知識點拓展
redis的所有數據結構都可以設置時間

  1. 設置時間
  2. key 時間
  3. 查看時間
  4. key

原文地址https://www.cnblogs.com/amberbar/p/11795805.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章