ECS コンソールで Alibaba Cloud Linux 3 を実行する Elastic Compute Service (ECS) インスタンスを作成すると、XPS (Transmit Packet Steering) が自動的に有効になります。Alibaba Cloud Linux 3 を実行する ECS インスタンスで XPS が無効になっている場合は、本トピックで説明する手順で XPS を設定できます。
XPS の概要
XPS は、マルチキューネットワークインターフェイス (NIC) でデータパケットを送信する際に、送信キューを自動的に選択するメカニズムです。XPS は送信キューと CPU セット間のマッピングを作成します。CPU がデータパケットを送信するとき、カーネルは自動的にその CPU にマッピングされた送信キューを選択してデータパケットを送信します。カーネルはデータフローの最初のパケットで選択された送信キューを記録し、そのフローの後続パケットの送信にも同じキューを使用します。この送信メカニズムにより、各パケットの送信キューを選択する際の計算オーバーヘッドが削減されます。
XPS には以下のメリットがあります。
XPS は、異なる CPU 間での同一送信キューの競合を緩和します。これにより、キューを使用したデータ送信時のロック競合が削減され、データパケットの伝送効率が向上します。
XPS は、送信キューがバインドされている virtio NIC のアフィニティと一致する、送信キューと CPU 間のマッピングを作成します。これにより、パケット送信中のキャッシュミスやロック競合によるキャッシュミスの可能性が低くなり、ネットワーク伝送性能が向上します。
XPS の設定
ECS インスタンスにリモート接続します。
詳細については、「ワークベンチを使用した Linux インスタンスへのログイン」をご参照ください。
次のコマンドを実行して、ECS インスタンスに XPS が設定されているかどうかを確認します。カーネルで CONFIG_XPS が有効になっていることを確認してください。
この例では、eth0 NIC を使用します。
cat /sys/class/net/eth0/queues/tx-*/xps_cpus次の図に示すように、返されたコマンド出力がすべてゼロの場合、ECS インスタンスで XPS は無効です。この場合は、以降の手順に進んで XPS を設定します。

NIC で使用可能な CPU と送信キューの数に基づいて、すべての virtio NIC の XPS を設定します。XPS の設定が、カーネルが各送信キューに CPU を割り当てる際に使用するポリシーに準拠していることを確認してください。
次のコマンドを実行して、現在のディレクトリに XPS 設定に使用するファイルを作成します。例えば、
xps_config.pyファイルを作成します。vim xps_config.pyIキーを押して挿入モードに入り、次の内容をxps_config.pyファイルにコピーします。# encoding: utf-8 # カーネル XPS のデフォルト設定を実装します。 # 注意: このスクリプトの設定は virtio-net NIC にのみ適用されます。 import os import multiprocessing def setup_xps(dev): cpu_count = multiprocessing.cpu_count() txq_dir = "/sys/class/net/{0}/queues/".format(dev) queue_count = len([f for f in os.listdir(txq_dir) if f.startswith("tx-")]) if queue_count <= 1: print("txq の数: {0} <= 1、終了します...".format(queue_count)) return group, stragglers = divmod(cpu_count, queue_count) stragglers = 0 if group == 0 else stragglers group = max(group, 1) cpu = 0 queue_final_bitmap = "" # NUMA ノード情報を考慮する必要はありません。 # そのため、複数の NUMA ノードのシナリオではパフォーマンスに注意が必要です! for i in range(queue_count): group_size = (group + 1) if i < stragglers else group queue_per_bitmap = 0 for j in range(group_size): cpu_bitmap = 1 << cpu cpu += 1 queue_per_bitmap |= cpu_bitmap cpu = 0 if cpu >= cpu_count else cpu queue_final_bitmap = hex(queue_per_bitmap)[2:] if "L" in queue_final_bitmap: queue_final_bitmap = queue_final_bitmap.replace("L", "") result_bitmap = output_seg(queue_final_bitmap) eth_txq_path = "/sys/class/net/{0}/queues/tx-{1}/xps_cpus".format(dev, i) with open(eth_txq_path, "w") as fxps: fxps.write(result_bitmap) print("{0} の XPS 設定が完了しました。".format(dev)) def output_seg(bitmap): result = "" count = 0 for char in reversed(bitmap): if count % 8 == 0 and count != 0: result = "," + result result = char + result count += 1 return result def process_devs(): eth_dir = "/sys/class/net/" eth_folders = [f for f in os.listdir(eth_dir) if os.path.isdir(os.path.join(eth_dir, f)) and f.startswith("eth")] for eth_folder in eth_folders: eth = eth_folder.split("/")[-1] setup_xps(eth) if __name__ == '__main__': process_devs()Escキーを押し、:wqと入力してファイルを保存し、終了します。
次のコマンドを実行して XPS を設定します。
sudo python3 xps_config.py(オプション)次のコマンドを実行して、XPS 設定が完了しているかどうかを確認します。
この例では、ECS インスタンスの 32 個の CPU が、eth0 NIC の 8 個の送信キューにマッピングされています。
cat /sys/class/net/eth0/queues/tx-*/xps_cpus次の出力は、XPS が設定されていることを示しています。出力内容は、CPU またはキューの数によって異なります。

影響
XPS を設定する目的は、ネットワークパフォーマンスを向上させることです。ただし、XPS を設定した後、ネットワークパフォーマンスに影響が出る場合があります。XPS がネットワークパフォーマンスに影響を与える場合は、次のコマンドを実行して XPS 設定をクリアします。この例では、eth0 NIC を使用します:
sudo sh -c 'for txq in /sys/class/net/eth0/queues/tx-*; do echo 0 > $txq/xps_cpus; done'