Redis基礎(chǔ)學(xué)習(xí):通用命令(二)今天我們繼續(xù)學(xué)習(xí) Redis 剩余的一些通用命令。這些命令也都是非常簡(jiǎn)單的命令,而且更重要的是,今天的內(nèi)容是我們基礎(chǔ)部分的最后一篇了哦,大家可要卯足精神堅(jiān)持學(xué)完啦。 數(shù)據(jù)類型查看要查看一個(gè) KEY 的數(shù)據(jù)類型直接使用 TYPE 命令就可以,我們就以五大基礎(chǔ)數(shù)據(jù)類型為例。 還記得之前講過(guò)的 Bitmap、HyperLogLog、GEO 之類的類型或功能嗎?現(xiàn)在你可以試試用 TYPE 命令看看它們本質(zhì)上都是屬于哪種類型。 真正的內(nèi)部類型對(duì)象及調(diào)試上面使用 TYPE 看到的只是基本的數(shù)據(jù)類型,但其實(shí)在 Redis 的內(nèi)部,不同的數(shù)據(jù)類型還有更深層次的優(yōu)化。我們把每一個(gè) KEY 都看成是一個(gè)類型對(duì)象,就和在編程語(yǔ)言中的對(duì)象一樣。不同類型的 KEY 對(duì)象在使用的時(shí)候會(huì)根據(jù)條件再次選取不同類型的數(shù)據(jù)結(jié)構(gòu)。這些內(nèi)容,我們可以通過(guò) OBJECT 相關(guān)的命令看到,它是一個(gè)復(fù)合命令,包含下面這些子命令。 OBJECT ENCODING首先來(lái)看到的就是如何查看某個(gè)數(shù)據(jù)類型的真實(shí)數(shù)據(jù)存儲(chǔ)結(jié)構(gòu),使用的就是 OBJECT ENCODING 這個(gè)命令。從字面意思也可以看出,它是獲得對(duì)象的編碼類型。 這都是個(gè)啥?別怕,官網(wǎng)文檔中有解釋。
其實(shí)呀,就是如果某個(gè) Key 在數(shù)據(jù)量較小的情況下,會(huì)使用某一種數(shù)據(jù)結(jié)構(gòu),而內(nèi)部的數(shù)量量大的時(shí)候會(huì)使用另一種數(shù)據(jù)結(jié)構(gòu)。比如說(shuō)普通字符串是 raw ,但如果你這個(gè) KEY 中只是數(shù)字的話,那么它會(huì)使用 int 類型來(lái)保存。同樣的,較小的 LIST 會(huì)使用 ziplist ,而當(dāng)數(shù)據(jù)項(xiàng)超過(guò)一定數(shù)量或者某個(gè)數(shù)據(jù)項(xiàng)的內(nèi)容長(zhǎng)度非常大時(shí),就會(huì)變成 linkedlist 。這個(gè) linkedlist 大家應(yīng)該不陌生吧,就是鏈表的意思。所以 LIST 在頭尾插入和刪除的時(shí)候能達(dá)到 O(1) 的速度。 不過(guò)我們這里顯示出來(lái)的 LIST 的數(shù)據(jù)結(jié)構(gòu)是 quicklist ,它是 Redis3.2 引入的數(shù)據(jù)結(jié)構(gòu),是結(jié)合了 ziplist 和 linkedlist 的一種快速鏈表?,F(xiàn)在默認(rèn)情況下 LIST 都是使用 quicklist 這種結(jié)構(gòu)了。 光說(shuō)不練假把式,注意看上面的 c 這個(gè) Hash 的類型是 ziplist ,我們直接給它增加一個(gè)內(nèi)容比較長(zhǎng)的 field ,看看它的數(shù)據(jù)結(jié)構(gòu)會(huì)不會(huì)發(fā)生改變。 怎么樣,是不是發(fā)生變化了,一般來(lái)說(shuō),集合中超過(guò)多少個(gè)元素,或者某一個(gè)元素的內(nèi)容長(zhǎng)度大于多少個(gè)字節(jié),就無(wú)法使用 ziplist 這種數(shù)據(jù)結(jié)構(gòu)了。大家可以自己再拿 Set 或者 Sorted Set 試下哦。具體的內(nèi)容我們將在進(jìn)階系列的文章中再進(jìn)行深入的學(xué)習(xí)。 OBJECT REFCOUNTRedis 為了節(jié)省內(nèi)存會(huì)在初始化服務(wù)器時(shí),創(chuàng)建一萬(wàn)個(gè)字符串對(duì)象,這些對(duì)象包含了1到9999的所有整數(shù)值,當(dāng)服務(wù)器需要用到值為0到9999的字符串對(duì)象時(shí),服務(wù)器就會(huì)使用這些共享對(duì)象,而不是創(chuàng)建新的對(duì)象 OBJECT REFCOUNT 就是用來(lái)查看對(duì)象的線上服務(wù)情況的,它只對(duì)value >= 0 && value < OBJ_SHARED_INTEGERS 的數(shù)值類對(duì)象生效,除此之外的其他redis對(duì)象,都不會(huì)相互引用。 OBJECT IDLETIMEIDLE 一般指的是閑置、懶散的意思,很明顯,這個(gè)命令就是獲取指定的 KEY 從被存儲(chǔ)之后空閑的時(shí)間,以秒為單位的。 在上個(gè)例子中我們修改過(guò)了 a 的值,所以 a 的空閑時(shí)間發(fā)生了改變。 OBJECT FREQ最后這個(gè) FREQ 子命令返回的是在 LFU 淘汰算法下,對(duì)于某個(gè) KEY 的使用計(jì)數(shù)。 當(dāng) a 被使用了一次之后,這個(gè) KEY 下面的相關(guān)計(jì)數(shù)器就會(huì)加一。關(guān)于具體的淘汰算法的問(wèn)題我們?cè)谥蟮倪M(jìn)階系列中再學(xué)習(xí),現(xiàn)在你只要知道,必須要使用 LFU 相關(guān)的緩存淘汰算法,這個(gè)命令才可以使用。 排序對(duì)于 List、Set、Sorted Set 來(lái)說(shuō),我們可以通過(guò) SORT 這個(gè)命令來(lái)對(duì)它們的值進(jìn)行排序。這個(gè)命令的參數(shù)比較多,它的命令簽名是這樣的。
先來(lái)進(jìn)行一個(gè)簡(jiǎn)單的不加任何參數(shù)的排序,默認(rèn)情況是正序排列。 直接使用 DESC 就可以進(jìn)行倒序的排列,同時(shí)還可以使用 LIMIT 控制偏移量和數(shù)量,和 MySQL 中非常類似。 對(duì)于數(shù)字來(lái)說(shuō),排序非常方便,那么能不能對(duì)字符串進(jìn)行排序呢? 通過(guò)上面的例子可以看出,直接對(duì)字符類型的元素排序是不行的,但是我們可以加一個(gè) ALPAH 參數(shù),這樣就可以對(duì)字符串進(jìn)行排序了。另外我們可以通過(guò) STORE 參數(shù)將排序后的內(nèi)容放到另一個(gè) KEY 中。 注意看這個(gè)例子中,排序的結(jié)果會(huì)是一個(gè) List 類型。 除了上面這些簡(jiǎn)單的排序操作外,我們還可以通過(guò) BY 和 GET 命令實(shí)現(xiàn)非常復(fù)雜的排序操作。BY 是通過(guò)外部元素的 KEY 作為權(quán)重來(lái)進(jìn)行排序。還是拿上面那個(gè) e 中的 Set 元素為例,這回我們定義三個(gè)外部 KEY ,它們的鍵名中包含 Set 集合中的元素信息,它們的值是用于排序的數(shù)字類型。 神奇嗎?現(xiàn)在的順序是按照新定義的那三個(gè)外部 KEY 的值來(lái)排序的,不信?你可以再通過(guò) GET 參數(shù)來(lái)驗(yàn)證。 GET 參數(shù)是將排序的結(jié)果信息顯示為外部鍵的值信息。如果想跳過(guò)排序的元素,可以直接使用一個(gè)不存在的 KEY 。 說(shuō)了半天 BY 和 GET ,感覺(jué)很強(qiáng)大,但是有什么實(shí)際用處呢?咱們來(lái)看一個(gè)例子,通過(guò) BY 和 GET 來(lái)對(duì)多個(gè) Hash 數(shù)據(jù)進(jìn)行排序。 看明白啥意思了沒(méi)?-> 這個(gè)符號(hào),就像我們?cè)?PHP 中調(diào)用對(duì)象的屬性或方法一樣的符號(hào),在這里也是類似的概念。BY xxx->score 就是通過(guò) Hash 對(duì)象中 score 字段進(jìn)行排序 ,然后再使用 GET 來(lái)獲得 ->title 標(biāo)題,是不是酷斃了。 刪除最后的最后,我們?cè)賮?lái)看兩個(gè)非常簡(jiǎn)單的命令,它們都是用于刪除數(shù)據(jù)的。 DEL 和 UNLINK 命令都可以刪除一個(gè)或多個(gè)鍵,但是,DEL 是在主線程中運(yùn)行的,大量刪除時(shí)會(huì)阻塞線程影響效率,而 UNLINK 是將鍵的引用標(biāo)記斷開(kāi),然后通過(guò)其它的線程回收內(nèi)存,真正的刪除會(huì)在異步完成。 DEL 刪除一個(gè)普通的 String 類型的 Key 是 O(1) ,但是,如果是 List、Hash、Set、Sorted Set 就不會(huì)這么輕松了,會(huì)達(dá)到 O(n) 的級(jí)別。另外,假如一個(gè) String 類型的值有幾百兆,要?jiǎng)h它的話,也會(huì)產(chǎn)生阻塞。 因此,估計(jì)大家也都猜到了,線上繁忙的生產(chǎn)環(huán)境,或許使用 UNLINK 會(huì)更合適一些。這也是 bigkey 刪除的一個(gè)面試點(diǎn)。 總結(jié)完結(jié)撒花!! 對(duì)于 Redis 的基礎(chǔ)命令的學(xué)習(xí)就告一段落了,其實(shí)明眼人應(yīng)該一眼就能看出,我這又是開(kāi)始在刷 Redis 的文檔了。接下來(lái)我們就要進(jìn)入更深層次的學(xué)習(xí),也就是進(jìn)階部分的學(xué)習(xí)。這部分,少不了各種面試的八股文。不過(guò)我們也并不是以面試為主,而是通過(guò)面試時(shí)的這些常見(jiàn)問(wèn)題,來(lái)更加深入的理解 Redis ,從而能更進(jìn)一步地用好它。 繼續(xù)跟著,別掉隊(duì)哦! |
|
|
來(lái)自: 硬核項(xiàng)目經(jīng)理 > 《待分類》