Redis快速扫描Scan
在平時我們維護線上Redis的時候需要從n個key里面找到某些特定規則的key,可能查看某些key可能清理某些不需要的key,可能我們第一印象就是keys這個指令,我們可以使用這個指令匹配我們想要的key,下面我們來試試。
keys指令基本用法
>?mset?name1?a?name2?a?na1me?a?na2me?aOK> keys name*1) "name"2) "name2"3) "name1"> keys na*me1) "name"2) "na1me"3)?"na2me"這個指令使用非常簡單,但是還是存在非常多的問題:
沒有一個類似獲取某幾條或某個區間的搜索,比如我只想要搜索第一條,比如我想分頁搜索獲取第一頁的10條數據。
keys的方法是遍歷整個redis樹,執行效率是O(n),所以當我們搜索的key非常龐大的時候。必須等到這個指令執行完后才能執行其他指令,redis搜索會延遲,這樣會阻塞其他指令或者延遲等問題。
所以針對這個問題,我們的Redis在2.8版本提出了scan這個指令,那么這個指令有哪些特色呢?
復雜度雖然也是O(n),但它是通過游標分步進行的,不會阻塞線程 。
提供limit參數,可以控制每次返回結果的最大條數,limit只是個hint,返回的結果可多可少。
同keys一樣,它也提供模式匹配功能。
服務器不需要為 游標保存狀態 ,游標的唯一狀態就是 scan 返回給客戶端的游標整數。
返回的結果可能會有重復,需要客戶端去重,這點非常重要。
遍歷的過程中如果有數據修改,改動后的數據能不能遍歷到是不確定的。
單次返回的結果是空的并不意昧著遍歷結束,而要看返回的游標值是否為零。
scan指令基本用法
..........漫長的添加數據> scan 0 match name* count 101) "30"2) 1) "name3" 2) "name9" 3) "name12" 4) "name" 5) "name6" 6) "name8" 7) "name11" 8) "name4" 9) "name2" 10) "name7"> scan 30 match name* count 101)?"0"????????????#游標為0,沒有數據了2) 1) "name10" 2) "name5" 3) "name1"scan遍歷原理
首先我們介紹redis整個模型,redis簡單來講其實就是一個大的字典,關于字典不了解的同學可以查看我的redis字典基礎。字典是由一維數組+鏈表構成,那么我們把這個一維數組叫做槽當然也有叫桶的,那么scan遍歷的時候就是遍歷這個槽,那么在上面我們發現有時候我們想返回10條記錄,但是redis返回的并沒有10條,這是因為我們的scan遍歷槽,每個槽下面不一定有鏈表或者鏈表值不一定只有一個,所以我們在有些時候使用scan返回的數據是不規則的就是這個原因。
關于scan的遍歷順序
scan的遍歷順序和我們普通的順序不同,普通方式就是從0->1->2->3....這樣遍歷下去,而scan的遍歷規則是反過來的,這樣的特殊遍歷方式是考慮到字典擴容和內存回收字典收縮時避免槽位重復或者沖突。scan指令擴展
scan指令是一系列指令,除了可以遍歷所有的key之外,還可以對指定的容器
集合進行遍歷。
比如zscan遍歷zset集合元素,hscan遍歷hash字典的元素,sscan遍歷set集合的元素。
它們的原理同scan類似,因為hash底層就是字典,set也是一個特殊的hash(所有的value指向同一個元素,zset內部也使用了字典來存儲所有的元素內容。
避免大key掃描
比如我們在操作hash或者zset的時候,它的底層實現是一個字典,我們知道當字典的值到達一定程度的時候就會擴容,每次擴容的時候都會開辟一個更大的內存空間,如果在集群環境中,這個key或被遷移或被刪除會影響系統性能導致系統卡頓現象,我們在運維redis系統的時候如果說redis內存大起大落的很有可能就是大key回收導致的。
那么我們在開發過程中如何避免呢?這里我們就需要用到scan指令了,對于掃描出來的每一個key,使用type指令獲得key的類型,然后使用相應數據結構的size或者len方法來得到它的大小,對于每一種類型,將大小排名的前若干名作為掃描結果展示出來。
上面這樣的過程需要編寫腳本,比較煩瑣,不過Redis官方已經在redis-cli指令
redis-cli?-h?127.0.0.1?-p?7001?--bigkeys -i 0.1?
?
一名正在搶救的coder
筆名:mangolove
CSDN地址:https://blog.csdn.net/mango_love
GitHub地址:https://github.com/mangoloveYu
?
總結
以上是生活随笔為你收集整理的Redis快速扫描Scan的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: rsync配置与报错总结
- 下一篇: 基于 Vue 的移动端富文本编辑器 vu