日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

面试突击 | Redis 如何从海量数据中查询出某一个 Key?视频版

發(fā)布時(shí)間:2025/3/11 数据库 11 豆豆
生活随笔 收集整理的這篇文章主要介紹了 面试突击 | Redis 如何从海量数据中查询出某一个 Key?视频版 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

作者 | 王磊

面試突擊 | 第 001 期

1 考察知識(shí)點(diǎn)

本題考察的知識(shí)點(diǎn)有以下幾個(gè):

  • Keys 和 Scan 的區(qū)別

  • Keys 查詢的缺點(diǎn)

  • Scan 如何使用?

  • Scan 查詢的特點(diǎn)

  • 2 解答思路

  • Keys 查詢存在的問題

  • Scan 的使用

  • Scan 的特點(diǎn)

  • 3 Keys 使用相關(guān)

    1)Keys 用法如下

    2)Keys 存在的問題

  • 此命令沒有分頁功能,我們只能一次性查詢出所有符合條件的 key 值,如果查詢結(jié)果非常巨大,那么得到的輸出信息也會(huì)非常多;

  • keys 命令是遍歷查詢,因此它的查詢時(shí)間復(fù)雜度是 o(n),所以數(shù)據(jù)量越大查詢時(shí)間就越長。

  • 4 Scan 使用相關(guān)

    我們先來模擬海量數(shù)據(jù),使用 Pipeline 添加 10w 條數(shù)據(jù),Java 代碼實(shí)現(xiàn)如下:

    import redis.clients.jedis.Jedis; import redis.clients.jedis.Pipeline; import utils.JedisUtils;public class ScanExample {public static void main(String[] args) {// 添加 10w 條數(shù)據(jù)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);}// 執(zhí)行命令pipe.sync();System.out.println("數(shù)據(jù)插入完成");} }

    我們來查詢用戶 id 為 9999* 的數(shù)據(jù),Scan 命令使用如下:?

    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)

    從以上的執(zhí)行結(jié)果,我們看出兩個(gè)問題:

  • 查詢的結(jié)果為空,但游標(biāo)值不為 0,表示遍歷還沒結(jié)束;

  • 設(shè)置的是 count 10000,但每次返回的數(shù)量都不是 10000,且不固定,這是因?yàn)?count 只是限定服務(wù)器單次遍歷的字典槽位數(shù)量 (約等于),而不是規(guī)定返回結(jié)果的 count 值。

  • 相關(guān)語法:scan cursor [MATCH pattern] [COUNT count]

    其中:

    • cursor:光標(biāo)位置,整數(shù)值,從 0 開始,到 0 結(jié)束,查詢結(jié)果是空,但游標(biāo)值不為 0,表示遍歷還沒結(jié)束;

    • match pattern:正則匹配字段;

    • count:限定服務(wù)器單次遍歷的字典槽位數(shù)量 (約等于),只是對(duì)增量式迭代命令的一種提示 (hint),并不是查詢結(jié)果返回的最大數(shù)量,它的默認(rèn)值是 10。

    5 Scan 代碼實(shí)戰(zhàn)

    本文我們使用 Java 代碼來實(shí)現(xiàn) Scan 的查詢功能,代碼如下:

    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 參數(shù)ScanParams params = new ScanParams();params.count(10000);params.match("user_token_9999*");// 游標(biāo)String cursor = "0";while (true) {ScanResult<String> res = jedis.scan(cursor, params);if (res.getCursor().equals("0")) {// 表示最后一條break;}cursor = res.getCursor(); // 設(shè)置游標(biāo)for (String item : res.getResult()) {// 打印查詢結(jié)果System.out.println("查詢結(jié)果:" + item);}}} }

    以上程序執(zhí)行結(jié)果如下:

    查詢結(jié)果:user_token_99997

    查詢結(jié)果:user_token_9999

    查詢結(jié)果:user_token_99996

    查詢結(jié)果:user_token_99998

    查詢結(jié)果:user_token_99992

    查詢結(jié)果:user_token_99994

    查詢結(jié)果:user_token_99993

    查詢結(jié)果:user_token_99995

    查詢結(jié)果:user_token_99990

    查詢結(jié)果:user_token_99991

    查詢結(jié)果:user_token_99999

    6 總結(jié)

    通過本文我們了解到,Redis 中如果要在海量的數(shù)據(jù)數(shù)據(jù)中,查詢某個(gè)數(shù)據(jù)應(yīng)該使用 Scan,Scan?具有以下特征:

  • Scan 可以實(shí)現(xiàn) keys 的匹配功能;

  • Scan 是通過游標(biāo)進(jìn)行查詢的不會(huì)導(dǎo)致 Redis 假死;

  • Scan 提供了 count 參數(shù),可以規(guī)定遍歷的數(shù)量;

  • Scan 會(huì)把游標(biāo)返回給客戶端,用戶客戶端繼續(xù)遍歷查詢;

  • Scan 返回的結(jié)果可能會(huì)有重復(fù)數(shù)據(jù),需要客戶端去重;

  • 單次返回空值且游標(biāo)不為 0,說明遍歷還沒結(jié)束;

  • Scan 可以保證在開始檢索之前,被刪除的元素一定不會(huì)被查詢出來;

  • 在迭代過程中如果有元素被修改, Scan 不保證能查詢出相關(guān)的元素。

  • 7 視頻版

    【END】

    近期熱文

    ?
    • 阿里巴巴2020招聘正式啟動(dòng)!附內(nèi)推和微信聯(lián)系信息

    • 面試珍藏:最常見的200多道Java面試題(2019年最新版)

    • 阿里面試官給你的一些忠告,這樣做肯定錯(cuò)不了!附視頻

    • Java面試詳解(2020版):500+ 面試題和核心知識(shí)點(diǎn)詳解

    關(guān)注下方二維碼,訂閱更多精彩內(nèi)容

    朕已閱?

    總結(jié)

    以上是生活随笔為你收集整理的面试突击 | Redis 如何从海量数据中查询出某一个 Key?视频版的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。