Saat ini saya sedang mengerjakan database MySQL tempat kami melihat sejumlah besar pembatalan dari cache permintaan, terutama karena tingginya jumlah pernyataan INSERT, DELETE dan UPDATE yang dieksekusi di banyak tabel.
Apa yang saya coba untuk menentukan adalah apakah ada atau tidak ada manfaat sama sekali untuk memungkinkan cache query digunakan untuk pernyataan SELECT yang sedang dijalankan terhadap tabel-tabel ini. Karena mereka batal begitu cepat, menurut saya hal terbaik adalah menggunakan SQL_NO_CACHE pada pernyataan SELECT dengan tabel-tabel ini.
Apakah overhead dari seringnya invalidation sepadan?
Sunting: Atas permintaan pengguna @Rando_MySQLDBA di bawah ini, inilah info tentang MyISAM dan INNODB.
InnoDB
- Ukuran Data: 177,414 GB
- Ukuran Indeks: 114.792 GB
- Ukuran Meja: 292.205 GB
MyISAM
- Ukuran Data: 379.762 GB
- Ukuran Indeks: 80.681 GB
- Ukuran Meja: 460.443 GB
Informasi tambahan:
- Versi: 5.0.85
- query_cache_limit: 1048576
- query_cache_min_res_unit: 4096
- kueri_cache_size: 104857600
- query_cache_type: ON
- query_cache_wlock_invalidate: OFF
- innodb_buffer_pool_size: 8841592832
- RAM 24GB
Jawaban:
Anda harus menonaktifkan cache permintaan dengan
dan kemudian restart mysql. Mengapa saya menyarankan itu ???
Cache Kueri akan selalu berbenturan dengan InnoDB. Alangkah baiknya jika MVCC InnoDB akan membiarkan kueri dilayani dari cache kueri jika modifikasi tidak memengaruhi pembacaan berulang untuk transaksi lainnya. Sayangnya, InnoDB tidak melakukan itu. Rupanya, Anda memiliki banyak pertanyaan yang dibatalkan agak cepat dan mungkin tidak digunakan kembali.
Untuk InnoDB di bawah MySQL 4.0, cache kueri dinonaktifkan untuk transaksi. Untuk MySQL 4.1+, InnoDB memainkan polisi lalu lintas ketika mengizinkan akses ke cache kueri berdasarkan tabel.
Dari sudut pandang pertanyaan Anda, saya akan mengatakan bahwa pembenaran untuk menghapus cache kueri tidak terlalu mahal, tetapi bagaimana InnoDB mengelolanya.
Untuk informasi lebih lanjut tentang bagaimana InnoDB berinteraksi dengan cache kueri, silakan baca halaman 213-215 dari buku "MySQL Kinerja Tinggi (Edisi Kedua)" .
Jika semua atau sebagian besar data Anda adalah MyISAM, Anda bisa menggunakan ide awal Anda menggunakan SQL_NO_CACHE.
Jika Anda memiliki campuran InnoDB dan MyISAM, Anda harus menemukan keseimbangan yang tepat untuk aplikasi Anda berdasarkan pada seberapa tinggi kesalahan cache Anda. Bahkan, halaman 209-210 dari buku yang sama menunjukkan alasan untuk melewatkan cache:
dan akar penyebab kesalahan cache tinggi dengan beberapa kueri yang tidak bisa disimpan adalah:
UPDATE 2012-09-06 10:10 EDT
Melihat info terbaru Anda, Anda telah
query_cache_limit
mengatur ke 1048576 (1M). Ini membatasi hasil apa pun yang ditetapkan ke 1 jt. Jika Anda mengambil sesuatu yang lebih besar, itu tidak akan di-cache. Meskipun Anda telahquery_cache_size
menetapkan untuk 104857600 (100M), ini hanya memungkinkan untuk 100 hasil yang di-cache ditetapkan di dunia yang sempurna. Jika Anda melakukan ratusan pertanyaan, fragmentasi akan terjadi lebih cepat. Anda juga memiliki 4096 (4K) sebagai hasil ukuran minimum yang ditetapkan. Sayangnya, mysql tidak memiliki mekanisme internal untuk defragmenting cache permintaan.Jika Anda harus memiliki cache kueri dan Anda memiliki begitu banyak RAM, Anda dapat menjalankan yang berikut:
untuk membersihkan cache kueri. Anda kehilangan semua hasil dalam tembolok, jadi jalankan baris ini selama jam sibuk.
Saya juga akan menetapkan yang berikut:
Itu menyisakan 23G RAM. Saya akan mengajukan yang berikut:
Itu menyisakan 7G. Ini harus memadai untuk Koneksi OS dan DB.
Perlu diingat bahwa buffer kunci hanya menyimpan cache halaman indeks MyISAM, sedangkan Pool Penyangga InnoDB menyimpan data dan indeks.
Satu rekomendasi lagi: tingkatkan ke MySQL 5.5 sehingga Anda dapat mengonfigurasi InnoDB untuk banyak CPU dan beberapa utas untuk baca / tulis I / O.
Lihat posting saya sebelumnya tentang penggunaan MySQL 5.5 bersamaan dengan mengakses beberapa CPU untuk InnoDB
Nov 24, 2011
: Mengapa mysql 5.5 lebih lambat dari 5.1 (linux, using mysqlslap)Oct 05, 2011
: Permintaan berjalan lama di beberapa versi MySQL yang lebih baruSep 20, 2011
: Multi core dan Kinerja MySQLJun 19, 2011
: Bagaimana cara saya menjalankan bake-off MySQL dengan benar?UPDATE 2012-09-06 14:56 EDT
Metode saya untuk membersihkan cache permintaan agak ekstrem karena menyemprotkan data yang di-cache dan membentuk segmen RAM yang sama sekali berbeda. Seperti yang Anda tunjukkan dalam komentar Anda,
FLUSH QUERY CACHE
(seperti yang Anda sarankan) atau bahkanRESET QUERY CACHE
akan lebih baik. Untuk klarifikasi, ketika saya mengatakan "tidak ada mekanisme internal," saya maksudkan itu. Defragmentasi diperlukan dan harus dilakukan secara manual. Itu harus crontab'd .Jika Anda melakukan DML (INSERT, UPDATE, DELETEs) di InnoDB lebih sering daripada di MyISAM, saya akan mengatakan hapus cache permintaan sama sekali, yang saya katakan di awal.
sumber
FLUSH QUERY CACHE
untuk men-defrag itu? Lihat: dev.mysql.com/doc/refman/5.0/en/flush.htmlBAD: query_cache_size = 1G
Mengapa? Karena berapa lama siram akan memakan waktu. Artinya, ketika beberapa penulisan terjadi, seluruh 1GB akan dipindai untuk menemukan referensi ke tabel yang telah dimodifikasi. Semakin besar QC, semakin lambat ini. Saya merekomendasikan ukuran tidak lebih dari 50 juta, kecuali data Anda jarang berubah.
QC adalah overhead untuk MyISAM dan InnoDB. Itu mengeluarkan Mutex global, dan mengeluarkannya terlalu cepat. Mutex ini adalah salah satu alasan mengapa MySQL tidak dapat menggunakan lebih dari 8 core secara efektif.
SQL_NO_CACHE tidak diketahui sampai setelah Mutex dikunci! Tentang satu-satunya penggunaan untuk bendera itu adalah untuk pembandingan.
Seringkali lebih baik untuk memberikan RAM ke beberapa cache lainnya.
sumber
Saya dapat memikirkan kasus yang sempurna untuk itu, dan kami telah menguji secara menyeluruh dan menjalankannya dalam produksi ... Saya menyebutnya strategi pengelompokan "jalur cepat" :
Jika Anda melakukan pemisahan baca-tulis dengan proxy seperti MaxScale, atau aplikasi Anda mampu, Anda dapat mengirim beberapa bacaan untuk tabel-tabel yang jarang batal hanya untuk budak yang memiliki cache kueri dihidupkan, dan sisanya untuk budak lain dengan itu matikan.
Kami melakukan ini dan menangani panggilan 4M per menit ke cluster selama tes beban kami (bukan patokan ... kesepakatan sebenarnya) sebagai hasilnya. Aplikasi tidak menunggu pada master_pos_wait () untuk beberapa hal, sehingga terhambat oleh ulangan replikasi, dan meskipun kami telah melihatnya dengan status menunggu pembatalan Qcache pada throughput yang sangat tinggi, level throughput tersebut lebih tinggi daripada klaster bahkan mampu tanpa Qcache.
Ini berfungsi karena jarang ada yang relevan dalam cache kueri kecil pada mesin-mesin itu untuk tidak valid (kueri itu hanya relevan dengan tabel yang jarang diperbarui). Kotak-kotak ini adalah "jalur cepat" kami. Untuk sisa kueri yang dilakukan aplikasi, mereka tidak harus bersaing dengan Qcache karena mereka pergi ke kotak tanpa dihidupkan.
sumber