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> {
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. 設置時間
expire key 時間
2. 查看時間
ttl key