最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Redis數(shù)據(jù)庫(kù)原理深入刨析

 更新時(shí)間:2022年11月22日 11:02:59   作者:zkyangll  
在之前的文章我們介紹過(guò),Redis服務(wù)器在啟動(dòng)之初,會(huì)初始化RedisServer的實(shí)例,在這個(gè)實(shí)例中存在很多重要的屬性結(jié)構(gòu),同理本篇博客中介紹的數(shù)據(jù)庫(kù)實(shí)現(xiàn)原理也會(huì)和其中的某些屬性相關(guān),我們繼續(xù)看一下吧

1.服務(wù)器和客戶(hù)端實(shí)現(xiàn)的數(shù)據(jù)庫(kù)

 Redis服務(wù)器在啟動(dòng)時(shí),會(huì)根據(jù)redis.conf文件的中databases xx這個(gè)配置決定創(chuàng)建多少個(gè)數(shù)據(jù)庫(kù)(默認(rèn)配置是16),啟動(dòng)后默認(rèn)使用的0號(hào)數(shù)據(jù)庫(kù),當(dāng)然可以使用select dbnum這個(gè)命令來(lái)切換。需要注意的是在redis集群模式下,只有0號(hào)數(shù)據(jù)庫(kù)可以用,是無(wú)法切換到其他庫(kù)的。

 Redis服務(wù)器會(huì)將所有的數(shù)據(jù)庫(kù)都保存在服務(wù)器狀態(tài)的redisServer的db數(shù)組中,數(shù)組的每一項(xiàng)都代表了一個(gè)數(shù)據(jù)庫(kù),用redisDb結(jié)構(gòu)來(lái)表示,首先看一下redisServer.db的源碼:

struct redisServer {
	...
	// 代表數(shù)據(jù)庫(kù)的數(shù)組
    redisDb *db;
    // 這個(gè)記錄的配置文件中數(shù)據(jù)庫(kù)的數(shù)量
	int dbnum;  
    ...
}

 我們通過(guò)客戶(hù)端向Redis寫(xiě)入的任何數(shù)據(jù)都會(huì)記錄到這個(gè)db數(shù)組中,根據(jù)前面描述,我們知道可以通過(guò)select命令切換到另一個(gè)目標(biāo)數(shù)據(jù)庫(kù),但是客戶(hù)端是怎么記錄的它當(dāng)前操作的哪個(gè)數(shù)據(jù)庫(kù)呢?我們繼續(xù)看一下源碼:

typedef struct client {
    ...
    // 指針指向當(dāng)前客戶(hù)端正在操作的數(shù)據(jù)庫(kù)
    redisDb *db;            /* Pointer to currently SELECTed DB. */
	...
} client;

 看,在client客戶(hù)端狀態(tài)中,有一個(gè)db指針,指向了server.db數(shù)組中的某一項(xiàng),代表了當(dāng)前客戶(hù)端正在操作的數(shù)據(jù)庫(kù)。所以通過(guò)切換client.db的指針,調(diào)整客戶(hù)端操作的數(shù)據(jù)庫(kù),這就是select命令的實(shí)現(xiàn)原理。

2.數(shù)據(jù)庫(kù)字典的實(shí)現(xiàn)

 Redis是支持key-value鍵值對(duì)存儲(chǔ)的,這其實(shí)是通過(guò)dict結(jié)構(gòu)來(lái)實(shí)現(xiàn)的,在前面講到的內(nèi)容中,服務(wù)器和客戶(hù)端都指向了一個(gè)redisDb的結(jié)構(gòu),在這個(gè)db結(jié)構(gòu)中,就包含存儲(chǔ)了鍵值對(duì)的字典結(jié)構(gòu),首先看一下源碼:

typedef struct redisDb {
	...
	// 這個(gè)存放的就是鍵值對(duì)
    dict *dict;                 /* The keyspace for this DB */
    // 這個(gè)存放的是鍵值對(duì)的過(guò)期時(shí)間,下面一節(jié)會(huì)說(shuō)到
    dict *expires;              /* Timeout of keys with a timeout set */
    ...
} redisDb;

 dict這個(gè)指針就指向了存儲(chǔ)鍵值對(duì)的字典結(jié)構(gòu),key是字符串robj類(lèi)型,value可以是任何的robj類(lèi)型。當(dāng)我們分別新增、刪除、更新或者查詢(xún)的時(shí)候,其實(shí)就是根據(jù)輸入的key在這個(gè)字典上做curd的操作。我們?cè)赗edis寫(xiě)入兩個(gè)鍵值對(duì),圖示如下:

 除了對(duì)數(shù)據(jù)庫(kù)鍵值對(duì)的curd操作,基于整個(gè)數(shù)據(jù)操作的一些命令也是在這個(gè)dict上面實(shí)現(xiàn)的,比如清空所有鍵值對(duì)的flushdb,或者exists、del、dbsize命令等等。在執(zhí)行命令前后,redis還會(huì)執(zhí)行一些其他操作,比如檢查是否超出最大內(nèi)存,更新lru時(shí)間,記錄慢查詢(xún)?nèi)罩荆蛘呦騧onitor客戶(hù)端發(fā)送命令等等,這就是redis數(shù)據(jù)字典的實(shí)現(xiàn)原理。

3.鍵值對(duì)的生命周期管理

 這里說(shuō)的生命周期,其實(shí)就是指鍵值對(duì)的過(guò)期時(shí)間。通常我們使用expire key這個(gè)命令設(shè)置鍵的過(guò)期時(shí)間,但其實(shí)Redis是有四個(gè)命令支持設(shè)置過(guò)期時(shí)間的:

  • expire key seconds 將key的生命周期設(shè)置為second秒;
  • pexpire key milliseconds 將key的生命周期設(shè)置為milliseconds毫秒;
  • expireat key timestamp 將key的過(guò)期時(shí)間設(shè)置在timestamp這個(gè)秒的時(shí)間戳過(guò)期;
  • pexpireat key timestamp 將key的過(guò)期時(shí)間設(shè)置在timestamp這個(gè)毫秒的時(shí)間戳過(guò)期;

 值得說(shuō)明的是,雖然有這么多命令支持設(shè)置過(guò)期時(shí)間,但是最終經(jīng)過(guò)轉(zhuǎn)換都是指向pexpireat這一個(gè)命令來(lái)實(shí)現(xiàn)?,F(xiàn)在的問(wèn)題是,這么多鍵值對(duì)的過(guò)期時(shí)間,在redis服務(wù)端是怎么保存和維護(hù)的呢?

 前面在看redisDb源碼的時(shí)候,有一個(gè)expires屬性,我們?cè)侔言创a拿過(guò)來(lái)看一下:

typedef struct redisDb {
	...
    // 這個(gè)存放的是鍵的過(guò)期時(shí)間
    dict *expires;              /* Timeout of keys with a timeout set */
    ...
} redisDb;

 這就很清晰了,通過(guò)expires這個(gè)指針,指向了一個(gè)dict結(jié)構(gòu),字典中記錄的就是所有鍵值對(duì)的過(guò)期時(shí)間。其中,key是鍵值對(duì)的鍵,value是long類(lèi)型的毫秒精度的unix時(shí)間戳,即過(guò)期的時(shí)間點(diǎn)。值得注意的是,保存鍵值對(duì)的dict字典和保存過(guò)期時(shí)間的expires字典,key指針都指向相同的一個(gè)鍵字符串對(duì)象,所以在內(nèi)存空間上是不會(huì)存在浪費(fèi)的。

 除此之外,跟過(guò)期時(shí)間操作相關(guān)的兩個(gè)命令,當(dāng)然也是基于expires這個(gè)字典來(lái)實(shí)現(xiàn)的:

  • ttl 返回鍵值對(duì)的剩余時(shí)間
  • persist刪除鍵值對(duì)的過(guò)期時(shí)間

4.過(guò)期鍵的管理策略

 既然有過(guò)期時(shí)間,那么鍵值對(duì)過(guò)期之后,是不是立即被刪除了呢?答案肯定不是,redis通過(guò)惰性刪除和定期刪除兩種策略實(shí)現(xiàn)對(duì)過(guò)期鍵的管理:

  • 惰性刪除策略:當(dāng)程序訪(fǎng)問(wèn)到某個(gè)鍵值對(duì)的時(shí)候,會(huì)對(duì)過(guò)期時(shí)間檢查,如果過(guò)期就刪除,否則不處理。
  • 定期刪除策略:基于serverCron時(shí)間事件函數(shù),從一定數(shù)量的數(shù)據(jù)庫(kù)中取出一定數(shù)量的隨機(jī)鍵進(jìn)行檢查,并刪除其中過(guò)期的鍵值對(duì)。

 使用這兩種過(guò)期鍵管理策略可以最大程度上在合理使用CPU時(shí)間和避免浪費(fèi)內(nèi)存空間之間取得平衡。

5.持久化對(duì)過(guò)期鍵的處理

rdb 持久化

  • save或者bgsave會(huì)檢查鍵的過(guò)期時(shí)間,已過(guò)期的鍵不會(huì)保存到的持久化的rdb文件中。
  • 服務(wù)器啟動(dòng)載入rdb文件時(shí),如果是主服務(wù)器,過(guò)期鍵會(huì)被忽略加載;如果是從服務(wù)器,不論是否過(guò)期,都會(huì)被加載。

aof 持久化

  • 寫(xiě)入aof文件時(shí),key是會(huì)寫(xiě)入的,過(guò)期之后,通過(guò)追加del命令,才會(huì)顯示的刪除此過(guò)期鍵。
  • bgrewriteaof 重寫(xiě)時(shí)會(huì)檢查鍵的過(guò)期時(shí)間,已過(guò)期的鍵不會(huì)寫(xiě)入新的aof文件中。
  • 服務(wù)器啟動(dòng)載入aof文件時(shí),過(guò)期鍵也會(huì)被忽略,不會(huì)被加載。

6.主從復(fù)制對(duì)過(guò)期鍵的處理

 主從復(fù)制,為了保證數(shù)據(jù)的一致性,通常由主服務(wù)器執(zhí)行更新的操作,然后將命令發(fā)送給從服務(wù)器。在3.2版本之前,由于惰性刪除策略的存在,主服務(wù)器遇到對(duì)過(guò)期鍵的訪(fǎng)問(wèn),會(huì)刪除此鍵值對(duì),并給客戶(hù)端返回null值,但是從服務(wù)器由于不能執(zhí)行刪除操作,即便是此鍵已過(guò)期,也會(huì)返回對(duì)應(yīng)的value值,出現(xiàn)數(shù)據(jù)不一致導(dǎo)致的臟讀問(wèn)題。

 在3.2版本之后,這個(gè)問(wèn)題得到了修改,從服務(wù)器會(huì)判斷當(dāng)前鍵是否過(guò)期,如果已過(guò)期并且是從服務(wù)器的話(huà),也會(huì)返回null值。

到此這篇關(guān)于Redis數(shù)據(jù)庫(kù)原理深入刨析的文章就介紹到這了,更多相關(guān)Redis數(shù)據(jù)庫(kù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 詳解Centos7下配置Redis并開(kāi)機(jī)自啟動(dòng)

    詳解Centos7下配置Redis并開(kāi)機(jī)自啟動(dòng)

    本篇文章主要介紹了Centos7下配置Redis并開(kāi)機(jī)自啟動(dòng),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。
    2016-11-11
  • 圖文詳解Windows下使用Redis緩存工具的方法

    圖文詳解Windows下使用Redis緩存工具的方法

    這篇文章以圖文結(jié)合的方式詳解Windows下使用Redis緩存工具的方法,感興趣的小伙伴們可以參考一下
    2015-12-12
  • Redis安裝與使用方法小結(jié)

    Redis安裝與使用方法小結(jié)

    這篇文章主要介紹了Redis安裝與使用方法,結(jié)合實(shí)例形式分析了Redis數(shù)據(jù)庫(kù)的下載、安裝、啟動(dòng)、設(shè)置及相關(guān)使用操作注意事項(xiàng),需要的朋友可以參考下
    2018-04-04
  • Win10下通過(guò)Ubuntu安裝Redis的過(guò)程

    Win10下通過(guò)Ubuntu安裝Redis的過(guò)程

    這篇文章主要介紹了Win10下通過(guò)Ubuntu安裝Redis,在安裝Ubuntu需要先打開(kāi)Windows功能,接著創(chuàng)建一個(gè)用戶(hù)及密碼,本文給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2022-04-04
  • Redis通用命令介紹以及key的層級(jí)結(jié)構(gòu)講解

    Redis通用命令介紹以及key的層級(jí)結(jié)構(gòu)講解

    這篇文章主要介紹了Redis通用命令以及key的層級(jí)結(jié)構(gòu),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)吧
    2022-12-12
  • 淺談Redis分布式鎖的正確實(shí)現(xiàn)方式

    淺談Redis分布式鎖的正確實(shí)現(xiàn)方式

    這篇文章主要介紹了淺談Redis分布式鎖的正確實(shí)現(xiàn)方式,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2019-05-05
  • redis連接報(bào)錯(cuò)error:NOAUTH Authentication required

    redis連接報(bào)錯(cuò)error:NOAUTH Authentication required

    本文主要介紹了redis連接報(bào)錯(cuò)error:NOAUTH Authentication required,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-05-05
  • Redis?集群模式(Cluster)原理詳解

    Redis?集群模式(Cluster)原理詳解

    redis?cluster集群是一個(gè)由多個(gè)主從節(jié)點(diǎn)集群組成的分布式服務(wù)集群,它具有復(fù)制、高可用和分片特性,cluster集群不需要sentinel?哨兵也能完成節(jié)點(diǎn)移除和故障轉(zhuǎn)移的功能,本文就詳細(xì)的給大家介紹一下Redis?集群模式原理,感興趣的朋友跟著小編一起來(lái)看看吧
    2023-07-07
  • Redis緩存降級(jí)的四種策略

    Redis緩存降級(jí)的四種策略

    在高并發(fā)系統(tǒng)架構(gòu)中,Redis作為核心緩存組件扮演著至關(guān)重要的角色,它不僅能夠顯著提升系統(tǒng)響應(yīng)速度,還能有效減輕數(shù)據(jù)庫(kù)壓力,然而,當(dāng)Redis服務(wù)出現(xiàn)故障、性能下降或連接超時(shí)時(shí),如果沒(méi)有適當(dāng)?shù)慕导?jí)機(jī)制,可能導(dǎo)致系統(tǒng)雪崩,所以本文給大家介紹了Redis緩存降級(jí)的四種策略
    2025-04-04
  • Redis Template使用詳解示例教程

    Redis Template使用詳解示例教程

    RedisTemplate的底層通過(guò)RedisConnectionFactory對(duì)多種Redis驅(qū)動(dòng)進(jìn)行集成,上層通過(guò)RedisOperations提供豐富的API,并結(jié)合Spring基于泛型的bean注入,為開(kāi)發(fā)提供了極大的便利,這篇文章主要介紹了Redis Template使用詳解示例教程,需要的朋友可以參考下
    2023-11-11

最新評(píng)論

襄樊市| 漳浦县| 松溪县| 革吉县| 陆丰市| 商河县| 克山县| 都昌县| 抚州市| 突泉县| 合阳县| 洛隆县| 报价| 都匀市| 娄烦县| 门头沟区| 南召县| 蕲春县| 磐石市| 通道| 江永县| 清流县| 诸城市| 永胜县| 海晏县| 佳木斯市| 电白县| 余姚市| 丰宁| 马尔康县| 塘沽区| 贡嘎县| 泽库县| 钟祥市| 双牌县| 山西省| 绍兴市| 陵川县| 石棉县| 台安县| 南漳县|