分佈式緩存redis 高可用 (上)

什麼是Redis?

Redis是由意大利人Salvatore Sanfilippo(網名:antirez)開發的一款內存高速緩存數據庫。Redis全稱為:Remote Dictionary Server(遠程數據服務),該軟件使用C語言編寫,Redis是一個key-value存儲系統,它支持豐富的數據類型,如:string、list、set、zset(sorted set)、hash。

Redis採用的是基於內存的採用的是單進程單線程模型的KV數據庫,由C語言編寫。官方提供的數據是可以達到100000+的qps

Redis單線程好處

代碼更清晰,處理邏輯更簡單

不用去考慮各種鎖的問題,不存在加鎖釋放鎖操作,沒有因為可能出現死鎖而導致的性能消耗

不存在多進程或者多線程導致的切換而消耗CPU

所以redis線程是安全的

單進程單線程弊端

無法發揮多核CPU性能,不過可以通過在單機開多個Redis實例來完善;

Redis應用場

1. 令牌(Token)生成

2. 短信驗證碼

3. 發佈訂閱

相當於消息系統,ActiveMQ,RocketMQ等工具類似,但是個人覺得簡單用一下還行,如果對於數據一致性要求高的話還是用RocketMQ等專業系統。

由於redis把數據添加到隊列是返回添加元素在隊列的第幾位,所以可以做判斷用戶是第幾個訪問這種業務

隊列不僅可以把併發請求變成串行,並且還可以做隊列或者棧使用

4. 分佈式鎖

驗證前端的重複請求(可以自由擴展類似情況),可以通過redis進行過濾:每次請求將request Ip、參數、接口等hash作為key存儲redis(冪等性請求),設置多長時間有效期,然後下次請求過來的時候先在redis中檢索有沒有這個key,進而驗證是不是一定時間內過來的重複提交

秒殺系統,基於redis是單線程特徵,防止出現數據庫“爆破”

全局增量ID生成,類似“秒殺”

5. 計數器

諸如統計點擊數等應用。由於單線程,可以避免併發問題,保證不會出錯,而且100%毫秒級性能!

6. 緩存(熱點數據)

熱點數據(經常會被查詢,但是不經常被修改或者刪除的數據),首選是使用redis緩存,畢竟強大到冒泡的QPS和極強的穩定性不是所有類似工具都有的,而且相比於memcached還提供了豐富的數據類型可以使用,另外,內存中的數據也提供了AOF和RDB等持久化機制可以選擇,要冷、熱的還是忽冷忽熱的都可選。

結合具體應用需要注意一下:很多人用spring的AOP來構建redis緩存的自動生產和清除,過程可能如下:

Select 數據庫前查詢redis,有的話使用redis數據,放棄select 數據庫,沒有的話,select 數據庫,然後將數據插入redis

update或者delete數據庫錢,查詢redis是否存在該數據,存在的話先刪除redis中數據,然後再update或者delete數據庫中的數據

上面這種操作,如果併發量很小的情況下基本沒問題,但是高併發的情況請注意下面場景:

為了update先刪掉了redis中的該數據,這時候另一個線程執行查詢,發現redis中沒有,瞬間執行了查詢SQL,並且插入到redis中一條數據,回到剛才那個update語句,這個悲催的線程壓根不知道剛才那個該死的select線程犯了一個彌天大錯!於是這個redis中的錯誤數據就永遠的存在了下去,直到下一個update或者delete。

Linux環境下安裝Redis

./redis-cli -h 127.0.0.1 -p 6379 -a "123456"
PING 結果表示成功
 
關閉防火牆
//臨時關閉
systemctl stop firewalld
//禁止開機啟動
systemctl disable firewalld
Removed symlink /etc/systemd/system/multi-user.target.wants/firewalld.service.
Removed symlink /etc/systemd/system/dbus-org.fedoraproject.FirewallD1.service.
停止Redis服務
./redis-cli -h 127.0.0.1 -p 6379 -a "123456" shutdown
修改redis.conf
註釋掉
#bind 127.0.0.1 開啟外網訪問

redis基本數據類型

Redis目前支持5種數據類型,分別是:

String(字符串)

List(列表)

Hash(字典)

Set(集合)

Sorted Set(有序集合)

下面就分別介紹這五種數據類型及其相應的操作命令。

String(字符串)

String是簡單的 key-value 鍵值對,value 不僅可以

是 String,也可以是數字。String在redis內部存儲默認就是一個字符串,被redisObject所引用,當遇到incr,decr等操作時會轉成數值型進行計算,此時redisObject的encoding字段為int。

String在redis內部存儲默認就是一個字符串,被redisObject所引用,當遇到incr,decr等操作時會轉成數值型進行計算,此時redisObject的encoding字段為int。

應用場景:

String是最常用的一種數據類型,普通的key/value存儲都可以歸為此類,這裡就不所做解釋了。

redis 127.0.0.1:6379> SET mykey "redis"
OK
redis 127.0.0.1:6379> GET mykey
"redis"

List(列表)

Redis列表是簡單的字符串列表,可以類比到C++中的std::list,簡單的說就是一個鏈表或者說是一個隊列。可以從頭部或尾部向Redis列表添加元素。列表的最大長度為2^32 - 1,也即每個列表支持超過40億個元素。

Redis list的實現為一個雙向鏈表,即可以支持反向查找和遍歷,更方便操作,不過帶來了部分額外的內存開銷,Redis內部的很多實現,包括髮送緩衝隊列等也都是用的這個數據結構。

應用場景

Redis list的應用場景非常多,也是Redis最重要的數據結構之一,比如twitter的關注列表、粉絲列表等都可以用Redis的list結構來實現,再比如有的應用使用Redis的list類型實現一個簡單的輕量級消息隊列,生產者push,消費者pop/bpop。

redis 127.0.0.1:6379> LPUSH runoobkey redis(integer) 1redis 127.0.0.1:6379> LPUSH runoobkey mongodb(integer) 2redis 127.0.0.1:6379> LPUSH runoobkey mysql(integer) 3redis 127.0.0.1:6379> LRANGE runoobkey 0 101) "mysql"2) "mongodb"3) "redis"

Hash(字典)

Redis Hash對應Value內部實際就是一個HashMap,實際這裡會有2種不同實現,這個Hash的成員比較少時Redis為了節省內存會採用類似一維數組的方式來緊湊存儲,而不會採用真正的HashMap結構,對應的value redisObject的encoding為zipmap,當成員數量增大時會自動轉成真正的HashMap,此時encoding為

Set(集合)

Redis的Set是string類型的無序集合。集合成員是唯一的,這就意味著集合中不能出現重複的數據。

Redis 中 集合是通過哈希表實現的,所以添加,刪除,查找的複雜度都是O(1)。

集合中最大的成員數為 232 - 1 (4294967295, 每個集合可存儲40多億個成員)。

redis 127.0.0.1:6379> SADD runoobkey redis(integer) 1redis 127.0.0.1:6379> SADD runoobkey mongodb(integer) 1redis 127.0.0.1:6379> SADD runoobkey mysql(integer) 1redis 127.0.0.1:6379> SADD runoobkey mysql(integer) 0redis 127.0.0.1:6379> SMEMBERS runoobkey1) "mysql"2) "mongodb"3) "redis"

Sorted Set(有序集合)

Redis 有序集合和集合一樣也是string類型元素的集合,且不允許重複的成員。

不同的是每個元素都會關聯一個double類型的分數。redis正是通過分數來為集合中的成員進行從小到大的排序。

有序集合的成員是唯一的,但分數(score)卻可以重複。

集合是通過哈希表實現的,所以添加,刪除,查找的複雜度都是O(1)。 集合中最大的成員數為 232 - 1 (4294967295, 每個集合可存儲40多億個成員)。

redis 127.0.0.1:6379> ZADD runoobkey 1 redis(integer) 1redis 127.0.0.1:6379> ZADD runoobkey 2 mongodb(integer) 1redis 127.0.0.1:6379> ZADD runoobkey 3 mysql(integer) 1redis 127.0.0.1:6379> ZADD runoobkey 3 mysql(integer) 0redis 127.0.0.1:6379> ZADD runoobkey 4 mysql(integer) 0redis 127.0.0.1:6379> ZRANGE runoobkey 0 10 WITHSCORES1) "redis"2) "1"3) "mongodb"4) "2"5) "mysql"6) "4"


Redis客戶端連接工具

redisclient-win32.x86.1.5

SrpingBoot整合Redis

Maven依賴
 
 org.springframework.boot
 spring-boot-starter-parent
 2.0.0.RELEASE
 
 
 
 
 org.springframework.boot
 spring-boot-starter-web
 
 
 org.springframework.boot
 spring-boot-starter-data-redis
 
 
 
 
 
 org.apache.maven.plugins
 
maven-compiler-plugin
 
 1.8
 1.8
 
 
 
 org.springframework.boot
 spring-boot-maven-plugin
  
 
 com.itmayiedu.controller.IndexController
 
 
 
 
 repackage
 
 
 
  
 
 

配置文件

spring:
 redis:
 database: 0
 host: 132.232.44.194
 port: 6379
 password: 123456
 jedis:
 pool:
 max-active: 8
 max-wait: -1
 max-idle: 8
 min-idle: 0
 timeout: 10000


@Component
public class RedisService {
 @Autowired
 private StringRedisTemplate stringRedisTemplate;
 public void set(String key, Object object, Long time) {
 // 存放String 類型
 if (object instanceof String) {
 setString(key, object); 
 }
 // 存放 set類型
 if (object instanceof Set) {
 setSet(key, object);
 }
 // 設置有效期 以秒為單位
 stringRedisTemplate.expire(key, time, TimeUnit.SECONDS);
 }
 public void setString(String key, Object object) {
 // 如果是String 類型
 String value = (String) object;
 stringRedisTemplate.opsForValue().set(key, value);
 }
 public void setSet(String key, Object object) {
 Set value = (Set) object;
 for (String oj : value) {
 stringRedisTemplate.opsForSet().add(key, oj);
 }
 }
 public String getString(String key) {
 return stringRedisTemplate.opsForValue().get(key);
 }
}

代碼整合Redi

 @Autowired
 private RedisService redisService;
 @RequestMapping("/setString")
 public String setString(String key, String value) {
 redisService.set(key, value, 60l);
 return "success";
 }
 @RequestMapping("/getString")
 public String getString(String key) {
 return redisService.getString(key);
 }
 @RequestMapping("/setSet")
 public String setSet() { 
 Set set = new HashSet();
 set.add("yushengjun");
 set.add("lisi");
 redisService.setSet("setTest", set);
 return "success";
 }
}

Redis發佈訂閱

Redis 發佈訂閱(pub/sub)是一種消息通信模式:發送者(pub)發送消息,訂閱者(sub)接收消息。

Redis 客戶端可以訂閱任意數量的頻道。

下圖展示了頻道 channel1 , 以及訂閱這個頻道的三個客戶端 —— client2 、 client5 和 client1 之間的關係:


分佈式緩存redis 高可用 (上)


當有新消息通過 PUBLISH 命令發送給頻道 channel1 時, 這個消息就會被髮送給訂閱它的三個客戶端:

分佈式緩存redis 高可用 (上)


在我們實例中我們創建了訂閱頻道名為 redisChat:

redis 127.0.0.1:6379> SUBSCRIBE redisChat

Reading messages... (press Ctrl-C to quit)

1) "subscribe"

2) "redisChat"

3) (integer) 1


現在,我們先重新開啟個 redis 客戶端,然後在同一個頻道 redisChat 發佈兩次消息,訂閱者就能接收到消息。

redis 127.0.0.1:6379> PUBLISH redisChat "Redis is a great caching technique"

(integer) 1

redis 127.0.0.1:6379> PUBLISH redisChat "Learn redis by runoob.com"

(integer) 1

# 訂閱者的客戶端會顯示如下消息

1) "message"

2) "redisChat"

3) "Redis is a great caching technique"

1) "message"

2) "redisChat"

3) "Learn redis by runoob.com"


Redis主從複製

概述

1、redis的複製功能是支持多個數據庫之間的數據同步。一類是主數據庫(master)一類是從數據庫(slave),主數據庫可以進行讀寫操作,當發生寫操作的時候自動將數據同步到從數據庫,而從數據庫一般是隻讀的,並接收主數據庫同步過來的數據,一個主數據庫可以有多個從數據庫,而一個從數據庫只能有一個主數據庫。

2、通過redis的複製功能可以很好的實現數據庫的讀寫分離,提高服務器的負載能力。主數據庫主要進行寫操作,而從數據庫負責讀操作。

主從複製過程:見下圖

分佈式緩存redis 高可用 (上)


過程:

1:當一個從數據庫啟動時,會向主數據庫發送sync命令,

2:主數據庫接收到sync命令後會開始在後臺保存快照(執行rdb操作),並將保存期間接收到的命令緩存起來

3:當快照完成後,redis會將快照文件和所有緩存的命令發送給從數據庫。

4:從數據庫收到後,會載入快照文件並執行收到的緩存的命令。

什麼是哨兵機制?

Redis的哨兵(sentinel) 系統用於管理多個 Redis 服務器,該系統執行以下三個任務:

· 監控(Monitoring): 哨兵(sentinel) 會不斷地檢查你的Master和Slave是否運作正常。

· 提醒(Notification):當被監控的某個 Redis出現問題時, 哨兵(sentinel) 可以通過 API 向管理員或者其他應用程序發送通知。

· 自動故障遷移(Automatic failover):當一個Master不能正常工作時,哨兵(sentinel) 會開始一次自動故障遷移操作,它會將失效Master的其中一個Slave升級為新的Master, 並讓失效Master的其他Slave改為複製新的Master; 當客戶端試圖連接失效的Master時,集群也會向客戶端返回新Master的地址,使得集群可以使用Master代替失效Master。

哨兵(sentinel) 是一個分佈式系統,你可以在一個架構中運行多個哨兵(sentinel) 進程,這些進程使用流言協議(gossipprotocols)來接收關於Master是否下線的信息,並使用投票協議(agreement protocols)來決定是否執行自動故障遷移,以及選擇哪個Slave作為新的Master.

每個哨兵(sentinel) 會向其它哨兵(sentinel)、master、slave定時發送消息,以確認對方是否”活”著,如果發現對方在指定時間(可配置)內未回應,則暫時認為對方已掛(所謂的”主觀認為宕機” Subjective Down,簡稱sdown).

若“哨兵群”中的多數sentinel,都報告某一master沒響應,系統才認為該master"徹底死亡"(即:客觀上的真正down機,Objective Down,簡稱odown),通過一定的vote算法,從剩下的slave節點中,選一臺提升為master,然後自動修改相關配置.

雖然哨兵(sentinel) 釋出為一個單獨的可執行文件 redis-sentinel ,但實際上它只是一個運行在特殊模式下的 Redis 服務器,你可以在啟動一個普通 Redis 服務器時通過給定 --sentinel 選項來啟動哨兵(sentinel).

哨兵(sentinel) 的一些設計思路和zookeeper非常類似

單個哨兵(sentinel)


分佈式緩存redis 高可用 (上)

哨兵模式修改配置

實現步驟:

1.拷貝到etc目錄

cp sentinel.conf /usr/local/redis/etc

2.修改sentinel.conf配置文件

sentinel monitor mymast 192.168.110.133 6379 1 #主節點 名稱 IP 端口號 選舉次數

sentinel auth-pass mymaster 123456

3. 修改心跳檢測 30毫秒

sentinel down-after-milliseconds mymaster 30

4.sentinel parallel-syncs mymaster 2 --- 做多多少合格節點

5. 啟動哨兵模式

./redis-server /usr/local/redis/etc/sentinel.conf --sentinel &


什麼是Redis持久化

什麼是Redis持久化,就是將內存數據保存到硬盤。

Redis 持久化存儲 (AOF 與 RDB 兩種模式)

RDB持久化

RDB 是以二進制文件,是在某個時間 點將數據寫入一個臨時文件,持久化結束後,用這個臨時文件替換上次持久化的文件,達到數據恢復。


優點:使用單獨子進程來進行持久化,主進程不會進行任何 IO 操作,保證了 redis 的高性能


缺點:RDB 是間隔一段時間進行持久化,如果持久化之間 redis 發生故障,會發生數據丟失。所以這種方式更適合數據要求不嚴謹的時候


這裡說的這個執行數據寫入到臨時文件的時間點是可以通過配置來自己確定的,通過配置redis 在 n 秒內如果超過 m 個 key 被修改這執行一次 RDB 操作。這個操作就類似於在這個時間點來保存一次 Redis 的所有數據,一次快照數據。所有這個持久化方法也通常叫做 snapshots。

RDB 默認開啟,redis.conf 中的具體配置參數如下;

#dbfilename:持久化數據存儲在本地的文件

dbfilename dump.rdb

#dir:持久化數據存儲在本地的路徑,如果是在/redis/redis-3.0.6/src下啟動的redis-cli,則數據會存儲在當前src目錄下

dir ./

##snapshot觸發的時機,save

##如下為900秒後,至少有一個變更操作,才會snapshot

##對於此值的設置,需要謹慎,評估系統的變更操作密集程度

##可以通過“save “””來關閉snapshot功能

#save時間,以下分別表示更改了1個key時間隔900s進行持久化存儲;更改了10個key300s進行存儲;更改10000個key60s進行存儲。

save 900 1

save 300 10

save 60 10000

##當snapshot時出現錯誤無法繼續時,是否阻塞客戶端“變更操作”,“錯誤”可能因為磁盤已滿/磁盤故障/OS級別異常等

stop-writes-on-bgsave-error yes

##是否啟用rdb文件壓縮,默認為“yes”,壓縮往往意味著“額外的cpu消耗”,同時也意味這較小的文件尺寸以及較短的網絡傳輸時間

rdbcompression yes

AOF持久化

Append-only file,將“操作 + 數據”以格式化指令的方式追加到操作日誌文件的尾部,在 append 操作返回後(已經寫入到文件或者即將寫入),才進行實際的數據變更,“日誌文件”保存了歷史所有的操作過程;當 server 需要數據恢復時,可以直接 replay 此日誌文件,即可還原所有的操作過程。AOF 相對可靠,它和 mysql 中 bin.log、apache.log、zookeeper 中 txn-log 簡直異曲同工。AOF 文件內容是字符串,非常容易閱讀和解析。


優點:可以保持更高的數據完整性,如果設置追加 file 的時間是 1s,如果 redis 發生故障,最多會丟失 1s 的數據;且如果日誌寫入不完整支持 redis-check-aof 來進行日誌修復;AOF 文件沒被 rewrite 之前(文件過大時會對命令進行合併重寫),可以刪除其中的某些命令(比如誤操作的 flushall)。


缺點:AOF 文件比 RDB 文件大,且恢復速度慢。


我們可以簡單的認為 AOF 就是日誌文件,此文件只會記錄“變更操作”(例如:set/del 等),如果 server 中持續的大量變更操作,將會導致 AOF 文件非常的龐大,意味著 server 失效後,數據恢復的過程將會很長;事實上,一條數據經過多次變更,將會產生多條 AOF 記錄,其實只要保存當前的狀態,歷史的操作記錄是可以拋棄的;因為 AOF 持久化模式還伴生了“AOF rewrite”。


AOF 的特性決定了它相對比較安全,如果你期望數據更少的丟失,那麼可以採用 AOF 模式。如果 AOF 文件正在被寫入時突然 server 失效,有可能導致文件的最後一次記錄是不完整,你可以通過手工或者程序的方式去檢測並修正不完整的記錄,以便通過 aof 文件恢復能夠正常;同時需要提醒,如果你的 redis 持久化手段中有 aof,那麼在 server 故障失效後再次啟動前,需要檢測 aof 文件的完整性。


AOF 默認關閉,開啟方法,修改配置文件 reds.conf:appendonly yes

##此選項為aof功能的開關,默認為“no”,可以通過“yes”來開啟aof功能

##只有在“yes”下,aof重寫/文件同步等特性才會生效

appendonly yes

##指定aof文件名稱

appendfilename appendonly.aof

##指定aof操作中文件同步策略,有三個合法值:always everysec no,默認為everysec

appendfsync everysec

##在aof-rewrite期間,appendfsync是否暫緩文件同步,"no"表示“不暫緩”,“yes”表示“暫緩”,默認為“no”

no-appendfsync-on-rewrite no

##aof文件rewrite觸發的最小文件尺寸(mb,gb),只有大於此aof文件大於此尺寸是才會觸發rewrite,默認“64mb”,建議“512mb”

auto-aof-rewrite-min-size 64mb

##相對於“上一次”rewrite,本次rewrite觸發時aof文件應該增長的百分比。

##每一次rewrite之後,redis都會記錄下此時“新aof”文件的大小(例如A),那麼當aof文件增長到A*(1 + p)之後

##觸發下一次rewrite,每一次aof記錄的添加,都會檢測當前aof文件的尺寸。

auto-aof-rewrite-percentage 100


AOF 是文件操作,對於變更操作比較密集的 server,那麼必將造成磁盤 IO 的負荷加重;此外 linux 對文件操作採取了“延遲寫入”手段,即並非每次 write 操作都會觸發實際磁盤操作,而是進入了 buffer 中,當 buffer 數據達到閥值時觸發實際寫入(也有其他時機),這是 linux 對文件系統的優化,但是這卻有可能帶來隱患,如果 buffer 沒有刷新到磁盤,此時物理機器失效(比如斷電),那麼有可能導致最後一條或者多條 aof 記錄的丟失。通過上述配置文件,可以得知 redis 提供了 3 中 aof 記錄同步選項:

always:每一條 aof 記錄都立即同步到文件,這是最安全的方式,也以為更多的磁盤操作和阻塞延遲,是 IO 開支較大。

everysec:每秒同步一次,性能和安全都比較中庸的方式,也是 redis 推薦的方式。如果遇到物理服務器故障,有可能導致最近一秒內 aof 記錄丟失(可能為部分丟失)。

no:redis 並不直接調用文件同步,而是交給操作系統來處理,操作系統可以根據 buffer 填充情況 / 通道空閒時間等擇機觸發同步;這是一種普通的文件操作方式。性能較好,在物理服務器故障時,數據丟失量會因 OS 配置有關。

其實,我們可以選擇的太少,everysec 是最佳的選擇。如果你非常在意每個數據都極其可靠,建議你選擇一款“關係性數據庫”吧。


AOF 文件會不斷增大,它的大小直接影響“故障恢復”的時間, 而且 AOF 文件中歷史操作是可以丟棄的。AOF rewrite 操作就是“壓縮”AOF 文件的過程,當然 redis 並沒有採用“基於原 aof 文件”來重寫的方式,而是採取了類似 snapshot 的方式:基於 copy-on-write,全量遍歷內存中數據,然後逐個序列到 aof 文件中。因此 AOF rewrite 能夠正確反應當前內存數據的狀態,這正是我們所需要的;*rewrite 過程中,對於新的變更操作將仍然被寫入到原 AOF 文件中,同時這些新的變更操作也會被 redis 收集起來(buffer,copy-on-write 方式下,最極端的可能是所有的 key 都在此期間被修改,將會耗費 2 倍內存),當內存數據被全部寫入到新的 aof 文件之後,收集的新的變更操作也將會一併追加到新的 aof 文件中,此後將會重命名新的 aof 文件為 appendonly.aof, 此後所有的操作都將被寫入新的 aof 文件。如果在 rewrite 過程中,出現故障,將不會影響原 AOF 文件的正常工作,只有當 rewrite 完成之後才會切換文件,因為 rewrite 過程是比較可靠的。*


觸發 rewrite 的時機可以通過配置文件來聲明,同時 redis 中可以通過 bgrewriteaof 指令人工干預。

redis-cli -h ip -p port bgrewriteaof

因為 rewrite 操作 /aof 記錄同步 /snapshot 都消耗磁盤 IO,redis 採取了“schedule”策略:無論是“人工干預”還是系統觸發,snapshot 和 rewrite 需要逐個被執行。

AOF rewrite 過程並不阻塞客戶端請求。系統會開啟一個子進程來完成。

AOF與RDB區別

AOF 和 RDB 各有優缺點,這是有它們各自的特點所決定:

RDB

RDB是在某個時間點將數據寫入一個臨時文件,持久化結束後,用這個臨時文件替換上次持久化的文件,達到數據恢復。


優點:使用單獨子進程來進行持久化,主進程不會進行任何IO操作,保證了redis的高性能


缺點:RDB是間隔一段時間進行持久化,如果持久化之間redis發生故障,會發生數據丟失。所以這種方式更適合數據要求不嚴謹的時候


AOF

Append-only file,將“操作 + 數據”以格式化指令的方式追加到操作日誌文件的尾部,在append操作返回後(已經寫入到文件或者即將寫入),才進行實際的數據變更,“日誌文件”保存了歷史所有的操作過程;當server需要數據恢復時,可以直接replay此日誌文件,即可還原所有的操作過程。AOF相對可靠,它和mysql中bin.log、apache.log、zookeeper中txn-log簡直異曲同工。AOF文件內容是字符串,非常容易閱讀和解析。


優點:可以保持更高的數據完整性,如果設置追加file的時間是1s,如果redis發生故障,最多會丟失1s的數據;且如果日誌寫入不完整支持redis-check-aof來進行日誌修復;AOF文件沒被rewrite之前(文件過大時會對命令進行合併重寫),可以刪除其中的某些命令(比如誤操作的flushall)。


缺點:AOF文件比RDB文件大,且恢復速度慢。


由於字數圖片限制,請參考我下面的文章創作不易謝謝大家支持,喜歡點贊轉發。


分享到:


相關文章: