一、持久化
1) Redis提供了兩種持久化方式: RDB和AOF。
2) RDB使用一次性生成內存快照的方式, 產生的文件緊湊壓縮比更高, 因此讀取RDB恢復速度更快。 由於每次生成RDB開銷較大, 無法做到實時持久化, 一般用於數據冷備和複製傳輸。
3) save命令會阻塞主線程不建議使用, bgsave命令通過fork操作創建子進程生成RDB避免阻塞。
4) AOF通過追加寫命令到文件實現持久化, 通過appendfsync參數可以控制實時/秒級持久化。 因爲需要不斷追加寫命令, 所以AOF文件體積逐漸變大, 需要定期執行重寫操作來降低文件體積。
5) AOF重寫可以通過auto-aof-rewrite-min-size和auto-aof-rewritepercentage參數控制自動觸發, 也可以使用bgrewriteaof命令手動觸發。
6) 子進程執行期間使用copy-on-write機制與父進程共享內存, 避免內存消耗翻倍。 AOF重寫期間還需要維護重寫緩衝區, 保存新的寫入命令避免數據丟失。
7) 持久化阻塞主線程場景有: fork阻塞和AOF追加阻塞。 fork阻塞時間跟內存量和系統有關, AOF追加阻塞說明硬盤資源緊張。
8) 單機下部署多個實例時, 爲了防止出現多個子進程執行重寫操作,建議做隔離控制, 避免CPU和IO資源競爭。
二、複製
1) Redis通過複製功能實現主節點的多個副本。 從節點可靈活地通過slaveof命令建立或斷開復制流程。
2) 複製支持樹狀結構, 從節點可以複製另一個從節點, 實現一層層向下的複製流。 Redis2.8之後複製的流程分爲: 全量複製和部分複製。 全量複製需要同步全部主節點的數據集, 大量消耗機器和網絡資源。 而部分複製有效減少因網絡異常等原因造成的不必要全量複製情況。 通過配置合理的複製積壓緩衝區儘量避免全量複製。
3) 主從節點之間維護心跳和偏移量檢查機制, 保證主從節點通信正常和數據一致。
4) Redis爲了保證高性能複製過程是異步的, 寫命令處理完後直接返回給客戶端, 不等待從節點複製完成。 因此從節點數據集會有延遲情況。
5) 當使用從節點用於讀寫分離時會存在數據延遲、 過期數據、 從節點可用性等問題, 需要根據自身業務提前作出規避。
6) 在運維過程中, 主節點存在多個從節點或者一臺機器上部署大量主節點的情況下, 會有複製風暴的風險。
三、阻塞情況
1) 客戶端最先感知阻塞等Redis超時行爲, 加入日誌監控報警工具可快速定位阻塞問題, 同時需要對Redis進程和機器做全面監控。
2) 阻塞的內在原因: 確認主線程是否存在阻塞, 檢查慢查詢等信息,發現不合理使用API或數據結構的情況, 如keys、 sort、 hgetall等。 關注CPU使用率防止單核跑滿。 當硬盤IO資源緊張時, AOF追加也會阻塞主線程。
3) 阻塞的外在原因: 從CPU競爭、 內存交換、 網絡問題等方面入手排查是否因爲系統層面問題引起阻塞。
四、內存管理
1) Redis實際內存消耗主要包括: 鍵值對象、 緩衝區內存、 內存碎片。
2) 通過調整maxmemory控制Redis最大可用內存。 當內存使用超出時,根據maxmemory-policy控制內存回收策略。
3) 內存是相對寶貴的資源, 通過合理的優化可以有效地降低內存的使用量, 內存優化的思路包括:
- 精簡鍵值對大小, 鍵值字面量精簡, 使用高效二進制序列化工具。
- 使用對象共享池優化小整數對象。
- 數據優先使用整數, 比字符串類型更節省空間。
- 優化字符串使用, 避免預分配造成的內存浪費。
- 使用ziplist壓縮編碼優化hash、 list等結構, 注重效率和空間的平衡。
- 使用intset編碼優化整數集合。
- 使用ziplist編碼的hash結構降低小對象鏈規模。