一. 通用命令
1. 通用命令
# 1-keys
# 打印出所有key
keys *
# 打印出所有以he開頭的key
keys he*
# 打印出所有以he開頭,第三個字母是h到l的范圍
keys he[h-l]
# 三位長度,以he開頭,?表示任意一位
keys he?
# keys命令一般不在生產環境中使用,生產環境key很多,時間復雜度為o(n),用scan命令
# 2-dbsize 計算key的總數
dbsize # redis內置了計數器,插入刪除值該計數器會更改,所以可以在生產環境使用,時間復雜度是o(1)
# 3-exists key 時間復雜度o(1)
# 設置a
set a b
# 返回存在的“a”的數量.
exists a
(integer) 1
# 4-del key 時間復雜度o(1)
刪除成功返回1,key不存在返回0
# 5-expire key seconds 時間復雜度o(1)
expire name 3 # 設置鍵值name過期時間為3s
ttl name # 查看name還有多長時間過期. -1表示永不過期
persist name # 去掉name的過期時間
# 6-type key 時間復雜度o(1)
type name # 查看name類型,返回string
# 7-其他
info # 查看內存,cpu,主從相關
client list # 查看正在連接的會話
client kill ip # 查看IP端口
dbsize # 總共有多少個key
flushall # 清空所有
flushdb # 只清空當前庫
select 數字 # 選擇某個庫 總共16個庫(范圍: 0~15)
monitor # 記錄操作日志,夯住(應用: 自動化運維的日志的審計)
2. 數據結構和內部編碼
3. 單線程架構
1) 單線程架構: 一瞬間只會執行一條命令
2) 單線程為什么這么快
1. 純內存
2. 非阻塞IO (epoll),自身實現了事件處理,不在網絡io上浪費過多時間
3. 避免線程間切換和競態消耗
3) 注意
1. 一次只運行一條命令
2. 拒絕長慢命令
keys,flushall, flushdb, 慢的lua腳本, mutil/exec, operate, big value
3. 其實不是單線程(在做持久化是另外的線程, 只有在執行命令的時候是單線程)
fysnc file descriptor
close file descriptor
二. 字符串類型
1. 字符串鍵值結構
# 注意: 字符串value不能大於512m,一般建議100k以內
# 作用: 用於緩存,計數器,分布式鎖...
key value
hello world 可以很復雜,如json格式字符串
counter 1 數字類型
bits 10101010 二進制(位圖)
2. 常用命令
# 1---基本使用get,set,del
get name # 時間復雜度 o(1)
set name yang # 時間復雜度 o(1)
del name # 時間復雜度 o(1)
# 2---其他使用incr,decr,incrby,decrby
'''
# 自增作用
1. 統計網站訪問量,頁面訪問量,接口訪問量(單線程無競爭,天然適合做計數器)
2. 緩存mysql的信息(json格式)
3. 分布式id生成(多個機器同時並發着生成,不會重復)
'''
incr age # 對age這個key的value值自增1
decr age # 對age這個key的value值自減1
incrby age 10 # 對age這個key的value值增加10
decrby age 10 # 對age這個key的value值減10
# 3---set,setnx,setxx
set name yang # 不管key是否存在,都設置
setnx name yang # key不存在時才設置(新增操作)
set name yang nx # 同上
set name yang xx # key存在,才設置(更新操作)
# 4---mget mset
'''
# 多次操作推薦使用mget: n次get和mget的區別
n次get時間 = n次命令時間 + n次網絡時間
mget時間 = 1次網絡時間 + n次命令時間
'''
mget key1 key2 key3 # 批量獲取key1,key2.。。時間復雜度o(n)
mset key1 value1 key2 value2 key3 value3 # 批量設置時間復雜度o(n)
# 5---其他:getset,append,strlen
getset name yangnb # 設置新值並返回舊值 時間復雜度o(1)
append name 666 # 將value拼接到舊的value之后 時間復雜度o(1)
strlen name # 計算字符串長度(注意中文) 時間復雜度o(1)
# 6---其他:incrybyfloat,getrange,setrange
incrybyfloat age 3.5 # 為age自增3.5,傳負值表示自減 時間復雜度o(1)
getrange key start end # 獲取字符串制定下標所有的值 時間復雜度o(1)
setrange key index value # 從指定index開始設置value值 時間復雜度o(1)
三. 哈希類型
1. 重要api
# 1---hget,hset,hdel
hget key field # 獲取hash key對應的field的value 時間復雜度為 o(1)
hset key field value # 設置hash key對應的field的value值 時間復雜度為 o(1)
hdel key field # 刪除hash key對應的field的值 時間復雜度為 o(1)
# 測試: user:1:info表示的是創建user目錄下id為1的文件中用的info作為key鍵存儲hash類型數據
hset user:1:info age 23
hget user:1:info ag
hset user:1:info name yang
hgetall user:1:info
hdel user:1:info age
# 2---hexists,hlen
hexists key field # 判斷hash key 是否存在field 時間復雜度為 o(1)
hlen key # 獲取hash key field的數量 時間復雜度為 o(1)
hexists user:1:info name
hlen user:1:info # 返回數量
# 3---hmget,hmset
hmget key field1 field2 ...fieldN # 批量獲取hash key 的一批field對應的值 時間復雜度是o(n)
hmset key field1 value1 field2 value2 # 批量設置hash key的一批field value 時間復雜度是o(n)
# 4--hgetall,hvals,hkeys
hgetall key # 返回hash key 對應的所有field和value 時間復雜度是o(n)
hvals key # 返回hash key 對應的所有field的value 時間復雜度是o(n)
hkeys key # 返回hash key對應的所有field 時間復雜度是o(n)
# 注意: 小心使用hgetall
# 1. 計算網站每個用戶主頁的訪問量
hincrby user:1:info pageview count # 不好
hincrby userinfopagecount user:1:info pageview count # 好
# 2. 緩存mysql的信息,直接設置hash格式
2. hash vs string
1) 相似的api
get | hget |
---|---|
set /sentnx | hset hsetnx |
del | hdel |
incr incrby dear decrby | hincrby |
mset | hmset |
mget | hmget |
2) 緩存三種方案
1. 直接json格式字符串
2. 每個字段一個key
3. 使用hash操作
3. 其他操作: hsetnx,hincrby,hincrbyfloat
# 設置hash key對應field的value(如果field# 已存在,則失敗),時間復雜度o(1)
hsetnx key field value
# hash key 對英的field的value自增 時間復雜度o(1)
hincrby key field intCounter
# hincrby 浮點數 時間復雜度o(1)
hincrbyfloat key field floatCounter
四. 列表類型
1. 列表特點
有序隊列,可以從左側添加,右側添加,可以重復,可以從左右兩邊彈出
1) API操作
插入操作
# rpush 從右側插入 時間復雜度為o(1~n)
rpush key value1 value2 ...valueN
# lpush 從左側插入 時間復雜度為o(1~n)
lpush key value1 value2 ...valueN
# linsert: 從元素value的前或后插入newValue 時間復雜度o(n) ,需要遍歷列表
linsert key before|after value newValue
linsert listkey before b java
linsert listkey after b php
刪除操作
# 從列表左側彈出一個item 時間復雜度o(1)
lpop key
# 從列表右側彈出一個item 時間復雜度o(1)
rpop key
# 根據count值,從列表中刪除所有value相同的項 時間復雜度o(n)
'''
count>0 # 從左到右,刪除最多count個value相等的項
count<0 # 從右向左,刪除最多 Math.abs(count)個value相等的項
count=0 # 刪除所有value相等的項
'''
lrem key count value
lrem listkey 0 a # 刪除列表中所有值a
lrem listkey -1 c # 從右側刪除1個c
# 按照索引范圍修剪列表 o(n)
key start end
ltrim listkey 1 4 # 只保留下表索引是1-4的元素
2) 查詢操作
lrange key start end # 包含end獲取列表指定索引范圍所有item o(n)
lrange listkey 0 2
lrange listkey 1 -1 # 獲取第一個位置到倒數第一個位置的元素
lindex key index # 獲取列表指定索引的item o(n)
lindex listkey 0
lindex listkey -1
llen key # 獲取列表長度
3) 修改操作
lset key index newValue # 設置列表指定索引值為newValue o(n)
lset listkey 2 ppp # 把第二個位置設為ppp
2. 實戰
實現timeLine時間軸功能,主要應用於微博關注的人,按時間軸排列,在列表中放入關注人的微博的即可
rpush 用戶狀態 用戶id1
rpush 用戶狀態 用戶id2
rpush 用戶狀態 用戶id3
3. 其他操作
blpop key timeout # lpop的阻塞版,timeout是阻塞超時時間,timeout=0為擁有不阻塞 o(1)
brpop key timeout # rpop的阻塞版,timeout是阻塞超時時間,timeout=0為擁有不阻塞 o(1)
# lpush+lpop實現棧的功能: 先進后出
lpush stack 1 2 3 4 # 4先進
lpop stact # 1
lpop stact # 2
lpop stact # 3
lpop stact # 4 # 4后出
# lpush+rpop實現隊列功能: 先進先出
lpush queue 1 2 3 4 # 4先進
rpop queue # 4 # 4先出
rpop queue # 3
rpop queue # 2
rpop queue # 1
# lpush+ltrim實現固定大小的列表
lpush fixation_list id1 id2 id3 id4
ltrim fixation_list 1 2 # 只保留列表中索引為1-2之間的數
# lpush+brpop實現簡單的消息隊列(先進先出)
lpush mq msg1 msg100 msg22 # msg22先進
brpop mq # msg22先進
brpop mq # brpop mq # msg22
brpop mq # msg1
五. 集合類型
1. 特點
無序,無重復,集合間操作(交叉並補)
2. API操作
sadd key element # 向集合key添加element(如果element存在,添加失敗) o(1)
srem key element # 從集合中的element移除掉 o(1)
scard key # 計算集合大小
sismember key element # 斷element是否在集合中
srandmember key count # 集合中隨機取出count個元素,不會破壞集合中的元素(應用: 抽獎)
spop key # 集合中隨機彈出一個元素(應用: 抽獎)
smembers key # 取集合中所有元素 ,無序,小心使用,會阻塞住 時間復雜度o(n)
sdiff user:1:follow user:2:follow # 算user:1:follow和user:2:follow的差集(作用: 關注)
sinter user:1:follow user:2:follow # 算user:1:follow和user:2:follow的交集
sunion user:1:follow user:2:follow # 算user:1:follow和user:2:follow的並集
sdiff|sinter|suion + store destkey... # 差集,交集,並集結果保存在destkey集合中
3. 實戰
# 抽獎系統:
通過spop來彈出用戶的id,活動取消,直接刪除
# 點贊,點踩,喜歡:
用戶如果點了贊,就把用戶id放到該條記錄的集合中
# 標簽:
給用戶/文章等添加標簽,sadd user:1:tags 標簽1 標簽2 標簽3
# 給標簽添加用戶,關注該標簽的人有哪些
# 共同好友:集合間的操作
4. 總結
# sadd:
可以做標簽相關
# spop/srandmember:
可以做隨機數相關
# sadd/sinter:
社交相關
六. 有序集合類型
1. 特點
# 有一個分值字段,來保證順序
key score value
user:ranking 1 yang
user:ranking 99 yang2
user:ranking 88 yang3
# 集合有序集合
集合:無重復元素,無序,element
有序集合:無重復元素,有序,element+score
# 列表和有序集合
列表:可以重復,有序,element
有序集合:無重復元素,有序,element+score
2. API使用
zadd key score element # score可以重復,可以多個同時添加,element不能重復 o(logN)
zrem key element # 刪除元素,可以多個同時刪除 o(1)
zscore key element # 獲取元素的分數 o(1)
zincrby key increScore element # 增加或減少元素的分數 o(1)
zomcrnu leu 12 element
zcard key # 返回元素總個數 o(1)
zrank key element # 返回element元素的排名(從小到大排)
zrange key 0 -1 # 返回排名,不帶分數 o(log(n)+m) n是元素個數,m是要獲取的值
zrange player:rank 0 -1 withscores # 返回排名,帶分數
zrangebyscore key minScore maxScore # 返回指定分數范圍內的升序元素 o(log(n)+m) n是元素個數,m是要獲取的值
zrangebyscore user:1:ranking 90 210 withscores # 獲取90分到210分的元素
zcount key minScore maxScore # 返回有序集合內在指定分數范圍內的個數 o(log(n)+m)
zremrangebyrank key start end # 刪除指定排名內的升序元素 o(log(n)+m)
zremrangebyrank user:1:rangking 1 2 # 刪除升序排名中1到2的元素
zremrangebyscore key minScore maxScore # 刪除指定分數內的升序元素 o(log(n)+m)
zremrangebyscore user:1:ranking 90 210 # 刪除分數90到210之間的元素
3. 實戰
排行榜:音樂排行榜,銷售榜,關注榜,游戲排行榜
4. 其他操作
zrevrank # 從高到低排序
10.0.0.100:6379> zrevrank youxu yang1
(integer) 2
zrevrange # 從高到低排序取一定范圍
10.0.0.100:6379> zrevrange youxu 0 -1
1) "yang3"
2) "yang2"
3) "yang1"
zrevrangebyscore # 返回指定分數范圍內的降序元素
10.0.0.100:6379> zrevrangebyscore youxu 3 0
1) "yang3"
2) "yang2"
3) "yang1"
zinterstore # 對兩個有序集合交集
zunionstore # 對兩個有序集合求並集
5. 總結
操作類型 | 命令 |
---|---|
基本操作 | zadd/ zrem/ zcard/ zincrby/ zscore |
范圍操作 | zrange/ zrangebyscore/ zcount/ zremrangebyrank |
集合操作 | zunionstore/ zinterstore |