在redis的介紹中,介紹redis的使用時,示例中就展現了部分的訪問jedis的方法,即對應着redis中的命令,如下着重介紹下redis命令。mysql
1、全局命令
keys * 查看全部鍵,*匹配任意字符多個字符,考慮到是單線程, 在生產環境不建議使用,若是鍵多可能會阻塞,採用如下漸進式遍歷,若是鍵少,能夠redis
keys *y //以結尾的鍵 sql
keys n*e //以n開頭以e結尾,返回name數據庫
keys n?me // ?問號表明只匹配一個字符 返回name,全局匹配 服務器
keys n?m* //返回name網絡
keys [j,l]* //返回以j l開頭的全部鍵併發
dbsize 查看的是當前所在redis數據庫的鍵總數,若量存在大量鍵,應禁止使用此指令運維
exists key 檢查鍵是否存在, 存在返回1,不然返回0dom
del key 刪除鍵,返回刪除鍵的個數,刪除不存在的鍵則返回0高併發
expire key seconds 設置鍵過時時間,單位是秒
ttl key 查看鍵剩餘的過時時間,和expire配合使用
type key 查看鍵的數據類型,鍵不存在則返回none
漸進式遍歷示例:
mset a a b b c c d d e e f f g g h h i i j j k k l l m m n n o o p p q q r r s s t t u u v v w w x x y y z z //初始化26個字母鍵值對
字符串類型:
scan 0 match n* count 20 //匹配以n開頭的鍵,取20條,第一次scan 0開始
第二次從遊標10開始取20個以n開頭的鍵,至關於一頁一頁的取,當最後返回0時,鍵被取完
注:漸進式遍歷可有效地解決keys命令可能產生的阻塞問題
除scan字符串外:還有如下
SCAN 命令用於迭代當前數據庫中的數據庫鍵。
SSCAN 命令用於迭代集合鍵中的元素。
HSCAN 命令用於迭代哈希鍵中的鍵值對。
ZSCAN 命令用於迭代有序集合中的元素(包括元素成員和元素分值)。
用法和scan同樣
2、Redis鍵管理
一、鍵重命名
rename oldKey newKey
rename oldKey newKey //若oldKey以前存在則被覆蓋
set name zhangsan;set name1 lisi//初始化數據
renamenx name name1//重命名失效,只有當name1不存在才能更名
二、返回隨機鍵
randomkey
三、鍵過時
expire name:03 20//鍵name:03 在10秒後過時
ttl name:03 //查看過時按秒倒計時,當返回-2說明已刪除
pttl name:03//查看過時按毫秒倒計時
set name:05 zhangsan
pexpire name:05 20000//20000毫秒(20s)後過時
expire name:06 -2 //直接過時,和del同樣
設置鍵在某個時間點過時,使用的是時間戳
expireat name:04 1566008420//設置在2019/8/17 10:20:20過時
時間轉時間戳:網址http://tool.chinaz.com/Tools/unixtime.aspx
hset user:01 name zhangsan //初始化數據
expire user:01 60 //設置60S後過時
ttl user:01 //查看過時剩餘時間
persist user:01 //去掉過時
ttl user:1 //返回-1 能夠永久查詢不失效
注意:對於字符串重設值後,expire無效,
set name zhangsan
expire name 50
ttl name
set name zhangsan1 //此時expire取消
ttl name //返回-1, 長期有效
四、鍵的遷移
把部分數據遷移到另外一臺redis服務器
1, move key db //reids有16個庫, 編號爲0-15
set name james1; move name 5 //遷移到第6個庫
select 5 ;//數據庫切換到第6個庫, get name 能夠取到james1
這種模式不建議在生產環境使用,在同一個reids裏能夠玩
2, dump key;
restore key ttl value//實現不一樣redis實例的鍵遷移,ttl=0表明沒有過時時間
例子:在A服務器上 192.168.1.111
set name james;
dump name; // 獲得"\x00\x05james\b\x001\x82;f\"DhJ"
在B服務器上:192.168.1.118
restore name 0 "\x00\x05james\b\x001\x82;f\"DhJ"
get name //返回james
3,migrate指令遷移到其它實例redis,在1.111服務器上將test移到118
migrate |
192.168.1.118 |
6379 |
test |
0 |
1000 |
copy |
replace |
keys |
指令 |
要遷移的目標IP |
端口 |
遷移鍵值 |
目標庫 |
超時時間 |
遷移後不刪除原鍵 |
無論目標庫是不存在test鍵都遷移成功 |
遷移多個鍵 |
3、設置和獲取鍵值的命令
set key value
get key
hset key field value [field value..]
hmget key field [field..]
lpush key value [value..]
rpush key value [value...]
lpop key
rpop key
sadd key member [member...]
srem key member [member...]
zadd key score member [score member...]
zscore key member 獲取分數
4、命令執行的順序
單線程執行:
執行過程:發送指令->執行命令->返回結果
執行命令:單線程執行,全部命令進入隊列,按順序執行,使用I/O多路複用解決I/O問題
單線程快緣由:純內存訪問,非阻塞I/O(使用多路複用),單線程避免線程切換和競爭產生資源消耗
5、Redis數據庫管理
select 0 //共16個庫, 0 --15, select切換數據庫
set name james
select 1
get name //隔離了,取不到,和mysql不一樣庫同樣
其中redis3.0之後的版本慢慢弱化了這個功能,如在redis cluster中只容許0數據庫
緣由:
- redis單線程,若是用多個庫,這些庫使用同一個CPU,彼此會有影響
- 多數據庫,調試與運維麻煩,如有一個慢查詢,會影響其它庫查詢速度
- 來回切換,容易混亂
flushdb: 只清空當前數據庫的鍵值對 dbsiz 0
flushall: 清空全部庫的鍵值對 (這兩個指令慎用!!!!)
6、Redis查詢分析
與mysql同樣:當執行時間超過閥值,會將發生時間耗時的命令記錄
redis命令生命週期:發送 排隊 執行 返回
若redis出現慢查詢,正常只會在執行階段出現,因此嘛查詢只統計第3個執行步驟的時間
預設閥值:兩種方式,默認爲10毫秒
1,動態設置6379:> config set slowlog-log-slower-than 10000 //10毫秒10000微秒
使用config set完後,若想將配置持久化保存到redis.conf,要執行config rewrite
2,redis.conf修改:找到slowlog-log-slower-than 10000 ,修改保存便可
注意:slowlog-log-slower-than =0記錄全部命令 -1命令都不記錄
原理:慢查詢記錄也是存在隊列裏的,slow-max-len 存放的記錄最大條數,好比設置的slow-max-len=10,當有第11條慢查詢命令插入時,隊列的第一條命令就會出列,第11條入列到慢查詢隊列中, 能夠config set動態設置,也能夠修改redis.conf完成配置。
2 命令:
獲取隊列裏慢查詢的命令:slowlog get 查詢返回的結構以下
獲取慢查詢列表當前的長度:slowlog len //返回7
對慢查詢列表清理(重置):slowlog reset //再查slowlog len 此時返回0 清空
對於線上slow-max-len配置的建議:線上可加大slow-max-len的值,記錄慢查詢存長命令時redis會作截斷,不會佔用大量內存,線上可設置1000以上
對於線上slowlog-log-slower-than配置的建議:默認爲10毫秒,根據redis併發量來調整,對於高併發比建議爲1毫秒
注意:
1,慢查詢只記錄命令在redis的執行時間,不包括排隊、網絡傳輸時間
2,慢查詢是先進先出的隊列,訪問日誌記錄出列丟失,需按期執行slow get,將結果存儲到其它設備中(如mysql)
6、管道
1.背景:
沒有pipeline以前,通常的redis命令的執行過程都是:發送命令-〉命令排隊-〉命令執行-〉返回結果。
多條命令的時候就會產生更多的網絡開銷
這個時候須要pipeline來解決這個問題:使用pipeline來打包執行N條命令,這樣的話就只需簡歷一次網絡鏈接,網絡開銷就少了
2. 使用pipeline和未使用pipeline的性能對比:
使用Pipeline執行速度與逐條執行要快,特別是客戶端與服務端的網絡延遲越大,性能體能越明顯
3.原生批命令(mset, mget)與Pipeline對比
1) 原生批命令是原子性,pipeline是非原子性, (原子性概念:一個事務是一個不可分割的最小工做單位,要麼都成功要麼都失敗。原子操做是指你的一個業務邏輯必須是不可拆分的. 處理一件事情要麼都成功要麼都失敗,其實也引用了生物裏概念,分子-〉原子,原子不可拆分)
2) 原生批命令一命令多個key, 但pipeline支持多命令(存在事務),非原子性
3) 原生批命令是服務端實現,而pipeline須要服務端與客戶端共同完成
4. pipeline正確使用方式:
使用pipeline組裝的命令個數不能太多,否則數據量過大,增長客戶端的等待時間,還可能形成網絡阻塞,能夠將大量命令的拆分多個小的pipeline命令完成
如:有300個命令須要執行,能夠拆分紅每30個一個pipeline執行
7、Redis事務
pipeline是多條命令的組合,爲了保證它的原子性,redis提供了簡單的事務;redis的事物與mysql事物的最大區別是redis事物不支持事物回滾
事務:事務是指一組動做的執行,這一組動做要麼都成功,要麼都失敗。
1. redis的簡單事務,將一組須要一塊兒執行的命令放到multi和exec兩個命令之間,其中multi表明事務開始,exec表明事務結束
2.中止事務discard
3. 命令錯誤,語法不正確,致使事務不能正常執行,即事物的原子性
4. watch命令:使用watch後, multi失效,事務失效,其餘的線程任然能夠對值進行修改
在客戶端1設置值使用watch監聽key並使用multi開啓事物,在客戶端2追加完c以後再來客戶端1追加redis,而後執行事物,能夠看到在客戶端1追加的redis沒有起效果:
客戶端1:
客戶端2: