自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

聊一聊Redis持久化開與關(guān)

開發(fā) 項(xiàng)目管理 Redis
Redis的持久化功能被夸大和誤解了,這個(gè)問題我解釋過無數(shù)遍了,早就想寫個(gè)說明了,今天“忍不了”,和大家聊聊我的一些認(rèn)知,歡迎大佬們吐槽。

本文轉(zhuǎn)載自微信公眾號「Redis開發(fā)運(yùn)維實(shí)戰(zhàn)」,作者付磊 。轉(zhuǎn)載本文請聯(lián)系Redis開發(fā)運(yùn)維實(shí)戰(zhàn)公眾號。

經(jīng)常能碰到這樣的問題:

  1. A: Redis開持久化了嗎? 
  2. B: 沒有 
  3. A: 你們?yōu)槭裁床婚_?數(shù)據(jù)丟了怎么辦?數(shù)據(jù)不一致怎么辦? 

Redis的持久化功能被夸大和誤解了,這個(gè)問題我解釋過無數(shù)遍了,早就想寫個(gè)說明了,今天“忍不了”,和大家聊聊我的一些認(rèn)知,歡迎大佬們吐槽。

一、Redis”3“種持久化方式

1. RDB

簡單來說,對Redis做一個(gè)快照(利用fork)保存在磁盤上

(1) 優(yōu)點(diǎn):

  • 結(jié)構(gòu)緊湊體積小,加載速度快(相比AOF)
  • 可以做定期備份:例如低峰期(順便搞個(gè)數(shù)據(jù)分析也行)

(2) 缺點(diǎn):

  • 動作大、消耗大:全量操作對于磁盤、CPU、內(nèi)存等均有消耗
  • 無法做到"實(shí)時(shí)"備份
  • 格式多變(Redis 3 4 5 6版本多次修改)

2. AOF

簡單說把Redis的每條寫操作記錄到日志中,例如set hello world

  1. *3 
  2. $3 
  3. set 
  4. $5 
  5. hello 
  6. $5 
  7. world 

簡單說,落盤策略有三種:

  1. appendfsync always:每次事件循環(huán)都進(jìn)行一次同步操作(主線程) 
  2. appendfsync everysec:每秒進(jìn)行一次同步操作(另一個(gè)線程) 
  3. appendfsync no:由操作系統(tǒng)控制同步操作(操作系統(tǒng)) 

(1) 優(yōu)點(diǎn):

  • RESP標(biāo)準(zhǔn)格式:無版本兼容性問題
  • 實(shí)時(shí)性更高且成本較小

(2) 缺點(diǎn):

  • 體積大:協(xié)議 + 明文
  • 加載慢:利用fakeclient做回放
  • AOF重寫還是動作不小(本文不討論AOF重寫)

3. RDB-AOF混合

持久化文件全量使用RDB,增量使用AOF,保證體積、實(shí)時(shí)性、加載速度。(Redis 4提供,本文不討論)

二、開AOF性能會差多少?(注:AOF重寫也是資源消耗大頭,這里不討論)

1.測試環(huán)境:

  • CPU: Intel(R) Xeon(R) Gold 6248 CPU @ 2.50GHz
  • 機(jī)械磁盤
  • Redis版本:4.0.14(未測試Redis 6多線程)
  • 壓測工具:redis-benchmark
  • AOF策略:appendfsync everysec

2.壓測方法:

測試Redis在”開和關(guān)“AOF情況下,在不同size(64字節(jié)、128字節(jié)、512字節(jié))的OPS和耗時(shí)

(1) d=64字節(jié)

命令 ops(開AOF) ops(關(guān)AOF) 耗時(shí)(開AOF) 耗時(shí)(關(guān)AOF)
set 97352 121624 100.00% <= 0 milliseconds(總:5.14s) 100.00% <= 0 milliseconds(總:4.11s)
get 108979 109241 100.00% <= 0 milliseconds(總:4.59s) 100.00% <= 0 milliseconds(總:4.58s)
incr 104755 113301 100.00% <= 0 milliseconds(總:4.77s) 100.00% <= 0 milliseconds(總:4.41s)
lpush 95347 110889 100.00% <= 0 milliseconds(總:5.24s) 100.00% <= 0 milliseconds(總:4.51s)
hset 97770 113791 100.00% <= 0 milliseconds(總:5.11s) 100.00% <= 0 milliseconds(總:4.39s)

(2) d=128字節(jié)

命令 ops(開AOF) ops(關(guān)AOF) 耗時(shí)(開AOF) 耗時(shí)(關(guān)AOF)
set 108908 114077 100.00% <= 1 milliseconds
100.00% <= 2 milliseconds
(總:4.59s)
100.00% <= 0 milliseconds(總:4.38s)
get 107388 111756 100.00% <= 1 milliseconds(總:4.66s) 100.00% <= 0 milliseconds(總:4.47s)
incr 105042 113430 100.00% <= 0 milliseconds(總:4.76s) 100.00% <= 0 milliseconds(總:4.41s)
lpush 103114 114025 100.00% <= 0 milliseconds(總:4.85s) 100.00% <= 0 milliseconds(總:4.39s)
hset 101440 113791 100.00% <= 1 milliseconds(總:4.93s) 100.00% <= 1 milliseconds(總:4.93s)

(3) d=512字節(jié)

命令 ops(開AOF) ops(關(guān)AOF) 耗時(shí)(開AOF) 耗時(shí)(關(guān)AOF)
set 96581 108790 99.99% <= 1 milliseconds
99.99% <= 2 milliseconds
99.99% <= 3 milliseconds
99.99% <= 5 milliseconds
100.00% <= 6 milliseconds
100.00% <= 7 milliseconds
100.00% <= 8 milliseconds
100.00% <= 8 milliseconds
(總:5.18s)
100.00% <= 1 milliseconds(總:4.60s)
get 107898 105374 100.00% <= 0 milliseconds(總:4.63s) 100.00% <= 0 milliseconds(總:4.74s)
incr 102438 107991 100.00% <= 0 milliseconds(總:4.88s) 100.00% <= 0 milliseconds(總:4.63s)
lpush 93231 105064 99.98% <= 2 milliseconds
99.98% <= 3 milliseconds
99.99% <= 4 milliseconds
99.99% <= 5 milliseconds
99.99% <= 6 milliseconds
100.00% <= 7 milliseconds
100.00% <= 8 milliseconds
100.00% <= 8 milliseconds
(總:5.36s)
100.00% <= 0 milliseconds(總:4.76s)
hset 96955 108225 100.00% <= 6 milliseconds
100.00% <= 8 milliseconds
100.00% <= 9 milliseconds
100.00% <= 9 milliseconds
(總:5.16s)
100.00% <= 0 milliseconds(總:4.62s)

3. 總結(jié)說明:(注意此處沒有考慮AOF重寫,只能更差)

(1) 開啟AOF后,Redis的寫性能下降了8~25%,讀性能未下降(注意此處測試為非讀寫混合場景)

(2) 開啟AOF后,隨著數(shù)據(jù)量的增加相關(guān)讀寫性能會下降。

(3) 開啟AOF后,實(shí)際測試中發(fā)現(xiàn)單核CPU也會少量上漲。

三、一些問題的討論?

1. aof刷盤策略改為always能保證不丟數(shù)據(jù)嗎?

(1) 答案

會丟。Redis執(zhí)行一條寫入命令時(shí),會將數(shù)據(jù)寫入aof_buf,但寫入aof_buf和刷盤還是存在一次事件時(shí)間差。

(2) 原理:

Redis處理命令(server.c)processCommand->call(執(zhí)行命令),其中包含

  1. void propagate(struct redisCommand *cmd, int dbid, robj **argv, int argc, int flags) 
  2.    //寫入到aof_buf中 
  3.     if (server.aof_state != AOF_OFF && flags & PROPAGATE_AOF) 
  4.         feedAppendOnlyFile(cmd,dbid,argv,argc); 
  5.     ...... 

每次文件事件前的beforesleep(ae.c)

  1. void aeMain(aeEventLoop *eventLoop) { 
  2.     eventLoop->stop = 0; 
  3.     while (!eventLoop->stop) { 
  4.         if (eventLoop->beforesleep != NULL
  5.             eventLoop->beforesleep(eventLoop); 
  6.         aeProcessEvents(eventLoop, AE_ALL_EVENTS|AE_CALL_AFTER_SLEEP); 
  7.     } 

其中beforesleep包含了aof_buf落盤(server.c)

  1. void beforeSleep(struct aeEventLoop *eventLoop) { 
  2.   ...... 
  3.    //aof落盤 
  4.     flushAppendOnlyFile(0); 
  5.     ...... 

flushAppendOnlyFile利用操作系統(tǒng)的write和fsync(加上aof的三種策略)完成落盤:

2.Redis是什么一致性?

最終一致性??蛻舳藢懼骱?,不等從寫完。(為什么這樣?Redis設(shè)計(jì)目標(biāo)是什么?快!)

3.master節(jié)點(diǎn)故障后Redis怎么恢復(fù)?

(1) 關(guān)閉AOF:B節(jié)點(diǎn)晉升成主節(jié)點(diǎn),對外提供服務(wù)。A節(jié)點(diǎn)恢復(fù)后變?yōu)閟lave,依賴全量復(fù)制獲取全部數(shù)據(jù)

(2) 開啟AOF:同上...(只不過A節(jié)點(diǎn)全量復(fù)制后做一次AOF重寫)

所以看起來此模式下,對于故障恢復(fù)持久化沒什么用!

4.我就不想丟理論上最少的數(shù)據(jù),怎么辦?

開啟always,不用主從切換,等待A節(jié)點(diǎn)恢復(fù),重新加載AOF在提供服務(wù),老哥這個(gè)現(xiàn)實(shí)嗎???

五、最佳實(shí)踐?

1.RDB最佳

(1) 自動save:關(guān)、關(guān)、關(guān)(性能殺手)

(2) save命令:同步,忘記它(除非你一點(diǎn)內(nèi)存沒有了,還需要RDB)

(3) bgsave命令:備份可以用,請關(guān)注fork時(shí)間(info stats可查)

(4) 關(guān)閉掉:做不到,因?yàn)槿繌?fù)制默認(rèn)會用。

2.AOF最佳

(1) always不要用(主線程執(zhí)行、以及IO影響)

(2) everysec、no按需使用,如果僅僅想不丟數(shù)據(jù),AOF做不到。

(3) 除非怕主從都掛了,可以考慮。

不要忘記AOF臭名昭著的:

  1. Asynchronous AOF fsync is taking too long (disk is busy). Writing the AOF buffer without waiting for fsync to complete, this may slow down Redis 

3.單機(jī)多實(shí)例:你玩得起嗎?

以一個(gè)80 core,500G內(nèi)存的機(jī)器為例子,出于成本考慮至少要部署80~90個(gè)* memory(5G)的實(shí)例。在此場景下CPU、內(nèi)存、網(wǎng)絡(luò)的開銷基本還能控制,但如果開了AOF,用普通的磁盤,行不行?

  1. 會有:很多公司會為了做持久化,預(yù)留“一半”內(nèi)存,所以就是40~45個(gè) 
  2.  
  3. 還有:用SSD解決AOF的問題。 

4. "旁門左道"用法

(1) RDB:

定期備份(例如低峰期)、數(shù)據(jù)分析(分析出bigkey、hotkey、idlekey等)(阿里云的做法)

(2) AOF

原生AOF語義太弱,如果想做類似binlog功能可以對Redis內(nèi)核進(jìn)行修改,多機(jī)房同步會用上。

六、總結(jié)

Redis的持久化功能是一個(gè)重要功能,但如果想指望它實(shí)現(xiàn)“不丟數(shù)據(jù)”、“一致性”,那可能帶來的就是:低性能、高成本。

有時(shí)間整理下Redis3~6 AOF的一些變化,附圖一張:繼續(xù)搬磚去了(現(xiàn)在實(shí)例已經(jīng)130萬了。。)

 

責(zé)任編輯:武曉燕 來源: Redis開發(fā)運(yùn)維實(shí)戰(zhàn)
相關(guān)推薦

2022-08-30 10:15:27

Kubernetes數(shù)據(jù)持久化管理

2022-03-08 16:10:38

Redis事務(wù)機(jī)制

2022-05-12 23:19:15

Redis內(nèi)存碎片處理

2023-03-06 21:23:23

Redis數(shù)據(jù)庫

2020-04-24 09:53:59

Go協(xié)作搶占

2022-05-18 16:35:43

Redis內(nèi)存運(yùn)維

2022-03-31 10:41:35

iOS應(yīng)用提審發(fā)布

2021-03-10 00:02:01

Redis

2018-03-23 10:30:56

微網(wǎng)關(guān)服務(wù)嚙合微服務(wù)

2023-09-27 09:04:50

2021-09-15 14:52:43

數(shù)字貨幣傳銷虛擬貨幣

2021-01-28 22:31:33

分組密碼算法

2023-09-22 17:36:37

2020-05-22 08:16:07

PONGPONXG-PON

2018-06-07 13:17:12

契約測試單元測試API測試

2022-08-08 08:25:21

Javajar 文件

2021-08-04 09:32:05

Typescript 技巧Partial

2018-11-29 09:13:47

CPU中斷控制器

2019-02-13 14:15:59

Linux版本Fedora

2021-01-29 08:32:21

數(shù)據(jù)結(jié)構(gòu)數(shù)組
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號