做者 | 王磊
面試突擊 | 第 001 期
1 考察知識點面試
本題考察的知識點有如下幾個:redis
Scan 查詢的特色
2 解答思路服務器
1)Keys 用法以下
微信
2)Keys 存在的問題ide
此命令沒有分頁功能,咱們只能一次性查詢出全部符合條件的 key 值,若是查詢結果很是巨大,那麼獲得的輸出信息也會很是多;
keys 命令是遍歷查詢,所以它的查詢時間複雜度是 o(n),因此數據量越大查詢時間就越長。
4 Scan 使用相關code
咱們先來模擬海量數據,使用 Pipeline 添加 10w 條數據,Java 代碼實現以下:視頻
import redis.clients.jedis.Jedis; import redis.clients.jedis.Pipeline; import utils.JedisUtils; public class ScanExample { public static void main(String[] args) { // 添加 10w 條數據 initData(); } public static void initData(){ Jedis jedis = JedisUtils.getJedis(); Pipeline pipe = jedis.pipelined(); for (int i = 1; i < 100001; i++) { pipe.set("user_token_" + i, "id" + i); } // 執行命令 pipe.sync(); System.out.println("數據插入完成"); } }
咱們來查詢用戶 id 爲 9999* 的數據,Scan 命令使用以下: blog
127.0.0.1:6379> scan 0 match user_token_9999* count 10000 1) "127064" 2) 1) "user_token_99997" 127.0.0.1:6379> scan 127064 match user_token_9999* count 10000 1) "1740" 2) 1) "user_token_9999" 127.0.0.1:6379> scan 1740 match user_token_9999* count 10000 1) "21298" 2) 1) "user_token_99996" 127.0.0.1:6379> scan 21298 match user_token_9999* count 10000 1) "65382" 2) (empty list or set) 127.0.0.1:6379> scan 65382 match user_token_9999* count 10000 1) "78081" 2) 1) "user_token_99998" 2) "user_token_99992" 127.0.0.1:6379> scan 78081 match user_token_9999* count 10000 1) "3993" 2) 1) "user_token_99994" 2) "user_token_99993" 127.0.0.1:6379> scan 3993 match user_token_9999* count 10000 1) "13773" 2) 1) "user_token_99995" 127.0.0.1:6379> scan 13773 match user_token_9999* count 10000 1) "47923" 2) (empty list or set) 127.0.0.1:6379> scan 47923 match user_token_9999* count 10000 1) "59751" 2) 1) "user_token_99990" 2) "user_token_99991" 3) "user_token_99999" 127.0.0.1:6379> scan 59751 match user_token_9999* count 10000 1) "0" 2) (empty list or set)
從以上的執行結果,咱們看出兩個問題:token
本文咱們使用 Java 代碼來實現 Scan 的查詢功能,代碼以下:ip
import redis.clients.jedis.Jedis; import redis.clients.jedis.Pipeline; import redis.clients.jedis.ScanParams; import redis.clients.jedis.ScanResult; import utils.JedisUtils; public class ScanExample { public static void main(String[] args) { Jedis jedis = JedisUtils.getJedis(); // 定義 match 和 count 參數 ScanParams params = new ScanParams(); params.count(10000); params.match("user_token_9999*"); // 遊標 String cursor = "0"; while (true) { ScanResult<String> res = jedis.scan(cursor, params); if (res.getCursor().equals("0")) { // 表示最後一條 break; } cursor = res.getCursor(); // 設置遊標 for (String item : res.getResult()) { // 打印查詢結果 System.out.println("查詢結果:" + item); } } } }
以上程序執行結果以下:
查詢結果:user_token_99997 查詢結果:user_token_9999 查詢結果:user_token_99996 查詢結果:user_token_99998 查詢結果:user_token_99992 查詢結果:user_token_99994 查詢結果:user_token_99993 查詢結果:user_token_99995 查詢結果:user_token_99990 查詢結果:user_token_99991 查詢結果:user_token_99999
6 總結
經過本文咱們瞭解到,Redis 中若是要在海量的數據數據中,查詢某個數據應該使用 Scan,Scan 具備如下特徵:
【END】
近期熱文
阿里巴巴2020招聘正式啓動!附內推和微信聯繫信息 面試珍藏:最多見的200多道Java面試題(2019年最新版) 阿里面試官給你的一些忠告,這樣作確定錯不了!附視頻 Java面試詳解(2020版):500+ 面試題和核心知識點詳解
關注下方二維碼,訂閱更多精彩內容