第四章 - 超越數(shù)據(jù)結(jié)構(gòu)

2018-02-24 16:17 更新

5種數(shù)據(jù)結(jié)構(gòu)組成了Redis的基礎(chǔ),其他沒有關(guān)聯(lián)特定數(shù)據(jù)結(jié)構(gòu)的命令也有很多。我們已經(jīng)看過一些這樣的命令:info,select,?flushdb,?multi,?exec,?discard,?watchkeys。這一章將看看其他的一些重要命令。

使用期限(Expiration)

Redis允許你標(biāo)記一個(gè)關(guān)鍵字的使用期限。你可以給予一個(gè)Unix時(shí)間戳形式(自1970年1月1日起)的絕對(duì)時(shí)間,或者一個(gè)基于秒的存活時(shí)間。這是一個(gè)基于關(guān)鍵字的命令,因此其不在乎關(guān)鍵字表示的是哪種類型的數(shù)據(jù)結(jié)構(gòu)。

expire pages:about 30
expireat pages:about 1356933600

第一個(gè)命令將會(huì)在30秒后刪除掉關(guān)鍵字(包括其關(guān)聯(lián)的值)。第二個(gè)命令則會(huì)在2012年12月31日上午12點(diǎn)刪除掉關(guān)鍵字。

這讓Redis能成為一個(gè)理想的緩沖引擎。通過ttl命令,你可以知道一個(gè)關(guān)鍵字還能夠存活多久。而通過persist命令,你可以把一個(gè)關(guān)鍵字的使用期限刪除掉。

ttl pages:about
persist pages:about

最后,有個(gè)特殊的字符串命令,setex命令讓你可以在一個(gè)單獨(dú)的原子命令里設(shè)置一個(gè)字符串值,同時(shí)里指定一個(gè)生存期(這比任何事情都要方便)。

setex pages:about 30 '<h1>about us</h1>....'

發(fā)布和訂閱(Publication and Subscriptions)

Redis的列表數(shù)據(jù)結(jié)構(gòu)有blpopbrpop命令,能從列表里返回且刪除第一個(gè)(或最后一個(gè))元素,或者被堵塞,直到有一個(gè)元素可供操作。這可以用來(lái)實(shí)現(xiàn)一個(gè)簡(jiǎn)單的隊(duì)列。

(譯注:對(duì)于blpopbrpop命令,如果列表里沒有關(guān)鍵字可供操作,連接將被堵塞,直到有另外的Redis客戶端使用lpushrpush命令推入關(guān)鍵字為止。)

此外,Redis對(duì)于消息發(fā)布和頻道訂閱有著一流的支持。你可以打開第二個(gè)redis-cli窗口,去嘗試一下這些功能。在第一個(gè)窗口里訂閱一個(gè)頻道(我們會(huì)稱它為warnings):

subscribe warnings

其將會(huì)答復(fù)你訂閱的信息?,F(xiàn)在,在另一個(gè)窗口,發(fā)布一條消息到warnings頻道:

publish warnings "it's over 9000!"

如果你回到第一個(gè)窗口,你應(yīng)該已經(jīng)接收到warnings頻道發(fā)來(lái)的消息。

你可以訂閱多個(gè)頻道(subscribe channel1 channel2 ...),訂閱一組基于模式的頻道(psubscribe warnings:*),以及使用unsubscribepunsubscribe命令停止監(jiān)聽一個(gè)或多個(gè)頻道,或一個(gè)頻道模式。

最后,可以注意到publish命令的返回值是1,這指出了接收到消息的客戶端數(shù)量。

監(jiān)控和延遲日志(Monitor and Slow Log)

monitor命令可以讓你查看Redis正在做什么。這是一個(gè)優(yōu)秀的調(diào)試工具,能讓你了解你的程序如何與Redis進(jìn)行交互。在兩個(gè)redis-cli窗口中選一個(gè)(如果其中一個(gè)還處于訂閱狀態(tài),你可以使用unsubscribe命令退訂,或者直接關(guān)掉窗口再重新打開一個(gè)新窗口)鍵入monitor命令。在另一個(gè)窗口,執(zhí)行任何其他類型的命令(例如getset命令)。在第一個(gè)窗口里,你應(yīng)該可以看到這些命令,包括他們的參數(shù)。

在實(shí)際生產(chǎn)環(huán)境里,你應(yīng)該謹(jǐn)慎運(yùn)行monitor命令,這真的僅僅就是一個(gè)很有用的調(diào)試和開發(fā)工具。除此之外,沒有更多要說的了。

隨同monitor命令一起,Redis擁有一個(gè)slowlog命令,這是一個(gè)優(yōu)秀的性能剖析工具。其會(huì)記錄執(zhí)行時(shí)間超過一定數(shù)量微秒的命令。在下一章節(jié),我們會(huì)簡(jiǎn)略地涉及如何配置Redis,現(xiàn)在你可以按下面的輸入配置Redis去記錄所有的命令:

config set slowlog-log-slower-than 0

然后,執(zhí)行一些命令。最后,你可以檢索到所有日志,或者檢索最近的那些日志:

slowlog get
slowlog get 10

通過鍵入slowlog len,你可以獲取延遲日志里的日志數(shù)量。

對(duì)于每個(gè)被你鍵入的命令,你應(yīng)該查看4個(gè)參數(shù):

  • 一個(gè)自動(dòng)遞增的id

  • 一個(gè)Unix時(shí)間戳,表示命令開始運(yùn)行的時(shí)間

  • 一個(gè)微妙級(jí)的時(shí)間,顯示命令運(yùn)行的總時(shí)間

  • 該命令以及所帶參數(shù)

延遲日志保存在存儲(chǔ)器中,因此在生產(chǎn)環(huán)境中運(yùn)行(即使有一個(gè)低閥值)也應(yīng)該不是一個(gè)問題。默認(rèn)情況下,它將會(huì)追蹤最近的1024個(gè)日志。

排序(Sort)

sort命令是Redis最強(qiáng)大的命令之一。它讓你可以在一個(gè)列表、集合或者分類集合里對(duì)值進(jìn)行排序(分類集合是通過標(biāo)記來(lái)進(jìn)行排序,而不是集合里的成員)。下面是一個(gè)sort命令的簡(jiǎn)單用例:

rpush users:leto:guesses 5 9 10 2 4 10 19 2
sort users:leto:guesses

這將返回進(jìn)行升序排序后的值。這里有一個(gè)更高級(jí)的例子:

sadd friends:ghanima leto paul chani jessica alia duncan
sort friends:ghanima limit 0 3 desc alpha

上面的命令向我們展示了,如何對(duì)已排序的記錄進(jìn)行分頁(yè)(通過limit),如何返回降序排序的結(jié)果(通過desc),以及如何用字典序排序代替數(shù)值序排序(通過alpha)。

sort命令的真正力量是其基于引用對(duì)象來(lái)進(jìn)行排序的能力。早先的時(shí)候,我們說明了列表、集合和分類集合很常被用于引用其他的Redis對(duì)象,sort命令能夠解引用這些關(guān)系,而且通過潛在值來(lái)進(jìn)行排序。例如,假設(shè)我們有一個(gè)Bug追蹤器能讓用戶看到各類已存在問題。我們可能使用一個(gè)集合數(shù)據(jù)結(jié)構(gòu)去追蹤正在被監(jiān)視的問題:

sadd watch:leto 12339 1382 338 9338

你可能會(huì)有強(qiáng)烈的感覺,想要通過id來(lái)排序這些問題(默認(rèn)的排序就是這樣的),但是,我們更可能是通過問題的嚴(yán)重性來(lái)對(duì)這些問題進(jìn)行排序。為此,我們要告訴Redis將使用什么模式來(lái)進(jìn)行排序。首先,為了可以看到一個(gè)有意義的結(jié)果,讓我們添加多一點(diǎn)數(shù)據(jù):

set severity:12339 3
set severity:1382 2
set severity:338 5
set severity:9338 4

要通過問題的嚴(yán)重性來(lái)降序排序這些Bug,你可以這樣做:

sort watch:leto by severity:* desc

Redis將會(huì)用存儲(chǔ)在列表(集合或分類集合)中的值去替代模式中的*(通過by)。這會(huì)創(chuàng)建出關(guān)鍵字名字,Redis將通過查詢其實(shí)際值來(lái)排序。

在Redis里,雖然你可以有成千上萬(wàn)個(gè)關(guān)鍵字,類似上面展示的關(guān)系還是會(huì)引起一些混亂。幸好,sort命令也可以工作在散列數(shù)據(jù)結(jié)構(gòu)及其相關(guān)域里。相對(duì)于擁有大量的高層次關(guān)鍵字,你可以利用散列:

hset bug:12339 severity 3
hset bug:12339 priority 1
hset bug:12339 details "{id: 12339, ....}"

hset bug:1382 severity 2
hset bug:1382 priority 2
hset bug:1382 details "{id: 1382, ....}"

hset bug:338 severity 5
hset bug:338 priority 3
hset bug:338 details "{id: 338, ....}"

hset bug:9338 severity 4
hset bug:9338 priority 2
hset bug:9338 details "{id: 9338, ....}"

所有的事情不僅變得更為容易管理,而且我們能通過severitypriority來(lái)進(jìn)行排序,還可以告訴sort命令具體要檢索出哪一個(gè)域的數(shù)據(jù):

sort watch:leto by bug:*->priority get bug:*->details

相同的值替代出現(xiàn)了,但Redis還能識(shí)別->符號(hào),用它來(lái)查看散列中指定的域。里面還包括了get參數(shù),這里也會(huì)進(jìn)行值替代和域查看,從而檢索出Bug的細(xì)節(jié)(details域的數(shù)據(jù))。

對(duì)于太大的集合,sort命令的執(zhí)行可能會(huì)變得很慢。好消息是,sort命令的輸出可以被存儲(chǔ)起來(lái):

sort watch:leto by bug:*->priority get bug:*->details store watch_by_priority:leto

使用我們已經(jīng)看過的expiration命令,再結(jié)合sort命令的store能力,這是一個(gè)美妙的組合。

小結(jié)

這一章主要關(guān)注那些非特定數(shù)據(jù)結(jié)構(gòu)關(guān)聯(lián)的命令。和其他事情一樣,它們的使用依情況而定。構(gòu)建一個(gè)程序或特性時(shí),可能不會(huì)用到使用期限、發(fā)布和訂閱或者排序等功能。但知道這些功能的存在是很好的。而且,我們也只接觸到了一些命令。還有更多的命令,當(dāng)你消化理解完這本書后,非常值得去瀏覽一下完整的命令列表

以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)