AOF vs. RDB 永続化におけるパフォーマンスのトレードオフ比較

Redisの2つの永続化モード、スナップショット (RDB) と追記専用ファイル (AOF) の間の重要なパフォーマンスのトレードオフについて詳しく見ていきます。RDBがバックグラウンド保存によって書き込みレイテンシを最小限に抑える一方で、AOFがコマンドのログ記録を通じて耐久性を最大化する方法を学びましょう。このガイドでは、設定例とベストプラクティスに加え、最適な速度とデータの安全性のために両方のメソッドを有効にする推奨戦略を紹介します。

90 ビュー

AOFとRDBの永続化パフォーマンスにおけるトレードオフの比較

Redisは、しばしばサブミリ秒のレイテンシを達成する驚異的な速度で知られています。しかし、再起動後のリカバリのためにデータをディスクに保存できるように永続化を有効にする場合、開発者はメカニズムを選択しなければなりません。Redisにおける主な永続化方法は、スナップショット(RDB)追記専用ファイル(AOF)の2つです。速度とデータ安全性の特定のアプリケーション要件を満たすようにRedisをチューニングするためには、それぞれのパフォーマンスへの影響、耐久性の特性、および設定のトレードオフを理解することが不可欠です。

本ガイドでは、RDBとAOFを徹底的に検証し、それらがどのように動作するか、レイテンシに与えるそれぞれのパフォーマンス上の影響、そして高性能なRedisデプロイメントに最適な永続化戦略を選択するための実践的な洞察を提供します。

Redis永続化の理解

Redisはそのデータセット全体を揮発性メモリに保存します。永続化メカニズムは、サービスの中断や再起動にわたってデータの可用性を確保するために、Redisが再起動時にデータセットをリロードできるように、このデータをディスクに移動させるために必要です。RDBとAOFはどちらも根本的に異なるアプローチを通じてこの目標を達成するため、異なるパフォーマンスプロファイルにつながります。

1. Redisデータベース (RDB) スナップショット

RDBは、指定された間隔でデータセット全体のコンパクトなポイントインタイムスナップショットを作成します。このデータはバイナリファイル(dump.rdb)に保存されます。

RDBの仕組みとそのパフォーマンスへの影響

RDB永続化は、BGSAVEコマンド(バックグラウンド保存)に大きく依存します。保存がトリガーされると、次のようになります。

  1. フォーク: Redisはメインプロセスを子プロセスにフォークします。
  2. スナップショット作成: 子プロセスはデータセット全体をディスク上のRDBファイルに書き込みます。
  3. メインスレッドは影響を受けない(ほぼ): 子プロセスがディスクI/Oを処理するため、メインのRedisスレッドは書き込み操作中にブロックされることなく、クライアント要求の処理を続行します。

パフォーマンスに関する考慮事項:

  • 書き込みレイテンシ: 一般に、RDBは作業がオフロードされるため、保存操作の書き込みレイテンシへの影響は最小限です。主なパフォーマンスコストは、フォークが発生したとき、および大規模なファイル書き込み中に必要となるCPUスパイクと最初のI/Oバーストです。
  • リカバリ時間: RDBは単一の最適化されたファイルであるため、再起動時に非常に迅速にロードされ、リカバリレイテンシを最小限に抑えます。
  • 耐久性のトレードオフ: スケジュールされた保存の間(例:5分ごと)にRedisがクラッシュした場合、最後の保存以降に発生したすべての書き込みが失われます。これにより、RDBはAOFよりも耐久性が低くなります。

RDB保存の設定

RDBの保存は、redis.confファイル内のsaveディレクティブを使用して設定され、時間間隔と変更の回数を指定します。

save 900 1     # 900秒(15分)で1つのキーが変更された場合に保存
save 300 10    # 300秒(5分)で10個のキーが変更された場合に保存
save 60 10000  # 60秒(1分)で10000個のキーが変更された場合に保存

2. 追記専用ファイル (AOF) 永続化

AOFは、Redisサーバーが受信したすべての書き込み操作を追記専用ログファイルに記録します。Redisが再起動すると、これらのコマンドが順番にリプレイされ、データセットが再構築されます。

AOFの仕組みとそのパフォーマンスへの影響

RDBとは異なり、AOFはトランザクションロギングに焦点を当てています。パフォーマンスプロファイルは、Redisがバッファリングされたデータを物理ディスクに書き込むことをOSに強制する頻度を決定するfsyncポリシーに大きく依存します。

AOF Fsyncポリシー:

ポリシー appendfsync 設定 耐久性 パフォーマンスへの影響
毎秒 everysec 良好(約1秒分のデータを失う) 良好なバランス。わずかなオーバーヘッド。推奨されるデフォルト。
同期なし no 悪い(OSバッファに依存) 最速。OSクラッシュ時にデータ損失のリスクが最大。
常時 always 優秀(アトミック書き込み) 最も遅い。すべての書き込みで必須のディスクI/Oが発生するため、レイテンシが大幅に増加。

パフォーマンスに関する考慮事項:

  • 書き込みレイテンシ: appendfsync alwaysを使用する場合、すべての書き込みコマンドでディスク同期のレイテンシが発生し、RDBまたはインメモリ操作と比較して操作が大幅に遅くなります。everysecを使用すると、fsyncがバッチ処理されるため、これが大幅に軽減されます。
  • リカバリ時間: AOFファイルは大きくなる可能性があり、数百万のコマンドをリプレイするには、コンパクトなRDBファイルをロードするよりも時間がかかるため、リカバリレイテンシが高くなります。
  • ファイルサイズ: AOFファイルは、データ構造の最終状態ではなくコマンド(例:SET key value)を保存するため、通常RDBファイルよりもはるかに大きくなります。

AOFの有効化と設定

AOFはデフォルトでは無効になっており、redis.confappendonly yesを設定することで有効になります。重要な設定はappendfsyncです。

appendonly yes
appendfilename "appendonly.aof"
# 耐久性 vs. 速度のトレードオフのための推奨設定
appendfsync everysec 

パフォーマンスのトレードオフ分析:AOF vs. RDB

RDBとAOFのどちらを選択するかは、生の運用速度(レイテンシ)と保証されたデータリカバリのどちらを優先するかを決定する必要があります。

レイテンシとスループット

  • RDB(生の速度に最適): 書き込みはバックグラウンドプロセスによって処理されるため、メインのRedisスレッドは保存中に直接的なI/Oの影響をほとんど受けません。これにより、一般的に、BGSAVEのフォーク時にシステムに大きな負荷がかからない限り、全体の書き込みレイテンシは低くなります。
  • AOF(alwaysモード): この設定は、ディスクレイテンシがすべてのクライアント書き込みコマンドに直接導入されるため、最も遅く、p99レイテンシが高くなります。
  • AOF(everysecモード): fsync操作がバッファリングされ、頻度が低くなるため、ほとんどの操作でRDBに近いパフォーマンスを提供します。

耐久性とデータ損失のリスク

  • AOF(耐久性に最適): 特にappendfsync alwaysを使用する場合、最高の耐久性を提供します。everysecを使用しても、データ損失は1秒に制限されます。
  • RDB(耐久性で最も劣る): 保存スケジュールに応じて、データ損失が数分または数時間に及ぶ可能性があります。

リカバリ時間

  • RDB(高速リカバリ): 最適化されたコンパクトなバイナリ形式により、再起動時間が短縮されます。
  • AOF(低速リカバリ): 大量のコマンドログをリプレイするには、スナップショットをロードするよりも時間がかかるため、再起動時のダウンタイムが増加します。

ベストプラクティス:両方の永続化方法の使用

高パフォーマンスと強力な耐久性の保証の両方を要求する環境では、RDBとAOFの両方の永続化を同時に有効にすることが推奨されるアプローチです。

両方が有効になっている場合、Redisは起動時にAOFファイルをリプレイに使用して最大のデータ一貫性を実現します。そして、定期的にRDBスナップショットの生成を続行します。

なぜ両方を使用するのか?

  1. より高速なリカバリ: AOFファイルが破損したり、極端に大きくなったりした場合、Redisは最新のRDBスナップショットを始点として使用できるため、その後のAOFリプレイプロセスを大幅に高速化できます。
  2. AOF書き換えの効率性: Redisは、最新のRDBスナップショットに基づいてAOF書き換え操作(冗長なコマンドを破棄して新しいコンパクトなAOFファイルを生成する)を自動的にトリガーできます。これは、既存のAOFログからのみ書き換えるよりも効率的であることがよくあります。

両方の設定スニペット:

# 1. RDBを有効にする
save 900 1

# 2. 'everysec'同期でAOFを有効にする
appendonly yes
appendfsync everysec

AOFファイルサイズの管理(書き換え)

AOFに関する重要な運用上の懸念は、ファイルサイズの増大です。時間の経過とともに、AOFファイルは、以前の値を上書きする変更であってもすべてログに記録するため、巨大になる可能性があります。これに対処するために、RedisはAOF書き換えを提供しています。

AOF書き換えは、データセットの現在の状態を再構築するために必要な最小限のコマンドセットのみを含む、新しい最適化されたAOFファイルを生成します。このプロセスは、現在のAOFファイルのサイズがベースサイズの特定の倍数を超えて増加したときに自動的にトリガーされます。

auto-aof-rewrite-percentage 100  # AOFファイルがベースサイズより100%大きくなったときに書き換え
auto-aof-rewrite-min-size 64mb    # ファイルが64MB以上でない限り、書き換えを行わない

書き換えに関する警告: RDB保存と同様に、AOF書き換えにはプロセスのフォークが伴います。システムがメモリ制約を受けている場合、この一時的なメモリ使用量の倍増(稼働中のインスタンスと書き換えられているコピー)は、不安定性やスワッピングを引き起こす可能性があります。

結論

Redisの永続化の選択は、レイテンシと耐久性の間の直接的なバランスを取る行為です。RDBは高速なリカバリと最小限の書き込みオーバーヘッドに優れていますが、データ損失のリスクがあります。AOFは優れたデータ安全性を提供しますが、fsyncポリシーによっては書き込みレイテンシが発生する可能性があります。

合理的な安全性で高いスループットを優先するほとんどのプロダクションワークロードでは、appendfsync everysecを使用したAOFを有効にすることが標準的な推奨事項です。ほぼゼロのデータ損失を必要とするミッションクリティカルなシステムでは、RDBとAOFの両方を有効にすることで、最高の運用弾力性とパフォーマンチューニングの柔軟性が提供されます。