Redis adalah single-threaded, lalu bagaimana cara meringkas I / O?

170

Mencoba memahami beberapa dasar Redis, saya menemukan sesuatu yang menarik posting blog yang .

Penulis menyatakan:

Redis adalah single-threaded dengan epoll / kqueue dan skala tanpa batas waktu dalam hal konkurensi I / O.

Saya benar-benar salah paham tentang keseluruhan masalah threading, karena saya merasa pernyataan ini membingungkan. Jika suatu program single-threaded, bagaimana ia melakukan sesuatu secara bersamaan? Mengapa ini sangat bagus sehingga operasi Redis bersifat atomik, jika servernya adalah single-threaded?

Adakah yang bisa menjelaskan masalah ini?

Przemysław Pietrzkiewicz
sumber

Jawaban:

362

Yah itu tergantung pada bagaimana Anda mendefinisikan konkurensi.

Dalam perangkat lunak sisi server, konkurensi dan paralelisme sering dianggap sebagai konsep yang berbeda. Dalam server, mendukung I / Os konkuren berarti server dapat melayani beberapa klien dengan mengeksekusi beberapa aliran yang sesuai dengan klien tersebut dengan hanya satu unit perhitungan. Dalam konteks ini, paralelisme akan berarti server mampu melakukan beberapa hal pada saat yang sama (dengan beberapa unit komputasi), yang berbeda.

Misalnya seorang bartender dapat menjaga beberapa pelanggan sementara dia hanya dapat menyiapkan satu minuman sekaligus. Jadi dia bisa memberikan konkurensi tanpa paralelisme.

Pertanyaan ini telah diperdebatkan di sini: Apa perbedaan antara konkurensi dan paralelisme?

Lihat juga presentasi ini dari Rob Pike.

Program single-threaded pasti dapat memberikan konkurensi pada tingkat I / O dengan menggunakan mekanisme multiplexing I / O dan loop peristiwa (yang dilakukan Redis).

Paralelisme memiliki biaya: dengan beberapa soket / beberapa inti yang dapat Anda temukan pada perangkat keras modern, sinkronisasi antar utas sangat mahal. Di sisi lain, hambatan mesin penyimpanan yang efisien seperti Redis sangat sering pada jaringan, jauh sebelum CPU. Oleh karena itu, loop acara yang terisolasi (yang tidak memerlukan sinkronisasi) dipandang sebagai desain yang baik untuk membangun server yang efisien, terukur.

Fakta bahwa operasi Redis adalah atom hanyalah konsekuensi dari loop peristiwa single-threaded. Yang menarik adalah atomicity disediakan tanpa biaya tambahan (tidak memerlukan sinkronisasi). Ini dapat dieksploitasi oleh pengguna untuk menerapkan penguncian optimis dan pola lainnya tanpa membayar biaya sinkronisasi.

Didier Spezia
sumber
135
Analogi bartender yang bagus :)
Sergio Tulentsev
3
v4 adalah pengubah permainan dalam hal ini - lihat jawaban saya di stackoverflow.com/a/45374864/3160475 :)
Itamar Haber
1
satu-satunya hal yang saya tidak begitu suka tentang jawaban dan perbandingan adalah bahwa hal itu membuatnya tampak seperti konkurensi tidak bekerja secara paralel dan pasti karena saya dapat menguji ini dengan menjalankan tugas async dan menyelesaikan pekerjaan yang pada akhirnya dianggap paralel. paralelisme dalam konteks artikel itu merujuk pada sifat multicore untuk dapat berjalan di atas untaian yang saling menguntungkan. Yaitu mengapa merujuknya menjadi threadsafe.
Christian Matthew
Masih berlaku di tahun 2020?
Roberto Manfreda
21

OK, Redis adalah single-threaded pada level pengguna, OTOH, semua I / O asinkron didukung oleh kumpulan thread kernel dan / atau driver level split.

' Bersamaan ', bagi sebagian orang, termasuk mendistribusikan acara jaringan ke mesin negara soket. Ini single-threaded, berjalan pada satu inti, (pada level pengguna), jadi saya tidak akan menyebut ini bersamaan. Yang lain berbeda ..

' skala tanpa batas waktu dalam hal konkurensi I / O ' hanya bersifat ekonomis dengan kebenaran. Mereka mungkin mendapatkan lebih banyak kepercayaan jika mereka mengatakan 'dapat meningkatkan skala lebih baik daripada satu-thread-per-klien, asalkan klien tidak meminta banyak', meskipun mereka kemudian mungkin merasa wajib untuk menambahkan 'terpesona pada pemuatan berat oleh solusi async lainnya yang menggunakan semua core di tingkat pengguna '.

Martin James
sumber
Mungkin di luar konteks tetapi apakah setiap operasi pembaruan (seperti dengan perintah INCR) membawa kunci? Jika ada 1000 permintaan bersamaan dan satu operasi kenaikan pada kunci (per permintaan), apakah itu memastikan bahwa variabel bertambah hanya 1000 kali?
Amanda