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