最近開始嘗試使用Redis Sentinel建置高可用性服務,在測試的時候碰到一些問題。我在一個由三個Redis實體組成的Master-Slave Cluster倒入約4GB的資料,然後在Master下KEYS *把所有鍵列出來,沒過幾秒在Sentinel出現Master down然後重新推舉Master的訊息。
我在Sentinel裡頭設定Master在5秒內無回應就會判定為down,那也就是說我做了列出所有鍵的操作阻擋了後續所有連線的作業,這是怎麼回事?
回想一下Redis的特性,大概是:
- 單執行緒、單行程
- 所有操作是以atomic方式進行,因此確保了資料的一致性
- 雖然運作時資料是存放於記憶體中,但是可回存為檔案,確保資料的持久性
- 因為資料是存放於記憶體,所以速度很快
Redis不像一般的RDBMS有實做Transaction Isolation,
任何操作都要等到前一個操作執行完才會進行,無法平行處理,Redis才能保證資料的一致性。因此非常不適合使用Redis進行以下操作:
- 列出所有鍵:KEYS *
如果存入的鍵很多,就得花很多時間處理。以我測試的情況,4GB的資料有將近1500萬個鍵,列出操作就花了183秒。
- 搜尋特定鍵:KEYS *name*
跟前一個是同樣的情況,列出了154個卻花了9秒多來處理。
我本職是系統管理者不是程式開發人員,所以有可能有其他的情況不適合使用Redis。如果要更有效率的使用Redis,那就盡量不要使用KEYS指令來列出或搜尋鍵。