Kinerja Replikasi MySQL

15

Saya mengalami masalah serius dengan kinerja replikasi MySQL 5.5 antara dua mesin, kebanyakan tabel myISAM dengan replikasi berbasis pernyataan. Direktori biner dan direktori data mysql keduanya terletak pada Fusion ioDrive yang sama.

Masalahnya adalah masalah besar baru-baru ini ketika kami perlu menjeda replikasi untuk kira-kira. 3 jam. Butuh sekitar 10 jam untuk mengejar ketinggalan tanpa beban lainnya.

10 jam untuk mengejar ketinggalan

Bagaimana saya dapat meningkatkan kinerja replikasi? Mesin B pada dasarnya idle (sedikit, IO, 2 core maksimal dari 16, banyak RAM gratis), karena hanya 1 utas mySQL menulis data. Berikut adalah beberapa ide yang saya miliki:

  • Beralih ke replikasi berbasis baris. Dalam tes ini hanya menghasilkan peningkatan kinerja 10-20%
  • Tingkatkan ke mySQL 5.6 dengan replikasi multi-ulir. Kami dapat dengan mudah membagi data kami menjadi basis data yang terpisah, dan tolok ukur tampaknya menunjukkan ini akan membantu, tetapi kode tersebut tampaknya tidak siap untuk diproduksi.
  • Beberapa variabel konfigurasi yang akan membantu mempercepat replikasi

Masalah utama adalah bahwa jika dibutuhkan 10 jam untuk mengejar ketinggalan setelah berhenti selama 3 jam, ini berarti replikasi menulis 13 jam data dalam 10 jam, atau mampu menulis pada 130% dari kecepatan data yang masuk. Saya ingin setidaknya menulis dua kali pada mesin Master dalam waktu dekat, jadi sangat membutuhkan cara untuk meningkatkan kinerja replikasi.

Mesin a:

  • Menguasai
  • Ram 24 GB
  • 1.2TB Fusion ioDrive2
  • 2x E5620
  • Interkoneksi gigabit

my.cnf:

[mysqld]
server-id=71
datadir=/data_fio/mysqldata
socket=/var/lib/mysql/mysql.sock
tmpdir=/data_fio/mysqltmp

log-error = /data/logs/mysql/error.log
log-slow-queries = /data/logs/mysql/stats03-slowquery.log
long_query_time = 2
port=3306

log-bin=/data_fio/mysqlbinlog/mysql-bin.log
binlog-format=STATEMENT
replicate-ignore-db=mysql

log-slave-updates = true

# Performance Tuning
max_allowed_packet=16M
max_connections=500
table_open_cache = 2048
max_connect_errors=1000
open-files-limit=5000

# mem = key_buffer + ( sort_buffer_size + read_buffer_size ) * max_connections
key_buffer=4G
max_heap_table_size = 1G
tmp_table_size = 4G
myisam_sort_buffer_size = 256M
sort_buffer_size=4M
read_buffer_size=2M
query_cache_size=16M
query_cache_type=2
thread_concurrency=32

user=mysql

symbolic-links=0

[mysqld_safe]
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid

[mysql]
socket=/var/lib/mysql/mysql.sock

[client]
socket=/var/lib/mysql/mysql.sock

Mesin B:

  • Budak
  • Ram 36 GB
  • 1.2TB Fusion ioDrive2
  • 2x E5620
  • Interkoneksi gigabit

my.cnf:

[mysqld]
server-id=72
datadir=/data_fio/mysqldata
socket=/var/lib/mysql/mysql.sock
tmpdir=/data_fio/mysqltmp

log-error = /data/logs/mysql/error.log
log-slow-queries = /data/logs/mysql/stats03-slowquery.log
long_query_time = 2
port=3306

# Performance Tuning
max_allowed_packet=16M
max_connections=500
table_open_cache = 2048
max_connect_errors=1000
open-files-limit=5000

# mem = key_buffer + ( sort_buffer_size + read_buffer_size ) * max_connections
key_buffer=4G
max_heap_table_size = 1G
tmp_table_size = 4G
myisam_sort_buffer_size = 256M
sort_buffer_size=4M
read_buffer_size=2M
query_cache_size=16M
query_cache_type=2
thread_concurrency=32

user=mysql

symbolic-links=0

plugin-load=archive=ha_archive.so;blackhole=ha_blackhole.so

[mysqld_safe]
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid

[mysql]
socket=/var/lib/mysql/mysql.sock

[client]
socket=/var/lib/mysql/mysql.sock
Nick
sumber
Mesin B pada dasarnya idle . Ini adalah pengalaman saya dengan replikasi pada MySQL 5.1. Replikasi adalah single-threaded, dan satu CPU akan dimaksimalkan sementara yang lain duduk diam di sana.
Stefan Lasiewski
apakah Anda melakukan backup dari slave?
Mike
@ stefan-lasiewski Agar lebih jelas, ini adalah MySQL 5.5, tapi ya. Ini single-threaded dan sangat membuat frustrasi
Nick
@ Mike Ya, dan juga pertanyaan berat yang membutuhkan waktu beberapa menit sepanjang hari. Replikasi melambat hingga ~ 100s atau lebih, dan kemudian butuh beberapa saat untuk mengejar ketinggalan. Layanan yang menjalankan kueri ini akan menjalankan satu kueri, menunggunya untuk mengejar, kemudian menjalankan yang lain, menunggu, dll ... Jika kami dapat mempercepat replikasi, kami dapat meningkatkan frekuensi kami menjalankan kueri ini
Nick
1
@ stefan-lasiewski Ya - Jika tidak ada yang menghentikan replikasi, itu jelas tidak akan ketinggalan. Masalah utama adalah bahwa kecepatan replikasi adalah hambatan untuk meningkatkan menulis pada master. Jika dibutuhkan 3.3s untuk mengejar 1s, itu berarti replikasi menulis data 4.3s dalam 3.3s, atau hanya mampu mereplikasi pada 130% dari kecepatan data yang masuk. Saya mencari setidaknya menulis ganda muat di server ini.
Nick

Jawaban:

4

Wow, Anda memiliki beberapa perangkat keras yang sangat gemuk untuk masalah ini. Tidak banyak lagi yang bisa Anda berikan pada perangkat keras, dengan pengecualian meningkatkan ke mungkin Sandy / Ivy Bridge CPUs untuk kinerja 20-50% lebih baik dari pencarian Btree, dll.

Harap dicatat bahwa keahlian saya adalah Innodb, jadi saya akan melakukannya

  1. Abaikan bahwa Anda adalah myisam dan bertindaklah seolah-olah itu tidak akan membuat perbedaan.
  2. Asumsikan masalah ini cukup mendorong Anda untuk meningkatkan. Ya, ini merupakan peningkatan.

Innodb dapat membantu memanfaatkan semua memori dengan menyimpan baris yang sering diakses ini di buffer pool. Anda dapat menyetelnya menjadi sebesar yang Anda inginkan (katakanlah 80% dari memori) dan baca / tulis baru tetap dalam memori sampai perlu mendorong mereka ke disk untuk membuat lebih banyak ruang untuk data terbaru yang diakses. Dalam memori adalah urutan besarnya lebih cepat daripada FusionIO Anda.

Ada banyak fitur Innodb lainnya, seperti hash adaptif, mekanisme penguncian otomatis, dll. Yang dapat menjadi keuntungan bagi lingkungan Anda. Namun, Anda tahu data Anda lebih baik daripada saya.

Di dunia innodb, solusi jangka pendek yang bagus adalah dengan mengoptimalkan budak Anda - apakah Anda benar-benar membutuhkan setiap indeks pada budak Anda yang Anda miliki di master Anda? Indeks adalah bola dan rantai pada sisipan / pembaruan / penghapusan, BAHKAN dengan kartu Fusion IO. IOPS bukanlah segalanya di sini. Procs Sandy / Ivy bridge memiliki throughput memori dan kinerja komputasi yang jauh lebih baik - mereka dapat membuat perbedaan besar dari Westmer yang Anda miliki sekarang. (Gambar 20-50% keseluruhan). Hapus semua indeks yang tidak Anda butuhkan pada slave!

Kedua, dan hampir pasti hanya berlaku untuk innodb, adalah bahwa mk-prefetch dapat mengetahui pembaruan mana dan sebelum budak menulisnya. Ini memungkinkan mk-prefetch untuk menjalankan kueri baca terlebih dahulu, sehingga memaksa data berada di memori pada saat repl tunggal menjalankan kueri tulis. Ini berarti data ada di memori dan bukan di fusionIO, urutan cepat dari peningkatan kinerja. Ini membuat perbedaan BESAR , lebih dari yang mungkin diharapkan. Banyak perusahaan menggunakan ini sebagai solusi permanen. Cari tahu lebih lanjut dengan memeriksa Percona Toolkit .

Ketiga, dan yang paling penting, setelah Anda meningkatkan ke Innodb, pasti checkout Tokutek. Orang-orang ini memiliki beberapa hal yang luar biasa jahat yang melebihi kinerja menulis / memperbarui / menghapus Innodb. Mereka memuji kecepatan replikasi yang ditingkatkan sebagai salah satu manfaat utama, dan Anda dapat melihat dari tolok ukur mereka mengapa Fusions crazy IOPS masih tidak akan membantu Anda dalam kasus Btrees . (Catatan: Tidak diverifikasi secara independen oleh saya.) Mereka menggunakan pengganti drop-in dari indeks btree yang, meskipun jauh lebih kompleks, memperbaiki banyak batasan kecepatan algoritmik dari indeks btree.

Saya sedang dalam proses mempertimbangkan adopsi Tokutek. Jika mereka membebaskan begitu banyak kecepatan tulis, itu memungkinkan saya untuk menambahkan lebih banyak indeks. Karena mereka mengompres data dan indeks pada rasio yang sangat bagus (25x mereka kutip), Anda bahkan tidak membayar harga (kinerja, pemeliharaan) untuk peningkatan data. Anda membayar ($) untuk mesin mereka, $ 2500 / tahun per GB pra-kompresi, IIRC. Mereka memiliki diskon jika Anda memiliki data yang direplikasi, tetapi Anda bahkan dapat menginstal Tokutek pada budak Anda dan membiarkan master Anda apa adanya. Lihat detail teknis di kuliah Algoritme Open Courseware MIT . Atau, mereka memiliki banyak hal teknis di blog mereka dan whitepaper reguler untuk mereka yang tidak memiliki 1:20 untuk menonton video. Saya percaya video ini juga memberikan rumus Big-O untuk seberapa cepat membaca. Saya punyauntuk menganggap bahwa membaca lebih lambat (Selalu ada tradeoff!), tetapi rumusnya terlalu rumit bagi saya untuk mengukur berapa banyak. Mereka mengklaim itu kira-kira sama, tetapi saya lebih suka memahami matematika (tidak mungkin!). Anda mungkin berada dalam situasi yang lebih baik untuk menemukan ini daripada saya.

PS Saya tidak berafiliasi dengan Tokutek, saya tidak pernah menjalankan produk mereka dan mereka bahkan tidak tahu saya sedang melihat mereka.

Perbarui :

Saya melihat Anda memiliki beberapa pertanyaan lain di halaman ini dan berpikir saya akan memasukkan:

Pertama, pra-pengambilan budak hampir pasti tidak akan bekerja untuk myisam kecuali Anda memiliki lingkungan yang luar biasa. Ini sebagian besar karena prefetching akan mengunci tabel yang ingin Anda tulis, atau slave thread mengunci tabel yang diperlukan oleh daemon pre-fetch. Jika tabel Anda sangat seimbang untuk replikasi dan tabel yang berbeda sedang ditulis dengan cara round-robin, ini mungkin berhasil - tetapi perlu diingat ini sangat teoretis. Buku "Mysql Kinerja Tinggi" memiliki informasi lebih lanjut di bagian "Masalah Replikasi".

Kedua, mungkin budak Anda menahan beban 1,0-1,5, mungkin lebih tinggi jika Anda memiliki procs atau kueri lain yang berjalan tetapi garis dasar 1,0. Ini berarti Anda kemungkinan terikat dengan CPU, yang kemungkinan besar terjadi pada FusionIO Anda. Seperti yang saya sebutkan sebelumnya, Sandy / Ivy Bridge akan memberi sedikit lebih banyak semangat, tetapi mungkin tidak cukup untuk membuat Anda melewati masa-masa sulit dengan jeda yang minimal. Jika beban pada slave ini sebagian besar hanya menulis (yaitu tidak banyak membaca), CPU Anda hampir pasti menghabiskan waktunya menghitung posisi untuk memasukkan / menghapus btree. Ini harus memperkuat poin saya di atas tentang menghapus indeks tidak kritis - Anda selalu dapat menambahkannya kembali nanti. Menonaktifkan hyperthreading tidak akan berfungsi, lebih banyak CPU bukan musuh Anda. Setelah Anda mendapatkan ram di atas 32GB, katakanlah 64GB, Anda perlu khawatir tentang distribusi ram, tetapi meskipun begitu gejalanya berbeda.

Akhirnya, dan yang paling penting (jangan lewatkan bagian ini;)), saya berasumsi Anda sekarang menjalankan RBR (replikasi berbasis baris) karena Anda menyebutkan peningkatan kinerja non-sepele ketika beralih juga. Namun - mungkin ada cara untuk mendapatkan lebih banyak kinerja di sini. Mysql bug 53375 dapat bermanifestasi jika Anda memiliki tabel yang direplikasi tanpa kunci primer. Budak pada dasarnya tidak cukup pintar untuk menggunakan apa pun kecuali kunci utama, sehingga tidak adanya satu kekuatan thread ulangan untuk melakukan pemindaian tabel penuh untuk setiap pembaruan. Perbaikan hanyalah menambahkan kunci primer jinak, pengganti otomatis. Saya hanya akan melakukan ini jika meja besar (katakanlah 10s dari ribuan baris atau lebih besar). Ini, tentu saja, datang pada biaya memiliki indeks lain di atas meja, yang memunculkan harga yang Anda bayar dalam CPU. Perhatikan ada sangat sedikit argumen teoretis yang menentang hal ini, karena InnoDB menambahkan satu di belakang layar jika tidak. Namun, hantu itu bukan pertahanan yang berguna melawan 53375. Tungsten juga dapat mengatasi masalah ini, tetapi Anda harus yakin saat menggunakan Tungsten bahwa Anda memiliki penyandian yang lurus. Terakhir kali saya bermain dengannya, itu akan mati mengerikan ketika string non-UTF8 perlu direplikasi. Itu tentang waktu saya menyerah.

fimbulvetr
sumber
Terima kasih banyak atas waktu Anda! Saya sangat menghargai informasi yang Anda berikan di sini. Pindah ke InnoDB adalah sesuatu yang telah kami pertimbangkan untuk sementara waktu, sebagian besar untuk manfaat penguncian tingkat baris. Ini memberi saya beberapa bahan untuk dipikirkan. Terima kasih lagi.
Nick
Wow, ini beberapa analisis mysql yang sangat brilian :)
Kevin
4

bukan jawaban tetapi Anda mungkin mempertimbangkan pengganda tungsten dan produk komersialnya untuk fleksibilitas yang lebih besar. apakah 100% penggunaan CPU pada single core yang menjadi hambatan?

pQd
sumber
Terima kasih! Itu adalah solusi yang menarik, meskipun saya agak ragu untuk menghubungkan perangkat lunak pihak ke-3 ke MySQL. Dalam dokumen itu tertulis "Tidak perlu memutakhirkan untuk menunggu versi MySQL yang akan datang atau bermigrasi ke alternatif yang belum diuji", sehingga tampaknya mirip dengan apa yang akan didukung oleh MySQL 5.6. Apakah Anda punya pengalaman dengan Tungsten Replicator?
Nick
tidak, hanya tahu bahwa kontributor ekosistem mysql terkemuka bekerja untuk mereka [ datacharmer.blogspot.com ]. bagaimana dengan bottleneck - apakah Anda yakin itu adalah beban inti tunggal yang merupakan faktor pembatas?
pQd
Terimakasih atas infonya. RE: faktor pembatas, tidak, saya tidak yakin sama sekali. Saya tidak berpikir itu I / O, karena iostat melaporkan bahwa Fusion ioDrive melakukan <10 MB / s dari penulisan. Saya cukup yakin bahwa perangkat ini mampu melakukan lebih dari itu. Di sisi lain, selalu ada 1, dan sebentar lagi 1 inti tambahan yang dipatok pada 100%, sementara yang lain menganggur. Bagaimana dengan menonaktifkan hyper-threading?
Nick
@Nick - maaf, saya tidak bisa saran tentang hyper-threading. tapi coba ... juga - coba instal munin atau cacti dengan templat mysql dan lihat lebih detail apa yang terjadi.
pQd
Lihat pos ini dari orang-orang Continuent: scale-out-blog.blogspot.ca/2011/10/… Quote: "Secara keseluruhan kami dapat mengatakan bahwa replikasi asli single-threaded kemungkinan tidak dapat diterapkan dalam I / O-terikat huruf tanpa pergi ke beberapa kombinasi SSD dan / atau pra-pengambilan budak. "
HTTP500
2

Jadi jika Anda melakukan backup pada slave .. dan Anda menggunakan tabel myiasm .. Anda mengunci tabel untuk melakukan backup untuk mencegah korupsi. Jadi replikasi tidak bisa berfungsi sampai cadangan selesai .. lalu menyusul.

Mike
sumber
Benar. Kami secara teratur mengunci tabel untuk pencadangan atau kueri panjang, tetapi masalahnya terletak pada kecepatan replikasi setelah utas dilanjutkan. Saya memperkirakan bahwa itu hanya mereplikasi pada 130% dari kecepatan data yang masuk, yang membatasi seberapa jauh kita dapat mengatur skala pengaturan ini kecuali kita dapat meningkatkan kecepatan replikasi. Apakah itu masuk akal?
Nick