溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Redis持久化的實(shí)現(xiàn)方法

發(fā)布時(shí)間:2021-07-05 15:58:27 來(lái)源:億速云 閱讀:97 作者:chen 欄目:大數(shù)據(jù)

本篇內(nèi)容主要講解“Redis持久化的實(shí)現(xiàn)方法”,感興趣的朋友不妨來(lái)看看。本文介紹的方法操作簡(jiǎn)單快捷,實(shí)用性強(qiáng)。下面就讓小編來(lái)帶大家學(xué)習(xí)“Redis持久化的實(shí)現(xiàn)方法”吧!

Redis之所以速度這么快,是因?yàn)镽edis是基于內(nèi)存的數(shù)據(jù)庫(kù),進(jìn)行讀寫操作時(shí),redis都會(huì)在內(nèi)存中完成,然后定時(shí)的刷新到磁盤中去,RDB和AOF就是兩種持久化內(nèi)存中數(shù)據(jù)的方式

在硬盤中數(shù)據(jù)是持久化的,重啟機(jī)子也會(huì)存在

在內(nèi)存中數(shù)據(jù)不是持久化的,重啟機(jī)子就沒了

根據(jù)一段自己寫的redis操作的代碼來(lái)學(xué)習(xí),這邊使用的是Jedis(Java連接開發(fā)工具),來(lái)一段最簡(jiǎn)單的set

    /**
     * set 字節(jié)數(shù)組
     *
     * @param key   字節(jié)key
     * @param value 字節(jié)value
     * @return OK
     */
    public String set(byte[] key, byte[] value) {
        Jedis jedis = null;
        String result = null;
        try {
            jedis = getJedis();
            result = jedis.set(key, value);
        } catch (Exception e) {
            log.error("set byte[] key:{} value:{} error", key, value, e);
        } finally {
            returnSource(jedis);
        }
        return result;
    }

快照存儲(chǔ) RDB(redis db)

redis 會(huì)把自身的數(shù)據(jù)以文件形式保存到硬盤中一份,在服務(wù)器重啟之后會(huì)自動(dòng)把硬盤數(shù)據(jù)恢復(fù)到內(nèi)存中
操作是一次性把redis中全部的數(shù)據(jù)保存一份到硬盤中,所以如果數(shù)據(jù)大的話,不太適合頻繁進(jìn)行該操作

默認(rèn)文件名dump.rdb  可以在redis.conf中設(shè)置

Redis持久化的實(shí)現(xiàn)方法

有三種方式觸發(fā)快照

第1種. redis客戶端發(fā)送的save命令進(jìn)行快照,會(huì)阻塞(代碼中需要調(diào)用jedis.save()的方法實(shí)現(xiàn))

阻塞redis服務(wù)器的進(jìn)程,直到RDB文件創(chuàng)建完,在該段時(shí)間內(nèi),redis不能處理其他的命令

第2種. redis客戶端發(fā)送的bgsave命令,不阻塞(代碼中需要調(diào)用jedis.bgsave()的方法實(shí)現(xiàn))
實(shí)際執(zhí)行過(guò)程:

  1. 客戶端bgsave命令

  2. 服務(wù)端返回ok

  3. 服務(wù)端fork創(chuàng)建一個(gè)子進(jìn)程來(lái)執(zhí)行備份

  4. 子進(jìn)程執(zhí)行完之后通知redis

主進(jìn)程和子進(jìn)程是同時(shí)存在的, 不會(huì)阻塞redis服務(wù)器進(jìn)程, 創(chuàng)建子進(jìn)程會(huì)消耗額外的內(nèi)存,所以bgsave比save要慢

第3種. redis根據(jù)redis.conf中的配置自動(dòng)執(zhí)行bgsave

save 900 1           #900秒之內(nèi)修改了1次,則執(zhí)行  
save 300 10          #300秒之內(nèi)修改了10次,則執(zhí)行    
save 60 10000        #60秒之內(nèi)修改了10000次,則執(zhí)行

服務(wù)器每次執(zhí)行之后,為實(shí)現(xiàn)自動(dòng)持久化而設(shè)置的時(shí)間計(jì)數(shù)器和次數(shù)計(jì)數(shù)器就會(huì)清零,重新計(jì)算

在redis命令執(zhí)行config get save查看redis的save配置

可用jedis.lastsave()命令查看生成RDB文件是否成功, 返回上次成功保存到磁盤的unix時(shí)間戳(save和bgsave都會(huì)修改時(shí)間) ,RDB文件每次都是覆蓋,需要控制備份的話,要定時(shí)定點(diǎn)另存?zhèn)浞?/p>

從上面學(xué)習(xí)過(guò)程中,得出主動(dòng)方式應(yīng)該選擇使用bgsave的方式來(lái)持久化

    public void bgsave() {
        Jedis jedis = null;
        try {
            jedis = getJedis();
            jedis.bgsave();
        } catch (Exception e) {
            log.error("bgsave error", e);
        } finally {
            returnSource(jedis);
        }
    }

給自己的工具類加個(gè)bgsave持久化方法,另外嘗試過(guò)程過(guò)遇到如果在一個(gè)Java方法中調(diào)兩次save或者bgsave是會(huì)報(bào)錯(cuò)的,所以持久化單提出來(lái),可能一個(gè)方法有好幾個(gè)redis操作

總結(jié):
1.bgsave子線程創(chuàng)建RDB文件,不會(huì)對(duì)redis服務(wù)器性能造成大的影響
2.快照生成的RDB文件是一種壓縮的二進(jìn)制文件,可以方便的在網(wǎng)絡(luò)中傳輸和保存
3.在一次備份完RDB之后產(chǎn)生了新數(shù)據(jù),但還未到達(dá)另一次生成RDB文件的條件,這時(shí)redis服務(wù)器宕機(jī),那么新的數(shù)據(jù)會(huì)丟失掉
4.數(shù)據(jù)量大的時(shí),觸發(fā)RDB持久化,包括創(chuàng)建子線程和生成RDB文件會(huì)占不少系統(tǒng)資源和時(shí)間,會(huì)對(duì)redis產(chǎn)生影響

持久化AOF(append only file)

把操作執(zhí)行的每個(gè)指令都備份到aof文件中,還原數(shù)據(jù)的時(shí)候執(zhí)行指令 , 每次在后面追加

aop重寫(不阻塞), redis.conf對(duì)應(yīng) appendonly yes 開啟aof

appendfilename "appendonly.aof"   //備份文件名
appendfsync always    //每次收到寫命令就立即寫入磁盤,最慢的方式,但是保證完全的持久化
appendfsync everysec   //每秒鐘強(qiáng)烈寫入磁盤一次,在性能和持久化方面很好的折中,默認(rèn) 
appendfsync no  //不同步到硬盤,由操作系統(tǒng)來(lái)決定

aof生成過(guò)程三個(gè)步驟:redis在執(zhí)行完一個(gè)寫命令后,把執(zhí)行的命令追加到redis內(nèi)部的aof_buf緩沖區(qū)末尾

調(diào)用調(diào)用fsync函數(shù), 緩沖區(qū)的寫命令會(huì)被寫入到 AOF 文件, 完成同步

在目前操作系統(tǒng)里,執(zhí)行系統(tǒng)調(diào)用write函數(shù),將一些內(nèi)容寫入到某個(gè)文件時(shí), 先將內(nèi)容放入一個(gè)內(nèi)存緩沖區(qū)(buffer)里面,等到緩沖區(qū)被填滿,或者用戶執(zhí)行fsync調(diào)用和fdatasync調(diào)用時(shí)才將存儲(chǔ)在緩沖區(qū)里面的內(nèi)容真正的寫入到硬盤里,那么在這個(gè)過(guò)程中出問(wèn)題了,數(shù)據(jù)是否就丟了?!

總結(jié):

使用 AOF 持久化會(huì)讓 Redis 變得非常耐久:你可以設(shè)置不同的 fsync策略,比如無(wú) fsync,每秒鐘一次 fsync ,或者每次執(zhí)行寫入命令時(shí) fsync 。 AOF 的默認(rèn)策略為每秒鐘 fsync一次,在這種配置下,Redis 仍然可以保持良好的性能,并且就算發(fā)生故障停機(jī),也最多只會(huì)丟失一秒鐘的數(shù)據(jù)

aof文件因?yàn)槟承┰蚨宋磳懭胪暾拿顁edis-check-aof 工具也可以輕易地修復(fù)這種問(wèn)題

Redis 可以在 AOF 文件體積變得過(guò)大時(shí),自動(dòng)地在后臺(tái)對(duì) AOF 進(jìn)行重寫: 重寫后的新 AOF 文件包含了恢復(fù)當(dāng)前數(shù)據(jù)集所需的最小命令集合。 整個(gè)重寫操作是絕對(duì)安全的,因?yàn)?Redis 在創(chuàng)建新 AOF 文件的過(guò)程中,會(huì)繼續(xù)將命令追加到現(xiàn)有的 AOF 文件里面,即使重寫過(guò)程中發(fā)生停機(jī),現(xiàn)有的 AOF 文件也不會(huì)丟失。 而一旦新 AOF 文件創(chuàng)建完畢,Redis 就會(huì)從舊 AOF 文件切換到新 AOF 文件,并開始對(duì)新 AOF 文件進(jìn)行追加操作
AOF文件可讀性交強(qiáng),也可手動(dòng)操作寫命令
AOF文件比RDB文件較大
官方文檔也指出,在某些情況下,AOF的確也存在一些bug,比如使用阻塞命令時(shí),這些bug的場(chǎng)景RDB是不存在的

------------------------------------

到此,相信大家對(duì)“Redis持久化的實(shí)現(xiàn)方法”有了更深的了解,不妨來(lái)實(shí)際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI