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
performance
database-recommendation
Jérôme Verstrynge
sumber
sumber
Jawaban:
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.
sumber
multithreaded
dalam konteks ini berarti sesuatu yang berbeda , yaitu bahwa semua transaksi diserialisasi seperti yang disebutkan Lukas dalam jawabannya.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.
sumber
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.
sumber
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
sumber
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
Dari daftar Todo ("Fitur yang tidak kami inginkan"):
http://wiki.postgresql.org/wiki/Todo#Features_We_Do_Not_Want
Jadi, sekali lagi ... Saya sama sekali tidak tahu tentang kelebihan di atas. Terlalu lama untuk memuat komentar.
sumber
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?
sumber