共有メモリ通信 (SMC) は、TCP ソケットをリモートダイレクトメモリアクセス (RDMA) を活用した SMC ソケットに透過的に置き換え、コード変更を伴わずにアプリケーションのレイテンシを低減し、スループットを向上させます。本ガイドでは、Alibaba Cloud Elastic Compute Service (ECS) および Container Service for Kubernetes (ACK) における SMC-R の有効化、Berkeley Packet Filter (BPF) ポリシーによる高速化範囲のファインチューニング、および SMC パラメーターの構成について説明します。
仕組み
TCP 接続のハンドシェイク中に、両方のピアが SMC 対応を通知するための特別な TCP オプションを交換します。ネゴシエーションが成功すると、以降のデータは RDMA 経由で送信されます。いずれかのピアが SMC をサポートしていない場合、または何らかの理由でネゴシエーションが失敗した場合は、接続は自動的に TCP へフォールバックします — アプリケーション側の変更は一切不要です。
ソケット変換方法の選択
既存の TCP ソケットアプリケーションを SMC ソケットに変換するには、以下の 2 つのアプローチがあります:
| 方法 | 適用範囲 | 動作概要 | 使用シーン |
|---|---|---|---|
| ネットワーク名前空間レベル | ネットワーク名前空間内の該当するすべての TCP ソケット | カーネルが新しい socket() 呼び出しをインターセプトして変換します | 環境全体を制御でき、名前空間内のすべてのサービスに対して SMC を適用したい場合 |
| プロセスレベル | 単一のプロセスおよびその子プロセス | smc_run が LD_PRELOAD を使用して glibc 内の socket() をインターセプトします | 特定のサービスのみに SMC を適用し、他のサービスへの影響を避けたい場合 |
どちらの方法でも、以下の 3 つの条件をすべて満たすソケットが変換対象となります:
family=AF_INETtype=SOCK_STREAMprotocol=IPPROTO_IP(0)またはIPPROTO_TCP(6)
smc_run によるプロセスレベルの変換には glibc が必要です。静的リンク済みバイナリや glibc をバイパスするアプリケーションでは動作しません。Alibaba Cloud ECS における SMC の使用
前提条件
開始する前に、以下の条件を満たしていることを確認してください:
弾力的なリモートダイレクトメモリアクセス (eRDMA) 機能を提供する Elastic RDMA Interface (ERI) をサポートする ECS インスタンス。詳細については、「エンタープライズ向けインスタンスでの eRDMA の構成」をご参照ください。
Alibaba Cloud eRDMA デバイスおよび SMC は IPv6 アドレスをサポートしていません。IPv6 を使用するアプリケーションは TCP にフォールバックします。詳細については、「SMC のトラブルシューティング」をご参照ください。
カーネルバージョン
ANCK 5.10.134-17.3以降では、SMC がIPv4-mapped IPv6アドレスをサポートします。
SMC のセットアップ
1. SMC カーネルモジュールをロードします。
sudo modprobe smc
sudo modprobe smc_diagdmesg を実行して、モジュールが正しくロードされたことを確認します:
smc: smc: load SMC module with reserve_mode
NET: Registered protocol family 43
smc: netns <netns ID> reserved ports [65500 ~ 65515] for eRDMA OOB
smc: adding ib device erdma_0 with port count 1
smc: ib device erdma_0 port 1 has pnetid必要がなくなった場合に SMC をアンロードするには、以下を実行します:
sudo rmmod smc_diag
sudo rmmod smc2. 運用・保守 (O&M) ツールセットをインストールします。
sudo yum install -y smc-tools
sudo yum install -y aliyun-smc-extensionsネットワーク名前空間レベルのソケット変換の有効化
この方法では、sysctl 設定後に作成されるすべての該当する TCP ソケットが変換され、既存のソケットには影響しません。
以下の図は変換プロセスを示しています。
現在のネットワーク名前空間に対して透過的なソケット変換を有効化します:
sudo sysctl net.smc.tcp2smc=1デフォルト値は
0(無効)です。TCP ソケットアプリケーションを通常通り起動します:
./<foo><foo>をご利用のアプリケーション名に置き換えます。アプリケーションの TCP ソケットは透過的に SMC ソケットに変換され、SMC-R スタックによって処理されます。「仕組み」でフォールバック動作についてご確認ください。(任意) 現在のネットワーク名前空間について変換を無効化します。新しい TCP ソケットは TCP に戻りますが、既存の変換済み SMC ソケットには影響があります:
sudo sysctl net.smc.tcp2smc=0
プロセスレベルのソケット変換の有効化
この方法では、smc_run コマンド(smc-tools ツールセットに含まれる)を用いて、単一のプロセスおよびその子プロセスに適用します。
以下の図は変換プロセスを示しています。
ご利用のアプリケーションの実行可能ファイルの先頭に smc_run を付加します:
smc_run ./<foo><foo> をご利用のプロセス名に置き換えます。このプロセスが作成する TCP ソケットは透過的に SMC ソケットに変換されます。「仕組み」でフォールバック動作についてご確認ください。
BPF ポリシーによる SMC ネゴシエーションの制御
ネットワーク名前空間レベルおよびプロセスレベルの変換は、広範囲に SMC を適用します。より詳細な制御が必要な場合(例:ポート 6379(Redis)でのみ SMC を有効化し、ポート 8080 は TCP のままにする)には、smc-ebpf を使用して BPF ベースのポリシーを設定します。
典型的なワークフローは以下のとおりです:
BPF ポリシーの構成およびロード
上記のとおり、ネットワーク名前空間レベルまたはプロセスレベルで SMC を有効化
デフォルトでは、SMC ソケットは常に SMC TCP オプションの送信および受信を試行します。BPF ポリシーを使用すると、ポート単位またはサーバーの IPv4 アドレス単位でこの動作をオーバーライドできます。
smc-ebpf のインストール
smc-ebpf は smc-tools に含まれています。インストール状況を確認するには、以下を実行します:
smc-ebpf policy help正常に実行された場合、利用可能なサブコマンドの一覧が表示されます:
smc-ebpf policy help
Usage: smc-ebpf policy COMMAND [OPTIONS]
smc-ebpf policy load [OPTIONS] load policy
--init load policy with pre-defination config
smc-ebpf policy stop stop policy
smc-ebpf policy unload unload policy
smc-ebpf policy init init policy with default config
smc-ebpf policy clear clear all policy config
smc-ebpf policy dump display all policy config
smc-ebpf policy config [OPTIONS] config policy
smc-ebpf policy delete [OPTIONS] delete policy
--ip [IPv4] target IPv4 address
--port target port
--mode [auto|disable|enable] target mode
Examples:
smc-ebpf policy load
#disable port 80 to use smc
smc-ebpf policy config --port 80 --mode disable
#delete ip xxx.xxx.x.x/24 policy
smc-ebpf policy delete --ip xxx.xxx.x.x --mask 24smc-ebpf のロード
sudo smc-ebpf policy load制御対象の接続を作成する前に、
smc-ebpfをロードしてください。ロード前に作成された接続にはポリシーは適用されません。ポリシーはグローバルであり、個別のネットワーク名前空間やコンテナにはスコープを限定できません。
smc-ebpfの機能は実験的であり、今後のリリースで変更される可能性があります。
正常にロードされた場合の出力例:
# sudo smc-ebpf policy load
Registered smc_sock_negotiator_ops anolis_smc id xxx出力が異なる場合は、以下の手順でトラブルシューティングを行ってください:
カーネルバージョンが
ANCK 5.10.134-016以降であることを確認します:uname -rBPF プログラムのロード権限があることを確認します。コンテナ環境では必要な機能が不足している可能性があります — 環境プロバイダーにお問い合わせください。
ポートポリシー
ポートポリシーは、接続のポートに基づいて SMC ネゴシエーションの使用可否を制御します。
デフォルト動作:smc-ebpf をロード後、マッチするポリシーがないポートは、SMC ネゴシエーションの使用が禁止されます。
マッチしないポートに対してデフォルトで SMC を許可するように変更するには:
# デフォルトを変更: 一致しないポートで SMC を有効化
sudo smc-ebpf policy config --port 0 --mode enable
# ポート 80 を無効化
sudo smc-ebpf policy config --port 80 --mode disableデフォルトを再び禁止に戻すには:
sudo smc-ebpf policy config --port 0 --mode disable例 1:ポート 80 のみを許可し、その他すべてをブロック
# Allow port 80
sudo smc-ebpf policy config --port 80 --mode enable
# Verify
sudo smc-ebpf policy dump期待される出力:
# sudo smc-ebpf policy dump
[{
"key": 80,
"value": {
"mode": 2,
[Other fields that ordinary users do not need to pay attention to]
}
}
]"key": 80 はポート番号を表します。"mode": 2 は SMC ネゴシエーションが許可されることを意味し、"mode": 0 は禁止を意味します。
ポリシーを削除するには:
sudo smc-ebpf policy delete --port 80例 2:ポート 80 のみをブロックし、その他すべてを許可
# Change default: allow SMC for unmatched ports
sudo smc-ebpf policy config --port 0 --mode enable
# Block port 80
sudo smc-ebpf policy config --port 80 --mode disableIPv4 アドレスポリシー
IPv4 アドレスポリシーは、クライアントソケットのみに適用されます。これは、クライアントが特定のサーバー IP アドレスへ接続する際に SMC ネゴシエーションを使用するかどうかを制御します。サーバーソケットの動作には影響しません。
すべてのポートポリシーおよび IPv4 アドレスポリシーは論理積(AND)で評価されます。すべてのマッチするポリシーが許可している場合にのみ、SMC ネゴシエーションが使用されます。
デフォルト動作:smc-ebpf をロード後、マッチするポリシーがないサーバー IP は、SMC ネゴシエーションが許可されます。
マッチしない IP に対してデフォルトで SMC をブロックするように変更するには:
# 一致しないIPをブロック
sudo smc-ebpf policy config --ip 0.0.0.0 --mask 32 --mode disable
# 192.168.2.0/24 を許可
sudo smc-ebpf policy config --ip 192.168.2.0 --mask 24 --mode enable
# 確認
sudo smc-ebpf policy dumpデフォルトを再び許可に戻すには:
sudo smc-ebpf policy config --ip 0.0.0.0 --mask 32 --mode enable例 1:192.168.2.0/24 のみを許可し、その他の宛先をすべてブロック
# Block unmatched IPs
sudo smc-ebpf policy config --ip 0.0.0.0 --mask 32 --mode disable
# Allow 192.168.2.0/24
sudo smc-ebpf policy config --ip 192.168.2.0 --mask 24 --mode enable
# Verify
sudo smc-ebpf policy dump期待される出力:
# sudo smc-ebpf policy dump
key: 0.0.0.0/32 value: "denied"
key: 192.168.2.0/24 value: "pass""pass" は SMC の許可、"denied" は禁止を意味します。
これらのポリシーを削除するには:
sudo smc-ebpf policy delete --ip 192.168.2.0 --mask 24
sudo smc-ebpf policy delete --ip 0.0.0.0 --mask 32例 2:192.168.2.0/24 のみをブロックし、その他の宛先をすべて許可
sudo smc-ebpf policy config --ip 192.168.2.0 --mask 24 --mode disable追加の構成は不要です。デフォルトでは、その他のすべてのサーバー IP に対して SMC が許可されます。
すべてのポリシーのクリア
sudo smc-ebpf policy clearこれにより、すべての構成済みポリシーが削除され、デフォルト状態が復元されます:すべてのポートに対して SMC ネゴシエーションは禁止(ポートのデフォルト:禁止)、すべての IPv4 アドレスに対しては許可(IP のデフォルト:許可)となります。ポートポリシーと IP ポリシーは論理積(AND)で評価されるため、すべての接続は最終的に SMC ネゴシエーションの使用が禁止されます。
Alibaba Cloud ACK における SMC の使用
Container Service for Kubernetes (ACK) では、ACK eRDMA Controller コンポーネントを使用して SMC を有効化します。eRDMA Controller は ERI を管理・スケジュールし、Pod にネットワーク機能を提供します。詳細については、「SMC-R を使用したアプリケーションネットワーキングの高速化」をご参照ください。
ACK ノード上でも、前述の smc-ebpf ワークフローを用いた、BPF ベースの詳細な SMC 有効化ポリシーが利用可能です。パラメーター
SMC スタックは、sysfs および smc-tools を通じて構成パラメーターを公開しています。
sysfs パラメーター
| パラメーター | デフォルト | 有効な値 | カーネルバージョン | 変更タイミング |
|---|---|---|---|---|
net.smc.autocorking_size | 65535 | 0–4294967295;0 = 無効 | 5.10.112-11 以降 | 小規模パケット帯域幅のシナリオでは増加します。パイプラインシナリオで autocorking の遅延が許容できない場合は、0 に設定します。 |
net.smc.autosplit_size | 131072 | 32768–536870912 | 5.10.134-18+;5.10.134-17.3+(17 シリーズ);5.10.134-16.5+(16 シリーズ) | 大規模パケットのレイテンシシナリオでは減少させます。この値の 1.3 倍を超えるパケットは、バッチ転送のために分割されます。 |
net.smc.experiment_vendor_options | 4294967295 (0xFFFFFFFF) | — | 5.10.134-16 以降 | デフォルト値を維持してください。 |
net.smc.global_mem | [システムメモリの 25%、50%、75%] | — | 5.10.134-18+;5.10.134-17.3+;5.10.134-16.5+ | global_mem[2] を予想されるメモリ使用量に基づいて調整します。SMC バッファーのサイズが global_mem[2] に達すると、新しい接続はシステム全体で TCP へフォールバックします。 |
net.smc.limit_smc_hs | 1 | 0 = フォールバックなし;1 = TCP へフォールバック | 5.10.134-18+;5.10.134-17.3+;5.10.134-16.5+ | 1 のまま維持してください。高負荷時の接続圧力下でフォールバックを防止したい場合にのみ、0 に設定します。 |
net.smc.mem | [システムメモリの 25%、50%、75%] | — | 5.10.134-18+;5.10.134-17.3+;5.10.134-16.5+ | mem[2] を予想されるネットワーク名前空間レベルのメモリ使用量に基づいて調整します。ネットワーク名前空間内の SMC バッファーのサイズが mem[2] に達すると、その名前空間内の新しい接続は TCP へフォールバックします。 |
net.smc.rmem | 262144 | SMC-R:16384–536870912;SMC-D:16384–1048576 | 5.10.134-14 以降 | Rx/Buffer fullRx/Buffer full メトリックが高い場合は増加させます。rmem の相手側で Tx/Buffer full(remote) または Tx/Buffer too small(remote) メトリックが高い場合は、相手側の を増加させます。メモリが制約されており、パフォーマンスに影響がない場合は減少させます。「SMC のモニタリング」をご参照ください。 |
net.smc.wmem | 262144 | SMC-R:16384–536870912;SMC-D:16384–1048576 | 5.10.134-14 以降 | Tx/Buffer full または Tx/Buffer too small メトリックが高い場合は増加させます。メモリが制約されており、パフォーマンスに影響がない場合は減少させます。「SMC のモニタリング」をご参照ください。 |
net.smc.smcr_buf_type | 2 | 0 = 物理的に連続;1 = 論理的に連続;2 = 物理的に連続を優先(論理的に連続へフォールバック) | 5.10.134-12 以降 | デフォルト値を維持してください。新しいリンクグループ上の SMC 接続にのみ適用されます。 |
net.smc.smcr_max_conns_per_lgr | 32 | 1–255(5.10.134-18+、5.10.134-17.3+、5.10.134-16.5+);16–255(その他のバージョン) | 5.10.134-16.1 以降 | 各接続がより多くの RDMA バンド幅を必要とする高スループットシナリオでは減少させます。増加はしないでください。 |
net.smc.smcr_max_links_per_lgr | 1 | 1 または 2 | 5.10.134-16.1 以降 | デフォルト値を維持してください。 |
net.smc.smcr_testlink_time | 30 | 0–2147483647(秒);0 = 無効 | 5.10.134-13 以降 | デフォルト値を維持してください。SMC-R における RDMA 信頼性接続のハートビート間隔を制御します。 |
net.smc.tcp2smc | 0 | 0 = 無効;1 = 有効 | 5.10.134-16 以降 | ネットワーク名前空間内で TCP から SMC への透過的変換を有効化するには、1 に設定します。無効化するには 0 に設定します。 |
EID の構成
Enterprise ID(EID)は SMCv2 プロトコルにおける概念です。同じ EID を共有するシステム同士のみが SMCv2 経由で通信可能であり、それ以外の場合は TCP へフォールバックします。1 つのシステムは最大 8 個の EID をサポートします。
Alibaba Cloud Linux 3 の eRDMA デバイスでは SMCv2 プロトコルが必須です。すべての Alibaba Cloud Linux 3 ノードには、EID SMCV2-DEFAULT-UEID が事前に搭載されているため、EID の手動構成を行わなくてもノード間で SMCv2 経由の通信が可能です。
EID の形式:最大 32 文字、大文字、数字、ハイフン(-)、ピリオド(.)のみ使用可能。先頭は文字または数字で始める必要があります。連続するピリオドは使用できません。
EID の表示、追加、削除を行うには:
# View existing EIDs
smcr ueid show
# Add an EID
sudo smcr ueid add <EID>
# Remove an EID
sudo smcr ueid del <EID>EID を使用したクロスゾーン SMC-R 通信の防止
SMC-R は同一可用性ゾーン内での通信が最も効果的です。SMC-R を同一ゾーン内トラフィックに限定し、クロスゾーントラフィックについては自動的に TCP へフォールバックさせるには、ゾーン ID を EID として設定します。
方法 1:ステップバイステップでの構成
# Fetch the zone ID from instance metadata and convert to uppercase
ZONE_ID=$(curl -s -m 1 100.100.100.200/latest/meta-data/zone-id | tr "[:lower:]" "[:upper:]")
# Add the zone ID as an EID
sudo smcr ueid add $ZONE_ID
# Remove the default EID
smcr ueid | grep SMCV2-DEFAULT-UEID > /dev/null && sudo smcr ueid del SMCV2-DEFAULT-UEID方法 2:aliyun-smc-extensions を使用したワンクリック構成
aliyunsmc-ueid サービスは、ゾーン ID を EID として自動的に追加し、デフォルトの EID を自動的に削除します。
sudo systemctl start aliyunsmc-ueidEID 構成は再起動時に保持されないため、起動時に自動的に開始されるようサービスを有効化します:
sudo systemctl enable aliyunsmc-ueidPNET ID の構成
TCP トラフィックが SMC-R に変換される際、SMC-R スタックは、そのトラフィックを運ぶイーサネットインターフェイスに関連付けられた Elastic RDMA Interface (ERI) を通じてトラフィックをルーティングします。
この関連付けは、eRDMA がイーサネットインターフェイスに直接有効化されている場合に自動的に機能します。ERI が異なるイーサネットインターフェイスに関連付けられている場合は、物理ネットワーク識別子(PNET ID)を手動で使用して関連付けます。
例:ノードに eth0 および eth1 が存在します。eth0 で eRDMA が有効化されており、erdma_0 と関連付けられています。
eth0上の TCP トラフィック — SMC-R が自動的にerdma_0を検出します。PNET ID は不要です。eth1上の TCP トラフィック — SMC-R が ERI を検出できず、TCP へフォールバックします。eth1をerdma_0と PNET ID を介して関連付けることで、eth1トラフィックの RDMA を有効化できます。
PNET ID の形式:最大 16 文字、大文字および数字のみ、スペース不可。
イーサネットインターフェイスと ERI を PNET ID で関連付けるには:
sudo smc_pnet構成済みの PNET ID を表示するには:
sudo smc_pnet出力例:
# sudo smc_pnet
00163E0CD751 n/a erdma_0 1
00163E0CD751 eth1 n/a 255PNET ID 00163E0CD751 は erdma_0 と eth1 を関連付けます。eth1 経由の TCP トラフィックは、SMC-R が有効化されている場合に erdma_0 を通じて高速化されます。
eRDMA のイーサネットインターフェイスへのチェックおよび有効化に関するリファレンス:
PNET ID を使用したホスト ERI 共有 Pod の構成
複数の Pod が 1 つ以上のホスト ERI を共有するセルフマネージドコンテナ環境では、Pod の仮想イーサネットインターフェイス(vEth)およびホスト ERI の両方に同じ PNET ID を割り当てます。これにより、カーネルがホスト ERI を検出し、RDMA を使用して Pod トラフィックを高速化できます。
# Assign the PNET ID to the vEth in the pod's net namespace
sudo ip netns exec <pod netns> smc_pnet -a <PNET ID> -I eth0
# Assign the same PNET ID to the host ERI
sudo smc_pnet -a <PNET ID> -D erdma_0ユースケース:ECS 上の Redis における SMC の活用
本例では、2 台の ECS インスタンス(1 台を Redis サーバー、1 台をクライアント)上で SMC-R を活用した Redis の高速化を実施します。BPF ポリシーはポート 6379 およびサーバーの vSwitch CIDR にスコープを限定します。
1. 2 台の ECS インスタンスを作成します(1 台を Redis サーバー、1 台を Redis クライアント)。詳細については、「カスタム起動タブからのインスタンス作成」をご参照ください。
2. 両方のインスタンスで SMC カーネルモジュールをロードします:
sudo modprobe smc
sudo modprobe smc_diag3. 両方のインスタンスで Redis をインストールします:
sudo yum install redis -y4. クロスゾーン SMC-R 通信を防止するために、両方のインスタンスでゾーンベースの EID を構成します:
sudo systemctl start aliyunsmc-ueid5. 両方のインスタンスで、SMC を Redis トラフィックのみに制限するように BPF ポリシーを設定します。
# Load smc-ebpf
sudo smc-ebpf policy load
# Allow SMC only on port 6379
sudo smc-ebpf policy config --port 6379 --mode enable
# Block SMC for unmatched server IPs, then allow the vSwitch CIDR
sudo smc-ebpf policy config --ip 0.0.0.0 --mask 32 --mode disable
cidr=$(curl -s -m 1 100.100.100.200/latest/meta-data/vswitch-cidr-block)
sudo smc-ebpf policy config --ip \
$(echo ${cidr} | awk -F'/' '{print $1}') --mask \
$(echo ${cidr} | awk -F'/' '{print $2}') --mode enable6. 両方のインスタンスで透過的なソケット変換を有効化します:
sudo sysctl -w net.smc.tcp2smc=17. サーバー上で Redis を起動します。<IP> をサーバーのプライマリ Elastic Network Interface(ENI)のプライベート IP アドレスに置き換えます:
redis-server --bind <IP> --port 6379 --protected-mode no --save8. クライアントから接続またはベンチマークを実行します。<IP> を Redis サーバーのプライベート IP アドレスに置き換えます:
# Connect interactively
redis-cli -h <IP> -p 6379
# Run a stress test
redis-benchmark -h <IP> -p 6379 -n 1000000 -t set -c 100次のステップ
SMC のモニタリング — バッファー使用率、接続数、フォールバック率を追跡
SMC のトラブルシューティング — SMC の一般的な問題を診断します
SMC の適用性 — SMC-R が最も優れた結果を提供する場合について理解します