All Products
Search
Document Center

Elastic Compute Service:Menggunakan Shared Memory Communication (SMC)

Last Updated:Apr 01, 2026

Shared Memory Communication (SMC) secara transparan menggantikan soket TCP dengan soket SMC-R (SMC over RDMA), mempercepat jaringan aplikasi melalui RDMA tanpa perubahan kode. Dokumen ini menjelaskan cara mengaktifkan SMC pada Instance ECS, mengontrol koneksi mana yang menggunakan negosiasi SMC, serta menyesuaikan parameter SMC sesuai beban kerja Anda.

Prasyarat

Sebelum memulai, pastikan Anda telah:

Penting

Perangkat eRDMA dan SMC tidak mendukung Alamat IPv6. Jika aplikasi Anda menggunakan IPv6, SMC akan kembali ke TCP. Lihat SMC kembali ke TCP saat alamat IPv6 digunakan. Mulai dari versi kernel ANCK 5.10.134-17.3, SMC mendukung alamat IPv6 yang dipetakan ke IPv4.

Gunakan SMC pada ECS

Langkah 1: Muat modul kernel dan instal tool

  1. Muat modul kernel smc dan smc_diag:

    sudo modprobe smc
    sudo modprobe smc_diag

    Verifikasi bahwa modul berhasil dimuat dengan menjalankan dmesg. Output harus mencakup:

    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
  2. Instal paket tool smc-tools dan aliyun-smc-extensions:

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

Untuk melepas SMC jika tidak lagi diperlukan:

sudo rmmod smc_diag
sudo rmmod smc

Langkah 2: Aktifkan konversi soket transparan

SMC-R secara otomatis mengonversi soket TCP yang memenuhi syarat menjadi soket SMC. Sebuah soket memenuhi syarat jika:

  • family adalah AF_INET

  • type adalah SOCK_STREAM

  • protocol adalah IPPROTO_IP(0) atau IPPROTO_TCP(6)

Tersedia dua mode konversi. Pilih berdasarkan cakupan trafik yang ingin Anda percepat:

ModeCara kerjaKapan digunakan
Tingkat namespace jaringanMengonversi semua soket TCP yang memenuhi syarat dalam namespace jaringan melalui sysctl kernel.Mempercepat semua koneksi yang memenuhi syarat dalam namespace dengan satu perintah.
Tingkat prosesMengonversi soket dari proses tertentu dan turunannya melalui LD_PRELOAD.Menargetkan aplikasi individual. Tidak tersedia untuk aplikasi yang tidak menggunakan glibc atau dikompilasi secara statis.
Jika aplikasi Anda dikompilasi secara statis atau tidak menggunakan glibc, gunakan konversi tingkat namespace jaringan — konversi tingkat proses tidak tersedia untuk aplikasi tersebut.

Konversi tingkat namespace jaringan

Aktifkan konversi soket transparan untuk namespace jaringan saat ini:

sudo sysctl net.smc.tcp2smc=1

Soket TCP baru dalam namespace tersebut akan dikonversi menjadi soket SMC. Soket TCP yang sudah ada tidak terpengaruh.

Jalankan aplikasi Anda secara normal:

./redis-server

Untuk menonaktifkan konversi (soket SMC yang sudah ada akan terpengaruh):

sudo sysctl net.smc.tcp2smc=0

Konversi tingkat proses

Tambahkan awalan smc_run pada aplikasi apa pun untuk mengonversi hanya soket TCP proses tersebut:

smc_run ./redis-server

smc_run menggunakan LD_PRELOAD untuk memuat libsmc-preload.so, yang mencegat pembuatan soket di glibc. Aplikasi yang tidak ditautkan ke glibc atau dikompilasi secara statis tidak dapat menggunakan metode ini.

Langkah 3: Kontrol koneksi mana yang menggunakan SMC (kebijakan BPF)

Secara default, mengaktifkan SMC di tingkat namespace atau proses akan mengonversi semua soket yang memenuhi syarat. Untuk kontrol lebih detail — misalnya, hanya mempercepat port 6379 sementara port manajemen tetap menggunakan TCP — gunakan kebijakan BPF.

Semua kebijakan port dan kebijakan alamat IPv4 dievaluasi dengan logika AND. Koneksi hanya menggunakan negosiasi SMC jika setiap kebijakan yang cocok mengizinkannya.

Muat tool smc-ebpf

sudo smc-ebpf policy load

Output sukses:

Registered smc_sock_negotiator_ops anolis_smc id xxx

Jika perintah gagal:

  • Verifikasi versi kernel adalah ANCK 5.10.134-016 atau lebih baru: uname -r

  • Pastikan Anda memiliki izin untuk memuat program BPF. Penyebab umum adalah kontainer pod tidak memiliki kemampuan memuat program BPF, atau tingkat hak istimewa Anda tidak mencukupi. Anda dapat berkonsultasi dengan penyedia lingkungan Anda untuk informasi lebih lanjut.

Peringatan

Muat smc-ebpf sebelum membuat koneksi apa pun yang ingin Anda kendalikan. Tool ini tidak berpengaruh pada koneksi yang telah dibuat sebelumnya. Kebijakan bersifat global dan berlaku di semua namespace jaringan — tidak dapat dibatasi ke kontainer individual. Fitur smc-ebpf bersifat eksperimental dan antarmukanya dapat berubah di versi kernel mendatang.

Konfigurasi kebijakan port

Setelah memuat smc-ebpf, setiap port tanpa kebijakan yang cocok secara default diblokir dari penggunaan SMC. Atur port 0 ke enable untuk membalikkan default ini sehingga port yang tidak cocok diizinkan:

sudo smc-ebpf policy config --port 0 --mode enable

Atur kembali port 0 ke disable untuk mengembalikan default:

sudo smc-ebpf policy config --port 0 --mode disable

Contoh 1: Izinkan hanya port 80, blokir semua port lainnya

sudo smc-ebpf policy config --port 80 --mode enable

Verifikasi kebijakan:

sudo smc-ebpf policy dump

Contoh output ("mode": 2 = diizinkan, "mode": 0 = diblokir):

[{
    "key": 80,
    "value": {
        "mode": 2,
        ...
    }
}]

Hapus kebijakan jika tidak lagi diperlukan:

sudo smc-ebpf policy delete --port 80

Contoh 2: Blokir hanya port 80, izinkan semua port lainnya

sudo smc-ebpf policy config --port 0 --mode enable
sudo smc-ebpf policy config --port 80 --mode disable

Konfigurasi kebijakan alamat IPv4

Kebijakan alamat IPv4 mengontrol apakah klien menggunakan negosiasi SMC saat terhubung ke IP server tertentu. Perilaku soket server tidak terpengaruh.

Setelah memuat smc-ebpf, setiap IP server tanpa kebijakan yang cocok secara default diizinkan menggunakan SMC (berlawanan dengan default kebijakan port).

Atur 0.0.0.0/32 ke disable untuk membalikkan default ini:

sudo smc-ebpf policy config --ip 0.0.0.0 --mask 32 --mode disable

Atur kembali ke enable untuk mengembalikan default:

sudo smc-ebpf policy config --ip 0.0.0.0 --mask 32 --mode enable

Contoh 1: Izinkan SMC hanya untuk 192.168.2.0/24, blokir semua IP server lainnya

sudo smc-ebpf policy config --ip 0.0.0.0 --mask 32 --mode disable
sudo smc-ebpf policy config --ip 192.168.2.0 --mask 24 --mode enable

Verifikasi:

sudo smc-ebpf policy dump

Contoh output:

key:     0.0.0.0/32           value:   "denied"
key:     192.168.2.0/24       value:   "pass"

Hapus kebijakan jika tidak lagi diperlukan:

sudo smc-ebpf policy delete --ip 192.168.2.0 --mask 24
sudo smc-ebpf policy delete --ip 0.0.0.0 --mask 32

Contoh 2: Blokir SMC hanya untuk 192.168.2.0/24, izinkan semua IP server lainnya

sudo smc-ebpf policy config --ip 192.168.2.0 --mask 24 --mode disable

Tidak diperlukan perintah tambahan. IP yang tidak cocok diizinkan secara default.

Bersihkan semua kebijakan

sudo smc-ebpf policy clear

Perintah ini menghapus semua kebijakan dan mengembalikan default: semua port diblokir, semua IP diizinkan. Karena kebijakan port dan IP dievaluasi dengan logika AND, semua koneksi diblokir dari penggunaan SMC.

Gunakan SMC pada ACK

Di Container Service for Kubernetes (ACK), aktifkan SMC menggunakan komponen ACK eRDMA Controller, yang mengelola dan menjadwalkan ERI untuk Pod. Lihat Gunakan SMC-R untuk mempercepat jaringan aplikasi.

Kebijakan detail halus berbasis BPF bekerja dengan cara yang sama pada node ACK seperti pada Instance ECS.

Contoh end-to-end: SMC dengan Redis

Contoh ini mengonfigurasi dua Instance ECS — satu sebagai klien Redis dan satu sebagai server Redis — untuk menggunakan SMC hanya pada koneksi port Redis 6379 dalam Blok CIDR vSwitch yang sama.

  1. Buat dua Instance ECS. Lihat Buat instans di tab Custom Launch.

  2. Pada kedua instans, muat modul kernel:

    sudo modprobe smc
    sudo modprobe smc_diag
  3. Instal Redis:

    sudo yum install redis -y
  4. Konfigurasi EID berbasis zona untuk mencegah komunikasi SMC-R lintas zona:

    sudo systemctl start aliyunsmc-ueid
  5. Konfigurasi kebijakan BPF untuk membatasi SMC hanya pada port 6379 dan CIDR vSwitch lokal:

    # Muat engine BPF
    sudo smc-ebpf policy load
    
    # Izinkan SMC hanya pada port 6379
    sudo smc-ebpf policy config --port 6379 --mode enable
    
    # Blokir SMC untuk semua IP server secara default, lalu izinkan CIDR vSwitch
    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. Aktifkan konversi soket transparan tingkat namespace:

    sudo sysctl -w net.smc.tcp2smc=1
  7. Pada server Redis, jalankan Redis yang terikat ke IP ENI pribadinya:

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

    Ganti <IP> dengan Alamat IP pribadi dari antarmuka jaringan elastis utama (ENI) pada instans server Redis.

  8. Pada klien Redis, sambungkan dan jalankan benchmark:

    # Sambungkan ke server
    redis-cli -h <IP> -p 6379
    
    # Jalankan uji stres
    redis-benchmark -h <IP> -p 6379 -n 1000000 -t set -c 100

Referensi

Parameter kernel (sysctl)

Konfigurasikan parameter berikut melalui sysctl. Perubahan pada sebagian besar parameter langsung berlaku untuk koneksi baru.

ParameterDefaultNilai validVersi kernel minimumKapan menyesuaikan
net.smc.tcp2smc00 (dinonaktifkan), 1 (diaktifkan)5.10.134-16Atur ke 1 untuk mengaktifkan konversi soket transparan tingkat namespace.
net.smc.autocorking_size6553504294967295 (0 = dinonaktifkan)5.10.112-11Small-packet, high-bandwidth: atur ke nilai yang menggabungkan penulisan dan meningkatkan throughput. Pipeline (latensi kritis): atur ke 0 untuk mencegah autocork menunda paket.
net.smc.autosplit_size131072327685368709125.10.134-18, 5.10.134-17.3 (seri 17.x), 5.10.134-16.5 (seri 16.x)Paket yang melebihi 1,3x nilai ini akan dibagi untuk transmisi batch guna mengurangi latensi. Paket besar, sensitif latensi: sesuaikan untuk menemukan ambang batas pemisahan optimal.
net.smc.global_mem25%/50%/75% dari memori sistem5.10.134-18, 5.10.134-17.3 (seri 17.x), 5.10.134-16.5 (seri 16.x)Saat total penggunaan buffer transmisi dan penerimaan SMC mencapai global_mem[2], semua koneksi SMC baru kembali ke TCP. Sesuaikan global_mem[2] berdasarkan batas memori yang Anda perkirakan.
net.smc.mem25%/50%/75% dari memori sistem5.10.134-18, 5.10.134-17.3 (seri 17.x), 5.10.134-16.5 (seri 16.x)Padanan per-namespace dari global_mem. Saat penggunaan buffer dalam namespace jaringan mencapai mem[2], koneksi baru dalam namespace tersebut kembali ke TCP.
net.smc.limit_smc_hs10 (tanpa fallback), 1 (fallback saat tekanan koneksi tinggi)5.10.134-18, 5.10.134-17.3 (seri 17.x), 5.10.134-16.5 (seri 16.x)Pertahankan nilai 1 dalam kebanyakan kasus. Atur ke 0 hanya jika Anda memerlukan stack SMC agar tidak pernah kembali ke TCP berdasarkan tekanan koneksi.
net.smc.rmem262144SMC-R: 16384536870912; SMC-D: 1638410485765.10.134-14Rx/Buffer penuh tinggi di ujung lokal: tingkatkan buffer penerima lokal. Tx/Buffer penuh(remote) atau Tx/Buffer terlalu kecil(remote) tinggi secara lokal: tingkatkan buffer penerima di ujung remote. Lihat Pemantauan SMC.
net.smc.wmem262144SMC-R: 16384536870912; SMC-D: 1638410485765.10.134-14Tx/Buffer penuh atau Tx/Buffer terlalu kecil tinggi di ujung lokal: tingkatkan buffer transmisi lokal. Lihat Pemantauan SMC.
net.smc.smcr_buf_type20 (kontigu fisik), 1 (kontigu virtual), 2 (lebih memilih kontigu fisik, fallback ke virtual)5.10.134-12Pertahankan nilai default 2. Perubahan hanya berlaku untuk grup tautan baru — grup tautan yang sudah ada tidak terpengaruh.
net.smc.smcr_max_conns_per_lgr321255 (kernel ≥ 5.10.134-18, 5.10.134-17.3, 5.10.134-16.5); 16255 (kernel sebelumnya)5.10.134-16.1Throughput tinggi: kurangi nilai ini untuk memberikan bandwidth RDMA lebih besar per koneksi SMC dalam grup tautan. Meningkatkan nilai ini tidak disarankan.
net.smc.smcr_max_links_per_lgr11, 25.10.134-16.1Pertahankan nilai default 1.
net.smc.smcr_testlink_time3002147483647 (0 = dinonaktifkan)5.10.134-13Pertahankan nilai default 30. Ini adalah interval heartbeat (dalam detik) untuk koneksi andal RDMA (RC). Saat tidak ada data yang dikirim pada tautan SMC, 16 byte dikirim setiap smcr_testlink_time detik untuk memastikan tautan masih aktif.
net.smc.experiment_vendor_options4294967295 (0xFFFFFFFF)5.10.134-16Pertahankan nilai default.

Konfigurasi Enterprise ID (EID)

Enterprise ID (EID) adalah konsep dari protokol SMCv2. Hanya sistem yang memiliki EID yang sama yang dapat berkomunikasi melalui SMCv2 — EID yang tidak cocok menyebabkan fallback ke TCP. Satu sistem mendukung hingga delapan EID.

image

Pada Alibaba Cloud Linux 3, perangkat eRDMA hanya bekerja dengan protokol SMCv2. Semua instans Alibaba Cloud Linux 3 dimulai dengan EID SMCV2-DEFAULT-UEID, sehingga dapat saling berkomunikasi melalui SMCv2 tanpa pengaturan tambahan.

Untuk mengontrol cakupan komunikasi dengan memodifikasi EID:

  1. Lihat EID yang ada:

    smcr ueid show
  2. Tambahkan EID (maksimal 32 karakter, huruf kapital, angka, tanda hubung, dan titik; harus dimulai dengan huruf atau angka; tidak boleh ada titik berurutan):

    sudo smcr ueid add <EID>
  3. Hapus EID:

    sudo smcr ueid del <EID>

Cegah komunikasi SMC-R lintas zona dengan EID

Untuk performa terbaik, gunakan SMC-R dalam zona tunggal dan TCP lintas zona. Menambahkan ID zona sebagai EID menerapkan aturan ini secara otomatis.

Metode 1: Konfigurasi langkah demi langkah

# Dapatkan ID zona dari metadata instans
ZONE_ID=$(curl -s -m 1 100.100.100.200/latest/meta-data/zone-id | tr "[:lower:]" "[:upper:]")

# Tambahkan ID zona sebagai EID
sudo smcr ueid add $ZONE_ID

# Hapus EID default
smcr ueid | grep SMCV2-DEFAULT-UEID > /dev/null && sudo smcr ueid del SMCV2-DEFAULT-UEID

Metode 2: Gunakan layanan aliyunsmc-ueid (satu perintah)

sudo systemctl start aliyunsmc-ueid

Layanan ini secara otomatis menambahkan ID zona sebagai EID dan menghapus EID default.

Karena konfigurasi EID tidak persisten setelah reboot, aktifkan layanan agar berjalan otomatis:

sudo systemctl enable aliyunsmc-ueid

Konfigurasi identifier jaringan fisik (PNET ID)

Saat trafik TCP dikonversi ke SMC-R, stack SMC-R memilih ERI yang akan digunakan berdasarkan antarmuka Ethernet yang membawa trafik tersebut. Asosiasi ini terbentuk dengan salah satu dari dua cara:

  • Otomatis: Saat Anda mengaktifkan eRDMA langsung pada antarmuka Ethernet, stack SMC-R secara otomatis mengasosiasikan antarmuka tersebut dengan ERI yang dihasilkan. Untuk mengelola eRDMA pada antarmuka, lihat Lihat ERIs. Untuk menambahkan ERI saat membuat antarmuka baru, lihat Buat ERI. Untuk mengaktifkan eRDMA pada ENI yang sudah ada, lihat Ubah status fitur ERI untuk ENI yang sudah ada.

  • Manual dengan PNET ID: Saat ERI diasosiasikan dengan antarmuka Ethernet yang berbeda dari yang membawa trafik, Anda harus menggunakan PNET ID untuk menghubungkannya.

Contoh: Sebuah node memiliki eth0 (eRDMA diaktifkan, diasosiasikan dengan erdma_0) dan eth1 (tanpa eRDMA). Trafik pada eth0 secara otomatis menggunakan erdma_0. Trafik pada eth1 kembali ke TCP karena tidak ada ERI yang diasosiasikan. Untuk menggunakan RDMA pada trafik eth1, tetapkan PNET ID yang sama untuk eth1 dan erdma_0.

image

Untuk mengonfigurasi PNET ID:

  1. Tetapkan PNET ID ke antarmuka Ethernet:

    sudo smc_pnet -a <PNET ID> -I <eth_interface>
  2. Tetapkan PNET ID yang sama ke ERI:

    sudo smc_pnet -a <PNET ID> -D <rdma_interface>

    PNET ID dapat terdiri dari maksimal 16 karakter dan hanya boleh berisi huruf kapital serta angka (tanpa spasi).

  3. Verifikasi konfigurasi:

    sudo smc_pnet

    Contoh output:

    00163E0CD751 n/a erdma_0 1
    00163E0CD751 eth1 n/a 255

    PNET ID 00163E0CD751 menghubungkan erdma_0 dan eth1. Trafik pada eth1 sekarang menggunakan erdma_0 untuk komunikasi RDMA setelah SMC-R diaktifkan.

Asosiasikan antarmuka veth Pod dengan ERI host

Pada pengaturan kontainer mandiri di mana beberapa Pod berbagi ERI host, tetapkan PNET ID yang sama untuk antarmuka Ethernet virtual Pod (veth) dan ERI host. Stack kernel SMC-R kemudian dapat mendeteksi ERI host dan mempercepat trafik jaringan kontainer.

image
  1. Tetapkan PNET ID untuk antarmuka veth (eth0 dalam contoh ini) di dalam namespace jaringan kontainer:

    sudo ip netns exec <pod netns> smc_pnet -a <PNET ID> -I eth0
  2. Tetapkan PNET ID yang sama untuk ERI host (erdma_0 dalam contoh ini):

    sudo smc_pnet -a <PNET ID> -D erdma_0