本文檔提供的資訊是有關Redis是如何應對不同POSIX系統下産生的信号異常,比如<code>SIGTERM</code>,<code>SIGSEGV</code>等等。
本文檔中的資訊隻适用于Redis2.6或更高版本。
SIGTERM信号會讓Redis安全的關閉。Redis收到信号時并不立即退出,而是開啟一個定時任務,這個任務就類似執行一次SHUTDOWN指令的。 這個定時關閉任務會在目前執行指令終止後立即施行,是以通常有有0.1秒或更少時間延遲。
萬一Server被一個耗時的LUA腳本阻塞,如果這個腳本可以被SCRIPT KILL指令終止,那麼定時執行任務就會在腳本被終止後立即執行,否則直接執行。
這種情況下的Shutdown過程也會同時包含以下的操作:
如果存在正在執行RDB檔案儲存或者AOF重寫的子程序,子程序被終止。
如果AOF功能是開啟的,Redis會通過系統調用fsync将AOF緩沖區資料強制輸出到硬碟。
如果Redis配置了使用RDB檔案進行持久化,那麼此時就會進行同步儲存。由于儲存時同步的,那也就不需要額外的記憶體。
如果Server是守護程序,PID檔案會被移除。
如果Unix域的Socket是可用的,它也會被移除。
Server退出,退出碼為0.
萬一RDB檔案儲存失敗,Shutdown失敗,Server則會繼續運作以保證沒有資料丢失。自從Redis2.6.11之後,Redis不會再次主動Shutdown,除非它接收到了另一個SIGTERM信号或者另外一個SHUTDOWN指令
Redis接收到以下幾種信号時會崩潰:
SIGSEGV
SIGBUS
SIGFPE
SIGILL
如果以上信号被捕獲,Redis會終止所有正在進行的操作,并進行以下操作:
包括調用棧資訊,寄存器資訊,以及clients資訊會以bug報告的形式寫入日志檔案。
自從Redis2.8(目前為開發版本)之後,Redis會在系統崩潰時進行一個快速的記憶體檢測以保證系統的可靠性。
最後server會取消自己對目前所接收信号的信号處理器的注冊,并重新把這個信号發給自己,這是為了保證一些預設的操作被執行,比如把Redis的核心Dump到檔案系統。
當一個正在進行AOF重寫的子程序被信号終止,Redis會把它當成一個錯誤并丢棄這個AOF檔案(可能是部分或者完全損壞)。AOF重寫過程會在以後被重新觸發。
當一個正在執行RDB檔案儲存的子程序被終止Redis會把它當做一個嚴重的錯誤,因為AOF重寫隻會導緻AOF檔案備援,但是RDB檔案儲存失敗會導緻Redis不可用。
如果一個正在儲存RDB檔案的子程序被信号終止或者自身出現了錯誤(非0退出碼),Redis會進入一種特殊的錯誤狀态,不允許任何寫操作。
Redis會繼續回複所有的讀請求。
Redis會回複給所有的寫請求一個MISCONFIG錯誤。
此錯誤狀态隻需被清楚一次就可以進行成功建立資料庫檔案。
但是有時使用者希望可以在不觸發錯誤的情況下終止儲存RDB檔案的子程序。自從Redis2.6.10之後就可以使用信号SIGUSR1,這個信号會被特殊處理:它會像其他信号一樣終止子程序,但是父程序不會檢測到這個嚴重的錯誤,照常接收所有的使用者寫請求。
本文作者:陳群
本文來自雲栖社群合作夥伴rediscn,了解相關資訊可以關注redis.cn網站。