這篇文章主要介紹“redis命令怎么使用”,在日常操作中,相信很多人在Redis命令怎么使用問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”Redis命令怎么使用”的疑惑有所幫助!接下來,請跟著小編一起來學(xué)習(xí)吧!
成都創(chuàng)新互聯(lián)公司專注為客戶提供全方位的互聯(lián)網(wǎng)綜合服務(wù),包含不限于網(wǎng)站制作、成都網(wǎng)站制作、崇義網(wǎng)絡(luò)推廣、成都小程序開發(fā)、崇義網(wǎng)絡(luò)營銷、崇義企業(yè)策劃、崇義品牌公關(guān)、搜索引擎seo、人物專訪、企業(yè)宣傳片、企業(yè)代運營等,從售前售中售后,我們都將竭誠為您服務(wù),您的肯定,是我們最大的嘉獎;成都創(chuàng)新互聯(lián)公司為所有大學(xué)生創(chuàng)業(yè)者提供崇義建站搭建服務(wù),24小時服務(wù)熱線:028-86922220,官方網(wǎng)址:jinyejixie.com
阿粉負(fù)責(zé)的應(yīng)用是一個管理后臺應(yīng)用,權(quán)限管理使用 Shiro 框架,由于存在多個節(jié)點,需要使用分布式 Session,于是這里使用 Redis 存儲 Session 信息。
由于 Shiro 并沒有直接提供 Redis 存儲 Session 組件,阿粉不得不使用 Github 一個開源組件 shiro-redis。
由于 Shiro 框架需要定期驗證 Session 是否有效,于是 Shiro 底層將會調(diào)用 SessionDAO#getActiveSessions
獲取所有的 Session 信息。
而 shiro-redis
正好繼承 SessionDAO
這個接口,底層使用用keys
命令查找 Redis 所有存儲的 Session
key。
public Set<byte[]> keys(byte[] pattern){
checkAndInit();
Set<byte[]> keys = null;
Jedis jedis = jedisPool.getResource();
try{
keys = jedis.keys(pattern);
}finally{
jedis.close();
}
return keys;
}
找到問題原因,解決辦法就比較簡單了,github 上查找到解決方案,升級一下 shiro-redis
到最新版本。
在這個版本,shiro-redis
采用 scan
命令代替 keys
,從而修復(fù)這個問題。
public Set<byte[]> keys(byte[] pattern) {
Set<byte[]> keys = null;
Jedis jedis = jedisPool.getResource();
try{
keys = new HashSet<byte[]>();
ScanParams params = new ScanParams();
params.count(count);
params.match(pattern);
byte[] cursor = ScanParams.SCAN_POINTER_START_BINARY;
ScanResult<byte[]> scanResult;
do{
scanResult = jedis.scan(cursor,params);
keys.addAll(scanResult.getResult());
cursor = scanResult.getCursorAsBytes();
}while(scanResult.getStringCursor().compareTo(ScanParams.SCAN_POINTER_START) > 0);
}finally{
jedis.close();
}
return keys;
}
雖然問題成功解決了,但是阿粉心里還是有點不解。
為什么keys
指令會導(dǎo)致其他命令執(zhí)行變慢?
為什么Keys
指令查詢會這么慢?
為什么Scan
指令就沒有問題?
首先我們來看第一個問題,為什么keys
指令會導(dǎo)致其他命令執(zhí)行變慢?
回答這個問題,我們首先看下 Redis 客戶端執(zhí)行一條命令的情況:
站在客戶端的視角,執(zhí)行一條命令分為三步:
但是這僅僅客戶端自己以為的過程,但是實際上同一時刻,可能存在很多客戶端發(fā)送命令給 Redis,而 Redis 我們都知道它采用的是單線程模型。
為了處理同一時刻所有的客戶端的請求命令,Redis 內(nèi)部采用了隊列的方式,排隊執(zhí)行。
于是客戶端執(zhí)行一條命令實際需要四步:
由于 Redis 單線程執(zhí)行命令,只能順序從隊列取出任務(wù)開始執(zhí)行。
只要 3 這個過程執(zhí)行命令速度過慢,隊列其他任務(wù)不得不進(jìn)行等待,這對外部客戶端看來,Redis 好像就被阻塞一樣,一直得不到響應(yīng)。
所以使用 Redis 過程切勿執(zhí)行需要長時間運行的指令,這樣可能導(dǎo)致 Redis 阻塞,影響執(zhí)行其他指令。
接下來開始回答第二個問題,為什么Keys
指令查詢會這么慢?
回答這個問題之前,請大家回想一下 Redis 底層存儲結(jié)構(gòu)。
不太清楚朋友的也沒關(guān)系,大家可以回看一下阿粉之前的文章「阿里面試官:HashMap 熟悉吧?好的,那就來聊聊 Redis 字典吧!」。
這里阿粉復(fù)制之前文章內(nèi)容,Redis 底層使用字典這種結(jié)構(gòu),這個結(jié)構(gòu)與 Java HashMap 底層比較類似。
keys
命令需要返回所有的符合給定模式 pattern
的 Redis 中鍵,為了實現(xiàn)這個目的,Redis 不得不遍歷字典中 ht[0]
哈希表底層數(shù)組,這個時間復(fù)雜度為 「O(N)」(N 為 Redis 中 key 所有的數(shù)量)。
如果 Redis 中 key 的數(shù)量很少,那么這個執(zhí)行速度還是也會很快。等到 Redis key 的數(shù)量慢慢更加,上升到百萬、千萬、甚至上億級別,那這個執(zhí)行速度就會很慢很慢。
下面是阿粉本地做的一次實驗,使用 lua 腳本往 Redis 中增加 10W 個 key,然后使用 keys
查詢所有鍵,這個查詢大概會阻塞十幾秒的時間。
eval "for i=1,100000 do redis.call('set',i,i+1) end" 0
最后我們來看下第三個問題,為什么scan
指令就沒有問題?
這是因為 scan
命令采用一種黑科技-「基于游標(biāo)的迭代器」。
每次調(diào)用 scan
命令,Redis 都會向用戶返回一個新的游標(biāo)以及一定數(shù)量的 key。下次再想繼續(xù)獲取剩余的 key,需要將這個游標(biāo)傳入 scan 命令, 以此來延續(xù)之前的迭代過程。
簡單來講,scan
命令使用分頁查詢 redis 。
下面是一個 scan 命令的迭代過程示例:
scan
命令使用游標(biāo)這種方式,巧妙將一次全量查詢拆分成多次,降低查詢復(fù)雜度。
雖然 scan
命令時間復(fù)雜度與 keys
一樣,都是 「O(N)」,但是由于 scan
命令只需要返回少量的 key,所以執(zhí)行速度會很快。
最后,雖然scan
命令解決 keys
不足,但是同時也引入其他一些缺陷:
以上這些缺陷,在我們開發(fā)中需要考慮這種情況。
除了 scan
以外,redis 還有其他幾個用于增量迭代命令:
sscan
:用于迭代當(dāng)前數(shù)據(jù)庫中的數(shù)據(jù)庫鍵,用于解決
smembers
可能產(chǎn)生阻塞問題hscan
命令用于迭代哈希鍵中的鍵值對,用于解決
hgetall
可能產(chǎn)生阻塞問題。zscan
:命令用于迭代有序集合中的元素(包括元素成員和元素分值),用于產(chǎn)生
zrange
可能產(chǎn)生阻塞問題。到此,關(guān)于“Redis命令怎么使用”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識,請繼續(xù)關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編會繼續(xù)努力為大家?guī)砀鄬嵱玫奈恼拢?/p>
新聞標(biāo)題:Redis命令怎么使用
轉(zhuǎn)載源于:http://jinyejixie.com/article26/jpdscg.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供服務(wù)器托管、、定制網(wǎng)站、企業(yè)網(wǎng)站制作、網(wǎng)頁設(shè)計公司、建站公司
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)