keys和scan

KEYS pattern

查找所有符合給定模式pattern的key。

  1. keys * 匹配數(shù)據(jù)庫中所有的key。
  2. keys h?llo 匹配hello、hfllo、hkllo等。
  3. keys h*llo 匹配hllo、heeello、hddffllo等。
  4. keys h[ae]llo 匹配hello、hallo。

keys的速度非常快,但是一個(gè)大的數(shù)據(jù)里中使用它仍然可能造成性能問題。

SCAN cursor [MATCH pattern] [COUNT count]

SCAN命令及其相關(guān)的SSCAN命令、HSCAN命令和ZSCAN命令都用于增量地迭代一個(gè)元素集合:

  • SCAN命令用于迭代當(dāng)前數(shù)據(jù)庫中的數(shù)據(jù)庫鍵。
  • SSCAN命令用于迭代集合鍵中的元素。
  • HSCAN命令用于迭代哈希鍵中的鍵值對(duì)。
  • ZSCAN命令用于迭代有序集合中的元素(包括元素成員和元素分值)。

以上列出的四個(gè)命令都支持增量式迭代,它們每次執(zhí)行都只會(huì)返回少量元素,所以這些命令可以用于生產(chǎn)環(huán)境,而不會(huì)像KEYS命令、SMEMBERS命令帶來的問題----當(dāng)KEYS命令被用于處理一個(gè)大的數(shù)據(jù)庫時(shí),又或者SMEMBERS命令被用于處理一個(gè)大的集合鍵時(shí),它們可能會(huì)阻塞服務(wù)器達(dá)數(shù)秒之久,所以在生產(chǎn)環(huán)境,要禁用調(diào)類似命令。

不過,增量式迭代命令也不是沒有缺點(diǎn):舉個(gè)例子,使用SMEMBERS命令可以返回集合鍵當(dāng)前包含的所有元素,但是對(duì)于SCAN這類增量式迭代命令來說,因?yàn)樵趯?duì)鍵進(jìn)行增量式迭代的過程中,鍵可能會(huì)被修改,所以增量式迭代命令只能對(duì)被返回的元素提供有限的保證。

因?yàn)?strong>SCAN、SSCANHSCANZSCAN四個(gè)命令的工作方式非常相似,所以這個(gè)文檔會(huì)一并介紹這四個(gè)命令,但要記住:

  • SCAN命令、HSCAN命令和ZSCAN命令的第一個(gè)參數(shù)總是一個(gè)數(shù)據(jù)庫鍵。
  • SCAN命令則不需要在第一個(gè)參數(shù)提供任何數(shù)據(jù)庫鍵-----因?yàn)樗氖钱?dāng)前數(shù)據(jù)庫的所有鍵。

SCAN命令的基本用法

SCAN命令是一個(gè)基于游標(biāo)的迭代器:SCAN命令每次被調(diào)用后,都會(huì)向用戶返回一個(gè)新的游標(biāo),用戶在下次迭代時(shí)需要使用這個(gè)新游標(biāo)作為SCAN命令的游標(biāo)參數(shù),以此來延續(xù)之前的迭代過程。
當(dāng)SCAN命令的游標(biāo)參數(shù)被設(shè)置為0時(shí),服務(wù)器將開始一次新的迭代,而當(dāng)服務(wù)器向用戶返回值為0的游標(biāo)時(shí),表示迭代結(jié)束,注意服務(wù)器返回的游標(biāo)并不總是遞增的。

最簡(jiǎn)單的SCAN命令執(zhí)行示例:

127.0.0.1:6380> scan 0
1) "22"
2)  1) "key18"
    2) "key6"
    3) "key14"
    4) "key3"
    5) "key13"
    6) "key15"
    7) "EUA.DEPTPUSHTYPE.0"
    8) "key"
    9) "key4"
   10) "EUA.NONEEDLOGIN.0"
127.0.0.1:6380> scan 22
1) "15"
2)  1) "key7"
    2) "key16"
    3) "key8"
    4) "key1"
    5) "key12"
    6) "key11"
    7) "key17"
    8) "key9"
    9) "key19"
   10) "key5"
   11) "key2"
127.0.0.1:6380> scan 15
1) "0"
2) (empty list or set)
127.0.0.1:6380>

SCAN命令的保證

SCAN命令,以及其他增量式迭代命令,在進(jìn)行完整遍歷的情況下可以為用戶帶來以下保證:

從完整遍歷開始直到完整遍歷結(jié)束期間,一直存在于數(shù)據(jù)集中的所有元素都會(huì)被完整遍歷返回

因?yàn)樵隽渴降顑H僅使用游標(biāo)來記錄迭代狀態(tài),所以這些命令有以下缺點(diǎn):

  • 同一個(gè)元素可能會(huì)被返回多次。處理重復(fù)元素的工作交由應(yīng)用程序負(fù)責(zé),比如,可以考慮將迭代返回的元素僅僅用于可以安全地重復(fù)執(zhí)行多次的操作上;
  • 如果一個(gè)元素在迭代執(zhí)行過程中被添加進(jìn)數(shù)據(jù)集或者從數(shù)據(jù)集中刪除,那么這個(gè)元素可能會(huì)被遍歷到也可能不會(huì)被遍歷到,這是未定義的。

SCAN命令每次執(zhí)行返回的元素?cái)?shù)量

增量式迭代命令并不保證每次執(zhí)行都返回某個(gè)給定數(shù)量的元素。
增量式命令甚至可能會(huì)返回0個(gè)元素,但只要命令返回的游標(biāo)不是0,應(yīng)用程序就不應(yīng)該將迭代視作結(jié)束。
不過命令返回的元素?cái)?shù)量總是符合一定規(guī)則的,在實(shí)際中:

  • 對(duì)于一個(gè)大數(shù)據(jù)集來說,增量式迭代命令每次最多可能會(huì)返回?cái)?shù)十個(gè)元素;
  • 而對(duì)于一個(gè)足夠小的數(shù)據(jù)集來說,如果這個(gè)數(shù)據(jù)集的底層表示為編碼數(shù)據(jù)結(jié)構(gòu)(encoded data structure,適用于小集合鍵、小哈希鍵、小有序集合鍵),那么增量式迭代命令將在一次調(diào)用中返回?cái)?shù)據(jù)集中的所有元素。

最后,用戶可以通過增量式迭代命令提供的COUNT選項(xiàng)來指定每次迭代返回元素的最大值。

COUNT選項(xiàng)

雖然增量式迭代命令不保證每次迭代所返回的元素?cái)?shù)量,但是可以利用COUNT選項(xiàng),對(duì)命令的行為進(jìn)行一定程度上的調(diào)整。
基本上,COUNT選項(xiàng)的作用就是讓用戶告知迭代命令,在每次迭代中應(yīng)該從數(shù)據(jù)集中返回多少個(gè)元素。
雖然COUNT選項(xiàng)只是對(duì)增量式迭代命令的一種提示,但是大多數(shù)情況下,這種提示是有效的。

  • COUNT參數(shù)的默認(rèn)值是10.
  • 在迭代一個(gè)足夠大的,由哈希表實(shí)現(xiàn)的數(shù)據(jù)庫、集合鍵、哈希鍵、有序集合鍵時(shí),如果用戶沒有使用MATCH選項(xiàng),那么命令返回的元素?cái)?shù)量通常和COUNT選項(xiàng)指定的一樣,或者比COUNT選項(xiàng)指定的數(shù)量稍多一些。
  • 在迭代一個(gè)編碼為整數(shù)集合(intset,一個(gè)只由整數(shù)值構(gòu)成的小集合)、或者編碼為壓縮列表(ziplist,由不同值構(gòu)成的一個(gè)小哈希或者小有序集合)時(shí),增量式迭代命令通常會(huì)無視COUNT選項(xiàng)指定的值,在一次迭代就將數(shù)據(jù)集中包含的所有元素都返回給用戶

并非每次迭代都要使用相同的COUNT值
用戶可以在每次迭代中按自己的需要隨意改變COUNT值,只要記得將上次迭代的游標(biāo)用到下次迭代里面就可以了。

MATCH選項(xiàng)

和KEYS命令一樣,增量式迭代命令也可以通過提供一個(gè)glob風(fēng)格的模式參數(shù),讓命令只返回和給定模式匹配的元素,這一點(diǎn)可以通過在執(zhí)行增量式迭代命令時(shí),通過給定MATCH <pattern>參數(shù)來實(shí)現(xiàn)。

注意:對(duì)元素的模式匹配工作是在命令從數(shù)據(jù)集中取出元素之后,向客戶端返回元素之前這段時(shí)間內(nèi)進(jìn)行的,所以如果迭代的數(shù)據(jù)集中只有少量元素和模式匹配,那么迭代命令或許會(huì)在多次執(zhí)行中都不會(huì)返回任何元素。

并發(fā)執(zhí)行多個(gè)迭代

在同一時(shí)間,可以有任意多個(gè)客戶端對(duì)同一數(shù)據(jù)集進(jìn)行迭代,客戶端每次執(zhí)行迭代都需要傳入一個(gè)游標(biāo),并在執(zhí)行迭代之后獲得一個(gè)新的游標(biāo),而這個(gè)游標(biāo)就包含了迭代的所有狀態(tài),因此,服務(wù)器無須為迭代記錄任何狀態(tài)。

中途停止迭代

因?yàn)榈乃袪顟B(tài)都保存在游標(biāo)里面,而服務(wù)器無須為迭代保存任何狀態(tài),所以客戶端可以在中途停止一個(gè)迭代,而無須對(duì)服務(wù)器進(jìn)行任何通知。
即使有任意數(shù)量的迭代在中途停止,也不會(huì)產(chǎn)生任何問題。

使用錯(cuò)誤的游標(biāo)進(jìn)行增量式迭代

使用錯(cuò)誤的游標(biāo)來執(zhí)行增量式迭代,并不會(huì)造成服務(wù)器崩潰,但可能會(huì)讓命令產(chǎn)生未定義的行為。
未定義的行為指的是,增量式命令對(duì)返回值所做的保證可能會(huì)不再為真。
只有兩種游標(biāo)時(shí)合法的:

  1. 在開始一個(gè)新的迭代時(shí),游標(biāo)必須為0;
  2. 增量式迭代命令再執(zhí)行之后,用于延續(xù)迭代過程的游標(biāo)。

迭代終結(jié)的保證

增量式迭代命令所使用的算法只保證在數(shù)據(jù)集大小有界的情況下,迭代才會(huì)停止,也就是說,如果被迭代的數(shù)據(jù)集的大小不斷增長的話,增量式迭代命令可能永遠(yuǎn)也無法完成一次完整的迭代。

返回值:
SCAN命令、SSCAN命令、HSCAN命令和ZSCAN命令都返回一個(gè)包含兩個(gè)元素的multi-bulk回復(fù):第一個(gè)元素是字符串表示的無符號(hào)64位整數(shù),第二個(gè)元素是另一個(gè)multi-bulk回復(fù),這個(gè)回復(fù)包含了本次所迭代的元素。
SCAN 命令返回的每個(gè)元素都是一個(gè)數(shù)據(jù)庫鍵。
SSCAN命令返回的每個(gè)元素都是一個(gè)集合成員。
HSCAN 命令返回的每個(gè)元素都是一個(gè)鍵值對(duì),一個(gè)鍵值對(duì)由一個(gè)鍵和一個(gè)值組成。
ZSCAN命令返回的每個(gè)元素都是一個(gè)有序集合元素,一個(gè)有序集合元素由一個(gè)成員(member)和一個(gè)分值(score)組成。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容