すべてのプロダクト
Search
ドキュメントセンター

Elastic Compute Service:共有メモリ通信 (SMC) の使用

最終更新日:Apr 01, 2026

共有メモリ通信 (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_runLD_PRELOAD を使用して glibc 内の socket() をインターセプトします特定のサービスのみに SMC を適用し、他のサービスへの影響を避けたい場合

どちらの方法でも、以下の 3 つの条件をすべて満たすソケットが変換対象となります:

  • family = AF_INET

  • type = SOCK_STREAM

  • protocol = IPPROTO_IP(0) または IPPROTO_TCP(6)

smc_run によるプロセスレベルの変換には glibc が必要です。静的リンク済みバイナリや glibc をバイパスするアプリケーションでは動作しません。

Alibaba Cloud ECS における SMC の使用

前提条件

開始する前に、以下の条件を満たしていることを確認してください:

重要
  • 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_diag

dmesg を実行して、モジュールが正しくロードされたことを確認します:

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 smc

2. 運用・保守 (O&M) ツールセットをインストールします。

sudo yum install -y smc-tools
sudo yum install -y aliyun-smc-extensions

ネットワーク名前空間レベルのソケット変換の有効化

この方法では、sysctl 設定後に作成されるすべての該当する TCP ソケットが変換され、既存のソケットには影響しません。

以下の図は変換プロセスを示しています。

image
  1. 現在のネットワーク名前空間に対して透過的なソケット変換を有効化します:

    sudo sysctl net.smc.tcp2smc=1

    デフォルト値は 0(無効)です。

  2. TCP ソケットアプリケーションを通常通り起動します:

    ./<foo>

    <foo> をご利用のアプリケーション名に置き換えます。アプリケーションの TCP ソケットは透過的に SMC ソケットに変換され、SMC-R スタックによって処理されます。「仕組み」でフォールバック動作についてご確認ください。

  3. (任意) 現在のネットワーク名前空間について変換を無効化します。新しい TCP ソケットは TCP に戻りますが、既存の変換済み SMC ソケットには影響があります:

    sudo sysctl net.smc.tcp2smc=0

プロセスレベルのソケット変換の有効化

この方法では、smc_run コマンド(smc-tools ツールセットに含まれる)を用いて、単一のプロセスおよびその子プロセスに適用します。

以下の図は変換プロセスを示しています。

image

ご利用のアプリケーションの実行可能ファイルの先頭に smc_run を付加します:

smc_run ./<foo>

<foo> をご利用のプロセス名に置き換えます。このプロセスが作成する TCP ソケットは透過的に SMC ソケットに変換されます。「仕組み」でフォールバック動作についてご確認ください。

BPF ポリシーによる SMC ネゴシエーションの制御

ネットワーク名前空間レベルおよびプロセスレベルの変換は、広範囲に SMC を適用します。より詳細な制御が必要な場合(例:ポート 6379(Redis)でのみ SMC を有効化し、ポート 8080 は TCP のままにする)には、smc-ebpf を使用して BPF ベースのポリシーを設定します。

典型的なワークフローは以下のとおりです:

  1. BPF ポリシーの構成およびロード

  2. 上記のとおり、ネットワーク名前空間レベルまたはプロセスレベルで SMC を有効化

デフォルトでは、SMC ソケットは常に SMC TCP オプションの送信および受信を試行します。BPF ポリシーを使用すると、ポート単位またはサーバーの IPv4 アドレス単位でこの動作をオーバーライドできます。

smc-ebpf のインストール

smc-ebpfsmc-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 24

smc-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 -r

  • BPF プログラムのロード権限があることを確認します。コンテナ環境では必要な機能が不足している可能性があります — 環境プロバイダーにお問い合わせください。

ポートポリシー

ポートポリシーは、接続のポートに基づいて 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 disable

IPv4 アドレスポリシー

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_size65535042949672950 = 無効5.10.112-11 以降小規模パケット帯域幅のシナリオでは増加します。パイプラインシナリオで autocorking の遅延が許容できない場合は、0 に設定します。
net.smc.autosplit_size13107232768–5368709125.10.134-18+;5.10.134-17.3+(17 シリーズ);5.10.134-16.5+(16 シリーズ)大規模パケットのレイテンシシナリオでは減少させます。この値の 1.3 倍を超えるパケットは、バッチ転送のために分割されます。
net.smc.experiment_vendor_options4294967295 (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_hs10 = フォールバックなし;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.rmem262144SMC-R:16384–536870912;SMC-D:16384–10485765.10.134-14 以降Rx/Buffer fullRx/Buffer full メトリックが高い場合は増加させます。rmem の相手側で Tx/Buffer full(remote) または Tx/Buffer too small(remote) メトリックが高い場合は、相手側の を増加させます。メモリが制約されており、パフォーマンスに影響がない場合は減少させます。「SMC のモニタリング」をご参照ください。
net.smc.wmem262144SMC-R:16384–536870912;SMC-D:16384–10485765.10.134-14 以降Tx/Buffer full または Tx/Buffer too small メトリックが高い場合は増加させます。メモリが制約されており、パフォーマンスに影響がない場合は減少させます。「SMC のモニタリング」をご参照ください。
net.smc.smcr_buf_type20 = 物理的に連続;1 = 論理的に連続;2 = 物理的に連続を優先(論理的に連続へフォールバック)5.10.134-12 以降デフォルト値を維持してください。新しいリンクグループ上の SMC 接続にのみ適用されます。
net.smc.smcr_max_conns_per_lgr321–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_lgr11 または 25.10.134-16.1 以降デフォルト値を維持してください。
net.smc.smcr_testlink_time300–2147483647(秒);0 = 無効5.10.134-13 以降デフォルト値を維持してください。SMC-R における RDMA 信頼性接続のハートビート間隔を制御します。
net.smc.tcp2smc00 = 無効;1 = 有効5.10.134-16 以降ネットワーク名前空間内で TCP から SMC への透過的変換を有効化するには、1 に設定します。無効化するには 0 に設定します。

EID の構成

Enterprise ID(EID)は SMCv2 プロトコルにおける概念です。同じ EID を共有するシステム同士のみが SMCv2 経由で通信可能であり、それ以外の場合は TCP へフォールバックします。1 つのシステムは最大 8 個の EID をサポートします。

image

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-ueid

EID 構成は再起動時に保持されないため、起動時に自動的に開始されるようサービスを有効化します:

sudo systemctl enable aliyunsmc-ueid

PNET 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 へフォールバックします。eth1erdma_0 と PNET ID を介して関連付けることで、eth1 トラフィックの RDMA を有効化できます。

image

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 255

PNET ID 00163E0CD751erdma_0eth1 を関連付けます。eth1 経由の TCP トラフィックは、SMC-R が有効化されている場合に erdma_0 を通じて高速化されます。

eRDMA のイーサネットインターフェイスへのチェックおよび有効化に関するリファレンス:

PNET ID を使用したホスト ERI 共有 Pod の構成

複数の Pod が 1 つ以上のホスト ERI を共有するセルフマネージドコンテナ環境では、Pod の仮想イーサネットインターフェイス(vEth)およびホスト ERI の両方に同じ PNET ID を割り当てます。これにより、カーネルがホスト ERI を検出し、RDMA を使用して Pod トラフィックを高速化できます。

image
# 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_diag

3. 両方のインスタンスで Redis をインストールします:

sudo yum install redis -y

4. クロスゾーン SMC-R 通信を防止するために、両方のインスタンスでゾーンベースの EID を構成します:

sudo systemctl start aliyunsmc-ueid

5. 両方のインスタンスで、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 enable

6. 両方のインスタンスで透過的なソケット変換を有効化します:

sudo sysctl -w net.smc.tcp2smc=1

7. サーバー上で Redis を起動します。<IP> をサーバーのプライマリ Elastic Network Interface(ENI)のプライベート IP アドレスに置き換えます:

redis-server --bind <IP> --port 6379 --protected-mode no --save

8. クライアントから接続またはベンチマークを実行します。<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

次のステップ