Alibaba Cloud Linux 2 (カーネルバージョン 4.19.36-12.al7 以降) および Alibaba Cloud Linux 3 では、cgroup v1 カーネルインターフェイスで cgroup ライトバック機能が利用できます。この機能により、バッファ付き I/O のレートを制限できます。
背景情報
コントロールグループ (本トピックでは cgroup と呼びます) は、リソースを割り当てるための Linux カーネルの機能です。cgroup には cgroup v1 と cgroup v2 の 2 つのバージョンがあります。詳細については、Resource Management Guide の What are Control Groups セクションをご参照ください。本トピックでは、cgroup v1 の cgroup ライトバック機能を有効にして、プロセスのバッファ付き I/O レートを制限する方法について説明します。
制限事項
cgroup ライトバック機能を有効にした後は、メモリサブシステム (memcg) と I/O サブシステム (blkcg) 間のマッピングが、このセクションで説明するルールに従っていることを確認する必要があります。これは、プロセスのバッファ付き I/O レートを制限するために必要です。
cgroup ライトバック機能でバッファ付き I/O レートを制限するには、memcg と blkcg が連携して動作する必要があります。デフォルトでは、cgroup v1 の制御サブシステムは連携して動作しません。そのため、特定のルールに基づいて memcg と blkcg を接続する必要があります。各 memcg は単一の blkcg にマッピングする必要があります。マッピングは 1 対 1 または多対 1 にはできますが、1 対多または多対多にすることはできません。
たとえば、プロセス A と B のバッファ付き I/O レートを制限する場合、次の制約が適用されます。
プロセス A と B が異なる memcg に属している場合、異なる blkcg に 1 対 1 でマッピングできます。たとえば、A は
memcg1とblkcg1に、B はmemcg2とblkcg0に属します。プロセス A と B が異なる memcg に属している場合、同じ blkcg にマッピングすることもできます。たとえば、A は
memcg1に、B はmemcg2に属していますが、A と B は両方ともblkcg2に属しています。プロセス A と B が同じ memcg に属している場合、同じ blkcg にマッピングする必要があります。たとえば、A と B は両方とも
memcg0とblkcg3に属することができます。
cgroup ライトバックを有効にした後に予期しない問題が発生するのを防ぐため、バッファ付き I/O レートを制限する前に、blkcg の cgroup.procs インターフェイスを設定してください。このインターフェイスにプロセス ID を書き込むことで、一意の blkcg マッピングを確保します。また、ツールを使用して memcg と blkcg 間のマッピングを表示することもできます。詳細については、「memcg と blkcg 間のマッピングの確認」をご参照ください。
運用保守 (O&M) 中に、プロセスが別の cgroup に移動される場合があります。マッピングルールに基づくと、プロセスが memcg 間で移動しても問題は発生しません。ただし、プロセスが blkcg 間で移動すると問題が発生します。これを防ぐため、この機能のコードには次のルールが実装されています。アクティブな blkcg 内のプロセスが別の blkcg に移動されると、マッピングがルート blkcg にリセットされます。通常、ルート blkcg にはレート制限のしきい値が設定されていないため、レート制限機能は無効になります。
カーネルコードには予期しない問題を防ぐためのルールが実装されていますが、運用中はプロセスを blkcg 間で移動することは避けてください。
cgroup ライトバック機能の有効化
cgroup v1 インターフェイスでは、cgroup ライトバック機能はデフォルトで無効になっています。次の手順に従って有効にします。
cgwb_v1フィールドをgrubbyコマンドを使用して追加し、機能を有効化します。この例では、カーネルバージョンは
4.19.36-12.al7.x86_64です。これを実際のカーネルバージョンに置き換えてください。uname -rコマンドを実行して、カーネルバージョンを確認できます。sudo grubby --update-kernel="/boot/vmlinuz-4.19.36-12.al7.x86_64" --args="cgwb_v1"変更を有効にするため、システムを再起動します。
sudo reboot次のコマンドを実行して
/proc/cmdlineカーネルファイルを読み取り、カーネルのコマンドラインパラメーターにcgwb_v1フィールドが含まれていることを確認します。これにより、blkcg のblkio.throttle.write_bps_deviceおよびblkio.throttle.write_iops_deviceインターフェイスが有効になり、バッファ付き I/O レートを制限できます。cat /proc/cmdline | grep cgwb_v1
Kubernetes (k8s) 環境では、cgroup ライトバック機能を有効にした後、memory と blkio cgroup サブシステムをマージする必要があります。これにより、プロセスが移動された場合にレート制限が失敗するのを防ぎます。
memory と blkio cgroup サブシステムをマージします。
system.conf ファイルを編集します。
sudo vim /etc/systemd/system.confJoinControllers 設定を変更します。例:
JoinControllers=cpu,cpuacct net_cls,net_prio memory,blkioEsc キーを押して編集モードを終了します。次に、:wq を入力して保存し、終了します。
次のコマンドを実行して初期 RAM ディスクイメージを再構築します。これにより、systemd 設定の変更が有効になります。
sudo dracut /boot/initramfs-4.19.36-12.al7.x86_64.img 4.19.36-12.al7.x86_64 --force次のコマンドを実行してシステムを再起動します。
sudo reboot次のコマンドを実行して、memory と blkio サブシステムがマージされていることを確認します。
ls /sys/fs/cgroup
cgroup ライトバックの有効性検証
この例では、2 つの I/O 生成プロセスをシミュレートして、cgroup ライトバック機能が有効であることを確認します。
ddコマンドは迅速なフィードバックを提供します。iostatコマンドを使用して結果を表示できます。ddコマンドは、データをシーケンシャルに書き込みます。 シーケンシャル I/O のリフレッシュ中に、システムは 1 MB のチャンクでデータを書き戻します。 したがって、blkio.throttle.write_bps_deviceのしきい値を少なくとも 1 MB (1048576) に設定します。 1 MB 未満の値を設定すると、I/O プロセスがハングする可能性があります。
I/O を生成する 2 つのプロセスをシミュレートします。 制限の要件に従い、まず blkcg の
cgroup.procsインターフェイスを設定します。sudo mkdir /sys/fs/cgroup/blkio/blkcg1 sudo mkdir /sys/fs/cgroup/memory/memcg1 sudo bash -c "echo $$ > /sys/fs/cgroup/blkio/blkcg1/cgroup.procs" # $$ は現在のプロセス ID です sudo bash -c "echo $$ > /sys/fs/cgroup/memory/memcg1/cgroup.procs" # $$ は現在のプロセス ID ですblkcg の
blkio.throttle.write_bps_deviceインターフェイスを使用して、バッファ付き I/O レートを制限します。sudo bash -c "echo 254:48 10485760 > /sys/fs/cgroup/blkio/blkcg1/blkio.throttle.write_bps_device" # デバイス番号に基づいて、ディスクライトバックレート制限を 10 MB/s に設定します。ddコマンドをoflag=syncパラメーターを指定せずに使用すると、キャッシュされた非同期 I/O が生成されます。sudo dd if=/dev/zero of=/mnt/vdd/testfile bs=4k count=10000iostat ツールを使用して結果を照会します。出力の
wMB/s列を確認します。レートが約 10 MB/s に制限されている場合、cgroup writeback 機能は正常に動作しています。iostat -xdm 1 vdd
memcg と blkcg 間のマッピングの確認
次のいずれかの方法を使用して、memcg と blkcg 間のマッピングが 1 対 1 または多対 1 であることを確認できます。
memcg と blkcg 間のマッピングを表示します。
sudo cat /sys/kernel/debug/bdi/bdi_wb_link次のサンプル出力は、memcg と blkcg が 1 対 1 のマッピングであることを示しています。
memory <---> blkio memcg1: 35 <---> blkcg1: 48ftrace カーネル監視ツールを使用します。
ftrace ツールを有効にします。
sudo bash -c "echo 1 > /sys/kernel/debug/tracing/events/writeback/insert_memcg_blkcg_link/enable"出力情報を表示できます。
sudo cat /sys/kernel/debug/tracing/trace_pipe次の出力例
memcg_ino=35 blkcg_ino=48は、memcg と blkcg が 1 対 1 でマッピングされていることを示します。<...>-1537 [006] .... 99.511327: insert_memcg_blkcg_link: memcg_ino=35 blkcg_ino=48 old_blkcg_ino=0