開発者のためのRedisチュートリアル(4)

これだけはしないでください!

それでは多くの方からリクエストいただいたRedisの障害ポイントについてお話したいと思います。Redisがよく分からなくてもこれだけは注意しましょう。

要件を把握する(キャッシュ用 or リポジトリ用?)

サービスにRedisを導入する際には、キャッシュ用に使用するか、あるいはリポジトリに使用するかを明確にする必要があります。つまり、Redisに保存したデータがなくなっても同じデータがRDBMSに残っていれば問題ないか、あるいは一部の値が失われても問題がないのか、確認が必要です。特別な場合を除き、一般的にはRedisを永久保存用として使用するのはおすすめしません。

その理由は、Redisのデータをファイルに保存するためのパーシステンス(Persistence)機能(RDB、AOF)によって障害が発生する可能性が非常に高いからです。fork()によるCOW(Copy-On-Write)から全体のパフォーマンスが低下したり、ファイルが生成されない場合にRedisに書き込みができないなど、さまざまな障害事例が存在します。

このようなことから、必ず必要な場合にのみデータを保存することをおすすめします。Redisをキャッシュ用途で使用する場合は、RDBとAOFは使用しないでください。ストレージ用途で使用する場合は、RDBよりもAOFをおすすめします。また、関連するパラメーターも修正した方が安全でしょう。パラメーターに関する説明は下に続きます。

オーバースペックを回避しよう

前述のように、Redisをどのように配置するかによって長所と短所が変わってきます。各構成を正確に理解せず適当にRedisを用いると、リソースの浪費はもちろんのこと、これによって障害が発生する可能性も高まります。(ex.クラスタが最良ならクラスタで作ってみようかな?1つのサーバーにRedisインスタンス6つ起動してみよう! -> Max Memoryを設定せず、パーシステンスを設定した状態で使用率が増加するとサーバーダウン発生)したがって、サービスを導入する前にどのような構成のRedisを使用すべきか十分に検討する必要があります。

どのように使えばよいか分からないという方は下図を参考にしてください。もちろんサービスに応じて構成が少しずつ異なります。センチネル(Sentinel)構造でレプリカ(Replica)の数が変わったり、または強力な高可用性のためクラスタを7つのノードで構成することもできるでしょう。このように決められた構造でデータを永久保存しなければならない場合は、パーシステンスオプションを追加すればよいでしょう。

危険なコマンド

Redisはシングルスレッドで動作します(正確には、コマンドを処理するスレッドが1つ)。そのため、もし実行に時間がかかるコマンドが1つスレッドを捉えれば残りのコマンドは待たされてしまいます。これもまた障害につながるケースです。したがって、次のコマンドを使用する前に、本当にこのコマンドを投げる必要があるか、もう一度考えてみてください。

※KEYS *

KEYS *はRedisに保存されたすべてのキーを出力するコマンドです。論理的にO(n)だけの時間が必要なため、メモリに保存された値が多いときにこのコマンドを使用すると大変なことになります。KEYSはSCANに代替可能です。カーソルを使ってキーの一部を照会することができ、KEYSと同様にGLOBパターンも使用できます。

※FLUSHALL / FLUSHDB

メモリに存在するすべてのデータを削除するコマンドです。すべてのデータが削除され、O(n)の時間が必要なため、注意して使用しなければなりません。

※SAVE

他のクライアントのコマンドを遮断し、全体のメモリ内容をファイルに保存します。

※MONITOR

Redisに接続されたすべてのクライアントから送信されたすべてのコマンドを表示するコマンドです。Redis公式文書によると、1つのクライアントでMONITORを使ってすべてのコマンドを監視している間、全体の処理量は50%以上減少するそうです。

★redis.conf★

Redisをインストールし、基本パラメーター値をそのまま使用した場合も予期せぬ障害を発生させることがあります。Redisをインストールした後、必ず確認すべきパラメーターをまとめてみました。

セキュリティ用パラメーター

bind <server IP>
protected-mode yes
requirepass <password>

セキュリティのためprotected-modeyesrequirepassには接続時に使用するパスワードを入力します。Redisに接続すべきサーバーのIPアドレスをbindにすべて追加してください。この場合、Redisはbindに追加されたサーバーのみと接続できます。

データをファイルに保存するパーシステンス機能

# RDB
save ""
stop-writes-on-bgsave-error no

# AOF
appendonly no
auto-aof-rewrite-percentage 100

キャッシュ用途にのみ使用するなら、RDBファイルを保存するオプションであるsave“”に設定することをおすすめします。もしこの設定をオンにするなら、stop-writes-on-bgsave-errorはオフにしてください。このオプションがyesのときにRDBファイルの保存に失敗すると、すぐにRedisにwriteできなくなります。AOFファイルを保存するオプションであるappendonlyもキャッシュ用に使用するときはnoに設定することをおすすめします。そして、Append-only方式AOFファイルはrewriteをしないと増え続けるので、auto-aof-rewrite-percentage100(100%サイズ)を指定し、定期的にrewriteされるようにする必要があります。

レプリケーション機能を使用する場合

replicaof <Master ip> <Master port>
masterauth <Master requirepass>

コンソールウィンドウに接続した状態でレプリケーション(replication)を使用することもありますが、設定ファイルにマスターの情報を指定したままサーバーを起動することもできます。このパラメーターは複製ノードに追加する必要があります。

その他の設定

daemonize yes

daemonizenoに設定した場合(基本設定)、Redisサーバー実行時にサーバーのメッセージが画面に表示され、Linuxのプロンプトが落ちないフォアグラウンドで実行されます。このとき、Ctrl+CでRedisサーバーがシャットダウンされます。したがって、サーバーをバックグラウンドで実行するためにdaemonizeをyesに設定するとよいでしょう。

maxmemory <可用メモリの60~70%>
maxmemory-policy volatile-lru

maxmemory値が0なら、swapメモリを使用するまでメモリは引き続き大きくなる場合があります。パーシステンス機能を使用したり、複製ノードを持つ場合には、fork()が発生することがありますので、メモリの使用にはさらに注意する必要があります。推奨する値は、使用可能なメモリの60〜70%のラインでmax memoryを設定することです。

また、メモリがいっぱいになったときにデータをどのように処理するかはmaxmemory-policy値によって異なります。デフォルト値はnoevictionで、メモリがいっぱいになるとそれ以上新しい入力を受けないというポリシーです。volatile-lruは最近使用されていない値を削除するポリシーです。サービスの特性によって異なりますが、キャッシュ用途で使用する場合は必要な値を削除し、新しい入力を受け入れることがよいでしょうから、volatile-lruを使用することをおすすめします。

EasyCache(TOAST)

ここまでRedisの基礎からクラスター、障害を引き起こす可能性があるポイントまで調べてきました。Redisを利用したいという気持ちになりましたか?思ったよりも注意すべき点が多く煩わしさを感じた方もいらっしゃるかもしれません。

そこで、Amazon ElastiCacheにも匹敵するTOASTのEasyCacheを紹介します!EasyCacheの日本リージョンは2020年4月28日リリース予定

EasyCacheを利用すれば、サーバーパラメーターやメモリ、パラメーターなどを心配せずにRedisを利用できるだけでなく、モニタリングも可能で、特定の状況において通知を受け取ることができます。2020年2月現在、センチネルを利用したHAが可能であり、今後さらに多くの機能がリリースされる予定です。詳しくは、EasyCacheドキュメントをご覧ください。

TOAST Meetup 編集部

TOASTの技術ナレッジやお得なイベント情報を発信していきます
pagetop