<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
Redis伺服器在啟動時,會根據redis.conf檔案的中databases xx
這個設定決定建立多少個資料庫(預設設定是16),啟動後預設使用的0號資料庫,當然可以使用select dbnum
這個命令來切換。需要注意的是在redis叢集模式下,只有0號資料庫可以用,是無法切換到其他庫的。
Redis伺服器會將所有的資料庫都儲存在伺服器狀態的redisServer的db陣列中,陣列的每一項都代表了一個資料庫,用redisDb結構來表示,首先看一下redisServer.db的原始碼:
struct redisServer { ... // 代表資料庫的陣列 redisDb *db; // 這個記錄的組態檔中資料庫的數量 int dbnum; ... }
我們通過使用者端向Redis寫入的任何資料都會記錄到這個db陣列中,根據前面描述,我們知道可以通過select命令切換到另一個目標資料庫,但是使用者端是怎麼記錄的它當前操作的哪個資料庫呢?我們繼續看一下原始碼:
typedef struct client { ... // 指標指向當前使用者端正在操作的資料庫 redisDb *db; /* Pointer to currently SELECTed DB. */ ... } client;
看,在client使用者端狀態中,有一個db指標,指向了server.db陣列中的某一項,代表了當前使用者端正在操作的資料庫。所以通過切換client.db的指標,調整使用者端操作的資料庫,這就是select命令的實現原理。
Redis是支援key-value鍵值對儲存的,這其實是通過dict結構來實現的,在前面講到的內容中,伺服器和使用者端都指向了一個redisDb的結構,在這個db結構中,就包含儲存了鍵值對的字典結構,首先看一下原始碼:
typedef struct redisDb { ... // 這個存放的就是鍵值對 dict *dict; /* The keyspace for this DB */ // 這個存放的是鍵值對的過期時間,下面一節會說到 dict *expires; /* Timeout of keys with a timeout set */ ... } redisDb;
dict這個指標就指向了儲存鍵值對的字典結構,key是字串robj型別,value可以是任何的robj型別。當我們分別新增、刪除、更新或者查詢的時候,其實就是根據輸入的key在這個字典上做curd的操作。我們在Redis寫入兩個鍵值對,圖示如下:
除了對資料庫鍵值對的curd操作,基於整個資料操作的一些命令也是在這個dict上面實現的,比如清空所有鍵值對的flushdb,或者exists、del、dbsize命令等等。在執行命令前後,redis還會執行一些其他操作,比如檢查是否超出最大記憶體,更新lru時間,記錄慢查詢紀錄檔,或者向monitor使用者端傳送命令等等,這就是redis資料字典的實現原理。
這裡說的生命週期,其實就是指鍵值對的過期時間。通常我們使用expire key
這個命令設定鍵的過期時間,但其實Redis是有四個命令支援設定過期時間的:
expire key seconds
將key的生命週期設定為second秒;pexpire key milliseconds
將key的生命週期設定為milliseconds毫秒;expireat key timestamp
將key的過期時間設定在timestamp這個秒的時間戳過期;pexpireat key timestamp
將key的過期時間設定在timestamp這個毫秒的時間戳過期; 值得說明的是,雖然有這麼多命令支援設定過期時間,但是最終經過轉換都是指向pexpireat
這一個命令來實現。現在的問題是,這麼多鍵值對的過期時間,在redis伺服器端是怎麼儲存和維護的呢?
前面在看redisDb原始碼的時候,有一個expires屬性,我們再把原始碼拿過來看一下:
typedef struct redisDb { ... // 這個存放的是鍵的過期時間 dict *expires; /* Timeout of keys with a timeout set */ ... } redisDb;
這就很清晰了,通過expires這個指標,指向了一個dict結構,字典中記錄的就是所有鍵值對的過期時間。其中,key是鍵值對的鍵,value是long型別的毫秒精度的unix時間戳,即過期的時間點。值得注意的是,儲存鍵值對的dict字典和儲存過期時間的expires字典,key指標都指向相同的一個鍵字串物件,所以在記憶體空間上是不會存在浪費的。
除此之外,跟過期時間操作相關的兩個命令,當然也是基於expires這個字典來實現的:
ttl
返回鍵值對的剩餘時間persist
刪除鍵值對的過期時間既然有過期時間,那麼鍵值對過期之後,是不是立即被刪除了呢?答案肯定不是,redis通過惰性刪除和定期刪除兩種策略實現對過期鍵的管理:
使用這兩種過期鍵管理策略可以最大程度上在合理使用CPU時間和避免浪費記憶體空間之間取得平衡。
rdb 持久化
aof 持久化
主從複製,為了保證資料的一致性,通常由主伺服器執行更新的操作,然後將命令傳送給從伺服器。在3.2版本之前,由於惰性刪除策略的存在,主伺服器遇到對過期鍵的存取,會刪除此鍵值對,並給使用者端返回null值,但是從伺服器由於不能執行刪除操作,即便是此鍵已過期,也會返回對應的value值,出現資料不一致導致的髒讀問題。
在3.2版本之後,這個問題得到了修改,從伺服器會判斷當前鍵是否過期,如果已過期並且是從伺服器的話,也會返回null值。
到此這篇關於Redis資料庫原理深入刨析的文章就介紹到這了,更多相關Redis資料庫內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45