最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

redis中數(shù)據(jù)模糊查詢scan用法詳解

 更新時間:2025年09月09日 09:31:01   作者:xswlw_guoquanbao  
Redis模糊查詢應避免KEYS,改用SCAN非阻塞迭代,優(yōu)先優(yōu)化鍵結(jié)構(gòu)(如IndexSet、SortedSet),提升效率,復雜場景可結(jié)合外部搜索引擎,平衡內(nèi)存、延遲及實時性需求,本文給大家介紹redis中數(shù)據(jù)模糊查詢scan用法,感興趣的朋友一起看看吧

redis中數(shù)據(jù)模糊查找-scan用法

1.查找方法

Redis中有一個經(jīng)典的問題,在巨大的數(shù)據(jù)量的情況下,做類似于查找符合某種規(guī)則的Key的信息,這里就有兩種方式,

一是keys命令,簡單粗暴,由于Redis單線程這一特性,keys命令是以阻塞的方式執(zhí)行的,keys是以遍歷的方式實現(xiàn)的復雜度是 O(n),Redis庫中的key越多,查找實現(xiàn)代價越大,產(chǎn)生的阻塞時間越長。

二是scan命令,以非阻塞的方式實現(xiàn)key值的查找,絕大多數(shù)情況下是可以替代keys命令的,可選性更強

2.keys命令

127.0.0.1:6379> keys s*
1) "s1"
2) "sddddf"
3) "sss"
4) "s358"
127.0.0.1:6379> 

3.scan命令

SCAN cursor [MATCH pattern] [COUNT count] 
cursor - 游標。
pattern - 匹配的模式。
count - 指定從數(shù)據(jù)集里返回多少元素,默認值為 10 。
可用版本
>= 2.8.0
 

示例:

127.0.0.1:6379> keys s*
1) "s1"
2) "sddddf"
3) "sss"
4) "s358"
127.0.0.1:6379> scan 0 match s* count 20
1) "0"
2) 1) "s1"
   2) "sss"
   3) "s358"
   4) "sddddf"
127.0.0.1:6379> scan 0 match s* count 2
1) "4"
2) 1) "s1"
127.0.0.1:6379> scan 4 match s* count 2
1) "1"
2) 1) "sss"
   2) "s358"
127.0.0.1:6379> scan 1 match s* count 2
1) "3"
2) 1) "sddddf"

SCAN 命令是一個基于游標的迭代器,每次被調(diào)用之后, 都會向用戶返回一個新的游標, 用戶在下次迭代時需要使用這個新游標作為 SCAN 命令的游標參數(shù), 以此來延續(xù)之前的迭代過程。

4.Java代碼中的實現(xiàn)

public Set<String> scan(String matchKey) {
    Set<String> keys = redisTemplate.execute((RedisCallback<Set<String>>) connection -> {
        Set<String> keysTmp = new HashSet<>();
        Cursor<byte[]> cursor = connection.scan(
                new ScanOptions.ScanOptionsBuilder().match("*" + matchKey + "*").count(1000).build()
        );
        while (cursor.hasNext()) {
            keysTmp.add(new String(cursor.next()));
        }
        return keysTmp;
    });
    return keys;
}

redis的模糊查詢提高效率

Redis 中進行模糊查詢(例如使用 KEYS pattern 或 SCAN cursor MATCH pattern)本質(zhì)上效率是相對較低的,尤其是在大型數(shù)據(jù)集上,因為 Redis 的核心優(yōu)勢在于通過精確鍵進行 O(1) 復雜度的快速訪問,而模糊查詢通常需要遍歷鍵空間。

提高 Redis 模糊查詢效率的核心策略是:避免在運行時進行全鍵空間掃描!

以下是一些有效的方法來提高效率或規(guī)避效率瓶頸:

?? 1. 避免使用 KEYS 命令 (最重要!)

  • 問題: KEYS 命令會阻塞 Redis 服務,直到遍歷完所有鍵并返回匹配結(jié)果。在生產(chǎn)環(huán)境的大數(shù)據(jù)集上,這可能導致服務不可用。
  • 解決方案: 絕對禁止 在生產(chǎn)環(huán)境使用 KEYS。使用 SCAN 替代。

?? 2. 使用 SCAN 命令進行迭代式查詢

原理: SCAN 命令使用游標(cursor)進行迭代,每次只返回一小部分匹配的鍵。它不會阻塞服務器,因為每次調(diào)用只占用少量時間。

優(yōu)點:

  • 非阻塞: 不會導致服務停頓。
  • 增量式: 可以分批處理結(jié)果,減輕客戶端和服務端壓力。

缺點:

  • 不是原子快照: 在迭代過程中,如果鍵空間發(fā)生變化(增、刪、改),可能會看到重復的鍵或遺漏部分鍵。這通??梢越邮?。
  • 整體耗時可能不短: 雖然每次調(diào)用快,但要獲取所有匹配結(jié)果,最終需要完成的“工作總量”和 KEYS 類似(都需要遍歷大部分或全部鍵空間)。
  • 客戶端邏輯復雜: 需要管理游標和循環(huán)。

用法:

SCAN 0 MATCH user:profile:*:email COUNT 100

0 是起始游標(第一次調(diào)用)。

MATCH pattern 指定模糊匹配模式(可選)。

COUNT n 建議每次迭代返回的元素數(shù)量(只是個提示,Redis 可能返回更多或更少)。適當增加 COUNT (如 500, 1000) 可以在網(wǎng)絡往返次數(shù)和單次耗時之間取得平衡,提高整體效率。

變種: SSCAN (掃描 Set), HSCAN (掃描 Hash), ZSCAN (掃描 Sorted Set)。這些用于掃描特定鍵內(nèi)部的大集合元素,避免阻塞或大結(jié)果集。

?? 3. 設(shè)計可查詢的鍵結(jié)構(gòu) (最重要的優(yōu)化方向!)

核心思想是將運行時掃描轉(zhuǎn)化為精確查找或小范圍查找。這通常需要犧牲一些存儲空間(空間換時間)和增加寫入/更新時的維護成本。

  • a) 使用索引集合 (Index Set):
    • 場景: 查詢具有特定前綴、后綴或中間部分的鍵(如 user:123:profileorder:abc:details)。
    • 方法:
      • 創(chuàng)建一個專門的 Set 類型鍵(如 index:user:ids)。
      • 每當創(chuàng)建一個新用戶鍵(如 SET user:123:profile {...}),同時將 123 添加到索引集合(SADD index:user:ids 123)。
      • 當需要查詢所有用戶鍵時,使用 SMEMBERS index:user:ids 或 SSCAN index:user:ids 獲取所有用戶 ID。
      • 客戶端拿到 ID 列表后,再通過精確鍵(GET user:<id>:profile)獲取數(shù)據(jù)。
    • 優(yōu)點: 獲取鍵列表非??欤∣(1) 或 O(N),N 是用戶數(shù)而非總鍵數(shù)),避免了全鍵掃描。
    • 缺點: 需要維護索引;占用額外內(nèi)存;獲取完整數(shù)據(jù)需要多次查詢(N+1 問題)。
  • b) 使用 Sorted Set 按模式存儲鍵或引用:
    • 場景: 需要按范圍(如時間范圍、分數(shù)范圍)查詢,或者需要排序。
    • 方法:
      • 創(chuàng)建一個 Sorted Set 鍵(如 zindex:orders:by_time)。
      • 成員(member)可以是:
        • 完整的鍵名(如 order:abc:details) - 適用于鍵名本身包含信息(如時間戳)。
        • 或一個唯一 ID(如 abc),分數(shù)(score)是查詢依據(jù)(如訂單創(chuàng)建時間戳)。
      • 當需要查詢某時間段內(nèi)的訂單:
        • 使用 ZRANGEBYSCORE zindex:orders:by_time start_timestamp end_timestamp 獲取鍵名或 ID。
        • 再通過精確鍵獲取數(shù)據(jù)。
    • 優(yōu)點: 支持高效的范圍查詢和排序。
    • 缺點: 維護索引;額外內(nèi)存;潛在 N+1 問題。
  •  使用 Hash 存儲子字段索引:

    • 場景: 需要根據(jù)對象內(nèi)部字段的值進行查詢(如查找所有 email 以 @gmail.com 結(jié)尾的用戶)。

    • 方法:

      創(chuàng)建輔助數(shù)據(jù)結(jié)構(gòu):

      • 反向索引(Inverted Index): 對于需要查詢的字段值(如郵箱后綴 gmail.com),創(chuàng)建一個 Set(如 index:email_suffix:gmail.com),存儲擁有該后綴的用戶 ID。

      更新數(shù)據(jù)時:

      • 修改用戶 Hash (HSET user:123 email new@domain.com)。

      • 將用戶 123 從舊后綴索引集移除(SREM index:email_suffix:old.com 123)。

      • 將用戶 123 添加到新后綴索引集(SADD index:email_suffix:new.com 123)。

      查詢時:SMEMBERS index:email_suffix:gmail.com 獲取用戶 ID 列表,然后 HGETALL user:<id>。

    • 優(yōu)點: 對于特定字段的等值查詢非常高效。

    • 缺點: 維護成本最高(尤其字段值頻繁更新時);占用大量額外內(nèi)存;只適用于等值查詢或有限模式(后綴=SADD 時存儲后綴);N+1 問題。

  • d) 拆分鍵名 + 利用集合操作:

    • 場景: 鍵名由多個部分組成(如 country:region:city:userid),需要按不同層級查詢。

    • 方法:

      為每個層級維護索引集:

      • countries = { 'us', 'uk', 'jp' ... }

      • regions:us = { 'ca', 'ny', 'tx' ... }

      • cities:us:ca = { 'sf', 'la', 'sd' ... }

      查詢用戶時:

      • 先通過精確鍵獲取國家列表、特定國家的地區(qū)列表、特定國家地區(qū)的城市列表。

      • 然后構(gòu)造出所有可能的鍵前綴(如 us:ca:sf)。

      • 最后用 SSCAN 遍歷 user:us:ca:sf:*(范圍大大縮小)。

    • 優(yōu)點: 將全鍵掃描縮小到特定小范圍掃描。

    • 缺點: 需要精心設(shè)計鍵結(jié)構(gòu)和索引;維護索引;可能仍需小范圍 SCAN。

?? 4. 緩存模糊查詢結(jié)果

  • 場景: 模糊查詢模式相對固定且結(jié)果變化不頻繁(如查詢所有“活躍用戶”列表)。
  • 方法: 定期(如每分鐘)或在數(shù)據(jù)變更時觸發(fā)一次 SCAN,將結(jié)果存入一個 Redis Set 或 List 中。
  • 查詢時: 直接讀取這個緩存的結(jié)果集合。
  • 優(yōu)點: 查詢速度極快(O(1) 或 O(N) 讀集合)。
  • 缺點: 數(shù)據(jù)不是實時最新(最終一致性);需要維護緩存更新邏輯;占用額外內(nèi)存。

?? 5. 使用外部索引/搜索引擎 (對于復雜查詢或海量數(shù)據(jù))

  • 原理: 當 Redis 內(nèi)置的查詢能力(即使是優(yōu)化后的索引)無法滿足復雜模式匹配(如全文搜索、多字段組合查詢)或數(shù)據(jù)量極大時。
  • 工具: Redis 官方模塊 RediSearchElasticsearchSolrOpenSearch 等。
  • 方法:
    • 數(shù)據(jù)寫入/更新 Redis 的同時,異步寫入索引到搜索引擎。
    • 查詢請求發(fā)送到搜索引擎,獲取匹配的鍵 ID 或文檔。
    • 根據(jù) ID 回 Redis 獲取完整數(shù)據(jù)(或搜索引擎已存儲所需數(shù)據(jù))。
  • 優(yōu)點: 提供極其強大和高效的全文搜索、復雜過濾、聚合分析能力;避免 Redis 自身遍歷。
  • 缺點: 系統(tǒng)架構(gòu)復雜度顯著增加;需要維護額外的服務;數(shù)據(jù)同步有延遲(異步);運維成本高。

?? 總結(jié)與建議

  • 絕對禁止 KEYS: 總是用 SCAN 替代。
  • 優(yōu)先考慮設(shè)計優(yōu)化: 這是最根本的解決方案。思考業(yè)務查詢需求,通過設(shè)計可查詢的鍵結(jié)構(gòu)(索引集合、Sorted Set、Hash 索引)將運行時模糊匹配轉(zhuǎn)化為精確查找或小范圍掃描。 這是“空間換時間”的經(jīng)典應用。
  • 合理使用 SCAN
    • 對于無法避免掃描的場景,務必用 SCAN。
    • 適當調(diào)整 COUNT 值(如 500-1000),在單次耗時和總網(wǎng)絡往返次數(shù)之間找到最佳平衡點。
    • 在客戶端處理好游標迭代。
  • 考慮緩存: 對結(jié)果變化慢、查詢頻繁的模式,緩存 SCAN 結(jié)果。
  • 評估外部索引: 當數(shù)據(jù)量大、查詢模式復雜、性能要求極高時,認真考慮引入 RediSearch 或 Elasticsearch 等專用搜索引擎。它們是為這類場景量身定制的。

關(guān)鍵權(quán)衡:

  • 內(nèi)存 vs CPU/延遲: 優(yōu)化設(shè)計(索引)會消耗更多內(nèi)存,但極大降低查詢延遲和 CPU 消耗(避免了遍歷)。
  • 寫入復雜度 vs 讀取復雜度: 維護索引增加了寫入/更新操作的復雜度(需要同時更新索引),但極大簡化并加速了讀取操作。
  • 實時性 vs 效率: 外部索引通常是異步更新,犧牲了一點實時性換取了強大的查詢能力和可擴展性。

選擇哪種策略取決于:

  • 你的數(shù)據(jù)規(guī)模
  • 查詢模式的復雜度和頻率
  • 對查詢延遲的要求
  • 對數(shù)據(jù)實時性的要求
  • 可接受的內(nèi)存開銷
  • 系統(tǒng)的復雜度容忍度

務必根據(jù)你的具體應用場景進行設(shè)計和選擇! 沒有放之四海而皆準的最優(yōu)解,但遵循“避免運行時掃描”的核心原則是關(guān)鍵。????

到此這篇關(guān)于redis中數(shù)據(jù)模糊查詢scan用法詳解的文章就介紹到這了,更多相關(guān)redis scan模糊查詢內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Redisson 加鎖解鎖的實現(xiàn)

    Redisson 加鎖解鎖的實現(xiàn)

    本文主要介紹了Redisson 加鎖解鎖的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-08-08
  • 詳解RedisTemplate下Redis分布式鎖引發(fā)的系列問題

    詳解RedisTemplate下Redis分布式鎖引發(fā)的系列問題

    這篇文章主要介紹了詳解RedisTemplate下Redis分布式鎖引發(fā)的系列問題,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-03-03
  • 基于Redis實現(xiàn)分布式鎖的三種方式

    基于Redis實現(xiàn)分布式鎖的三種方式

    在現(xiàn)代分布式系統(tǒng)中,多個節(jié)點同時操作共享資源是常見的情況,因此,分布式鎖成為了確保分布式系統(tǒng)中各節(jié)點協(xié)調(diào)一致、避免資源沖突的一個重要工具,本文將介紹三種常用的分布式鎖實現(xiàn)方式,需要的朋友可以參考下
    2026-02-02
  • 淺談Redis 緩存的三大問題及其解決方案

    淺談Redis 緩存的三大問題及其解決方案

    Redis 經(jīng)常用于系統(tǒng)中的緩存,這樣可以解決目前 IO 設(shè)備無法滿足互聯(lián)網(wǎng)應用海量的讀寫請求的問題。本文主要介紹了淺談Redis 緩存的三大問題及其解決方案,感興趣的可以了解一下
    2021-07-07
  • Spring?Boot?3.0x的Redis?分布式鎖的概念和原理

    Spring?Boot?3.0x的Redis?分布式鎖的概念和原理

    Redis?分布式鎖是一種基于?Redis?的分布式鎖解決方案,它的原理是利用?Redis?的原子性操作實現(xiàn)鎖的獲取和釋放,從而保證共享資源的獨占性,這篇文章主要介紹了適合?Spring?Boot?3.0x的Redis?分布式鎖,需要的朋友可以參考下
    2024-08-08
  • Redis源碼閱讀:Redis字符串SDS詳解

    Redis源碼閱讀:Redis字符串SDS詳解

    這篇文章主要介紹了Redis源碼閱讀:Redis字符串SDS,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • Redis Cluster的圖文講解

    Redis Cluster的圖文講解

    今天小編就為大家分享一篇關(guān)于Redis Cluster的圖文講解,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-01-01
  • 你了解Redis事務嗎

    你了解Redis事務嗎

    說到事務,大家會立刻想到Mysql的事務,所謂的事務就是對數(shù)據(jù)進行一系列的操作,要么都執(zhí)行成功,要么都執(zhí)行失敗,下面就介紹一下Redis如何實現(xiàn)事務,感興趣的可以了解一下
    2022-08-08
  • Redis實現(xiàn)客戶端緩存的4種方式

    Redis實現(xiàn)客戶端緩存的4種方式

    客戶端緩存是指在應用程序內(nèi)存中維護一份Redis數(shù)據(jù)的本地副本,以減少網(wǎng)絡請求次數(shù),降低延遲,并減輕Redis服務器負擔,本文將分享Redis客戶端緩存的四種實現(xiàn)方式,大家可以參考一下
    2025-05-05
  • ubuntu 16.04安裝redis的兩種方式教程詳解(apt和編譯方式)

    ubuntu 16.04安裝redis的兩種方式教程詳解(apt和編譯方式)

    這篇文章主要介紹了ubuntu 16.04安裝redis的兩種方式教程詳解(apt和編譯方式),需要的朋友可以參考下
    2018-03-03

最新評論

周宁县| 河源市| 随州市| 根河市| 宁蒗| 娱乐| 防城港市| 鸡东县| 肥西县| 霞浦县| 宜兰县| 南江县| 定边县| 阿图什市| 黄大仙区| 江山市| 汽车| 呼和浩特市| 武平县| 久治县| 安达市| 屯昌县| 万源市| 昌宁县| 甘肃省| 徐水县| 美姑县| 上高县| 伊金霍洛旗| 萍乡市| 来安县| 九江县| 灵台县| 博罗县| 亚东县| 额尔古纳市| 舟曲县| 乐东| 彰化县| 遂宁市| 读书|