redis開發與運維 頂 原

1. 初識redis

    redis的8個特性:速度快、基於鍵值對的數據結構服務器、功能豐富、簡單穩定、客戶端語言多、持久化、主從複製、支持高可用和分佈式。
    redis不是萬金油,有些場景不符合redis
    開發運維結合以及閱讀源碼
    生產環境中使用配置文件啓動redis
    Redis3.0是重要的里程碑, 發佈了Redis官方的分佈式實現Redis Cluster。

2. API的理解和使用

    Redis提供5種數據結構, 每種數據結構都有多種內部編碼實現。
    純內存存儲、 IO多路複用技術、 單線程架構是造就Redis高性能的三個因素。
    由於Redis的單線程架構, 所以需要每個命令能被快速執行完, 否則會存在阻塞Redis的可能, 理解Redis單線程命令處理機制是開發和運維Redis的核心之一。
    批量操作(例如mget、 mset、 hmset等) 能夠有效提高命令執行的效率, 但要注意每次批量操作的個數和字節數。
    瞭解每個命令的時間複雜度在開發中至關重要, 例如在使用keys、 hgetall、 smembers、 zrange等時間複雜度較高的命令時,需要考慮數據規模對於Redis的影響。
    persist命令可以刪除任意類型鍵的過期時間, 但是set命令也會刪除字符串類型鍵的過期時間, 這在開發時容易被忽視。
    move、 dump+restore、 migrate是Redis發展過程中三種遷移鍵的方式, 其中 move命令基本廢棄, migrate命令用原子性的方式實現了dump+restore, 並且支持批量操作, 是Redis Cluster實現水平擴容的重要工具。
    scan命令可以解決keys命令可能帶來的阻塞問題, 同時Redis還提供了hscan、 sscan、 zscan漸進式地遍歷hash、 set、 zset。

3. 小功能大用處

    慢查詢中的兩個重要參數slowlog-log-slower-than和slowlog-max-len。
    慢查詢不包含命令網絡傳輸和排隊時間。
    有必要將慢查詢定期存放。
    redis-cli一些重要的選項, 例如--latency、 –-bigkeys、 -i和-r組合。
    redis-benchmark的使用方法和重要參數。
    Pipeline可以有效減少RTT次數, 但每次Pipeline的命令數量不能無節制。
    Redis可以使用Lua腳本創造出原子、 高效、 自定義命令組合。
    Redis執行Lua腳本有兩種方法: eval和evalsha。
    Bitmaps可以用來做獨立用戶統計, 有效節省內存。
    Bitmaps中setbit一個大的偏移量, 由於申請大量內存會導致阻塞。
    HyperLogLog雖然在統計獨立總量時存在一定的誤差, 但是節省的內存量十分驚人。
    Redis的發佈訂閱機制相比許多專業的消息隊列系統功能較弱, 不具備堆積和回溯消息的能力, 但勝在足夠簡單。
    Redis3.2提供了GEO功能, 用來實現基於地理位置信息的應用, 但底層實現是zset。

4. 客戶端

    RESP(Redis Serialization Protocol Redis) 保證客戶端與服務端的正常通信, 是各種編程語言開發客戶端的基礎。
    要選擇社區活躍客戶端, 在實際項目中使用穩定版本的客戶端。
    區分Jedis直連和連接池的區別, 在生產環境中, 應該使用連接池。
    Jedis.close() 在直連下是關閉連接, 在連接池則是歸還連接。
    Jedis客戶端沒有內置序列化, 需要自己選用。
    客戶端輸入緩衝區不能配置, 強制限制在1G之內, 但是不會受到maxmemory限制。
    客戶端輸出緩衝區支持普通客戶端、 發佈訂閱客戶端、 複製客戶端配置, 同樣會受到maxmemory限制。
    Redis的timeout配置可以自動關閉閒置客戶端, tcp-keepalive參數可以週期性檢查關閉無效TCP連接
    monitor命令雖然好用, 但是在大併發下存在輸出緩衝區暴漲的可能性。
    info clients幫助開發和運維人員找到客戶端可能存在的問題。
    理解Redis通信原理和建立完善的監控系統對快速定位解決客戶端常見問題非常有幫助。

5. 持久化

    Redis提供了兩種持久化方式: RDB和AOF。
    RDB使用一次性生成內存快照的方式, 產生的文件緊湊壓縮比更高, 因此讀取RDB恢復速度更快。 由於每次生成RDB開銷較大, 無法做到實時持久化, 一般用於數據冷備和複製傳輸。
    save命令會阻塞主線程不建議使用, bgsave命令通過fork操作創建子進程生成RDB避免阻塞。
    AOF通過追加寫命令到文件實現持久化, 通過appendfsync參數可以控制實時/秒級持久化。 因爲需要不斷追加寫命令, 所以AOF文件體積逐漸變大, 需要定期執行重寫操作來降低文件體積。
    AOF重寫可以通過auto-aof-rewrite-min-size和auto-aof-rewrite-percentage參數控制自動觸發, 也可以使用bgrewriteaof命令手動觸發。
    子進程執行期間使用copy-on-write機制與父進程共享內存, 避免內存消耗翻倍。 AOF重寫期間還需要維護重寫緩衝區, 保存新的寫入命令避免數據丟失。
    持久化阻塞主線程場景有: fork阻塞和AOF追加阻塞。 fork阻塞時間跟內存量和系統有關, AOF追加阻塞說明硬盤資源緊張。
    單機下部署多個實例時, 爲了防止出現多個子進程執行重寫操作, 建議做隔離控制, 避免CPU和IO資源競爭。

6. 複製

    Redis通過複製功能實現主節點的多個副本。 從節點可靈活地通過slaveof命令建立或斷開復制流程。
    複製支持樹狀結構, 從節點可以複製另一個從節點, 實現一層層向下的複製流。 Redis2.8之後複製的流程分爲: 全量複製和部分複製。 全量複製需要同步全部主節點的數據集, 大量消耗機器和網絡資源。 而部分複製有效減少因網絡異常等原因造成的不必要全量複製情況。 通過配置合理的複製積壓緩衝區儘量避免全量複製。
    主從節點之間維護心跳和偏移量檢查機制, 保證主從節點通信正常和數據一致
    Redis爲了保證高性能複製過程是異步的, 寫命令處理完後直接返回給客戶端, 不等待從節點複製完成。 因此從節點數據集會有延遲情況。
    當使用從節點用於讀寫分離時會存在數據延遲、 過期數據、 從節點可用性等問題, 需要根據自身業務提前作出規避。
     在運維過程中, 主節點存在多個從節點或者一臺機器上部署大量主節點的情況下, 會有複製風暴的風險。

7. redis的噩夢:阻塞

    客戶端最先感知阻塞等Redis超時行爲, 加入日誌監控報警工具可快速定位阻塞問題, 同時需要對Redis進程和機器做全面監控。
    阻塞的內在原因: 確認主線程是否存在阻塞, 檢查慢查詢等信息, 發現不合理使用API或數據結構的情況, 如keys、 sort、 hgetall等。 關注CPU使用率防止單核跑滿。 當硬盤IO資源緊張時, AOF追加也會阻塞主線程。
    阻塞的外在原因: 從CPU競爭、 內存交換、 網絡問題等方面入手排查是否因爲系統層面問題引起阻塞。

8. 理解內存

     Redis實際內存消耗主要包括: 鍵值對象、 緩衝區內存、 內存碎片。
    通過調整maxmemory控制Redis最大可用內存。 當內存使用超出時, 根據maxmemory-policy控制內存回收策略。
    內存是相對寶貴的資源, 通過合理的優化可以有效地降低內存的使用量, 內存優化的思路包括:
        精簡鍵值對大小, 鍵值字面量精簡, 使用高效二進制序列化工具。
        使用對象共享池優化小整數對象。
        數據優先使用整數, 比字符串類型更節省空間。
        優化字符串使用, 避免預分配造成的內存浪費
        使用ziplist壓縮編碼優化hash、 list等結構, 注重效率和空間的平衡。
        使用intset編碼優化整數集合。
        使用ziplist編碼的hash結構降低小對象鏈規模。

9. 哨兵

    Redis Sentinel是Redis的高可用實現方案: 故障發現、 故障自動轉移、 配置中心、 客戶端通知。
    Redis Sentinel從Redis2.8版本開始才正式生產可用, 之前版本生產不可用。
    儘可能在不同物理機上部署Redis Sentinel所有節點。
    Redis Sentinel中的Sentinel節點個數應該爲大於等於3且最好爲奇數。
    Redis Sentinel中的數據節點與普通數據節點沒有區別。
    客戶端初始化時連接的是Sentinel節點集合, 不再是具體的Redis節點, 但Sentinel只是配置中心不是代理。
    Redis Sentinel通過三個定時任務實現了Sentinel節點對於主節點、 從節點、 其餘Sentinel節點的監控。
    Redis Sentinel在對節點做失敗判定時分爲主觀下線和客觀下線。
    看懂Redis Sentinel故障轉移日誌對於Redis Sentnel以及問題排查非常有幫助。
    Redis Sentinel實現讀寫分離高可用可以依賴Sentinel節點的消息通知, 獲取Redis數據節點的狀態變化。

10. 集羣

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章