データ永続化機能
RabbitMQにおける永続化は、エクスチェンジ、キュー、メッセージの3つのレベルで実装されます。
- 永続化エクスチェンジの定義:第3引数のdurableパラメータで永続化を有効/無効化
channel.declareExchange(exchangeName, exchangeType, true)
- 永続化キューの定義:第2引数のdurableパラメータで永続化を制御
channel.declareQueue(queueName, true, exclusiveFlag, autoDeleteFlag, queueArgs);
- 永続化メッセージの送信:BasicProperties内でdeliveryMode=2を設定する必要があります。このプロパティはbasicPublishメソッドのpropsパラメータ経由で渡されます。
channel.publishToQueue(exchangeName, routingKey, messageProps, messageBody);
BasicPropertiesオブジェクトはRabbitMQが提供する標準MessagePropertiesクラスから取得可能です:
MessageProperties.PERSISTENT_BASIC
他のプロパティも同時に設定する必要がある場合は、AMQP.BasicProperties.Builderを使用してカスタムオブジェクトを構築します:
AMQP.BasicProperties customProps = new AMQP.BasicProperties.Builder()
.deliveryMode(2)
.contentType("text/plain")
.build();
メモリ警告メカニズム
デフォルトではset_vm_memory_high_watermarkの値は0.4に設定されており、これはRabbitMQが使用するメモリが全体の40%を超えるとメモリ警告が発生し、すべてのプロデューサー接続がブロックされることを意味します。警告が解除されると(メッセージが消費されるかメモリからディスクへ移動すると)、通常状態に戻ります。
メモリ警告発生後、すべてのクライアント接続がブロック状態になります。ブロッキングには以下の2種類があります:
- blocking:メッセージ送信していない接続
- blocked:メッセージ送信を試みている接続
メモリ警告中にマシンに空きメモリがある場合、以下のコマンドでメモリ閾値を調整して警告を解除できます:
rabbitmqctl set_vm_memory_high_watermark 0.8
または絶対値で指定:
rabbitmqctl set_vm_memory_high_watermark absolute 2GB
ただし、これらの変更は一時的なものであり、RabbitMQサービス再起動時に元に戻ります。永続的な変更を行うには設定ファイルを編集する必要があります。設定ファイルの変更はRabbitMQサービスの再起動後に有効になります。
- 設定ファイル編集:vim /etc/rabbitmq/rabbitmq.conf
vm_memory_high_watermark.relative = 0.6
または:
vm_memory_high_watermark.absolute = 2GB
メモリ警告シミュレーション手順
- メモリ閾値を調整して警告を模擬し、RabbitMQサーバー上で変更します。変更前に管理画面で現在の使用量を確認し、現在値より小さい値に設定してください:
rabbitmqctl set_vm_memory_high_watermark absolute 100MB
- 管理画面を更新(複数回更新が必要な場合があります)。Overview → NodesでMemoryが赤色になり、ノードでメモリ警告が発生したことを示します
- ProducerとConsumerを起動
- 管理画面のConnectionsページで、ProducerとConsumerの接続がblocking状態になっていることを確認
- ProducerのコンソールでEnterキーを押してから管理画面のConnectionsページを再度確認すると、Producerの状態がblockedになることがわかります
- Producerコンソールで2つのメッセージ送信情報を確認できますが、Consumerはメッセージを受信しません。また、管理画面のQueuesページでもキューのメッセージ数に変化がありません
- メモリ警告を解除すると、ConsumerがProducerが送信した2つのメッセージを受信することが確認できます
メモリページング処理
- Brokerノードがメモリ閾値に近づくと、キュー内のメッセージをディスクに保存してメモリ空間を解放しようとします。この処理をメモリページングと呼びます
- 永続化および非永続化メッセージはいずれもディスクにダンプされます。永続化メッセージは既にディスクにコピーを持っているため、メモリから削除されます
- デフォルトでは、メモリが閾値の50%に達した時点でページング処理が実行されます。つまり、デフォルトのメモリ閾値0.4の場合、メモリが0.4 × 0.5 = 0.2を超えるとページングが開始されます
- 設定ファイルを変更してメモリページング比率を調整できます(コマンドでの調整は不可):
# この値が1以上の場合、ページング機能が実質的に無効になります
vm_memory_high_watermark_paging_ratio = 0.8
ディスク警告メカニズム
- ディスクの空き容量が閾値を下回ると、RabbitMQはプロデューサーをブロックします。これにより、非永続化メッセージの継続的なページングによるディスク容量の枯渇を防ぎ、サービスのクラッシュを回避します
- デフォルトではディスク閾値は50MBに設定されています。ディスクの空き容量が50MB未満になると、プロデューサーがブロックされ、メモリメッセージのページング動作も停止します
- この閾値を小さく設定することは可能ですが、ディスク容量の枯渇によるクラッシュリスクを完全に排除することはできません。例えば、2回のディスク容量検出の間にディスク容量が50MB以上から0MBまで消費される可能性があります
- 以下のコマンドでディスク閾値を調整可能です(一時的な変更、再起動で元に戻ります):
# disk_limitは固定サイズ、単位はMBまたはGB
rabbitmqctl set_disk_free_limit <disk_limit>
または相対値で指定:
# fractionは相対比率、1.0〜2.0の範囲での使用を推奨
rabbitmqctl set_disk_free_limit mem_relative <ratio>
ディスク警告シミュレーション手順
- サーバー上でコマンドを使用してディスク閾値を一時的に調整します(現在のディスク容量より大きな絶対値を設定してください):
rabbitmqctl set_disk_free_limit 204800GB
- 管理画面を更新(複数回更新が必要な場合があります)。Overview → NodesでDisk spaceが赤色になり、ノードでディスク警告が発生したことを示します
- 以降の手順はメモリ警告シミュレーションと同じです