redis RDB

簡介

  1. RDB數(shù)據(jù)落地的2種方式塑娇。
  2. 3種觸發(fā)RDB數(shù)據(jù)落地的方式澈侠。
  3. RDB的主要流程。
  4. object落地的序列化埋酬。
  5. RDB數(shù)據(jù)落地的互斥哨啃。

2種落地方式方式

  1. 自身進(jìn)程阻塞式的進(jìn)行數(shù)據(jù)落地,這種方式會使得進(jìn)程阻塞写妥,無法處理其它命令拳球。
  2. fork子進(jìn)程進(jìn)行數(shù)據(jù)落地,父進(jìn)程繼續(xù)處理client的命令珍特,但這個(gè)時(shí)候父進(jìn)程會排斥其它落地的請求祝峻,任何RDB數(shù)據(jù)落地在子進(jìn)程完成之前都會拒絕,同時(shí)也會拒絕部分AOF數(shù)據(jù)落地請求扎筒。

3種觸發(fā)RDB數(shù)據(jù)落地的方式

關(guān)于數(shù)據(jù)恢復(fù):數(shù)據(jù)恢復(fù)的邏輯比較簡單呼猪,在redis啟動(dòng)時(shí),判斷指定目錄下是否有rdb文件砸琅,有則通過rdb文件進(jìn)行數(shù)據(jù)恢復(fù)。

  1. client通過命令觸發(fā)RDB轴踱,SAVE和BGSAVE命令症脂,分別對應(yīng)上面的2種落地方式。
  2. 通過配置文件配置落地條件,在serverCron中定期檢查條件是否滿足诱篷,滿足則進(jìn)行數(shù)據(jù)落地壶唤,該種落地方式默認(rèn)是fork子進(jìn)程異步的數(shù)據(jù)落地。配置的格式如下:
save time_ivl dirty_num  // 格式
save 900  1  // 示例1
save 300 10 // 示例2
save 60 1000 // 示例3

配置的含義是棕所,如果距離上次RDB數(shù)據(jù)落地的時(shí)間超過time_ivl且修改的數(shù)據(jù)的數(shù)量大于dirty_num闸盔,那么就需要再次RDB數(shù)據(jù)落地。如果有多個(gè)配置琳省,則逐一比較迎吵,任何一個(gè)條件滿足,則進(jìn)行RDB數(shù)據(jù)落地针贬。

  1. 關(guān)機(jī)前進(jìn)行數(shù)據(jù)落地击费,這種方式通常都是自身進(jìn)程來執(zhí)行。

RDB的主要流程

  1. RDB數(shù)據(jù)落地調(diào)用的函數(shù)為:rdbSaveRio桦他。redisdb的結(jié)構(gòu)如下圖蔫巩,每個(gè)redisserver可以有多個(gè)db,每個(gè)db會有一個(gè)dict快压,存儲鍵值對圆仔,其中鍵為sds字符串類型,值為object蔫劣,具體的類型由object中的type字段指定坪郭。(其實(shí)還有expire_dict,存儲的是具有過期屬性的鍵和對應(yīng)的到期時(shí)間)


    redis db的結(jié)構(gòu)
  2. RDB過程主要偽碼:

save(redis_version); // redis的版本號
save(save_info_aux_fields); // rdb的一些輔助字段
save(save_modules_aux); // rdb的輔助模塊
for db in server.db_arr:
  save(RDB_OPCODE_SELECTDB); // 表示后續(xù)數(shù)據(jù)類型為db的下標(biāo)
  save(db_index); // 存儲db的下標(biāo)
  save(RDB_OPCODE_RESIZEDB); // 表示后續(xù)的數(shù)據(jù)是db的空間大小
  save(db.db_size); // db的鍵的dict的size
  save(db.expire_size); // db的設(shè)置了過期時(shí)間的鍵dict的size
  for it in db.db_dict:
    save(it.key); // sds db的dict的鍵
    save(it.value); // object db的dict的值
  for it in db.expire_dict:
    save(it.key); // sds expire_dict中的鍵
    save(it.value); // int expire_dict中到期時(shí)間

上面的dict中的key-value在內(nèi)存中通常是非連續(xù)的內(nèi)存拦宣,要進(jìn)行序列化才能寫入到文件中截粗。

object的序列化

1. 主要的object

在了解序列化之前,需要先了解redis中主要有哪些object鸵隧。


redis中的object
2. object的屬性绸罗。

redis中,object有2個(gè)類型字段豆瘫,一個(gè)是type珊蟀,一個(gè)是encoding,其中type表示上層業(yè)務(wù)使用對應(yīng)的類型外驱,encoding表示底層的實(shí)現(xiàn)育灸。以Hash為例,在業(yè)務(wù)層表示的是該結(jié)構(gòu)是鍵值對類型的數(shù)據(jù)結(jié)構(gòu)昵宇,必須實(shí)現(xiàn)鍵值對所應(yīng)該具有的接口磅崭,hashtable和ziplist是其2種不同的底層實(shí)現(xiàn)。

3. 連續(xù)內(nèi)存存儲的object

用連續(xù)內(nèi)存存儲的object類型(特點(diǎn)是數(shù)據(jù)都存儲在連續(xù)的內(nèi)存中瓦哎,在落地時(shí)砸喻,直接將對應(yīng)內(nèi)存寫到文件中即可)有:int柔逼,sds,ziplist割岛,intset愉适,zipmap(已不再使用)。這些object最終都可以通過以下方式寫入dump文件癣漆。

    if ((n = rdbSaveLen(rdb,len)) == -1) return -1; // 先存值的長度
    nwritten += n;
    if (len > 0) {
        if (rdbWriteRaw(rdb,s,len) == -1) return -1; // 再將值寫入到文件中
        nwritten += len;
    }

static int rdbWriteRaw(rio *rdb, void *p, size_t len) {
    if (rdb && rioWrite(rdb,p,len) == 0)
        return -1;
    return len;
}
4. 非連續(xù)內(nèi)存存儲的數(shù)據(jù)的序列化

在這之前需要了解復(fù)合的數(shù)據(jù)類型维咸,redis中的最基本的數(shù)據(jù)類型是sds和數(shù)值(int, double等)這2種類型。其它的類型都是由這2種類型組合而成惠爽。上面提到的每個(gè)db都有個(gè)dict癌蓖,存儲了該db中所有的數(shù)據(jù),其中key為sds類型疆股,value為object费坊,object可能的類型和對應(yīng)的客戶端命令關(guān)系如下。

命令 object的type object的encoding key的類型 value的類型
db.dict(特指db中的dict) hash dict sds object
set string sds 無key 無value
sadd set hashtable/ziplist sds 無value
hset hash hashtable/ziplist sds sds
lpush list linklist/ziplist/quicklist sds 無value
zset zset skiplist/quicklist sds double

從上面的復(fù)合數(shù)據(jù)類型的分析可知旬痹,db中的object的復(fù)合類型最復(fù)雜的hash也只是由sds類型的K-V鍵值對組成附井。hashtable的序列化代碼如下:

    } else if (o->type == OBJ_HASH) {
        /* Save a hash value */
        if (o->encoding == OBJ_ENCODING_ZIPLIST) {
            if ((n = rdbSaveRawString(rdb,o->ptr, ziplist_len)) == -1) return -1;
        } else if (o->encoding == OBJ_ENCODING_HT) {
            rdbSaveLen(rdb,dictSize((dict*)o->ptr))) // 先存儲鍵值對的數(shù)量

            while((de = dictNext(di)) != NULL) {
                rdbSaveRawString(rdb,(unsigned char*)field, sdslen(field))); // 將key以sds類型進(jìn)行存儲
                rdbSaveRawString(rdb,(unsigned char*)value, sdslen(value))); // 將value以sds類型進(jìn)行存儲
            }
        }

復(fù)合的數(shù)據(jù)類型都是基于sds和數(shù)值這2種基本類型組合而成,最終都可以變成基本類型的存儲两残。

數(shù)據(jù)落地之間的沖突關(guān)系

1.RDB數(shù)據(jù)落地期間永毅,其它的RDB請求都會被拒絕執(zhí)行,至于AOF數(shù)據(jù)落地人弓,待確定沼死。

總結(jié)

RDB數(shù)據(jù)落地主要掌握以下幾點(diǎn):

  1. 2種數(shù)據(jù)落地方式。
  2. 3種觸發(fā)RDB的方式崔赌。
  3. RDB落地的主要流程意蛀,了解了該流程即可知道RDB文件內(nèi)容的格式。
  4. RDB數(shù)據(jù)落地需要把每個(gè)db中的data_dict和expire_dict進(jìn)行序列化健芭,其中data_dict的value為object類型县钥,需要知道object類型如何進(jìn)行序列化。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末慈迈,一起剝皮案震驚了整個(gè)濱河市若贮,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌痒留,老刑警劉巖谴麦,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異伸头,居然都是意外死亡匾效,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進(jìn)店門恤磷,熙熙樓的掌柜王于貴愁眉苦臉地迎上來面哼,“玉大人雪侥,你說我怎么就攤上這事【铮” “怎么了?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵锌妻,是天一觀的道長代乃。 經(jīng)常有香客問我,道長仿粹,這世上最難降的妖魔是什么搁吓? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮吭历,結(jié)果婚禮上堕仔,老公的妹妹穿的比我還像新娘。我一直安慰自己晌区,他們只是感情好摩骨,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著朗若,像睡著了一般恼五。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上哭懈,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天灾馒,我揣著相機(jī)與錄音,去河邊找鬼遣总。 笑死睬罗,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的旭斥。 我是一名探鬼主播容达,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼琉预!你這毒婦竟也來了董饰?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤圆米,失蹤者是張志新(化名)和其女友劉穎卒暂,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體娄帖,經(jīng)...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡也祠,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了近速。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片诈嘿。...
    茶點(diǎn)故事閱讀 39,690評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡堪旧,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出奖亚,到底是詐尸還是另有隱情淳梦,我是刑警寧澤,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布昔字,位于F島的核電站爆袍,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏作郭。R本人自食惡果不足惜陨囊,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望夹攒。 院中可真熱鬧蜘醋,春花似錦、人聲如沸咏尝。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽状土。三九已至无蜂,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間蒙谓,已是汗流浹背斥季。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留累驮,地道東北人酣倾。 一個(gè)月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像谤专,于是被迫代替她去往敵國和親躁锡。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,577評論 2 353