Halaman yang menjawab dalam 200 ms terhadap Redis lokal membutuhkan empat detik begitu klien berada di belakang VPN, sementara penghitung server tetap diam. Log lambat tidak menunjukkan apa pun di atas satu milidetik, grafik CPU datar, dan instans melayani klien lain tanpa keluhan. Yang berubah adalah jarak, dan yang melipatgandakan jarak adalah jumlah kali kode Anda berhenti dan menunggu. Telusuri jalur permintaan dari klien ke luar dan solusinya hampir selalu lebih sedikit penantian berurutan, bukan server yang lebih cepat.

Mulai dari klien, bukan dari metrik server

Amati proses klien antara perintah pertama dan terakhir. Jika jejak menunjukkan balasan, jeda, lalu perintah berikutnya, Anda membayar satu perjalanan penuh per perintah dan tidak ada penyetelan server yang mengubahnya. Log lambat adalah alat yang salah di sini, karena mencatat waktu eksekusi dan dengan sengaja mengecualikan I/O komunikasi. Log lambat yang bersih di samping endpoint yang lambat adalah tanda masalah perjalanan pulang-pergi.

Ukur jalurnya sendiri sebelum menyentuh kode. redis-cli -h redis.example.internal --latency mengirim PING berulang dan mencetak rata-rata waktu permintaan dan balasan, yaitu biaya Anda per pertukaran. Kalikan dengan jumlah perintah berurutan dalam satu aksi pengguna dan Anda punya batas bawah untuk endpoint.

Hitung perjalanan pulang-pergi yang benar-benar dibutuhkan satu aksi pengguna

Ambil satu endpoint dan catat setiap panggilan Redis secara berurutan, termasuk yang tersembunyi di dalam ORM, middleware sesi, atau pencarian feature flag. Sebagian besar endpoint lambat ternyata melakukan dua puluh atau tiga puluh panggilan padahal tiga sudah cukup, dan yang tersembunyi biasanya mayoritas.

Rantai dependensi tidak bisa dilipat: jika perintah kedua membutuhkan kunci yang dikembalikan perintah pertama, penantian itu nyata dan satu-satunya pilihan adalah model data berbeda atau operasi sisi server yang menyatakan seluruh langkah sekaligus. Pembacaan independen adalah kasus lain, karena tidak ada yang memaksa Anda menunggu balasan pertama sebelum mengirim yang kedua. Tandai setiap panggilan sebagai bergantung atau independen sebelum mengubah apa pun, dan bentuk solusinya menjadi jelas.

Angka yang penting adalah penantian berurutan, bukan total perintah. Tiga puluh perintah dalam satu batch tetap hanya memakan satu penantian.

Batch hanya perintah yang tidak saling bergantung

Pipeline mengantrekan perintah independen dan mengumpulkan balasan secara berurutan, mengubah N penantian menjadi satu. Sebagian besar klien menawarkannya sebagai blok, callback, atau pengelola konteks alih-alih mode koneksi terpisah, jadi periksa API yang disediakan versi terpasang Anda. Keuntungannya berskala dengan waktu perjalanan, dan itulah sebabnya hal ini penting di VPN dan hampir tak terasa di localhost.

import redis

r = redis.Redis(host="redis.example.internal", port=6379, socket_timeout=2)
pipe = r.pipeline(transaction=False)
for key in ("user:1001", "user:1002", "user:1003"):
    pipe.get(key)
print(pipe.execute())

Berikan transaction=False saat Anda hanya ingin batching. Dengan pengaturan bawaan klien membungkus batch dalam MULTI dan EXEC, yang membuatnya atomik dan mengubah apa yang dapat diamati klien lain di tengah jalan. Atomisitas adalah keputusan kebenaran, bukan tombol kinerja, dan pipeline bukan transaksi hanya karena keduanya mengurangi perjalanan pulang-pergi.

Baca setiap balasan, bukan hanya pengiriman batch. Perintah yang diantrekan bisa mengembalikan galat sementara batch secara keseluruhan selesai, dan klien yang membuang daftar balasan mengubah penulisan gagal menjadi penulisan senyap. Bandingkan panjang daftar balasan dengan jumlah perintah yang Anda antrekan.

Jaga koneksi tetap hidup di antara aksi

Setiap koneksi baru membayar resolusi nama, jabat tangan TCP, jabat tangan TLS, dan AUTH, dan di atas VPN masing-masing adalah perjalanan yang tidak bisa Anda batch. Buat klien sekali per proses dan gunakan ulang, atau pakai pool yang disediakan pustaka Anda dengan ukuran terbatas. Menyambung ulang per permintaan adalah penyebab kedua paling umum dari gejala ini setelah penantian per perintah.

Simpan nama host privat di konfigurasi alih-alih alamat literal. Validasi sertifikat dan identitas layanan tetap berlaku di jaringan privat, dan menyematkan IP rusak begitu penyedia menomori ulang subnet. Jika resolusi adalah bagian yang lambat, perbaiki jalur resolver, bukan string koneksi.

Tetapkan timeout soket eksplisit agar terowongan yang macet gagal cepat alih-alih menggantungkan pekerja. Lalu pastikan pool benar-benar digunakan ulang dengan mencatat pembuatan koneksi di klien.

Tentukan ukuran batch sebelum menjadi masalah memori

Redis menyimpan balasan yang diantrekan selama batch berlangsung, dan klien menyimpan hasil yang telah diurai setelahnya. Pipeline sepuluh ribu nilai besar menukar penantian jaringan dengan lonjakan memori dan jeda panjang di kedua ujung.

Pilih ukuran batch berdasarkan volume balasan, bukan jumlah perintah. Beberapa ratus perintah kecil dalam satu batch biasanya nyaman, sedangkan seratus muatan berukuran beberapa kilobyte tidak. Bagi berdasarkan byte dan juga jumlah, dan jaga setiap batch dalam anggaran latensi yang benar-benar dimiliki endpoint.

Ukur dari ujung ke ujung setelah perubahan: redis-cli -h redis.example.internal --latency-history menunjukkan apakah jalurnya sendiri stabil, dan pengatur waktu permintaan Anda sendiri menunjukkan apakah endpoint membaik. Jika endpoint masih lambat sementara riwayat latensi datar, biaya yang tersisa adalah kerja sisi server atau serialisasi Anda sendiri, dan langkah berikutnya adalah profil handler, bukan perubahan batching lain.

Artikel terkait