1.scan前言
從Redis v2.8開始,SCAN指令已經可用,它允許使用遊标從keyspace中檢索鍵。
對比KEYS指令,雖然SCAN無法一次性傳回所有比對結果,但是卻規避了阻塞系統這個高風險,進而也讓一些操作可以放在主節點上執行。
2.SCAN相關指令
- SCAN相關指令包括SSCAN 指令、HSCAN 指令和 ZSCAN 指令,分别用于集合、哈希鍵及有續集等
SCAN 指令用于疊代目前資料庫中的資料庫鍵。
SSCAN 指令用于疊代集合鍵中的元素。
HSCAN 指令用于疊代哈希鍵中的鍵值對。
ZSCAN 指令用于疊代有序集合中的元素(包括元素成員和元素分值)。
- 因為 SCAN 、 SSCAN 、 HSCAN 和 ZSCAN 四個指令的工作方式都非常相似, 要記住:
SSCAN 指令、 HSCAN 指令和 ZSCAN 指令的第一個參數總是一個資料庫鍵。
而 SCAN 指令則不需要在第一個參數提供任何資料庫鍵 —— 因為它疊代的是目前資料庫中的所有資料庫鍵。
3.基本用法:
指令格式:
SCAN cursor [MATCH pattern] [COUNT count]
指令解釋:scan 遊标 MATCH <傳回和給定模式相比對的元素> count 每次疊代所傳回的元素數量
SCAN指令是增量的循環,每次調用隻會傳回一小部分的元素。是以不會有KEYS指令的坑(key的數量比較多,一次KEYS查詢會block其他操作)。
SCAN指令傳回的是一個遊标,從0開始周遊,到0結束周遊。
通過scan中的MATCH <pattern> 參數,可以讓指令隻傳回和給定模式相比對的元素,實作模糊查詢的效果
示例:
scan 0 match DL* count 5
sscan myset 0 match f*

SCAN指令:Jedis用法:
@Test
public void testScan() {
// 建立一個jedis的對象。
Jedis jedis = new Jedis("192.168.112.65", 6379);
jedis.auth("zhifu123");
// 調用jedis對象的方法,方法名稱和redis的指令一緻。
ScanParams scanParams = new ScanParams();
scanParams.match("DL*");
scanParams.count(5);
jedis.select(1);
// scan(curso,params) cursor 表示開始周遊的遊标 params 是ScanParams 對象,此對象可以設定 每次傳回的數量,以及周遊時的正規表達式
// 需要注意的是,對元素的模式比對工作是在指令從資料集中取出元素之後,向用戶端傳回元素之前的這段時間内進行的,
// 是以如果被疊代的資料集中隻有少量元素和模式相比對,那麼疊代指令或許會在多次執行中都不傳回任何元素。
ScanResult<String> scan = jedis.scan("0", scanParams);
System.out.println("scan:傳回用于下次周遊的遊标"+scan.getStringCursor());
System.out.println("scan:傳回結果"+scan.getResult());
// 關閉jedis。
jedis.close();
}
4.傳回值:
SCAN 指令、 SSCAN 指令、 HSCAN 指令和 ZSCAN 指令都傳回一個包含兩個元素的 multi-bulk 回複:
- 回複的第一個元素是字元串表示的無符号 64 位整數(遊标)
SCAN 指令每次被調用之後, 都會向使用者傳回一個新的遊标, 使用者在下次疊代時需要使用這個新遊标作為 SCAN 指令的遊标參數, 以此來延續之前的疊代過程。
當 SCAN 指令的遊标參數被設定為 0 時, 伺服器将開始一次新的疊代, 而當伺服器向使用者傳回值為 0 的遊标時, 表示疊代已結束。
- 回複的第二個元素是另一個 multi-bulk 回複
這個 multi-bulk 回複包含了本次被疊代的元素。
注意:SCAN指令不能保證每次傳回的值都是有序的,另外同一個key有可能傳回多次,不做區分,需要應用程式去處理。
SCAN 指令傳回的每個元素都是一個資料庫鍵。
SSCAN 指令傳回的每個元素都是一個集合成員。
HSCAN 指令傳回的每個元素都是一個鍵值對,一個鍵值對由一個鍵和一個值組成。
ZSCAN 指令傳回的每個元素都是一個有序集合元素,一個有序集合元素由一個成員(member)和一個分值(score)組成。
參考來源:
http://redisdoc.com/key/scan.html#scan