redis是單線程的(4.0之前),keys查詢鍵類似hbase的全表掃描(也可以理解為select *),大數據量時非常耗時,因此官方給出了scan,使用scan類似數據庫分頁,可以指定查詢多少個元素,官網的說明是scan是一種遍歷,只不過可以用count指定每次查詢多少個元素
語法:scan cursor match pattern count num
cursor:游標,默認從0開始,每一次執行scan除了返回查詢結果還會返回游標的位置,即便某次查詢結果為空,並不能代表遍歷結束,只有當返回的游標為0時,才能代表遍歷結束
match:默認是 * ,匹配指定的元素
count:默認是10,redis的底層實現類似java的hashmap,都是hash表,所以真正存儲數據的是數組,count指定的是每次查詢數組多少個元素
綜上:scan查詢count數量的元素返回滿足match條件的結果
使用Jedis來操作redis
1 @Test 2 public void test2() { 3 Jedis jedis = new Jedis("192.168.101.101"); 4 System.out.println(jedis.ping()); 5
6
7 // 0 單次返回的結果為0並不代表遍歷結束,只有當返回的cursor為0時才代表遍歷結束
8 String cursor = ScanParams.SCAN_POINTER_START; 9
10 ScanParams params = new ScanParams(); 11 //默認的count數量為10,count並非限定返回結果的數量, 12 // 而是單次遍歷的數組元素數量(redis底層是hash表實現的,所以存放數據的是數組),返回其中匹配的元素 13 //當元素較多,而count設置的比較小時,此時會進行多次查詢
14 params.count(10); 15 params.match("u*"); 16
17 ScanResult<String> scanResult; 18 boolean flag = true; 19 while (flag) { 20 scanResult = jedis.scan(cursor, params); 21 cursor = scanResult.getCursor(); 22 if (Integer.parseInt(cursor) == 0) { 23 flag = false; 24 } 25 System.out.println(cursor); 26 scanResult.getResult().forEach(i -> System.out.println(i)); 27 } 28
29 jedis.close(); 30 }
類似的還有hscan(hash),zscan(zset),sscan(set),不再贅述
什么是二進制安全?比如你用word打開了一張圖片,顯示的是亂碼,如果你修改了這些亂碼,再用圖片查看器打開圖片時你會發現圖片打不開了,這個操作就是非二進制安全的
還有一個例子,寫入文件時如果寫入的編碼與文件編碼不一致,寫入之后會產生大量的無意義的亂碼,很容易導致文件無法正常顯示,c語言默認將空格作為字符串的結尾,這就導致c保存字符串時會出現內容丟失的問題,redis底層存儲字符串的是sds,雖然使用的是char類型的數組,但里面保存的卻是字節,此外redis沒有對字符串設定任何的過濾及修改,從這點上看redis是二進制安全的,可以存儲視頻,音頻,redis的字符串最大長度是512M,擴容的方式類似java中的hashmap,list等都是預先分配多余的空間,從而減少頻繁的內存分配帶來的性能開銷