男人的av一区二区资源,亚洲日韩国产精品无码av,蜜桃久久久aaaa成人网一区,亚洲日韩中文字幕一区,在线观看国产亚洲视频免费

【Redis源碼】RDB持久化源碼實(shí)現

【Redis源碼】RDB持久化源碼實(shí)現

RDB執行流程

RDB快照有兩種觸發(fā)方式,其一為通過(guò)配置參數,例如在配置文件中寫(xiě)入如下配置:

save 60 1000

則在60秒內如果有1000個(gè)key發(fā)生變化,就會(huì )觸發(fā)一次RDB快照的執行。

其二是通過(guò)在客戶(hù)端執行bgsave命令顯式觸發(fā)一次RDB快照的執行。bgsave執行流程如圖20-1所示。

image.png

在客戶(hù)端輸入bgsave命令后,Redis調用bgsaveCommand函數,該函數fork一個(gè)子進(jìn)程執行rdbSave函數進(jìn)行實(shí)際的快照存儲工作,而父進(jìn)程可以繼續處理客戶(hù)端請求。當子進(jìn)程退出后,父進(jìn)程調用相關(guān)回調函數進(jìn)行后續處理。

RDB文件結構

本節會(huì )先介紹整體文件結構,然后分別介紹RDB鍵的保存形式(即字符串的保存)和值的保存形式(根據數據類(lèi)型有不同的保存方法)。

整體文件結構

RDB的整體文件結構如圖所示。

image.png

各個(gè)部分按順序詳細介紹如下。

  • 頭部5字節固定為“REDIS”字符串。
  • 4字節的RDB版本號(RDB_VERSION,注意不是Redis的版本號),當前RDB版本號為9,填充為4字節之后為0008。
  • 輔助字段(AUX_FIELD_KEY_VALUE_PAIRS,見(jiàn)表20-1)。

image.png

輔助字段可以標明以下信息。

  • 數據庫序號:指明數據需要存放到哪個(gè)數據庫。
  • 當前數據庫鍵值對散列表的大小。Redis的每個(gè)數據庫是一個(gè)散列表,這個(gè)字段指明當前數據庫散列表的大小。這樣在加載時(shí)可以直接將散列表擴展到指定大小,提升加載速度。
  • 當前數據庫過(guò)期時(shí)間散列表的大小。Redis的過(guò)期時(shí)間也是保存為一個(gè)散列表,該字段指明當前數據庫過(guò)期時(shí)間散列表的大小。
  • Redis中具體鍵值對的存儲。
  • RDB文件結束標志。
  • 8字節的校驗碼。

通過(guò)上述結構的描述,請思考:加載RDB文件的時(shí)候怎么區分加載的是輔助字段還是數據庫序號或者是其他類(lèi)型呢?其實(shí),在RDB每一部分之前都有一個(gè)類(lèi)型字節,在Redis中稱(chēng)為opcodes。如下所示:

#define RDB_OPCODE_MODULE_AUX 247   /*  module相關(guān)輔助字段 */
#define RDB_OPCODE_IDLE       248   /* lru空閑時(shí)間 */
#define RDB_OPCODE_FREQ       249   /*  lfu頻率*/
#define RDB_OPCODE_AUX        250   /*  輔助字段類(lèi)型 */
#define RDB_OPCODE_RESIZEDB   251   /* ESIZEDB,即上文中介紹的5和6兩項 */
#define RDB_OPCODE_EXPIRETIME_MS 252    /* 毫秒級別過(guò)期時(shí)間 */
#define RDB_OPCODE_EXPIRETIME 253       /*  秒級別過(guò)期時(shí)間*/
#define RDB_OPCODE_SELECTDB   254   /*  數據庫序號,即第4項*/
#define RDB_OPCODE_EOF        255   /* 結束標志,即第8項*/

RDB帶opcodes的整體文件結構如圖20-3所示。

image.png

第2項輔助字段涉及字符串類(lèi)型在RDB文件中的保存方式,可以參考本節后面將要講解的內容。為了敘述方便,接下來(lái)對RDB結構的介紹中不會(huì )特意加上opcodes。

鍵值對結構

下面具體介紹一下第7項——鍵值對的結構,如圖20-4所示。

image.png

  • EXPIRE_TIME:可選。根據具體的鍵是否有過(guò)期時(shí)間決定,該字段固定為8個(gè)字節。
  • LRU或者LFU:可選。根據配置的內存淘汰算法決定。LRU算法保存秒級別的時(shí)間戳,LFU算法只保存counter的計數(0~255,1字節)。
  • VALUE_TYPE:值類(lèi)型。Redis數據類(lèi)型和底層編碼結構,值類(lèi)型對應關(guān)系見(jiàn)表20-2。

image.png

表20-2中字符串在Redis中都是宏,括號中即為該宏對應的值。

  • KEY:鍵。鍵保存為字符串,下文會(huì )詳細介紹字符串的保存形式。
  • ·VALUE:值。值根據數據類(lèi)型和編碼結構保存為不同的形式,下文詳細介紹。

鍵的保存形式

Redis中鍵都是字符串,所以本節介紹的就是RDB中如何保存一個(gè)字符串,其實(shí)也是一個(gè)比較常見(jiàn)的方法,如圖20-5所示。

image.png

前邊LENGTH字段表示字符串長(cháng)度,后邊STRING即具體的字符串內容。LENGTH為了通用可以使用8個(gè)字節保存,但這樣很明顯會(huì )導致空間的浪費。Redis中的LENGTH是個(gè)變長(cháng)字段,通過(guò)首字節能夠知道LENGTH字段有多長(cháng),然后讀取LENGTH字段可以知道具體的STRING長(cháng)度。LENGTH字段類(lèi)型如下:

00xxxxxx 字符串長(cháng)度<64
01xxxxxx xxxxxxxx 字符串長(cháng)度<16384
10000000 xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx 字符串長(cháng)度<=UINT32_MAX
10000001 xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx 字符串長(cháng)度>UINT32_MAX

首字節頭兩個(gè)比特是00時(shí),表示LENGTH字段占用1個(gè)字節,STRING的長(cháng)度保存在后6個(gè)比特中,最長(cháng)為63。

同理當首字節頭兩個(gè)比特是01時(shí),表示LENGTH字段占用2個(gè)字節,而STRING的長(cháng)度保存在后14個(gè)字節中,最長(cháng)為16383。

如果首字節為10000000,則表示LENGTH字段共占用5個(gè)字節,正好是一個(gè)無(wú)符號整型,STRING的長(cháng)度最長(cháng)為UINT32_MAX。

如果STRING長(cháng)度大于UINT32_MAX,則首字節表示為10000001,LENGTH字段共占用9個(gè)字節。后8字節表示實(shí)際長(cháng)度,為一個(gè)LONG類(lèi)型。

RDB中對字符串的保存還有兩種優(yōu)化形式:一種是嘗試將字符串按整型保存,一種是通過(guò)將字符串進(jìn)行LZF壓縮之后保存。下邊分別討論這兩種情況。

image.png

TYPE字段其實(shí)類(lèi)似圖20-5中的LENGTH字段,LENGTH字段首字節頭兩個(gè)比特取值為00、01、10這種類(lèi)型,TYPE字段首字節頭兩個(gè)比特取值為11,后6個(gè)比特表明存儲的整型類(lèi)型,如下:

11000000 xxxxxxxx INT8 取值范圍[-128,127]
11000001 xxxxxxxx xxxxxxxx INT16 取值范圍[-32768,32767]
11000010 xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx INT32 取值范圍[-2147483648, 2147483647]

后6個(gè)比特是000000,表明存儲的是一個(gè)有符號INT8類(lèi)型,000001表明存儲的是一個(gè)有符號INT16類(lèi)型,000010表明存儲的是一個(gè)有符號INT32類(lèi)型。更長(cháng)的長(cháng)度直接按字符串類(lèi)型保存。

image.png

TYPE首字節頭兩個(gè)比特仍然為11,后六個(gè)比特是000011。COMPRESS_LEN表明壓縮之后的長(cháng)度,該字段保存形式同圖20-5中LENGTH字段的保存。LZF還保存了一個(gè)ORIGINAL_LEN字段,該字段記錄壓縮之前原始字符串的長(cháng)度,保存形式也與圖20-5中LENGTH字段的保存相同。最后一個(gè)DATA字段保存具體的LZF壓縮之后的數據,數據長(cháng)度從COMPRESS_LEN字段取得。

至此,RDB如何保存一個(gè)字符串已經(jīng)講解完畢。

轉載自:Redis 5設計與源碼實(shí)現



標 題:《【Redis源碼】RDB持久化源碼實(shí)現
作 者:zeekling
提 示:轉載請注明文章轉載自個(gè)人博客:浪浪山旁那個(gè)村

    評論
    4 評論
    2020-11-27 21:26 回復?

    我這篇也是抄的。

    2020-11-27 20:52 回復?

    哦哦~謝謝大佬,那我抄走啦??

    2020-11-27 19:40 回復?

    在開(kāi)源博客的皮膚上面做了增強:https://git.zeekling.cn/zeekling/bolo-fantastic

    2020-11-27 14:40 回復?

    大佬,你的博客空間好好看,是用了什么特別的技巧嗎????

avatar

取消
男人的av一区二区资源,亚洲日韩国产精品无码av,蜜桃久久久aaaa成人网一区,亚洲日韩中文字幕一区,在线观看国产亚洲视频免费