RedisでKEYSコマンドによる障害を抑止するプラクティス

2020/11/08に公開

Redis の KEYS コマンドは危険

Redis には Key を全走査して検索する KEYS コマンドがあります。
開発・運用中、稀に良く Key を検索したい事象に出くわすのが「Redisあるある」なのですが
この KEYS コマンドは、走査対象となる KEY 数に比例して Redis の処理をブロッキングします。

Redis にまだ不慣れなとき、開発環境では KEY 数が少なく問題にならず、本番環境で KEYS コマンドを発行してしまい障害を起こしてしまった方が少なくないのではないでしょうか?

コマンド名をリネームして KEYS の誤爆を抑止する

Redis には設定値に rename-command があります。
redis/redis.conf at 6.0 · redis/redis · GitHub

下記のように redis.conf に追記して、 Redis を再起動します。

rename-command KEYS KEYS_KAKUGO_OK

こうすることで KEYS コマンドを打つのは覚悟が出来てる方のみとなります。

127.0.0.1:6379> keys *
(error) ERR unknown command 'keys'
127.0.0.1:6379> keys_kakugo_ok *
1) "hoge"

Appendix

rename-command はオンラインでは設定出来ない

この方法の注意点として、 Redis の再起動が必要となる点です。
Redis にはオンラインで設定値を書き換える CONFIG SET コマンドがありますが、
この rename-command 設定はオンラインで変更はサポートされていません。

安全に KEY を検索するには?

主に下記の 3 つの方法が考えられます。

1. アプリケーションから参照のない Replica で KEYS

どうしても KEYS を使いたい場合は専用の Replica で KEYS を利用しましょう。
cluster-replica-no-failover の設定値を有効にすることで
Redis Cluster でも自動フェイルオーバーしない Replica を作ることも可能です。

コマンドの発行先をミスると障害になるため、 MONITOR コマンドや CLIENT LIST コマンドを併用して
KEYS を打とうとしてるインスタンスにアプリケーションからクエリがないことを確認しましょう。

2. SCAN コマンドでページングしながら検索

専用の REPLICA を用意出来ない場合は、 SCAN コマンドでページングしながら検索しましょう。

3. 永続化ファイル (rdb) を分析

RDB 取得時点のデータをバッチ処理的に検索できれば良い場合は、
sripathikrishnan/redis-rdb-tools: などを利用して
CSV や JSON に変換して利用しましょう。
私が過去一番使っているのはこの方法です。

Discussion