redis指令keys指令用于列出所有滿足特定正則字串規則的key
兩個缺點:
- 沒有offset,limit引數,一次性吐出所有滿足條件的key
- 演算法是遍歷演算法,復雜度是O(n),如果有千萬級以上的key,這個指令會導致redis卡頓,因為redis是單執行緒的
為了解決上訴問題redis在2.8中引入了scan,具有以下特點
- 雖然復雜度也是O(n),但是它通過游標分步進行,不會阻塞執行緒
- 提供limit引數,回傳結果可控
- 同樣具備匹配功能
- 回傳結果可能重復,需要客戶端去重
- 單次回傳的結果為空,不一定意味著遍歷結束,需要看游標值是否為0
scan引數:scan 0 match name* count 10
- cursor:回傳為0時將結果中第一個整數值作為下一次遍歷的cursor,一直遍歷到回傳的cursor值為0時結束
- key的正則模式:
- 遍歷的limit hint
127.0.0.1:6379> keys *
1) "name3"
2) "a1"
3) "name1"
4) "name2"
5) "age"
6) "codehole"
7) "dd"
8) "d"
9) "name"
10) "foo"
11) "a"
127.0.0.1:6379> scan 0 match name* count 10
1) "0"
2) 1) "name3"
2) "name1"
3) "name2"
4) "name"
127.0.0.1:6379> scan 0 match name* count 2
1) "4"
2) 1) "name3"
127.0.0.1:6379>
原理:
redis的所有key都存盤在一個很大的字典中,優點類似于java中的HashMap(一維陣列+二維鏈表),每次擴容空間加倍,
scan指令回傳的游標就是一維陣列的位置索引,我們將這個位置成為槽(slot),每次遍歷會將limit數量的槽位上掛接的所有鏈表元素進行模式匹配后回傳,可能為空!
遍歷演算法:高位進位加法


漸進式rehash
java的hashmap早擴容時會一次性將舊陣列下掛載的全部元素轉移到新陣列下面,如果hashmao中的元素特別多,執行緒就會出現卡頓,redis為了解決則個問題提出了漸進式rehash
原理:它會同時保存新舊兩個陣列,然后再定時任務中以及后續對hash的指令操作中漸漸的將舊陣列中掛接的元素遷移到新陣列中,這意味著要操作處于rehash中的字典,需要同事訪問新舊兩個陣列結構,如果在舊陣列下面找不到元素,還要去新陣列下面去尋找,
sacn也需要考慮這個問題,對于rehash中的欄位,他需要同時掃描新舊槽位,融合后回傳給客戶端,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/224127.html
標籤:其他
