Fast Query Cache adalah query cache yang dikembangkan oleh Alibaba Cloud untuk menggantikan query cache asli MySQL dengan desain bebas kunci (lock-free) dan konkurensi tinggi. Fitur ini secara signifikan meningkatkan queries per second (QPS) pada workload berat baca sambil menambahkan overhead minimal dalam skenario campuran baca/tulis.
Fast Query Cache hanya tersedia pada instans RDS yang menjalankan MySQL 5.7 dengan versi mesin minor 20200331 atau lebih baru, serta memerlukan layanan dedicated proxy dinonaktifkan.
Prasyarat
Sebelum memulai, pastikan bahwa:
-
Instans RDS Anda menjalankan MySQL 5.7 dengan versi mesin minor 20200331 atau lebih baru.
-
Layanan dedicated proxy dinonaktifkan untuk instans RDS Anda. Untuk detailnya, lihat Nonaktifkan layanan dedicated proxy untuk instans ApsaraDB RDS for MySQL.
Cara kerja
Query cache meningkatkan performa dengan menyimpan set hasil untuk kueri yang memenuhi syarat. Ketika kueri yang sama dijalankan kembali, database langsung mengembalikan hasil dari cache — melewati parsing SQL, optimasi, dan eksekusi — sehingga mengurangi overhead CPU dan waktu respons untuk kueri sederhana berfrekuensi tinggi.
Mengapa tidak menggunakan query cache asli MySQL?
Query cache asli MySQL menggunakan kunci global (global lock) pada semua operasi cache. Dalam kondisi konkurensi tinggi, kunci ini menjadi bottleneck: penambahan core CPU justru dapat mengurangi QPS alih-alih meningkatkannya. Manajemen memori yang buruk memperparah masalah ini — fragmentasi menumpuk, proses reclamation lambat, dan rasio hit cache rendah menyebabkan degradasi performa signifikan. Masalah-masalah ini mendorong MySQL untuk sepenuhnya menghapus query cache asli di MySQL 8.0 dan menonaktifkannya secara default di versi sebelumnya.
Bagaimana Fast Query Cache mengatasi masalah tersebut
Alibaba Cloud mendesain ulang query cache dari awal:
| Area peningkatan | Perubahan yang dilakukan |
|---|---|
| Konkurensi | Menghapus kunci global. Menggunakan desain bebas kunci dengan sharding, memungkinkan pemrosesan paralel multi-core sejati tanpa kontensi kunci |
| Manajemen memori | Mengalokasikan memori sesuai kebutuhan. Kebijakan reclamation cerdas mengurangi fragmentasi dan meningkatkan pemanfaatan |
| Kebijakan cache | Memantau rasio hit cache secara Real-time dan menyesuaikan secara dinamis kebijakan penggantian serta periode validitas cache untuk mencegah entri usang tetap menempati sumber daya |
| Kompatibilitas tulis | Menggunakan invalidasi inkremental untuk membatalkan hanya entri cache yang terpengaruh oleh operasi tulis, sehingga mengurangi dampak terhadap pembacaan dari cache |
Aktifkan Fast Query Cache
Fast Query Cache dikontrol oleh dua parameter: query_cache_type (sakelar on/off) dan query_cache_size (alokasi memori).
Parameter
| Parameter | Deskripsi |
|---|---|
query_cache_type |
Mengontrol sakelar cache. Nilai yang valid: 0 — dinonaktifkan (default); 1 — diaktifkan untuk semua kueri yang memenuhi syarat (SQL_NO_CACHE melewatkan caching per pernyataan); 2 — dinonaktifkan secara global, tetapi SQL_CACHE mengaktifkan caching untuk pernyataan tertentu |
query_cache_size |
Memori yang dialokasikan untuk cache. Nilai yang valid: 0 hingga 10.485.760.000 byte (harus kelipatan 1.024). Satuan: byte |
Langkah-langkah
Karena Fast Query Cache mengonsumsi memori tambahan, konfigurasi ulang innodb_buffer_pool_size terlebih dahulu untuk membebaskan ruang:
-
Kurangi
innodb_buffer_pool_sizemenjadi 90% dari nilai saat ini. Memori 10% yang Anda bebaskan akan tersedia untuk query cache. Misalnya, jika nilai saat ini adalah{DBInstanceClassMemory*7/10}, atur menjadi{DBInstanceClassMemory*63/100}. Untuk detailnya, lihat Ubah ukuran InnoDB buffer pool. -
Atur
query_cache_sizeberdasarkan workload Anda. Untuk detail cara memodifikasi parameter, lihat Modifikasi parameter instans.-
Jika Anda mengetahui ukuran set hasil: atur
query_cache_sizemenjadi 20% dari ukuran set hasil. -
Jika Anda tidak mengetahui ukuran set hasil: atur
query_cache_sizemenjadi 10% of `innodb_buffer_pool_size`.
PentingSaat Anda mengubah ukuran instans RDS,
query_cache_sizetidak diskalakan secara otomatis. Konfigurasi ulang segera setelah perubahan spesifikasi diterapkan. -
-
Atur
query_cache_typeke 1 untuk mengaktifkan Fast Query Cache. Untuk detailnya, lihat Modifikasi parameter instans.
Pengujian pada tingkat session
Sebelum mengubah konfigurasi global, uji Fast Query Cache pada satu koneksi tanpa memengaruhi pengguna lain:
-- Aktifkan Fast Query Cache hanya untuk session ini
SET SESSION query_cache_type = 1;
-- Nonaktifkan Fast Query Cache hanya untuk session ini
SET SESSION query_cache_type = 0;
Verifikasi cache berfungsi
Setelah mengaktifkan Fast Query Cache, jalankan pernyataan berikut untuk memeriksa aktivitas cache:
SHOW STATUS LIKE 'Qcache%';
Metrik utama yang perlu ditinjau:
| Metrik | Maknanya |
|---|---|
Qcache_hits |
Jumlah kueri yang dilayani dari cache. Nilai yang meningkat mengonfirmasi cache aktif |
Qcache_inserts |
Jumlah kueri yang ditambahkan ke cache |
Qcache_lowmem_prunes |
Jumlah entri cache yang dihapus karena tekanan memori. Nilai tinggi berarti query_cache_size terlalu kecil |
Qcache_not_cached |
Jumlah kueri yang tidak di-cache (jenis kueri tidak memenuhi syarat atau menggunakan SQL_NO_CACHE) |
Cache yang sehat menunjukkan Qcache_hits tumbuh lebih cepat daripada Qcache_inserts.
Benchmark performa
Benchmark berikut membandingkan QPS pada tiga konfigurasi berbeda pada instans RDS dedicated (4 core CPU, memori 8 GB, data uji 250 MB menggunakan Sysbench):
-
QC-OFF: tanpa query cache
-
MySQL-QC: query cache asli MySQL
-
Fast-QC: Fast Query Cache
Workload baca all-hit (rasio hit cache 100%, cache 512 MB)
Menggunakan skrip oltp_point_select dengan pernyataan POINT SELECT pada primary key.
Tabel 1. QPS untuk kueri baca dengan rasio hit cache 100%
| Jumlah kueri konkuren | QC-OFF | MySQL-QC (peningkatan QPS dibanding QC-OFF) | Fast-QC (peningkatan QPS dibanding QC-OFF) |
|---|---|---|---|
| 1 | 8.093 | 8.771 (8,38%) | 9.261 (14,43%) |
| 8 | 62.262 | 65.686 (5,50%) | 75.313 (20,96%) |
| 16 | 97.083 | 73.027 (-24,78%) | 139.323 (43,51%) |
| 32 | 97.337 | 60.567 (-37,78%) | 200.978 (106,48%) |
| 64 | 106.283 | 60.216 (-43,34%) | 221.659 (108,56%) |
| 128 | 107.781 | 62.844 (-41,69%) | 231.409 (114,70%) |
| 256 | 106.694 | 63.832 (-40,17%) | 222.187 (108,25%) |
| 512 | 101.733 | 64.866 (-36,24%) | 203.789 (100,32%) |
| 1.024 | 89.548 | 62.291 (-30,44%) | 203.542 (127,30%) |
Saat konkurensi meningkat, QPS query cache asli MySQL turun tajam — hingga 43% pada 64 thread. QPS Fast Query Cache terus meningkat, melebihi QC-OFF hingga 127% pada 1.024 thread.
Workload baca dengan rasio hit tinggi (>80% rasio hit cache, cache 512 MB)
Menggunakan skrip oltp_read_only dengan kueri range yang mengembalikan beberapa record.
Tabel 2. QPS untuk kueri baca dengan rasio hit cache lebih dari 80%
| Jumlah kueri konkuren | QC-OFF | MySQL-QC (peningkatan QPS dibanding QC-OFF) | Fast-QC (peningkatan QPS dibanding QC-OFF) |
|---|---|---|---|
| 1 | 5.099 | 6.467 (26,83%) | 7.022 (37,71%) |
| 8 | 28.782 | 28.651 (-0,46%) | 45.017 (56,41%) |
| 16 | 35.333 | 31.099 (-11,98%) | 66.770 (88,97%) |
| 32 | 34.864 | 27.610 (-20,81%) | 67.623 (93,96%) |
| 64 | 35.503 | 27.518 (-22,49%) | 75.981 (114,01%) |
| 128 | 35.744 | 27.733 (-22,41%) | 80.396 (124,92%) |
| 256 | 35.685 | 27.738 (-22,27%) | 80.925 (126,78%) |
| 512 | 35.308 | 27.398 (-22,40%) | 79.323 (124,66%) |
| 1.024 | 34.044 | 26.861 (-22,10%) | 75.742 (122,48%) |
QPS Fast Query Cache terus meningkat seiring konkurensi dan mencapai puncak lebih dari 124% di atas QC-OFF. Query cache asli MySQL mengalami degradasi hingga 22% di bawah QC-OFF pada konkurensi tinggi.
Workload baca dengan rasio hit rendah (~10% rasio hit cache, cache 16 MB)
Menggunakan skrip oltp_read_only. Cache 16 MB jauh lebih kecil daripada set data, menyebabkan eviksi sering dan rasio hit mendekati 10%.
Tabel 3. QPS untuk kueri baca dengan rasio hit cache sekitar 10%
| Jumlah kueri konkuren | QC-OFF | MySQL-QC (peningkatan QPS dibanding QC-OFF) | Fast-QC (peningkatan QPS dibanding QC-OFF) |
|---|---|---|---|
| 1 | 5.004 | 4.727 (-5,54%) | 5.199 (3,90%) |
| 8 | 28.795 | 22.542 (-21,72%) | 28.578 (-0,75%) |
| 16 | 35.455 | 24.064 (-32,13%) | 35.682 (0,64%) |
| 32 | 34.526 | 21.330 (-38,22%) | 35.871 (3,90%) |
| 64 | 35.514 | 19.791 (-44,27%) | 36.051 (1,51%) |
| 128 | 35.983 | 19.519 (-45,75%) | 36.253 (0,75%) |
| 256 | 35.695 | 19.168 (-46,30%) | 36.337 (1,80%) |
| 512 | 35.182 | 18.420 (-47,64%) | 35.972 (2,25%) |
| 1.024 | 33.915 | 20.168 (-40,53%) | 34.546 (1,86%) |
Query cache asli MySQL kehilangan hingga 48% QPS dalam kondisi rasio hit rendah. Fast Query Cache tetap berada dalam rentang 1–4% dari QC-OFF, hampir tidak menambah overhead meskipun cache sebagian besar tidak terpakai.
Workload campuran baca/tulis
Menggunakan skrip oltp_read_write dengan pembaruan tabel yang sering sehingga terus-menerus membatalkan entri cache.
Tabel 4. QPS untuk kueri baca dan tulis
| Jumlah kueri konkuren | QC-OFF | Fast-QC (peningkatan QPS dibanding QC-OFF) |
|---|---|---|
| 1 | 4.152 | 4.098 (-1,30%) |
| 8 | 21.359 | 21.195 (-0,77%) |
| 16 | 26.020 | 25.548 (-1,81%) |
| 32 | 27.595 | 26.996 (-2,17%) |
| 64 | 29.229 | 28.733 (-1,70%) |
| 128 | 29.265 | 28.828 (-1,49%) |
| 256 | 29.911 | 29.616 (-0,99%) |
| 512 | 29.148 | 28.816 (-1,14%) |
| 1.024 | 29.204 | 28.824 (-1,30%) |
Fast Query Cache mengurangi QPS paling banyak 2,17% pada workload campuran baca/tulis — mekanisme invalidasi inkremental menjaga overhead pemeliharaan cache tetap rendah bahkan di bawah beban tulis konstan.
Penentuan ukuran cache
query_cache_size secara langsung memengaruhi rasio hit dan QPS. Benchmark berikut menunjukkan hubungan antara ukuran cache dan performa pada dataset 10 GB (100 tabel, 400.000 record per tabel, 20% data hot, 64 thread konkuren, innodb_buffer_pool_size = 6 GB):
Tabel 5. QPS dengan ukuran cache berbeda
| query_cache_size (MB) | QC-OFF | Rasio hit Fast-QC | Fast-QC (peningkatan QPS dibanding QC-OFF) |
|---|---|---|---|
| 64 | 98.236 | 22% | 99.440 (1,23%) |
| 128 | 98.236 | 45% | 114.155 (16,21%) |
| 256 | 98.236 | 72% | 140.668 (43,19%) |
| 512 | 98.236 | 82% | 151.260 (53,98%) |
| 1.024 | 98.236 | 84% | 153.866 (56,63%) |
| 2.048 | 98.236 | 87% | 159.597 (62,46%) |
| 4.096 | 98.236 | 92% | 169.412 (72,45%) |
Pengamatan utama dari pengujian ini:
-
Fast Query Cache tidak pernah mengurangi QPS berapa pun ukuran cache-nya, bahkan pada rasio hit 22%.
-
Untuk kueri primary key, Fast Query Cache mengungguli query cache asli MySQL pada rasio hit berapa pun — dalam beberapa kasus lebih dari 90%.
-
Untuk kueri range dan kueri dengan
ORDER BY, Fast Query Cache memberikan performa lebih baik daripada query cache asli MySQL ketika rasio hit di bawah 90%, serta menghemat sumber daya CPU secara signifikan.
Ukuran set hasil aktual untuk pengujian ini adalah 2,5 GB. Menyesuaikan ukuran untuk mencakup data hot (20% dari 10 GB = 2 GB) memerlukan sekitar 512 MB–1 GB query_cache_size untuk mencapai rasio hit 80%+ dalam skenario ini.
Mengalokasikan terlalu banyak memori untuk query_cache_size mengurangi memori yang tersedia untuk InnoDB Buffer Pool, yang dapat merusak performa keseluruhan. Selalu kurangi innodb_buffer_pool_size secara proporsional saat menambah query_cache_size.
Kapan menggunakan Fast Query Cache
Gunakan Fast Query Cache ketika
-
Workload Anda bersifat intensif baca dengan frekuensi tulis rendah — misalnya, halaman detail produk e-commerce atau kueri pelaporan.
-
Anda ingin meng-cache tabel tertentu dengan rasio baca/tulis tinggi. Periksa tabel
TABLE_STATISTICSuntuk mengidentifikasi tabel-tabel tersebut, lalu gunakan kata kunciSQL_CACHEdenganquery_cache_type = 2untuk hanya meng-cache kueri tersebut. Untuk detail cara mengaksesTABLE_STATISTICS, lihat Performance Insight.
Sebelum mengaktifkan Fast Query Cache secara global, periksa rasio hit InnoDB Buffer Pool Anda:
SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_reads';
SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_read_requests';
Rasio hit = 1 - (Innodb_buffer_pool_reads / Innodb_buffer_pool_read_requests)
Jika rasio hit InnoDB Buffer Pool di bawah 80%, kolam buffer sudah mengalami tekanan memori. Mengaktifkan Fast Query Cache dalam kondisi ini — yang memerlukan pengurangan innodb_buffer_pool_size — kemungkinan besar akan merusak performa. Tingkatkan memori instans atau optimalkan kueri sebelum mengaktifkan cache.
Hindari Fast Query Cache ketika
-
Workload intensif tulis: Tulis yang sering menyebabkan invalidasi cache konstan, menambah overhead dengan manfaat caching minimal. Untuk sistem transaksi berfrekuensi tinggi, pertahankan
query_cache_type = 0. -
Kebutuhan data Real-time: Hasil cache mungkin tertinggal dari data terkini. Untuk kasus penggunaan seperti data pasar keuangan di mana pembacaan usang tidak dapat diterima, nonaktifkan cache atau gunakan
SQL_NO_CACHEper kueri.
Pilih nilai query_cache_type yang tepat
query_cache_type mendukung perubahan tingkat session, sehingga Anda dapat menyesuaikan perilaku caching per koneksi tanpa mengubah pengaturan global:
SET SESSION query_cache_type = 1; -- aktifkan untuk session ini
SET SESSION query_cache_type = 0; -- nonaktifkan untuk session ini
| Nilai | Perilaku | Paling cocok untuk |
|---|---|---|
| 0 | Menonaktifkan Fast Query Cache secara global | Workload intensif tulis atau skenario rasio hit sangat rendah |
| 1 | Diaktifkan untuk semua kueri yang memenuhi syarat; gunakan SQL_NO_CACHE untuk melewatkan pernyataan tertentu |
Workload intensif baca dengan perubahan data jarang |
| 2 | Dinonaktifkan secara global; hanya meng-cache kueri dengan SQL_CACHE |
Dataset besar, pola akses tidak terprediksi, atau saat Anda memerlukan kontrol caching tingkat tabel |