Saya merancang sistem untuk menangani 10.000 koneksi TCP per detik, masalah apa yang akan saya hadapi?

18

Saya memiliki kotak 8-core yang relatif baru menjalankan CentOS. Saya ingin mengembangkan server statistik yang menggunakan TCP. Ini sangat sederhana, ia menerima koneksi TCP, menambah penghitung dan menutup koneksi. Tangkapannya adalah perlu melakukan ini setidaknya 10k permintaan per detik. Saya mencurigai CPU / Memory tidak akan menjadi masalah, tapi saya lebih khawatir tentang batasan buatan (seperti koneksi setengah terbuka) yang mungkin perlu saya konfigurasi di server saya untuk memungkinkan volume semacam ini. Jadi, apakah ini mungkin? Pengaturan mana yang harus saya ketahui? Apakah NIC saya tidak dapat menanganinya?


sumber
1
pastikan untuk tidak menelurkan utas untuk setiap koneksi yang masuk, itu akan mematikan kinerja
1
+1 untuk melaporkan hasil akhir Anda di sini :)
agsamek

Jawaban:

17

Ini umumnya dikenal sebagai masalah c10k . Halaman itu memiliki banyak info bagus tentang masalah yang akan Anda hadapi.

Greg Hewgill
sumber
ya, tautan yang bagus!
sybreon
1
Saya berharap melihat lebih banyak / masalah yang berbeda dari yang disebutkan di halaman c10k. Membuat dan menutup koneksi 10k per detik berbeda dengan memiliki koneksi terbuka 10k. Koneksi yang tetap dalam status TIME_WAIT akan menjadi satu, dengan menekan batas simpanan untuk soket pendengaran mungkin adalah yang lain. Dan saya tidak akan terkejut jika case-use itu tidak menerima profiling / optimisasi dalam kode kernel daripada kasus koneksi terbuka 10k yang lebih umum.
cmeerw
2

Anda harus bisa melakukannya [walaupun itu mungkin ide yang buruk].

pada resin appserv saya bisa mendapatkan ~ 5 k req / detik pada quad core xeon 2.6ghz. permintaan memanggil servlet sederhana yang membaca 1 baris dari mysql dan mengirimkan respons xml yang sangat kecil.

Tes dilakukan dengan

ab -n 10000 -c 16 http://some/url/

hasil tes:

Concurrency Level:      16
Time taken for tests:   1.904 seconds
Complete requests:      10000
Failed requests:        0
Write errors:           0
Total transferred:      3190000 bytes
HTML transferred:       1850000 bytes
Requests per second:    5252.96 [#/sec] (mean)
Time per request:       3.046 [ms] (mean)
Time per request:       0.190 [ms] (mean, across all concurrent requests)
Transfer rate:          1636.42 [Kbytes/sec] received

tapi saya pikir Anda akan jauh lebih baik menggunakan program c sederhana, tentunya tanpa menelurkan utas baru untuk setiap permintaan. Tautan dari Greg Hewgill seharusnya memberi Anda ide bagus tentangnya.

bahkan selama tes yang berkepanjangan saya tidak mendapatkan masalah dengan konektivitas [disebutkan soket yang dibuka]; tes berjalan antara dua kotak linux yang terhubung melalui gigabit ethernet [meskipun seperti yang Anda lihat bandwidth bukan hambatan].

pQd
sumber
Apakah koneksi Anda ditutup setelah setiap respons seperti OP? Apakah ab mengirim Koneksi: tutup tajuk?
Nate
1
@Nate itu http 1.0 - koneksi tunggal untuk setiap permintaan http tunggal.
pQd
1

Anda mungkin tertarik pada batas kernel Linux yang saya tekan saat memuat pengujian Apache. Dalam kasus saya, kernel menghasilkan beberapa pesan kesalahan yang berguna sehingga saran saya adalah menulis program Anda dan jika Anda tampaknya mencapai batas, perhatikan log kernel.

Ben Williams
sumber
0

Saya akan menggunakan UDP bukan TCP jika memungkinkan. Seharusnya lebih ringan dan karenanya skala yang lebih baik.

Zimmy-DUB-Zongy-Zong-DUBBY
sumber
Saya setuju. UDP akan jauh lebih ringan
fpmurphy
1
UDP memiliki kekurangannya, seperti pengirim dan verifikasi pengiriman, jadi orang harus mempertimbangkannya sebelum menggunakan UDP dalam produksi.
SaveTheRbtz
0

Nic Anda harus bisa mengatasinya, tapi saya mempertanyakan desain memiliki 10k koneksi TCP baru per detik; jika Anda membuat / menghancurkan koneksi dengan cepat, maka Anda harus a) membiarkannya terbuka lebih lama atau b) menggunakan UDP sebagai gantinya.

Dalam kasus di mana Anda memiliki 1M klien yang perlu melakukan kueri dari waktu ke waktu, tetapi di mana beban akan mencapai 10rb per detik, UDP mungkin merupakan pilihan yang lebih baik.

Dalam kasus di mana Anda hanya punya 10 ribu klien yang perlu melakukan kueri setiap detik, mereka bisa membuka koneksi yang ada dan menggunakannya kembali. Ini akan jauh lebih baik untuk OS dan juga menghasilkan latensi jauh lebih sedikit karena tidak memerlukan jabat tangan baru setiap kali.

Jika Anda memiliki permintaan 10 ribu per detik, saya kira Anda memiliki penyeimbang beban front-end, jadi Anda harus mengujinya juga.

(NB: Saya pikir ini milik Stack Overflow)

MarkR
sumber