目錄
1、keys鍵命令缺點
2、引入scan命令
3、scan使用
- cursor整數值 用戶將遊標設置爲0,表示開始新一次的迭代
- pattern正則表達式
- count limit
- 默認10
- 注意這裏的limit並不是限定返回結果的數量,而是限定服務器單次遍歷的字典槽位數)
- 注意並非每次迭代都要使用相同的 COUNT 值。用戶可以在每次迭代中按自己的需要隨意改變 COUNT 值, 只要記得將上次迭代返回的遊標用到下次迭代裏面就可以了
- 使用了錯誤的遊標。使用間斷的(broken)、負數、超出範圍或者其他非正常的遊標來執行增量式迭代並不會造成服務器崩潰, 但可能會讓命令產生未定義的行爲。
- 遊標的合法值只有2個:
- 在開始一個新的迭代時, 遊標必須爲0;
- 使用前一次迭代命令返回的迭代遊標值。
- 下一次迭代遊標
- 本次迭代結果集(有可能爲空)
4、scan指令實例:
$ redis-cli scan 0 match key99* count 1000
1) "13912"
2) 1) "key997"
2) "key9906"
3) "key9957"
4) "key9902"
5) "key9971"
6) "key9935"
7) "key9958"
8) "key9928"
9) "key9931"
10) "key9961"
11) "key9948"
12) "key9965"
13) "key9937"
$ redis-cli scan 13912 match key99* count 1000
1) "5292"
2) 1) "key996"
2) "key9960"
3) "key9973"
4) "key9978"
5) "key9927"
6) "key995"
7) "key9992"
從上面的過程可以看到雖然設置的limit是1000,但是返回的結果只有 10 個左右。這是因爲因爲這個 limit 不是限定返回結果的數量,而是限定服務器單次遍歷的字典槽位數量(約等於)。所以如果將limit 設置爲 10,你會發現返回結果是空的,但是遊標值不爲零,意味着遍歷還沒結束。
如果將limit設置爲10,例如下:
$ redis-cli scan 0 match key99* count 10
1) "15360"
2) (empty list or set)
$ redis-cli scan 15360 match key99* count 10
1) "2304"
2) (empty list or set)
4、更多scan指令
scan 指令是一系列指令,除了可以遍歷所有的 key 之外,還可以對指定的容器集合進行遍歷。’
- SCAN 命令用於迭代當前數據庫中的數據庫鍵,
- zscan 遍歷 zset 集合元素,
- hscan 遍歷 hash 字典的鍵值對,
- sscan 遍歷 set 集合的元素。
注意,SSCAN 命令、 HSCAN 命令和 ZSCAN 命令的第一個參數總是一個數據庫鍵。而 SCAN 命令則不需要在第一個參數提供任何數據庫鍵 —— 因爲它迭代的是當前數據庫中的所有數據庫鍵。
5、允許中途停止迭代
因爲迭代的所有狀態都保存在遊標裏面, 而服務器無須爲迭代保存任何狀態, 所以客戶端可以在中途停止一個迭代, 而無須對服務器進行任何通知。即使有任意數量的迭代在中途停止, 也不會產生任何問題。
6、迭代什麼時候終結
當redis服務器向用戶返回值爲0的遊標時,表示迭代已結束,這是唯一迭代結束的判定方式,而不能通過返回結果集是否爲空判斷迭代結束。
同時增量式迭代命令所使用的算法只保證在數據集的大小有界(bounded)的情況下, 迭代纔會停止, 換句話說, 如果被迭代數據集的大小不斷地增長的話, 增量式迭代命令可能永遠也無法完成一次完整迭代。
7、時間複雜度
每次執行的複雜度爲 O(1),對數據集進行一次完整迭代的複雜度爲 O(N),其中 N 爲數據集中的元素數量。
8、參考資料
http://jinguoxing.github.io/redis/2018/09/04/redis-scan/
http://doc.redisfans.com/key/scan.html