it-swarm.asia

Tentang kinerja database single threaded versus multithreaded

H2 adalah database berulir tunggal dengan reputasi yang baik tentang kinerja. Database lain adalah 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 satu sistem utas akan memblokir semua yang lain
  • Mengkonfigurasi sistem multi-threading bisa rumit
  • Database multithreaded bermanfaat bahkan pada sistem inti tunggal
59

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 ada 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 cepat maka waktu tunggu akan rendah. DB multi-threaded akan lebih cepat daripada DB single-threaded, karena dalam DB single-threaded akan ada overhead dari 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.

31
StanleyJohns

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 diberi pengaturan default. Untuk memanfaatkan kemampuan multithreading InnoDB, Anda harus ingat untuk mengaktifkan banyak opsi.

innodb_thread_concurrency menetapkan batas atas pada jumlah utas bersamaan yang dapat dibuka oleh InnoDB. Nomor bulat terbaik untuk ditetapkan untuk ini adalah (2 X Jumlah CPU) + Jumlah Disk. [~ # ~] pembaruan [~ # ~] : 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 yang sedang berjalan.

innodb_concurrency_tickets menetapkan jumlah utas yang dapat melewati pengecekan 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, untaian InnoDB dapat tidak aktif sebelum memasuki kembali 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 slave adalah mencapai innodb_thread_concurrency.

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

Waktu akan lepas 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 Tweak salah satu dari 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 tenaga ahli Percona 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, Sentakan, 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 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.

49
RolandoMySQLDBA

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 database, 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 kueri potensial dengan kinerja kasus terburuk setengah detik, 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 pemuatan (hanya memulai sejumlah x utas yang mengenai kode Anda secara bersamaan menggunakan beberapa usecases khas). Ini akan memberi Anda metrik aktual mengenai kinerja dan hambatan dalam 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.

11
Luke Hutteman

Dari apa yang bisa saya katakan, "single-threaded" adalah sedikit keliru untuk H2. Intinya adalah ini membuat serial semua transaksi (mis. Melakukannya 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 menyelesaikannya, 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.

--EDIT

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

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 Pengembang FAQ ("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 sebagai ganti 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.

5