redis多服务器共享_【数据库】Redis(二)持久化及事务
Redis的數(shù)據(jù)持久化
??? Redis是基于內(nèi)存對數(shù)據(jù)操作的數(shù)據(jù)庫,計算機(jī)重啟后,內(nèi)存中的數(shù)據(jù)就會丟失,所以redis提供了持久化的功能,可以將redis操作的內(nèi)存中數(shù)據(jù)持久化到本地的硬盤中。在redis重啟之后,會自動把硬盤的持久化好的數(shù)據(jù)加載到redis操作的內(nèi)存中。redis的持久化機(jī)制有兩種,RDB和AOF,下面我們分別描述。
01
RDB
????RDB全稱是Redis Database,RDB機(jī)制就是對當(dāng)前Redis操作的內(nèi)存中的數(shù)據(jù)做一次全量的備份(snap shotting),把數(shù)據(jù)從內(nèi)存寫入到硬盤中。在持久化的過程中,會涉及到比較多的知識點(diǎn),比如在持久化的過程中,redis的服務(wù)進(jìn)程還可以處理新的對數(shù)據(jù)的讀寫請求嗎?在持久化的過程中,redis突然崩了,持久化中斷了怎么辦,等等問題。為了解決上述問題,我們有必要了解一下RDB持久化的原理。
準(zhǔn)備知識—COW機(jī)制
????COW(copy-on-write)寫入時復(fù)制,它不是Redis中特定的概念,是一種計算機(jī)程序設(shè)計領(lǐng)域的優(yōu)化策略。其核心思想是,如果有多個調(diào)用者(callers)同時請求相同資源(如內(nèi)存或磁盤上的數(shù)據(jù)存儲),他們會共同獲取相同的指針指向相同的資源,直到某個調(diào)用者試圖修改資源的內(nèi)容時,系統(tǒng)才會真正復(fù)制一份專用副本(private copy)給該調(diào)用者,而其他調(diào)用者所見到的最初的資源仍然保持不變。這過程對其他的調(diào)用者都是透明的(transparently)。此做法主要的優(yōu)點(diǎn)是如果調(diào)用者沒有修改該資源,就不會有副本(private copy)被建立,因此多個調(diào)用者只是讀取操作時可以共享同一份資源。
????我們總結(jié)成一句話:“多個線程訪問某個共享資源,當(dāng)對這個資源有寫操作的時候拷貝一份新的,在新的上面進(jìn)行寫入,寫入完成后,再將新的結(jié)果賦值給舊的數(shù)據(jù)。”
RDB持久化的實(shí)現(xiàn)過程
????在這里我們說的RDB持久化的過程其實(shí)就是后面我們要提到的使用bgsave命令后RDB持久化的過程(save命令基本上廢棄不用了),從這個命令的名稱bg(background)“后臺”,可以看出,這個命令在持久化的過程中,redis主線程(或者叫服務(wù)器)仍然可以處理客戶端發(fā)來的請求。我們來看具體過程:
1、執(zhí)行bgsave命令,Redis父進(jìn)程首先判斷:當(dāng)前是否在執(zhí)行save,或bgsave/bgrewriteaof(aof文件重寫命令)的子進(jìn)程,如果在執(zhí)行則bgsave命令直接返回。
2、父進(jìn)程執(zhí)行fork操作創(chuàng)建子進(jìn)程,fork操作過程中父進(jìn)程會阻塞的,Redis不能執(zhí)行來自客戶端的任何命令;通過info status命令查看lastest_fork_usee選項,可以獲取最近一個fork操作的耗時,該過程時間極其的短,單位為微秒。
3、父進(jìn)程fork完成后,bgsave命令返回”Background saving started”信息并不再阻塞父進(jìn)程,并可以響應(yīng)其他客戶端命令。
4、子進(jìn)程根據(jù)父進(jìn)程內(nèi)存快照生成臨時快照文件,開始對數(shù)據(jù)進(jìn)行持久化,完成后對原有的.rdb文件進(jìn)行原子替換。
注:在這個過程中就會使用到COW機(jī)制,創(chuàng)建子進(jìn)程的時,子進(jìn)程與父進(jìn)程共享父進(jìn)程的內(nèi)存數(shù)據(jù),如果父進(jìn)程有對數(shù)據(jù)的寫操作,父進(jìn)程會復(fù)制一份內(nèi)存數(shù)據(jù)的副本進(jìn)行操作,而不會影響到子進(jìn)程對數(shù)據(jù)的持久化操作。
5、子進(jìn)程持久化完畢后,子進(jìn)程發(fā)送信號給父進(jìn)程表示完成,父進(jìn)程更新統(tǒng)計信息。
RDB持久化的觸發(fā)方式
手動觸發(fā):
????save命令:同步持久化,在主線程中保存快照;阻塞當(dāng)前Redis服務(wù)器,直到RDB過程完成為止,對于內(nèi)存比較大的實(shí)例會造成長時間阻塞。
????bgsave命令:異步持久化,Redis進(jìn)程執(zhí)行fork操作創(chuàng)建子進(jìn)程,RDB持久化過程由子進(jìn)程負(fù)責(zé),完成后自動結(jié)束。堵塞只發(fā)生在fork階段,一般時間很短;BGSAVE命令是針對SAVE堵塞問題做的優(yōu)化。因此Redis內(nèi)部所有的設(shè)計RDB的操作都采用BGSAVE的方式,而save命令已經(jīng)廢棄。
自動觸發(fā):
????命令格式:save m n
????過程:指定當(dāng)m秒內(nèi)發(fā)生n次變化時,會自動觸發(fā)bgsave
優(yōu)缺點(diǎn)
優(yōu)點(diǎn):在重啟時,對于保存了大數(shù)據(jù)集的實(shí)例,恢復(fù)時比 AOF 要快,適合大規(guī)模數(shù)據(jù)的恢復(fù)。
缺點(diǎn):
????1、主線程復(fù)制副本的時候增加的內(nèi)存消耗
????2、意外掛了主線程更新的數(shù)據(jù)沒有備份進(jìn)去,數(shù)據(jù)丟失的風(fēng)險比較大
02
AOF
????AOF(append only file)日志記錄了Redis服務(wù)器中從實(shí)例創(chuàng)建之初“對內(nèi)存修改指令”的所有指令序列。所以恢復(fù)數(shù)據(jù)時,只需要在一個空的Redis實(shí)例序列中AOF日志中所有的指令全部執(zhí)行一遍,就會使redis的服務(wù)器狀態(tài)恢復(fù)到最新。
AOF操作方式
開啟AOF持久化:appendonly yes|no
AOF寫數(shù)據(jù)策略:appendfsync? always|everysec|no
???????????????????????always:每個redis的寫命令都要同步寫入硬盤
???????????????????????everysec:每秒執(zhí)行一次同步
????????????????????? ?no:讓操作系統(tǒng)決定。
缺點(diǎn)
AOF的文件體積過大,還原數(shù)據(jù)的時間較長。
解決:bgrewriteaof命令對AOF文件瘦身。
Redis中的事務(wù)
????事務(wù)提供了一種將多個命令請求打包,然后一次性、按順序地執(zhí)行多個命令的機(jī)制,并且在事務(wù)執(zhí)行期間,服務(wù)器不會中斷事務(wù)而去執(zhí)行其他客戶端命令。Redis提供了“簡單的”事務(wù)處理能力。
Redis的事務(wù)命令
????一個事務(wù)從開始到執(zhí)行會經(jīng)歷以下三個階段:
1、開始事務(wù):命令:multi
2、命令入隊:mul命令之后對redis的操作會放入命令隊列
3、事務(wù)執(zhí)行:命令:exec
示例:
127.0.0.1:6379> multiOK127.0.0.1:6379> zadd nametable 100 zhangsanQUEUED127.0.0.1:6379> zadd nametable 99 lisiQUEUED127.0.0.1:6379> exec1) (integer) 12) (integer) 1Redis事務(wù)中的其他命令:
??? discard:丟棄
Redis的事務(wù)是原子性的嗎
????事務(wù)的原子性:一個事務(wù)中的多條指令,要么全部執(zhí)行,要么全都不執(zhí)行,只要有一條指令的執(zhí)行過程中出錯,就會導(dǎo)致整個事務(wù)的回滾。但是在redis中,如果一個事務(wù)中的某條指令出錯,其余指令仍然會執(zhí)行,所以Redis中的事務(wù)并不滿足原子性。僅僅是滿足了事務(wù)的隔離性,也就是執(zhí)行過程中不被打斷的權(quán)力。示例如下:
127.0.0.1:6379> multiOK127.0.0.1:6379> set age 20QUEUED127.0.0.1:6379> incr ageQUEUED127.0.0.1:6379> set name zhangsanQUEUED127.0.0.1:6379> incr nameQUEUED127.0.0.1:6379> exec1) OK2) (integer) 213) OK4) (error) ERR value is not an integer or out of range127.0.0.1:6379> get age"21"watch指令
??? watch指令用于監(jiān)聽一個變量,當(dāng)事務(wù)執(zhí)行時,服務(wù)器收到了exec命令時,會檢查watch的變量是否做了更改,如果變量被更改,則返回null告訴客戶端執(zhí)行失敗。注意:watch指令必須在multi之前,multi和exec之間不允許
127.0.0.1:6379> watch sexOK127.0.0.1:6379> set sex maleOK127.0.0.1:6379> multiOK127.0.0.1:6379> set sex femaleQUEUED127.0.0.1:6379> exec(nil)end
總結(jié)
以上是生活随笔為你收集整理的redis多服务器共享_【数据库】Redis(二)持久化及事务的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 请确定指定的驱动器中是否有盘_百格拉伺服
- 下一篇: python统计窗口函数怎么处理_pyt