redis同步效率秒_redis过期策略、内存淘汰策略、持久化方式、主从复制
一、Redis的過期策略以及內(nèi)存淘汰策略:
1、過期策略:定期刪除+惰性刪除:
①定期刪除:redis默認(rèn)每隔100ms就隨機抽取一些設(shè)置了過期時間的key,檢查其是否過期,如果有過期就刪除。注意這里是隨機抽取的。為什么要隨機呢?你想一想假如 redis 存了幾十萬個 key ,每隔100ms就遍歷所有的設(shè)置過期時間的 key 的話,就會給 CPU 帶來很大的負(fù)載。
②惰性刪除:定期刪除可能導(dǎo)致很多過期的key 到了時間并沒有被刪除掉。這時就要使用到惰性刪除。在你獲取某個key的時候,redis會檢查一下,這個key如果設(shè)置了過期時間并且過期了,是的話就刪除。
2、定期刪除+惰性刪除存在的問題:
如果定期刪除沒刪除key,然后也沒即時去請求key,也就是說惰性刪除也沒生效。這時,如果大量過期的key堆積在內(nèi)存中,redis的內(nèi)存會越來越高,導(dǎo)致redis的內(nèi)存塊耗盡。那么就應(yīng)該采用內(nèi)存淘汰機制。
3、為什么不用定時刪除策略?
定時刪除,用一個定時器來負(fù)責(zé)監(jiān)視key,過期則自動刪除。雖然內(nèi)存及時釋放,但是十分消耗CPU資源。在大并發(fā)請求下,CPU要將時間應(yīng)用在處理請求,而不是刪除key,因此沒有采用這一策略。
4、redis內(nèi)存數(shù)據(jù)淘汰策略:
問題:MySQL里有2000w數(shù)據(jù),redis中只存20w的數(shù)據(jù),如何保證redis中的數(shù)據(jù)都是熱點數(shù)據(jù)?redis內(nèi)存數(shù)據(jù)集大小上升到一定大小的時候,就會施行數(shù)據(jù)淘汰策略。
①allkeys-lru:在所有的鍵空間中,移除最近最少使用的key。推薦使用,目前項目在用這種。
②volatile-lru:在設(shè)置了過期時間的鍵空間中,移除最近最少使用的key。這種情況一般是把redis既當(dāng)緩存,又做持久化存儲的時候才用。不推薦
③allkeys-random:在鍵空間中,隨機移除某個key。應(yīng)該也沒人用吧,你不刪最少使用Key,去隨機刪。
④volatile-random:在設(shè)置了過期時間的鍵空間中,隨機移除某個key。依然不推薦。
⑤volatile-ttl:在設(shè)置了過期時間的鍵空間中,移除即將過期的key進(jìn)行淘汰。不推薦。
⑥noeviction:不進(jìn)行移除,新寫入操作會報錯。應(yīng)該沒人用吧。
ps:如果沒有設(shè)置 expire 的key, 不滿足先決條件(prerequisites); 那么 volatile-lru, volatile-random 和 volatile-ttl 策略的行為, 和 noeviction(不刪除) 基本上一致。
二、Reids的持久化方式:RDB和AOF
第一種持久化方式:RDB
1、什么是RDB:
在指定的時間間隔內(nèi)將內(nèi)存中的數(shù)據(jù)集快照寫入磁盤(dump.rdb文件),即Snapshot快照,它恢復(fù)時是將快照文件從磁盤直接讀到內(nèi)存里。
2、默認(rèn)持久化設(shè)置:
save 900 1 #在900秒(15分鐘)之后,如果至少有1個key發(fā)生變化,則dump內(nèi)存快照。
save 300 10 #在300秒(5分鐘)之后,如果至少有10個key發(fā)生變化,則dump內(nèi)存快照。
save 60 10000 #在60秒(1分鐘)之后,如果至少有10000個key發(fā)生變化,則dump內(nèi)存快照。
是1分鐘內(nèi)改了1萬次,或5分鐘內(nèi)改了10次,或15分鐘內(nèi)改了1次。
3、持久化原理:
Redis會單獨創(chuàng)建(fork)一個子進(jìn)程來進(jìn)行持久化,會先將數(shù)據(jù)寫入到一個臨時文件中,待持久化過程都結(jié)束了,再用這個臨時文件替換上次持久化好的文件。整個過程中,主進(jìn)程是不進(jìn)行任何IO操作的,這就確保了極高的性能。
fork的作用是復(fù)制一個與當(dāng)前進(jìn)程一樣的進(jìn)程。新進(jìn)程的所有數(shù)據(jù)(變量、環(huán)境變量、程序計數(shù)器等)數(shù)值都和原進(jìn)程一致,但是是一個全新的進(jìn)程,并作為原進(jìn)程的子進(jìn)程。
4、優(yōu)勢:
(1)如果需要進(jìn)行大規(guī)模數(shù)據(jù)的恢復(fù),且對于數(shù)據(jù)恢復(fù)的完整性不是非常敏感,那RDB方式要比AOF方式更加的高效。
(2)相比于AOF機制,如果數(shù)據(jù)集很大,RDB的啟動效率會更高。
5、劣勢:
(1)在一定間隔時間做一次備份,所以如果redis意外down掉的話,就會丟失最后一次快照后的所有修改。
(2)fork的時候,內(nèi)存中的數(shù)據(jù)被克隆了一份,大致2倍的膨脹性需要考慮。
第二種持久化方式:AOF:
1、什么是AOF:
以日志的形式來記錄每個寫操作,將Redis執(zhí)行過的所有寫指令記錄下來(讀操作不記錄),只許追加文件但不可以改寫文件,redis啟動之初會讀取該文件重新構(gòu)建數(shù)據(jù),換言之,redis重啟的話就根據(jù)日志文件的內(nèi)容將寫指令從前到后執(zhí)行一次以完成數(shù)據(jù)的恢復(fù)工作。(appendonly.aof文件)
2、AOF文件的rewrite機制:
(1)因為AOF采用文件追加方式,文件會越來越大,為避免出現(xiàn)此種情況,新增了重寫機制,當(dāng)AOF文件的大小超過所設(shè)定的閾值時,Redis就會啟動AOF文件的內(nèi)容壓縮,只保留可以恢復(fù)數(shù)據(jù)的最小指令集,可以使用命令bg rewriteaof,異步執(zhí)行一個 AOF(AppendOnly File) 文件重寫操作。
(2)重寫原理:AOF文件持續(xù)增長而過大時,會fork出一條新進(jìn)程來將文件重寫(也是先寫臨時文件最后再rename),遍歷新進(jìn)程的內(nèi)存中數(shù)據(jù),每條記錄有一條的Set語句。重寫aof文件的操作,并沒有讀取舊的aof文件,而是將整個內(nèi)存中的數(shù)據(jù)庫內(nèi)容用命令的方式重寫了一個新的aof文件,這點和快照有點類似。
在執(zhí)行 BGREWRITEAOF 命令時,Redis 服務(wù)器會維護(hù)一個 AOF 重寫緩沖區(qū),該緩沖區(qū)會在子進(jìn)程創(chuàng)建新AOF文件期
間,記錄服務(wù)器執(zhí)行的所有寫命令。當(dāng)子進(jìn)程完成創(chuàng)建新AOF文件的工作之后,服務(wù)器會將重寫緩沖區(qū)中的所有內(nèi)容追加到新AOF文件的末尾,使得新舊兩個AOF文件所保存的數(shù)據(jù)庫狀態(tài)一致。最后,服務(wù)器用新的AOF文件替換舊的AOF文件,以此來完成AOF文件重寫操作。
(3)觸發(fā)時機:Redis會記錄上次重寫時的AOF大小,默認(rèn)配置是當(dāng)AOF文件大小是上次rewrite后大小的一倍且文件大于64M時觸發(fā)。
3、AOF持久化配置:
(1)每修改同步:appendfsync always 同步持久化,每次發(fā)生數(shù)據(jù)變更會被立即記錄到磁盤,性能較差但數(shù)據(jù)完整性比較好。
(2)每秒同步:appendfsync everysec 異步操作,每秒記錄,如果一秒內(nèi)宕機,有數(shù)據(jù)丟失。
(3)不同步:appendfsync no 從不同步
4、劣勢:
(1)相同數(shù)據(jù)集的數(shù)據(jù)而言aof文件要遠(yuǎn)大于rdb文件,恢復(fù)速度慢于rdb。
(2)aof運行效率要慢于rdb,每秒同步策略效率較好,不同步效率和rdb相同。
注:如果同時開啟兩種持久化方式,在這種情況下,當(dāng)redis重啟的時候會優(yōu)先載入AOF文件來恢復(fù)原始的數(shù)據(jù),因為在通常情況下AOF文件保存的數(shù)據(jù)集要比RDB文件保存的數(shù)據(jù)集要完整。
Redis4.0對于持久化機制的優(yōu)化:
Redis4.0開始支持RDB和AOF的混合持久化(默認(rèn)關(guān)閉,可以通過配置項 aof-use-rdb-preamble 開啟)。
如果把混合持久化打開,AOF 重寫的時候就直接把 RDB 的內(nèi)容寫到 AOF 文件開頭。這樣做的好處是可以結(jié)合 RDB和 AOF 的優(yōu)點, 快速加載同時避免丟失過多的數(shù)據(jù)。當(dāng)然缺點也是有的, AOF 里面的 RDB 部分是壓縮格式不再是AOF 格式,可讀性較差。
三、Redis事務(wù):
可以一次執(zhí)行多個命令,本質(zhì)是一組命令的集合。一個事務(wù)中的所有命令都會序列化,一次性地按順序地串行化執(zhí)行,并且在事務(wù)執(zhí)行期間,服務(wù)器不會中斷事務(wù)而改去執(zhí)行其他客戶端的命令請求,即不會被其它命令插入,不許加塞,它會將事務(wù)中的所有命令都執(zhí)行完畢,然后才去處理其他客戶端的命令請求。即一個隊列中,一次性、順序性、排他性的執(zhí)行一系列命令。
1、常用命令:
(1)開啟事務(wù):MULTI。MULTI執(zhí)行之后,客戶端可以繼續(xù)向服務(wù)器發(fā)送任意多條命令,這些命令不會立即被執(zhí)行,而是被放到一個緩存隊列中,當(dāng)EXEC命令被調(diào)用時,所有隊列中的命令才會被執(zhí)行。
(2)執(zhí)行事務(wù):EXEC。
(3)放棄事務(wù):DISCARD。開啟事務(wù)之后,可以通過調(diào)用DISCARD,清空事務(wù)隊列,并放棄執(zhí)行事務(wù)。
(4)監(jiān)視key:WATCH。作為WATCH命令的參數(shù)的鍵會受到Redis的監(jiān)控,Redis能夠檢測到它們的變化。如果在事務(wù)執(zhí)行之前這些key被其他命令所改動,那么整個事務(wù)將會被打斷。WATCH命令可用于提供CAS(check-and-set)功能。
(5)取消監(jiān)視:UNWATCH。
2、Redis事務(wù)的特性:
(1)非原子性,不支持回滾:執(zhí)行EXEC命令的時候,Redis同一個事務(wù)中如果有一條命令執(zhí)行失敗,其后的命令仍然會被執(zhí)行,沒有回滾。在 EXEC 命令只保證批量操作的一次性批量執(zhí)行過程。
Redis 操作失敗的原因只可能是語法錯誤或者錯誤的數(shù)據(jù)庫類型操作,這些都是在開發(fā)層面能發(fā)現(xiàn)的問題不會進(jìn)入到生產(chǎn)環(huán)境,因此不需要回滾。
Redis 內(nèi)部設(shè)計推崇簡單和高性能,因此不需要回滾能力。
并且,Redis 的應(yīng)用場景明顯不是為了數(shù)據(jù)存儲的高可靠而設(shè)計的,而是為了數(shù)據(jù)訪問的高性能而設(shè)計,設(shè)計者為了簡單性和高性能而部分放棄了原子性。
②一致性:
③單獨的隔離操作,事務(wù)中的所有命令都會被序列化,按順序地執(zhí)行。事務(wù)在執(zhí)行的過程中,其他客戶端發(fā)送來的命令請求不會插入到事務(wù)執(zhí)行命令序列中。沒有隔離級別的概念,事務(wù)隊列中的命令沒有提交之前都不會實際的被執(zhí)行。
④持久性:如果Redis運行在某種特定的持久化模式下時,事務(wù)也具有持久性。當(dāng)使用Append-Only模式時,Redis會通過調(diào)用系統(tǒng)函數(shù)write將該事務(wù)內(nèi)的所有寫操作在本次調(diào)用中全部寫入磁盤。然而如果在寫入的過程中出現(xiàn)系統(tǒng)崩潰,如電源故障導(dǎo)致的宕機,那么此時也許只有部分?jǐn)?shù)據(jù)被寫入到磁盤,而另外一部分?jǐn)?shù)據(jù)卻已經(jīng)丟失。
四、Redis主從復(fù)制:
Redis支持主從復(fù)制的模式。原則:主機數(shù)據(jù)更新后根據(jù)配置和策略,自動同步到備機的master/slaver機制,slave不會將數(shù)據(jù)同步到master,Master以寫為主,Slave以讀為主。這樣可以有效減少單個機器的并發(fā)訪問數(shù)量。
1、配置要點:
(1)配從庫不配主。
(2)從庫配置:slaveof 主庫IP 主庫端口:
(3)slave每次與master斷開之后,都需要重新連接,除非你配置進(jìn)redis.conf文件。
(4)查看redis的配置信息:info replication
2、主從復(fù)制原理:
(1)slave啟動成功連接到master后會發(fā)送一個sync命令;
(2)Master接到slave的sync命令后,啟動后臺的存盤進(jìn)程,同時收集所有接收到的用于修改數(shù)據(jù)集命令,在后臺進(jìn)程執(zhí)行完畢之后,master將傳送整個數(shù)據(jù)文件到slave,以完成一次完全同步。
(3)全量復(fù)制:slave服務(wù)在接收到主機數(shù)據(jù)庫文件數(shù)據(jù)后,將其存盤并加載到內(nèi)存中。
(4)增量復(fù)制:Master繼續(xù)將新的所有收集到的修改命令依次傳給slave,完成同步。
(5)但是只要是重新連接master,一次完全同步(全量復(fù)制)將被自動執(zhí)行。
3、常用三招:
a、一主二從:一個Master兩個Slave
(1)切入點問題?slave1、slave2是從頭開始復(fù)制還是從切入點開始復(fù)制?比如從k4進(jìn)來,那之前的123是否也可以復(fù)制。答:從頭開始復(fù)制。
(2)從機是否可以寫?是否可以使用set命令?答:不可以。
(3)主機shutdown后情況如何?從機是上位還是原地待命?答:如果沒有配置哨兵模式,則是原地待命。
(4)主機又回來了后,主機新增記錄,從機還能否順利復(fù)制?答:能。
(5)其中一臺從機down后情況如何?依照原有它能跟上大部隊嗎?答:需要重新連接。
b、薪火相傳:
上一個Slave可以是下一個slave的Master,Slave同樣可以接收其他slaves的連接和同步請求,那么該slave作為了鏈條中下一個的master,可以有效減輕master的寫壓力。但是,如果中途變更轉(zhuǎn)向,則會清除之前的數(shù)據(jù),重新建立拷貝最新的主機數(shù)據(jù)。
c、反客為主:SLAVEOF no one。原本的Master掛掉之后,執(zhí)行此命令,會重新選擇一臺Master。
4、哨兵模式(sentinel):
反客為主的自動版,能夠后臺監(jiān)控主機是否故障,如果故障了根據(jù)投票數(shù)自動將從庫轉(zhuǎn)換為主庫。
如果之前的master重啟回來,不會造成雙master沖突,因為原本的master會變成slave。
配置步驟:
(1)在自定義的/myredis目錄下新建sentinel.conf文件,名字絕不能錯。
(2)配置哨兵,在配置文件中寫: sentinel monitor 被監(jiān)控數(shù)據(jù)庫名字(自己起名字) 127.0.0.1 6379 1
上面最后一個數(shù)字1,表示主機掛掉后salve投票看讓誰接替成為主機,得票數(shù)多少后成為主機。
(3)啟動哨兵:redis-sentinel /myredis/sentinel.conf
5、主從復(fù)制的缺點:由于所有的寫操作都是先在Master上操作,然后同步更新到Slave上,所以從Master同步到Slave機器有一定的延遲,當(dāng)系統(tǒng)很繁忙的時候,延遲問題會更加嚴(yán)重,Slave機器數(shù)量的增加也會使這個問題更加嚴(yán)重。
總結(jié)
以上是生活随笔為你收集整理的redis同步效率秒_redis过期策略、内存淘汰策略、持久化方式、主从复制的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python add argument
- 下一篇: 二阶矩阵转置怎么求_矩阵求导术(下)