Redis基礎(chǔ)學(xué)習:五大數(shù)據(jù)類型總結(jié)通過之前的學(xué)習,我們已經(jīng)了解了 Redis 中五大數(shù)據(jù)類型相關(guān)的一些命令,通過這些命令操作其實也能知道這五種數(shù)據(jù)類型都能夠應(yīng)用在哪些場景中。但是,今天我們依然要總結(jié)一下,為什么呢?因為這五大數(shù)據(jù)類型是非常常見的面試題呀。 如果你在簡歷上寫了用過 Redis ,或者說寫了“精通” Redis 的話,那么大部分面試官第一個問題就是用過哪些數(shù)據(jù)類型,都用在什么場景解決了什么問題。當然,也有可能會問你 Redis 和 Memcached 之間的區(qū)別。即使是問區(qū)別,Redis 豐富的數(shù)據(jù)類型也是它和 Memcached 之間的一個重點區(qū)別之一。 既然如此的話,那么今天我們就來總結(jié)一下這五大數(shù)據(jù)類型。 String字符串類型,就是我們最常見也最常使用的 k/v 形式的數(shù)據(jù)類型啦。最基礎(chǔ)的緩存操作基本上都是基于這個數(shù)據(jù)類型的,同時在 Memcached 中也僅有這一種數(shù)據(jù)類型。你可以把它想象成我們程序代碼中的一個字符串變量,key 就是變量名,value 就是變量的值。這個變量被定義在 Redis 服務(wù)器中,可以指定它的過期時間,也可以永久保存,不跟隨程序的生命周期而結(jié)束。 對于 Redis 來說,字符串類型是二進制安全的,有 512M 的空間可以使用,也就是說,一個 key 可以存放最大 512M 的數(shù)據(jù)。同時,它也可以存儲二進制數(shù)據(jù),比如圖片或者文件之類的二進制內(nèi)容。 因此,我們可以直接緩存整個頁面、整張圖片、序列化后的 JSON 對象等等,前提是它們不會超過 512M 的大小。 List列表類型,或者說就是一個字符串列表,可以按照指定的順序添加元素。同樣的,將它想象成是我們 PHP 中的數(shù)組也是可以的,只不過這個數(shù)組同樣是在程序之外運行在 Redis 服務(wù)上的。 列表最重要的一點就是可以方便地實現(xiàn)隊列和棧的功能,它可以支持非??斓念^尾數(shù)據(jù)插入和彈出,但是如果是訪問中間的元素就非常慢了,畢竟這是一個鏈表實現(xiàn)的數(shù)據(jù)結(jié)構(gòu)。 要實現(xiàn)隊列,我們可以 LPUSH 之后 RPOP ,或者 RPUSH 之后 LPOP ,只要不是從同一邊 POP 出來數(shù)據(jù)就是一個隊列應(yīng)用。而棧的話,只要同邊操作就可以了,比如 LPUSH 之后 LPOP 。 更為方便的是使用阻塞操作,也就是 BLPOP/BRPOP ,之前在文章中也說過,在取隊列的時候,我們往往要用一個守護進程不停的 POP 新數(shù)據(jù),如果沒有新數(shù)據(jù)了一般會 sleep() 一會程序。但有了阻塞操作之后,其實我們就可以不用 sleep() 了,直接進行阻塞獲取就可以。 典型的應(yīng)用場景上面已經(jīng)說過了,就是隊列和棧的應(yīng)用。像我們實現(xiàn)微博的最新動態(tài)、消息之類的功能,就可以將用戶發(fā)布的最新數(shù)據(jù) PUSH 到 List 中。另外,發(fā)郵件、短信之類的耗時操作,都可以通過隊列實現(xiàn)解耦。當然,經(jīng)典的秒殺場景也是可以直接上隊列實現(xiàn)的。 如果你的項目本身不大,每秒請求入庫的量在幾千或者幾萬的情況下,使用 Redis 來實現(xiàn)隊列就足夠了,完全沒必要上專業(yè)的隊列服務(wù),比如 RabbitMQ 或者 Kafka 之類的。我之前最高的項目在最高峰有單機 2 萬并發(fā),每秒 2000 條左右的日志數(shù)據(jù)入 Redis 隊列,使用的是阿里云單機版4G的 Redis ,完全無壓力。(Redis理論讀寫可以達到 11萬/秒 和 8萬/秒 ,比 RabbitMQ 快) Hash哈希類型,這個類型怎么說好呢?想象成是一個對象吧。一個 key 是我們的變量名,然后里面又存儲了一堆鍵值對數(shù)據(jù),就像我們對象里面的屬性。或者叫它字典類型也是可以的,一個 key 里面的數(shù)據(jù)就像是一個數(shù)據(jù)字典。 對于一個少于 100 個字段的哈希類型來說,可以使用很少的空間來保存它,不過,哈希類型可以創(chuàng)建的字段數(shù)量遠比100個多,在可使用內(nèi)存的范圍內(nèi)你可以無限制的為它添加字段。話又說回來,其實這個意思也就是你可以創(chuàng)建很多哈希數(shù)據(jù),比如數(shù)據(jù)庫查詢出來的列表,不想使用序列化存儲成 String 或者 List 的話,那么就可以直接一個接一個的創(chuàng)建成 Hash 。在 PHP 中,直接使用 hGetAll 返回的就是一個數(shù)組,不需要再進行反序列化的操作,非常方便。 Set集合類型,同樣可以看成是數(shù)組,不過它是值不能重復(fù)的數(shù)組。也就說,它是完全符合數(shù)學(xué)上集合定義的一種數(shù)據(jù)類型。通過 Set 類型,可以非??焖俚靥砑?、刪除以及測試元素是否存在。一個集合可以包含 40 億個元素,同時,因為是集合,所以交、并、差的計算命令都已經(jīng)提供了,能夠方便地實現(xiàn)這些運算。 通過集合類型,我們可以方便地實現(xiàn)一些標簽操作,比如給文章打標簽,合并同類標簽之類的。另外還可以快速方便地獲取隨機的數(shù)據(jù),統(tǒng)計不重復(fù)的訪問IP等等。 Sorted Set有序集合,高大上了吧,在集合的基礎(chǔ)上加上了一個 score 分數(shù)的設(shè)置,從而讓集合實現(xiàn)有序排列。因為元素在插入的時候就會根據(jù)分數(shù)進行排序,所以可以很快地獲得當前集合中的一個有序列表。應(yīng)用場景不用我說大家也能想到了,排行榜、延時隊列等等。 假如我們使用 Hash 存儲了很多用戶的信息,這時候我們想按用戶的某一個屬性返回一個排行數(shù)據(jù),那么就可以將屬性設(shè)置為 score ,將 Hash 的 key 設(shè)置為值。比如用戶的年齡作為 score ,返回一個關(guān)于年齡的排行榜。當然,你直接把序列化后的整個用戶對象屬性全部放在值里也是沒問題的。 而對于延時隊列,則是在 ThinkPHP 的隊列組件中看到的,同時 Laravel 中的延時隊列也是用它實現(xiàn)的。分數(shù)使用時間戳,內(nèi)容保存的是隊列需要使用的數(shù)據(jù)。在彈出數(shù)據(jù)前,先查看時間是否到了,如果小于當前時間,就彈出這條數(shù)據(jù)并執(zhí)行相應(yīng)的操作,具體的源碼大家可以查閱 TP 的 think-queue 組件,這個比 Laravel 的看得要簡單一些。 總結(jié)基礎(chǔ)五大類型的內(nèi)容就到這里了,我們后面還將繼續(xù)學(xué)習其它基礎(chǔ)方面的知識,畢竟是從頭重新刷一遍文檔,所以小伙伴們也不要著急哦。高階面試八股文我們早晚也會學(xué)到,但是在這之前,基礎(chǔ)才是更重要的,畢竟我們要真正的把知識學(xué)到,而不是僅僅為了通過面試而已。 |
|
來自: 硬核項目經(jīng)理 > 《待分類》