Tentang kinerja basis data single threaded versus multithreaded

58

H2 adalah database berulir tunggal dengan reputasi yang baik tentang kinerja. Basis data lainnya multi-threaded.

Pertanyaan saya adalah: kapan database multi-thread menjadi lebih menarik daripada database single-thread? Berapa banyak pengguna? Berapa banyak proses? Apa pemicunya? Adakah yang punya pengalaman untuk dibagikan?

Ringkasan

  • Hambatan yang biasa terjadi adalah akses disk
  • SSD cepat, tetapi rapuh (prosedur kegagalan adalah suatu keharusan)
  • Satu permintaan panjang pada sistem utas tunggal akan memblokir semua yang lain
  • Mengkonfigurasi sistem multi-threading bisa rumit
  • Database multithreaded bermanfaat bahkan pada sistem inti tunggal
Jérôme Verstrynge
sumber
Utas berarti "utas atau proses" untuk tujuan pertanyaan ini sejauh yang saya tahu - mis. Postgres tidak multi-utas tetapi pertanyaannya adalah tidak mencoba membandingkan (H2, postgres) terhadap (Oracle, SQL Server dll)
Jack Douglas

Jawaban:

31

Inilah pendapat saya:

Biasanya hambatan (atau bagian paling lambat) dari sistem DB adalah disk. CPU hanya lonjakan selama operasi aritmatika, pemrosesan, atau tugas lain yang dilakukan CPU. Dengan arsitektur yang tepat, multithreading dapat membantu mengimbangi beban kueri ke CPU alih-alih melakukan baca / tulis disk yang lambat. Ada kasus di mana lebih cepat untuk menghitung nilai menggunakan siklus CPU daripada membuat kolom yang dihitung (yang sebelumnya disimpan ke disk) dan membaca kolom ini dari disk.

Dalam beberapa RDBMS terdapat DB sementara (tempdb) yang digunakan oleh semua DB pada contoh itu untuk menyortir, hashing, variabel sementara, dll ... Multithreading dan memecah file tempdb ini dapat digunakan untuk meningkatkan throughput tempdb , dengan demikian meningkatkan kinerja server secara keseluruhan.

Menggunakan multithreading (paralelisme), kumpulan hasil kueri dapat dibagi untuk diproses pada inti server yang berbeda, daripada menggunakan satu inti saja. Fitur ini tidak selalu meningkatkan kinerja, tetapi ada beberapa kasus di mana itu terjadi, dan karenanya fitur tersebut tersedia.

Utas yang tersedia untuk DB digunakan untuk berbagai tujuan: membaca / menulis ke disk, koneksi pengguna, pekerjaan latar belakang, mengunci / mengunci, IO jaringan, dll ... Bergantung pada arsitektur OS, utas diberikan terlebih dahulu ke CPU dan dikelola menggunakan tunggu dan antrian. Jika CPU dapat memecahkan thread ini dengan cukup cepat maka waktu tunggu akan rendah. DB multi-threaded akan lebih cepat daripada DB single-threaded, karena dalam DB single-threaded akan ada overhead daur ulang hanya satu thread daripada memiliki tapak lain yang tersedia.

Skalabilitas juga menjadi masalah, karena lebih banyak utas diperlukan untuk mengelola dan menjalankan sistem DB yang diskalakan.

StanleyJohns
sumber
Terima kasih atas wawasannya. Saya mendengar orang memuji solid state drive. Saya kira berinvestasi dalam hal-hal itu mungkin adalah hal terbaik untuk dilakukan setelah memastikan pertanyaan ditulis dengan baik dan aplikasi ini diparalelkan.
Jérôme Verstrynge
@Stan - Saya pikir multithreadeddalam konteks ini berarti sesuatu yang berbeda , yaitu bahwa semua transaksi diserialisasi seperti yang disebutkan Lukas dalam jawabannya.
Jack Douglas
@ JPerstry ~ Tidak, tidak juga. Baca pikiran Jeff Atwood tentang SSD ... mereka memiliki tingkat kegagalan yang tinggi. Hal terbaik untuk dilakukan adalah dengan mengindeks data dengan benar dan memiliki pertanyaan yang ditulis dengan baik.
jcolebrand
@jcolebrand Ok, ia tampaknya menganjurkan mereka untuk kecepatan hanya dengan sistem cadangan yang kuat ketika mereka gagal
Jérôme Verstrynge
2
@Jverstry ~ Ya, dan jika Anda memahami konsep itu, dan tidak masalah dengan itu, dan tidak keberatan membangun kembali seluruh lingkungan produksi Anda (atau menunggu kegagalan otomatis untuk memulai dan kemudian membangun kembali pada titik tertentu dalam waktu dekat itu) maka lakukanlah, mereka akan membuat segalanya lebih cepat lagi, ya.
jcolebrand
47

Jika ada satu hal yang dapat saya katakan tentang MySQL adalah InnoDB, mesin penyimpanan transaksionalnya (ACID-compliant), memang multithreaded. Namun, itu multithreaded seperti ANDA MENGONFIGURASINYA !!! Bahkan tepat "di luar kotak," InnoDB berkinerja bagus dalam lingkungan CPU tunggal mengingat pengaturan defaultnya. Untuk memanfaatkan kemampuan multithreading InnoDB, Anda harus ingat untuk mengaktifkan banyak opsi.

innodb_thread_concurrency menetapkan batas atas jumlah utas bersamaan yang bisa dibuka oleh InnoDB. Nomor bulat terbaik untuk ditetapkan untuk ini adalah (2 X Jumlah CPU) + Jumlah Disk. UPDATE : Seperti yang saya pelajari secara langsung dari Percona NYC Conference, Anda harus mengatur ini ke 0 untuk mengingatkan InnoDB Storage Engine untuk menemukan jumlah utas terbaik untuk lingkungan tempat ia berjalan.

innodb_concurrency_tickets menetapkan jumlah utas yang dapat melewati pemeriksaan konkurensi dengan impunitas. Setelah batas itu tercapai, pengecekan konkurensi thread menjadi norma lagi.

innodb_commit_concurrency menetapkan jumlah transaksi bersamaan yang dapat dilakukan. Karena defaultnya adalah 0, tidak menetapkan ini memungkinkan sejumlah transaksi untuk melakukan secara bersamaan.

innodb_thread_sleep_delay menetapkan jumlah milidetik yang dapat dinonaktifkan oleh InnoDB sebelum masuk kembali ke antrian InnoDB. Standarnya adalah 10.000 (10 detik).

innodb_read_io_threads dan innodb_write_io_threads (keduanya sejak MySQL 5.1.38) mengalokasikan jumlah utas yang ditentukan untuk membaca dan menulis. Default adalah 4 dan maksimum 64.

innodb_replication_delay memberlakukan keterlambatan utas pada seorang budak adalah Innodb_thread_concurrency tercapai.

innodb_read_ahead_threshold memungkinkan pembacaan linear dari jumlah luasan yang ditetapkan (64 halaman [halaman = 16K]) sebelum beralih ke pembacaan asinkron.

Waktu akan luput dari saya jika saya menyebutkan lebih banyak opsi. Anda dapat membacanya di Dokumentasi MySQL .

Kebanyakan orang tidak mengetahui fitur-fitur ini dan cukup puas dengan InnoDB hanya melakukan transaksi yang sesuai dengan ACID. Jika Anda mengubah salah satu opsi ini, Anda melakukannya dengan risiko sendiri.

Saya telah bermain dengan MySQL 5.5 Multiple Buffer Pool Instances (162GB dalam 9 buffer pools instance) dan telah berupaya membuat data yang dipartisi secara otomatis dalam memori dengan cara ini. Beberapa ahli mengatakan bahwa ini akan memberi Anda peningkatan kinerja 50%. Apa yang saya dapatkan adalah satu ton penguncian utas yang sebenarnya membuat InnoDB merangkak. Saya beralih ke 1 buffer (162GB) dan semuanya baik-baik saja di dunia. Saya kira Anda membutuhkan ahli Percona yang Anda inginkan untuk mengatur ini. Saya akan berada di Konferensi MySQL Percona di New York besok dan akan menanyakan hal ini jika ada peluang.

Sebagai kesimpulan, InnoDB berperilaku baik sekarang di server multi-CPU mengingat pengaturan default untuk operasi multithreaded. Tweak mereka sangat hati-hati, kesabaran, dokumentasi yang bagus, dan kopi yang enak (atau Red Bull, Goncangan, dll.).

Selamat pagi, selamat malam, dan selamat malam !!!

UPDATE 2011-05-27 20:11

Kembali dari Percona MySQL Conference di New York pada hari Kamis. Konferensi yang luar biasa. Belajar banyak, tapi saya mendapat jawaban saya akan melihat tentang InnoDB. Saya diberitahu oleh Ronald Bradford bahwa menetapkan innodb_thread_concurrency ke 0 akan membuat InnoDB memutuskan tindakan terbaik secara internal dengan thread concurrency. Saya akan bereksperimen dengan ini lebih lanjut di MySQL 5.5.

UPDATE 2011-06-01 11:20

Sejauh satu permintaan panjang, InnoDB adalah ACID-compliant dan beroperasi dengan sangat baik menggunakan MultiVersion Concurrency Control . Transaksi harus dapat membawa tingkat isolasi (dibaca berulang secara default) yang mencegah pemblokiran orang lain dari mengakses data.

Adapun sistem multi-inti, InnoDB telah datang jauh. Di masa lalu, InnoDB tidak dapat bekerja dengan baik di lingkungan multicore. Saya ingat harus menjalankan beberapa instance mysql pada satu server untuk mendapatkan beberapa core untuk mendistribusikan beberapa proses mysqld di seluruh CPU. Ini tidak lagi diperlukan, terima kasih kepada Percona, dan kemudian MySQL (eh, Oracle, mengatakan bahwa masih membuat saya muntah), karena mereka telah mengembangkan InnoDB menjadi mesin penyimpanan yang lebih matang yang dapat mengakses inti dengan kesederhanaan tanpa banyak penyetelan. Contoh InnoDB saat ini dapat beroperasi dengan baik di server inti tunggal.

RolandoMySQLDBA
sumber
11

Segera setelah Anda memiliki beberapa pengguna atau proses bersamaan, atau bahkan satu proses dengan akses basis data multi-utas, memiliki basis data yang mendukung threading akan berpotensi menarik.

H2 aman-utas, tetapi membuat serial semua permintaan ke basis data, yang mungkin menjadi masalah kinerja potensial dalam skenario beban berat. Apakah ini benar-benar kasus untuk proyek tertentu tergantung pada kombinasi dari persyaratan kinerja Anda, jumlah utas / pengguna / proses mengakses database, frekuensi kueri yang dieksekusi oleh utas ini, dan kinerja rata-rata dan terburuk dari Anda pertanyaan.

Misalnya, jika persyaratan kinerja Anda memiliki respons dalam satu detik, Anda tidak memiliki lebih dari 10 pengguna bersamaan yang mengeksekusi satu query tunggal yang membutuhkan waktu 0,05 detik untuk dieksekusi, database single-threaded masih akan memungkinkan Anda mencapai sasaran tersebut (meskipun multithreaded mungkin sudah memberikan peningkatan kinerja yang nyata). Dengan skenario yang sama dengan satu permintaan potensial dengan kinerja kasus terburuk setengah detik, membuat serialisasi akses basis data Anda tidak akan memungkinkan Anda untuk memenuhi tujuan kinerja Anda lagi.

Jika saat ini Anda menggunakan H2 pada proyek Anda, saya akan menyarankan Anda untuk menjalankan profiler terhadap basis kode Anda di bawah skenario memuat (hanya memulai sejumlah x utas yang mengenai kode Anda secara bersamaan menggunakan beberapa penggunaan umum yang khas). Ini akan memberi Anda metrik aktual tentang kinerja dan kemacetan di basis kode Anda, bukan hanya berteori. Jika ini menunjukkan permintaan Anda menghabiskan sebagian besar waktu mereka hanya menunggu untuk mengakses basis data, saatnya untuk pindah ke basis data berulir.

Luke Hutteman
sumber
Apakah H2 mengelompokkan semua permintaan - atau hanya DML?
Jack Douglas
8

Dari apa yang bisa saya katakan, "single-threaded" sedikit keliru untuk H2. Intinya adalah serialisasi semua transaksi (yaitu melakukan satu per satu).

Pertanyaan penting mengenai apakah itu "ok" atau tidak untuk aplikasi Anda bukanlah "Berapa banyak pengguna?" atau bahkan "Berapa banyak proses?", tetapi "Berapa lama transaksi saya akan berlangsung?"

Jika semua transaksi Anda adalah sub-detik yang mungkin baik-baik saja, jika beberapa membutuhkan waktu beberapa jam untuk menyelesaikan, itu mungkin tidak baik karena semua transaksi yang tertunda lainnya akan menunggu mereka untuk menyelesaikannya. Keputusan apakah itu "baik" atau tidak akan tergantung pada persyaratan kinerja Anda sendiri - yaitu berapa lama menunggu yang dapat diterima untuk pengguna saya memukul database dengan transaksi.

--SUNTING

Tampaknya H2 tidak benar-benar membuat serial transaksi - hanya DML. Dengan kata lain banyak pembaruan singkat dalam satu transaksi panjang tidak akan memblokir pembaruan lainnya . Namun, kecuali jika Anda menggunakan fitur MVCC eksperimental , penguncian tabel berarti ini memiliki efek yang sama dalam praktiknya. Ada juga fitur eksperimental "multi_threaded" tetapi tidak dapat digunakan bersamaan dengan MVCC

Jack Douglas
sumber
5

Mengutip sedikit demi sedikit dari situs PostgreSQL ... Harap dicatat bahwa saya sama sekali tidak tahu manfaat argumen ini - mereka hanya tidak cocok dengan komentar.

Dari FAQ Pengembang ("Mengapa utas tidak digunakan ..."):

http://wiki.postgresql.org/wiki/Developer_FAQ#Why_don.27t_you_use_threads.2C_raw_devices.2C_async-I.2FO.2C_.3Cinsert_your_favorite_wizz-bang_feature_here.3E.3F

Utas saat ini tidak digunakan alih-alih beberapa proses untuk backends karena: (...)

  • Kesalahan dalam satu backend dapat merusak backend lainnya jika mereka thread dalam satu proses
  • Peningkatan kecepatan menggunakan utas kecil dibandingkan dengan waktu startup backend yang tersisa.
  • Berbagi pemetaan yang dapat dieksekusi hanya-baca dan penggunaan shared_buffers berarti proses, seperti utas, sangat efisien dalam memori
  • Pembuatan dan penghancuran proses secara teratur membantu melindungi terhadap fragmentasi memori, yang mungkin sulit dikelola dalam proses yang berjalan lama

Dari daftar Todo ("Fitur yang tidak kami inginkan"):

http://wiki.postgresql.org/wiki/Todo#Features_We_Do_Not_Want

Semua backends berjalan sebagai utas dalam satu proses (tidak diinginkan)

Ini menghilangkan perlindungan proses yang kami dapatkan dari pengaturan saat ini. Pembuatan thread biasanya merupakan overhead yang sama dengan pembuatan proses pada sistem modern, sehingga tampaknya tidak bijaksana untuk menggunakan model threaded murni, dan MySQL dan DB2 telah menunjukkan bahwa thread memperkenalkan masalah sebanyak yang mereka pecahkan. (...)

Jadi, sekali lagi ... Saya sama sekali tidak tahu tentang kelebihan di atas. Terlalu lama untuk memuat komentar.

Denis de Bernardy
sumber
-3

Database multithreaded hanya akan menguntungkan Anda ketika Anda memiliki lebih dari 1 permintaan paralel ke database. Itu tergantung pada jumlah pengguna yang Anda miliki. Jika Anda memiliki lebih dari sepuluh pengguna yang mengerjakan aplikasi pada saat bersamaan, kemungkinan besar mereka akan menghasilkan lebih dari satu permintaan pada basis data pada saat yang sama.

Selain itu, database multithreaded hanya bisa mendapatkan keuntungan ketika ada multi-core pada CPU. Jika ada single core, database multi-threaded harus mengantri pekerjaan dan menjalankannya secara berurutan pada single core. Ketika ada multi-core, setiap core dapat menjalankan satu thread secara paralel. Dengan demikian kinerjanya lebih baik.

Apakah ini menjawab pertanyaan Anda?

oazabir
sumber
7
Database multithreaded bermanfaat bahkan pada sistem inti tunggal. Ini mencegah permintaan lama berjalan dari memblokir semua akses database lain, ditambah Anda bisa memiliki beberapa utas menunggu di disk atau I / O jaringan, sementara utas lain secara aktif mengurai kueri, memproses data yang diambil sebelumnya, dll.
Satu pengguna dapat menggunakan satu program yang melumpuhkan beberapa operasi. Program ini kemungkinan besar akan mendapat manfaat jika database memiliki kemampuan multi-threading / multi-pemrosesan juga.
joanolo