內存
命令:
info memory
配置分析:
# Memory
used_memory:2587328
free_memory:4949498790
used_memory_human:2.47M
used_memory_rss:120233984
used_memory_peak:642276608
used_memory_peak_human:612.52M
used_memory_lua:36864
mem_fragmentation_ratio:46.47
mem_allocator:jemalloc-3.6.0
- used_memory
Redis分配器分配的內存總量(單位是字節),包括使用的虛擬內存(即swap) - used_memory_rss
Redis進程佔據操作系統的內存(單位是字節),與top及ps命令看到的值是一致的 - mem_fragmentation_ratio
內存碎片比率,該值是used_memory_rss / used_memory
的比值
if (ratio > 1) {
// 內存碎片比例越大,浪費嚴重
// 對於jemalloc來說,1.03比較健康
} else if (ratio < 1) {
// 說明Redis使用了虛擬內存,由於虛擬內存的媒介是磁盤,比內存速度要慢很多,當這種情況出現時,應該及時排查,如果內存不足應該及時處理,如增加Redis節點、增加Redis服務器的內存、優化應用等
} else {
// =1
}
- mem_allocator
Redis使用的內存分配器,在編譯時指定;可以是 libc 、jemalloc或者tcmalloc,默認是jemalloc
持久化(單機備份問題)
命令
info persittence
配置分析
loading:0
rdb_changes_since_last_save:190029650
rdb_bgsave_in_progress:0
rdb_last_save_time:1526278587
rdb_last_bgsave_status:ok
rdb_last_bgsave_time_sec:0
rdb_current_bgsave_time_sec:-1
aof_enabled:0
aof_rewrite_in_progress:0
aof_rewrite_scheduled:0
aof_last_rewrite_time_sec:-1
aof_current_rewrite_time_sec:-1
aof_last_bgrewrite_status:ok
aof_last_write_status:ok
- rdb_last_bgsave_status:上次bgsave 執行結果,可以用於發現bgsave錯誤
- rdb_last_bgsave_time_sec:上次bgsave執行時間(單位是s),可以用於發現bgsave是否耗時過長
- aof_enabled:AOF是否開啓
- aof_last_rewrite_time_sec: 上次文件重寫執行時間(單位是s),可以用於發現文件重寫是否耗時過長
- aof_last_bgrewrite_status: 上次bgrewrite執行結果,可以用於發現bgrewrite錯誤
- aof_buffer_length和aof_rewrite_buffer_length:aof緩存區大小和aof重寫緩衝區大小
- aof_delayed_fsync:AOF追加阻塞情況的統計
RDB
手動觸發保存RDB文件命令
# 會阻塞Redis服務器進程,直到RDB文件創建完畢爲止,不推薦
save
# 後臺生成線程保存數據
bgsave
配置自動觸發
# redis.conf
# 當時間到900秒時,如果redis數據發生了至少1次變化,則執行bgsave
save 900 1
save 300 10
save 60 10000
原理
每隔100ms,執行serverCron函數;在serverCron函數中,遍歷save m n配置的保存條件,只要有一個條件滿足,就進行bgsave。對於每一個save m n條件,只有下面兩條同時滿足時纔算滿足:
(1)當前時間-lastsave > m
(2)dirty >= n
其他場景觸發:
- 在主從複製場景下,如果從節點執行全量複製操作,則主節點會執行bgsave命令,並將rdb文件發送給從節點
- 執行shutdown命令時,自動執行rdb持久化,如下圖所示:
RDB文件分析
分析工具:
案例:使用內存過高問題分析
問題:redis作爲緩存使用時,查詢DB不存在時,value設置爲empty,防止數據庫穿透,發現短時間內存使用較高
分析:大量不存在的數據併發,導致empty的key劇增
方案:對於不存在的數據,適當減少key的生存時間
AOF
RDB持久化是將進程數據寫入文件,而AOF持久化(即Append Only File持久化),則是將Redis執行的每次寫命令記錄到單獨的日誌文件中(有點像MySQL的binlog);當Redis重啓時再次執行AOF文件中的命令來恢復數據。
與RDB相比,AOF的實時性更好,因此已成爲主流的持久化方案
配置
原理
主動複製(多機熱備)
命令
info Replication
主要作用
- 數據冗餘:主從複製實現了數據的熱備份,是持久化之外的一種數據冗餘方式
- 故障恢復:當主節點出現問題時,可以由從節點提供服務,實現快速的故障恢復;實際上是一種服務的冗餘
- 負載均衡:在主從複製的基礎上,配合讀寫分離,可以由主節點提供寫服務,由從節點提供讀服務(即寫Redis數據時應用連接主節點,讀Redis數據時應用連接從節點),分擔服務器負載;尤其是在寫少讀多的場景下,通過多個從節點分擔讀負載,可以大大提高Redis服務器的併發量
- 高可用基石:除了上述作用以外,主從複製還是哨兵和集羣能夠實施的基礎,因此說主從複製是Redis高可用的基礎
搭建
從節點配置主節點的ip+port
,通過slaveof異步命令,從節點完成主節點ip和port的保存後,向發送slaveof命令的客戶端直接返回OK,實際的複製操作在這之後纔開始進行。
功能演示
原理
時序圖
接建立階段、數據同步階段、命令傳播階段
總結
哨兵
Redis Sentinel,主節點故障恢復的自動化
- 監控(Monitoring):哨兵會不斷地檢查主節點和從節點是否運作正常。
- 自動故障轉移(Automatic failover):當主節點不能正常工作時,哨兵會開始自動故障轉移操作,它會將失效主節點的其中一個從節點升級爲新的主節點,並讓其他從節點改爲複製新的主節點。
- 配置提供者(Configuration provider):客戶端在初始化時,通過連接哨兵來獲得當前Redis服務的主節點地址。
- 通知(Notification):哨兵可以將故障轉移的結果發送給客戶端。
搭建
功能演示
原理
總結
- 哨兵節點的數量應不止一個,一方面增加哨兵節點的冗餘,避免哨兵本身成爲高可用的瓶頸;另一方面減少對下線的誤判。此外,這些不同的哨兵節點應部署在不同的物理機上。
- 哨兵節點的數量應該是奇數,便於哨兵通過投票做出“決策”:領導者選舉的決策、客觀下線的決策等。哨兵節點的數量應該是奇數,便於哨兵通過投票做出“決策”:領導者選舉的決策、客觀下線的決策等。
- 各個哨兵節點的配置應一致,包括硬件、參數等;此外,所有節點都應該使用ntp或類似服務,保證時間準確、一致。各個哨兵節點的配置應一致,包括硬件、參數等;此外,所有節點都應該使用ntp或類似服務,保證時間準確、一致。
- 哨兵的配置提供者和通知客戶端功能,需要客戶端的支持才能實現,如前文所說的Jedis;如果開發者使用的庫未提供相應支持,則可能需要開發者自己實現。哨兵的配置提供者和通知客戶端功能,需要客戶端的支持才能實現,如前文所說的Jedis;如果開發者使用的庫未提供相應支持,則可能需要開發者自己實現。
- 當哨兵系統中的節點在docker(或其他可能進行端口映射的軟件)中部署時,應特別注意端口映射可能會導致哨兵系統無法正常工作,因爲哨兵的工作基於與其他節點的通信,而docker的端口映射可能導致哨兵無法連接到其他節點。例如,哨兵之間互相發現,依賴於它們對外宣稱的IP和port,如果某個哨兵A部署在做了端口映射的docker中,那麼其他哨兵使用A宣稱的port無法連接到A。當哨兵系統中的節點在docker(或其他可能進行端口映射的軟件)中部署時,應特別注意端口映射可能會導致哨兵系統無法正常工作,因爲哨兵的工作基於與其他節點的通信,而docker的端口映射可能導致哨兵無法連接到其他節點。例如,哨兵之間互相發現,依賴於它們對外宣稱的IP和port,如果某個哨兵A部署在做了端口映射的docker中,那麼其他哨兵使用A宣稱的port無法連接到A。
參考:
《Redis設計與實現》
《Redis開發與運維》
《Redis實戰》