這篇文章主要介紹redis底層數(shù)據(jù)結(jié)構(gòu)的示例分析,文中介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們一定要看完!
雙塔網(wǎng)站建設(shè)公司創(chuàng)新互聯(lián),雙塔網(wǎng)站設(shè)計制作,有大型網(wǎng)站制作公司豐富經(jīng)驗。已為雙塔上千提供企業(yè)網(wǎng)站建設(shè)服務(wù)。企業(yè)網(wǎng)站搭建\外貿(mào)營銷網(wǎng)站建設(shè)要多少錢,請找那個售后服務(wù)好的雙塔做網(wǎng)站的公司定做!
全局命令
Redis有5種數(shù)據(jù)結(jié)構(gòu),雖然它們底層不同,但還是有一些通用的命令是相同的。
查看所有鍵(返回所有的鍵,并它具體的鍵輸出出來)
keys *
查看鍵總數(shù)(返回當前數(shù)據(jù)庫中的鍵的個數(shù))
dbsize
備注:dbsize命令在計算鍵總數(shù)時不會遍歷所有的鍵,而是直接獲Redis內(nèi)置的鍵總數(shù)變量,所以dbsize命令的時間復(fù)雜度是O(1)。而keys命令則會遍歷所有鍵,所以它的時間復(fù)雜度是O(n),所以如果Redis中保存了大量的鍵時,keys命令要慎用。
檢查鍵是否存在
exists key
我們看exists命令是有返回值的當鍵存在時則返回值為1,當然鍵不存時返回值則為0。
刪除鍵
del key
我們知道在Redis中有5種數(shù)據(jù)結(jié)構(gòu),但del命令可以直接刪除任意類型的數(shù)據(jù)結(jié)構(gòu),而不用擔心它底層的實現(xiàn)。
我們看del命令和exists命令一樣,都是有返回值的。只不過不同的是del命令返回的時成功刪除鍵的個數(shù)。如果返回的是0,說明該鍵沒有被成功刪除,也就說明該鍵不存在。如果返回的是大于0的數(shù),是表示多個鍵被刪除了。下面我們看一下刪除多個鍵的操作。
鍵過期
expire key seconds
Redis支持對鍵添加過期時間,當超過這個過期時間時,Redis會自動將鍵刪除。
當我們通過expire命令設(shè)置鍵的過期時間后,我們可以使用
ttl key
命令查看該鍵的剩余過期時間,所以ttl命令是有返回值的,也就是該鍵的剩余時間,單位是秒。除此之外,ttl命令有3種類型的返回值。下面我們看一下這3種返回值的區(qū)別。
>=0:表示剩余的過期時間
-1:鍵沒設(shè)置過期時間
-2:鍵不存在
鍵的數(shù)據(jù)結(jié)構(gòu)類型
type key
如果鍵是字符串則type命令返回的就是字符串,如果是其它的數(shù)據(jù)類型則會返回其它的數(shù)據(jù)類型(因為我們還沒有學習其它的類型,這里暫時只考慮字符串),如果鍵不存在時,在返回none。
數(shù)據(jù)結(jié)構(gòu)和內(nèi)部編碼
上面我們知道type命令會返回Redis中鍵的數(shù)據(jù)類型,也就是string(字符串)、hash(哈希)、list(列表)、set(集合)、zset(有序集合)等。但這些只是對外的數(shù)據(jù)結(jié)構(gòu),實際上在Redis的內(nèi)部不同的數(shù)據(jù)結(jié)構(gòu)有不同的底層的內(nèi)部編碼。不同內(nèi)部編碼在Redis中有些不同的性能,并且在Redis中會自動判斷應(yīng)該用哪種編碼來存儲數(shù)據(jù),已保證Redis的性能。我們可以通過下面的命令來查看鍵的內(nèi)部編碼。
object encoding key
我們可以看出,上面保存的jilinwula這個鍵的內(nèi)部編碼就是embstr。下面我們看一下在Redis中所有的數(shù)據(jù)結(jié)構(gòu)所對應(yīng)的內(nèi)部編碼。
下面我們分析一下,為什么Redis要這樣設(shè)計數(shù)據(jù)結(jié)構(gòu)及底層編碼呢。首先第一個好處就是可以改進內(nèi)部編碼。當這樣做時,而不需要改變內(nèi)部的數(shù)據(jù)結(jié)構(gòu),也就無需修改外部結(jié)構(gòu)及命令了。第二個好處就是,我們知道不同的內(nèi)部編碼有著不同的性能,當這樣設(shè)計時,如果我們要改變底層的內(nèi)部編碼時,我們只需要根據(jù)Redis配置選項就可以,將我們曾經(jīng)存儲過的key的底層編碼更改,這樣就可以針對不同的業(yè)務(wù)場景,個性化配置,進而提升性能。
單線程架構(gòu)
我們知道Redis使用了單線程架構(gòu)和I/O多路復(fù)用模型來實現(xiàn)高性能的內(nèi)存服務(wù)。
單線程模型
每當客戶端調(diào)用命令時都會經(jīng)歷3個步驟:發(fā)送命令、執(zhí)行命令、返回結(jié)果3個過程。我們之前介紹過Redis是單線程的,所以每一條命令從客戶端發(fā)送到服務(wù)端,命令不會立即執(zhí)行,而是將所有的命令都會進入一個隊列中,然后在順序執(zhí)行。這樣,當我們客戶端啟動多個時執(zhí)行命令時,不用考慮并發(fā)的問題,因為它們都會進入隊列,順序執(zhí)行。
為什么單線程處理速度這么快 第一,我們知道Redis是將數(shù)據(jù)都存儲到內(nèi)存中的,內(nèi)存的處理速度,要比純硬盤IO的速度要快的多。
第二,非阻塞I/O,Redis使用epoll作為I/O多路復(fù)用技術(shù)實現(xiàn)的,在加上Redis自身的事件處理模型將epoll中的連接、讀寫、關(guān)閉都轉(zhuǎn)換為事件,不在網(wǎng)絡(luò)I/O上浪費過多的時間。
單線程避免線程切換等消耗
第一,我們知道做項目開發(fā)時,如果要對多線程做兼容,那么它要比單線程要復(fù)雜多了,代碼變復(fù)雜了,出現(xiàn)BUG的可能性也就多了。
第二,在開發(fā)多種線程時,我們知道線程間的切換,是很耗資源的,并且對服務(wù)端來說,對線程添加鎖,每次執(zhí)行時都會判斷鎖,是很費時間的。
雖然Redis的單線程架構(gòu)是有好處的,但是這也是它的弊端,我們知道,在執(zhí)行命令時是順序執(zhí)行的,如果上一個命令沒有執(zhí)行完,那么剩下的命令是不會執(zhí)行的,這也就造成了命令的阻塞。這對于Redis這種內(nèi)存數(shù)據(jù)庫來說,如果發(fā)生了阻塞,那么后果,可想而知,所以,我們在執(zhí)行相關(guān)命令時,一定要慎重。
以上是“Redis底層數(shù)據(jù)結(jié)構(gòu)的示例分析”這篇文章的所有內(nèi)容,感謝各位的閱讀!希望分享的內(nèi)容對大家有幫助,更多相關(guān)知識,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!