Redis中Scan命令的基本使用教程
前言
Redis中有一個經(jīng)典的問題,在巨大的數(shù)據(jù)量的情況下,做類似于查找符合某種規(guī)則的Key的信息,這里就有兩種方式,
一是keys命令,簡單粗暴,由于Redis單線程這一特性,keys命令是以阻塞的方式執(zhí)行的,keys是以遍歷的方式實(shí)現(xiàn)的復(fù)雜度是 O(n),Redis庫中的key越多,查找實(shí)現(xiàn)代價越大,產(chǎn)生的阻塞時間越長。
二是scan命令,以非阻塞的方式實(shí)現(xiàn)key值的查找,絕大多數(shù)情況下是可以替代keys命令的,可選性更強(qiáng)
以下寫入100000條key***:value***格式的測試數(shù)據(jù)(ps:用pipline的話,1w一筆,每一筆在秒級完成)
# -*- coding: utf-8 -*- # !/usr/bin/env python3 import redis import sys import datetime def create_testdata(): r = redis.StrictRedis(host='***.***.***.***', port=****, db=0, password='root') counter = 0 with r.pipeline(transaction=False) as p: for i in range(0, 100000): p.set('key' + str(i), "value" + str(i)) counter = counter + 1 if (counter == 10000): p.execute() counter = 0 print("set by pipline loop") if __name__ == "__main__": create_testdata()
比如這里查詢key111開頭的key有哪些?
若使用keys命令,則執(zhí)行keys key1111*,一次性全部查出來。
同樣,如果使用scan命令,則用scan 0 match key1111* count 20
scan的語法為:SCAN cursor [MATCH pattern] [COUNT count]The default COUNT value is 10
.
SCAN命令是一個基于游標(biāo)的迭代器。這意味著命令每次被調(diào)用都需要使用上一次這個調(diào)用返回的游標(biāo)作為該次調(diào)用的游標(biāo)參數(shù),以此來延續(xù)之前的迭代過程。
這里使用scan 0 match key1111* count 20
命令來完成這個查詢,稍顯意外的是,使用一開始都沒有查詢到結(jié)果,這個要從scan命令的原理來看。
scan在遍歷key的時候,0就代表第一次,key1111*代表按照key1111開頭的模式匹配,count 20中的20并不是代表輸出符合條件的key,而是限定服務(wù)器單次遍歷的字典槽位數(shù)量(約等于)。
那么,什么又叫做槽的數(shù)據(jù)?這個槽是不是Redis集群中的slot?答案是否定的。其實(shí)上圖已經(jīng)給出了答案了。
如果上面說的“字典槽”的數(shù)量是集群中的slot,又知道集群中的slot數(shù)量是16384,那么遍歷16384個槽之后,必然能遍歷出來所有的key信息,上面清楚地看到,當(dāng)遍歷的字典槽的數(shù)量20000的時候,游標(biāo)依舊沒有走完遍歷結(jié)果,因此這個字典槽并不等于集群中的slot的概念。
經(jīng)過測試,在scan的時候,究竟遍歷多大的COUNT值能完全match到符合條件的key,跟具體對象的key的個數(shù)有關(guān),
如果以超過key個數(shù)的count來scan,必定會一次性就查找到所有符合條件的key,比如在key個數(shù)為10W個的情況下,一次遍歷20w個字典槽,肯定能完全遍歷出來結(jié)果。
scan 指令是一系列指令,除了可以遍歷所有的 key 之外,還可以對指定的容器集合進(jìn)行遍歷。
zscan 遍歷 zset 集合元素,
hscan 遍歷 hash 字典的元素、
sscan 遍歷 set 集合的元素。
SSCAN 命令、 HSCAN 命令和 ZSCAN 命令的第一個參數(shù)總是一個數(shù)據(jù)庫鍵(某個指定的key)。
另外,使用redis desktop manager
的時候,當(dāng)刷新某個庫的時候,控制臺自動不斷刷新scan命令,也就知道它在干嘛了
參考:http://jinguoxing.github.io/redis/2018/09/04/redis-scan/
總結(jié)
以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,謝謝大家對腳本之家的支持。
相關(guān)文章
基于Redis的分布式鎖的簡單實(shí)現(xiàn)方法
這篇文章主要介紹了基于Redis的分布式鎖的簡單實(shí)現(xiàn)方法,Redis官方給出兩種思路,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-10-10Redis中有序集合的內(nèi)部實(shí)現(xiàn)方式的詳細(xì)介紹
本文主要介紹了Redis中有序集合的內(nèi)部實(shí)現(xiàn)方式的詳細(xì)介紹,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-03-03SpringMVC集成redis配置的多種實(shí)現(xiàn)方法
這篇文章主要介紹了SpringMVC集成redis配置的多種實(shí)現(xiàn)方法,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-03-03Redis鏈表底層實(shí)現(xiàn)及生產(chǎn)實(shí)戰(zhàn)
Redis 的 List 是一個雙向鏈表,鏈表中的每個節(jié)點(diǎn)都包含了一個字符串。是redis中最常用的數(shù)據(jù)結(jié)構(gòu)之一,本文主要介紹了Redis鏈表底層實(shí)現(xiàn)及生產(chǎn)實(shí)戰(zhàn),文中通過示例代碼介紹的非常詳細(xì),需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-03-03Redis五大基本數(shù)據(jù)類型及對應(yīng)使用場景總結(jié)
Redis有五種基本數(shù)據(jù)類型,分別是字符串(String)、哈希(Hash)、列表(List)、集合(Set)和有序集合(Sorted?Set),這些基本數(shù)據(jù)類型使得Redis具備了豐富的數(shù)據(jù)結(jié)構(gòu)和功能,適用于各種不同的應(yīng)用場景,本文就給大家詳細(xì)的介紹一下這五大類型2023-08-08