阻塞分析
客戶端
復雜度高的增刪改查操作
1、集合全量查詢和聚合操作
2、bigkey 刪除
3、清空數據庫
磁盤
1、AOF 日志同步寫
主從節點
1、從庫接收 RDB 文件后、清空數據庫、加載 RDB 文件;
切片集群
向其他實例傳輸哈希槽信息,數據遷移時遇到big key。
小結
關鍵路徑:集合全量查詢和聚合操作和從庫加載 RDB 文件
非關鍵路徑: bigkey 刪除,清空數據庫,以及 AOF 日志同步寫。
解決方案
異步的子線程機制
Redis 主線程啟動后,會使用操作系統提供的 pthread_create 函數創建 3 個子線程,分別由它們負責 AOF 日志寫操作、鍵值對刪除以及文件關閉的異步執行。主線程通過一個鏈表形式的任務隊列和子線程進行交互。當收到鍵值對刪除和清空數據庫的操作時,主線程會把這個操作封裝成一個任務,放入到任務隊列中,然后給客戶端返回一個完成信息,表明刪除已經完成(惰性刪除)。當 AOF 日志配置成 everysec 選項后,主線程會把 AOF 寫日志操作封裝成一個任務,也放到任務隊列中。后台子線程讀取任務后,開始自行寫入 AOF 日志,這樣主線程就不用一直等待 AOF 日志寫完了。
注:異步的鍵值對刪除和數據庫清空操作是 Redis 4.0 后提供的功能。之前的版本Big key刪除可以先使用集合類型提供的 SCAN 命令讀取數據,然后再進行刪除。因為用 SCAN 命令可以每次只讀取一部分數據並進行刪除,這樣可以避免一次性刪除大量 key 給主線程帶來的阻塞。
分批讀取
集合全量查詢和聚合操作:可以使用 SCAN 命令,分批讀取數據,再在客戶端進行聚合計算
控制RBD大小
從庫加載 RDB 文件:把主庫的數據量大小控制在 2~4GB 左右,以保證 RDB 文件能以較快的速度加載。