Pengoptimalan TCP untuk performa jaringan

Halaman ini menguraikan metode untuk menghitung setelan yang benar untuk mengurangi latensi koneksi TCP Anda di skenario Google Cloud dan hybrid. Halaman ini juga membantu Anda memahami cara meningkatkan latensi koneksi antar-proses dalam Google Cloud.

Arsitektur microservice modern mengadvokasi bahwa developer harus membuat layanan kecil dengan satu tanggung jawab. Layanan harus berkomunikasi menggunakan TCP atau UDP, berdasarkan ekspektasi keandalan sistem. Oleh karena itu, sangat penting bagi sistem berbasis microservice untuk berkomunikasi dengan keandalan dan latensi rendah.

Google Cloud memberikan keandalan dan latensi rendah dengan menyediakan jaringan global, yang berarti pengguna aplikasi Anda juga dapat go global. Memiliki jaringan global berarti Anda membuat jaringan Virtual Private Cloud (VPC) yang mencakup region dan zona. Aplikasi dapat saling terhubung di seluruh region dan zona tanpa harus keluar dari jaringan Google Cloud.

Aplikasi yang telah ditulis untuk lingkungan pusat data tradisional dapat menunjukkan performa yang lambat saat dipindahkan ke lingkungan hybrid cloud—yaitu, ketika beberapa komponen aplikasi berjalan di pusat data perusahaan dan komponen aplikasi lainnya berjalan di cloud. Performa yang lambat dapat disebabkan oleh sejumlah faktor. Artikel ini berfokus pada latensi dua arah dan pengaruh latensi terhadap performa TCP dalam aplikasi yang memindahkan sejumlah besar data melalui bagian mana pun pada jaringan.

Masalah: latensi dan perilaku TCP

TCP menggunakan mekanisme windowing untuk mencegah pengirim yang cepat melewati penerima yang lambat. Penerima memberitahukan berapa banyak data yang harus dikirim pengirim sebelum pengirim harus menunggu update jendela dari penerima. Akibatnya, jika aplikasi penerima tidak dapat menerima data pada koneksi, ada batasan berapa banyak data yang dapat diantrekan untuk menunggu aplikasi.

Jendela TCP memungkinkan penggunaan memori yang efisien pada sistem pengiriman dan penerimaan. Karena aplikasi penerimaan menggunakan data, update jendela akan dikirim ke pengirim. Update jendela tercepat yang dapat terjadi adalah dalam satu perjalanan dua arah, yang menghasilkan formula berikut untuk salah satu batas performa transfer massal koneksi TCP:

Throughput <= Latensi ukuran jendela / waktu round-trip (RTT)

Dalam desain asli untuk TCP, jendela ini memiliki ukuran maksimum 65.535 byte (64 KiB - 1). Ini adalah jumlah data maksimum yang dapat dikirim pengirim sebelum pengirim menerima update jendela untuk memungkinkan lebih banyak data dikirim.

Perubahan TCP sejak diperkenalkan

Sejak TCP diperkenalkan, beberapa fitur utama telah berubah:

  • Kecepatan jaringan tipikal telah meningkat sebesar empat kali lipat.
  • Memori tipikal dalam suatu sistem telah meningkat empat kali lipat.

Hasil dari perubahan pertama adalah ukuran jendela TCP asli menyebabkan penggunaan resource jaringan yang tidak efisien. Pengirim akan mengirim data jendela dengan kecepatan terbaik dalam kondisi jaringan, lalu tidak ada aktivitas untuk waktu yang cukup lama sambil menunggu update jendela TCP. Hasil dari perubahan kedua adalah pengirim dan penerima dapat menggunakan lebih banyak memori untuk jaringan guna mengatasi batasan yang diekspos oleh perubahan pertama.

Diagram berikut mengilustrasikan pertukaran ini.

Pengirim hanya mengirim 64K data dan menghabiskan waktu menunggu yang sangat lama untuk mendapatkan update jendela setelah mengirim

Pengirim tidak dapat sepenuhnya memanfaatkan jaringan karena sedang menunggu update jendela TCP sebelum mengirim data tambahan.

Mengirim lebih banyak data sekaligus

Solusinya adalah mengirim lebih banyak data sekaligus. Seiring dengan meningkatnya bandwidth jaringan, semakin banyak data yang dapat masuk ke dalam pipa (jaringan), dan seiring semakin panjangnya pipa, diperlukan waktu lebih lama untuk mengonfirmasi penerimaan data. Hubungan ini dikenal sebagai produk penundaan bandwidth (BDP). Nilai ini dihitung sebagai bandwidth dikalikan dengan waktu round-trip (RTT), sehingga menghasilkan nilai yang menentukan jumlah bit optimal yang akan dikirim untuk mengisi pipa. Formulanya adalah:

BDP (bit) = bandwidth (bit/detik) * RTT (detik)

BDP hasil perhitungan digunakan sebagai ukuran jendela TCP untuk pengoptimalan.

Misalnya, bayangkan Anda memiliki jaringan 10 Gbps dengan RTT 30 milidetik. Untuk ukuran jendela, gunakan nilai ukuran jendela TCP asli (65.535 byte). Nilai ini belum tentu memanfaatkan kemampuan bandwidth. Performa TCP maksimum yang mungkin di link ini adalah sebagai berikut:

(65535 byte * 8 bit/byte) = bandwidth * 0,030 detik
bandwidth = (65535 byte * 8 bit/byte) / 0,030 detik
bandwidth = 524280 bit / 0,030 detik
bandwidth = 17476000 bit / detik

Dengan kata lain, nilai-nilai ini menghasilkan throughput sedikit lebih dari 17 Mbit per detik, yang merupakan sebagian kecil dari kemampuan jaringan 10 Gbps.

Solusi: Penskalaan ukuran jendela TCP

Untuk mengatasi batasan performa yang diberlakukan oleh desain asli ukuran jendela TCP, ekstensi ke protokol TCP diperkenalkan sehingga ukuran jendela dapat diskalakan ke nilai yang jauh lebih besar. Penskalaan jendela mendukung jendela hingga 1.073.725.440 byte, atau hampir 1 GiB. Fitur ini diuraikan dalam RFC 7323 sebagai opsi skala jendela TCP.

Ekstensi skala jendela memperluas definisi jendela TCP untuk menggunakan 30 bit, lalu menggunakan faktor penskalaan implisit untuk membawa nilai 30-bit ini dalam kolom jendela 16-bit pada header TCP. Untuk melihat apakah fitur ini diaktifkan pada sistem berbasis Linux, gunakan perintah berikut:

sudo sysctl net.ipv4.tcp_window_scaling

Semua virtual machine Linux Google Cloud mengaktifkan fitur ini secara default. Nilai yang ditampilkan sebesar 1 menunjukkan bahwa opsi diaktifkan. Jika fitur ini dinonaktifkan, Anda dapat mengaktifkannya menggunakan perintah berikut:

sudo sysctl -w net.ipv4.tcp_window_scaling=1

Throughput dengan ukuran jendela yang lebih besar

Anda dapat menggunakan contoh sebelumnya untuk menunjukkan manfaat memiliki penskalaan jendela. Seperti sebelumnya, asumsikan jaringan 10 Gbps dengan latensi 30 milidetik, lalu hitung ukuran jendela baru menggunakan formula ini:

(Kecepatan link * latensi) / 8 bit = ukuran jendela

Jika Anda memasukkan angka contoh, Anda mendapatkan pesan ini:

(10 Gbps * 30 md/1000 detik) / 8 bit/byte = ukuran jendela
(10.000 Mbps * 0,030 detik) / 8 bit/byte = 37,5 MB

Meningkatkan ukuran jendela TCP menjadi 37 MB dapat meningkatkan batas teoretis performa transfer massal TCP ke nilai yang mendekati kemampuan jaringan. Tentu saja, banyak faktor lainnya yang dapat membatasi performa, termasuk overhead sistem, ukuran paket rata-rata, dan jumlah alur lain yang berbagi link, tetapi seperti yang dapat Anda lihat, ukuran jendela secara substansial mengurangi batas yang diberlakukan dengan ukuran jendela terbatas sebelumnya.

Menyetel tunable Linux untuk mengubah ukuran jendela TCP

Di Linux, ukuran jendela TCP dipengaruhi oleh tunable sysctl(8) berikut:

net.core.rmem_max
net.core.wmem_max
net.ipv4.tcp_rmem
net.ipv4.tcp_wmem

Dua tunable pertama memengaruhi ukuran jendela TCP maksimum untuk aplikasi yang mencoba mengontrol ukuran jendela TCP secara langsung, dengan membatasi permintaan aplikasi tidak lebih dari nilai tersebut. Dua tunable kedua memengaruhi ukuran jendela TCP untuk aplikasi yang memungkinkan penyesuaian otomatis Linux melakukan tugasnya.

Nilai ukuran jendela yang optimal bergantung pada situasi tertentu, tetapi satu titik awal adalah BDP (produk penundaan bandwidth) terbesar untuk jalur tersebut atau jalur yang Anda perkirakan akan digunakan sistem untuk mengirim data. Dalam hal ini, Anda ingin menyetel tunable menggunakan langkah-langkah berikut:

  1. Pastikan Anda memiliki hak istimewa root.
  2. Mendapatkan setelan buffer saat ini. Simpan setelan ini jika Anda ingin melakukan roll back perubahan ini.

    sudo sysctl -a | grep mem
    
  3. Tetapkan variabel lingkungan ke ukuran jendela TCP baru yang ingin Anda gunakan:

    MaxExpectedPathBDP=8388608
    
  4. Tetapkan ukuran buffer penerimaan OS maksimum untuk semua jenis koneksi:

    sudo sysctl -w net.core.rmem_max=$MaxExpectedPathBDP
    
  5. Menetapkan ukuran buffer pengiriman OS maksimum untuk semua jenis koneksi:

    sudo sysctl -w net.core.wmem_max=$MaxExpectedPathBDP
    
  6. Tetapkan setelan buffer memori penerimaan TCP (tcp_rmem):

    sudo sysctl -w net.ipv4.tcp_rmem="4096 87380 $MaxExpectedPathBDP"
    

    Setelan tcp_rmem mengambil tiga nilai:

    • Ukuran buffer penerimaan minimum yang bisa dialokasikan untuk soket TCP. Dalam contoh ini, nilainya adalah 4096 byte.
    • Ukuran buffer penerimaan default, yang juga menggantikan nilai /proc/sys/net/core/rmem_default yang digunakan oleh protokol lain. Dalam contoh, nilainya adalah 87380 byte.
    • Ukuran buffer penerimaan maksimum yang bisa dialokasikan untuk soket TCP. Dalam contoh, nilai ini ditetapkan ke nilai yang Anda tetapkan sebelumnya (8388608 byte).
  7. Tetapkan setelan buffer memori pengiriman TCP (tcp_wmem):

    sudo sysctl -w net.ipv4.tcp_wmem="4096 16384 $MaxExpectedPathBDP"
    

    Setelan tcp_wmem mengambil tiga nilai:

    • Ruang buffer pengiriman TCP minimum yang tersedia untuk satu soket TCP.
    • Ruang buffer default yang diizinkan untuk satu soket TCP.
    • Ruang buffer pengiriman TCP maksimum.
  8. Tetapkan tunable sehingga koneksi berikutnya menggunakan nilai yang Anda tentukan:

    sudo sysctl -w net.ipv4.route.flush=1
    

Untuk mempertahankan setelan ini saat mulai ulang, tambahkan perintah yang Anda tetapkan sebelumnya ke file /etc/sysctl.conf:

sudo bash -c 'cat << EOF >> /etc/sysctl.conf
net.core.rmem_max=8388608
net.core.wmem_max=8388608
net.ipv4.tcp_rmem=4096 87380 8388608
net.ipv4.tcp_wmem=4096 16384 8388608
net.ipv4.route.flush=1
EOF'

Menguji RTT dengan ukuran jendela yang diperbarui

Saat TCP memiliki ukuran jendela yang cukup besar untuk memanfaatkan BDP, gambar akan berubah, seperti yang ditunjukkan pada diagram berikut:

Pengirim mengirim data dalam jumlah besar pada satu waktu dan menghabiskan sangat sedikit waktu untuk menunggu update jendela

Ukuran jendela TCP selalu dapat disesuaikan berdasarkan resource yang tersedia untuk proses yang terlibat dan algoritma TCP yang digunakan. Seperti yang ditunjukkan pada diagram, penskalaan jendela memungkinkan koneksi melampaui ukuran jendela 65 KiB yang ditentukan dalam spesifikasi TCP asli.

Anda dapat mengujinya sendiri. Pertama, pastikan Anda telah membuat perubahan ukuran jendela TCP ke komputer lokal dan ke komputer jarak jauh dengan menyetel tunable di kedua mesin. Lalu, jalankan perintah berikut:

dd if=/dev/urandom of=sample.txt bs=1M count=1024 iflag=fullblock
scp sample.txt your_username@remotehost.com:/some/remote/directory

Perintah pertama akan membuat file sample.txt 1 GB yang memiliki data acak. Perintah kedua menyalin file tersebut dari mesin lokal Anda ke mesin jarak jauh.

Perhatikan output perintah scp di konsol, yang menampilkan bandwidth dalam Kbps. Anda akan melihat perbedaan yang cukup besar dalam hasil dari sebelum dan setelah perubahan ukuran jendela TCP.

Langkah selanjutnya