ค่าใช้จ่ายในการตรวจสอบแคชแบบสอบถามบ่อยครั้งคุ้มค่าหรือไม่


22

ขณะนี้ฉันกำลังทำงานกับฐานข้อมูล MySQL ที่เราเห็นการตรวจสอบความถูกต้องจำนวนมากจากแคชแบบสอบถามเป็นหลักเนื่องจากคำสั่ง INSERT, DELETE และ UPDATE จำนวนมากที่ถูกเรียกใช้งานในหลาย ๆ ตาราง

สิ่งที่ฉันพยายามตรวจสอบคือการมีประโยชน์ใด ๆ หรือไม่ที่จะอนุญาตให้ใช้แคชแบบสอบถามสำหรับคำสั่ง SELECT ที่กำลังเรียกใช้กับตารางเหล่านี้ เนื่องจากพวกเขาได้รับการทำให้ใช้งานไม่ได้อย่างรวดเร็วดูเหมือนว่าสิ่งที่ดีที่สุดคือการใช้ SQL_NO_CACHE ในคำสั่ง SELECT ด้วยตารางเหล่านี้

ค่าใช้จ่ายในการตรวจสอบความถูกต้องบ่อยครั้งเป็นสิ่งที่คุ้มค่าหรือไม่?

แก้ไข: ตามคำขอของผู้ใช้ @RolandoMySQLDBA ด้านล่างนี่คือข้อมูลเกี่ยวกับ MyISAM และ INNODB

InnoDB

  • ขนาดข้อมูล: 177.414 GB
  • ขนาดดัชนี: 114.792 GB
  • ขนาดโต๊ะ: 292.205 GB

MyISAM

  • ขนาดข้อมูล: 379.762 GB
  • ขนาดดัชนี: 80.681 GB
  • ขนาดโต๊ะ: 460.443 GB

ข้อมูลเพิ่มเติม:

  • เวอร์ชัน: 5.0.85
  • query_cache_limit: 1048576
  • query_cache_min_res_unit: 4096
  • query_cache_size: 104857600
  • query_cache_type: ON
  • query_cache_wlock_invalidate: ปิด
  • innodb_buffer_pool_size: 8841592832
  • RAM 24GB

2
dom.as/tech/query-cache-tunerสรุปมันออกมาได้สวยมาก
Laurynas Biveinis

เฮ้ลึกซึ้งมาก
Craig Sefton

คำตอบ:


16

คุณควรปิดการใช้งานแคชคิวรีด้วย

[mysqld]
query_cache_size = 0

จากนั้นรีสตาร์ท mysql ทำไมฉันถึงแนะนำว่า ???

Query Cache จะชนหัวกับ InnoDB เสมอ มันจะดีถ้า MVCC ของ InnoDB จะอนุญาตให้มีการสอบถามจากแคชแบบสอบถามหากการปรับเปลี่ยนไม่มีผลต่อการอ่านซ้ำสำหรับธุรกรรมอื่น ๆ น่าเสียดายที่ InnoDB ไม่ได้ทำเช่นนั้น เห็นได้ชัดว่าคุณมีคำถามจำนวนมากที่ได้รับการตรวจสอบความถูกต้องค่อนข้างเร็วและอาจไม่ถูกนำมาใช้ซ้ำ

สำหรับ InnoDB ภายใต้ MySQL 4.0 แคชแบบสอบถามถูกปิดใช้งานสำหรับการทำธุรกรรม สำหรับ MySQL 4.1+, InnoDB จะเล่นตำรวจจราจรเมื่ออนุญาตให้เข้าถึงแคชแบบสอบถามในแบบต่อตาราง

จากมุมมองของคำถามของคุณฉันจะบอกว่าเหตุผลในการลบแคชแบบสอบถามไม่ได้เป็นค่าใช้จ่ายมาก แต่ InnoDB จัดการอย่างไร

สำหรับข้อมูลเพิ่มเติมเกี่ยวกับวิธีการปฏิสัมพันธ์กับ InnoDB แคชแบบสอบถามโปรดอ่านหน้า 213-215 ของหนังสือเล่มนี้"High Performance MySQL (Second Edition)"

หากข้อมูลส่วนใหญ่ของคุณทั้งหมดคือ MyISAM คุณสามารถใช้แนวคิดดั้งเดิมของคุณในการใช้ SQL_NO_CACHE

หากคุณมีส่วนผสมของ InnoDB และ MyISAM คุณจะต้องค้นหายอดเงินที่เหมาะสมสำหรับแอปพลิเคชันของคุณโดยพิจารณาจากจำนวนแคชที่คุณพลาดไป ในความเป็นจริงหน้า 209-210 ของหนังสือเล่มเดียวกันชี้ให้เห็นเหตุผลของการพลาดแคช:

  • แบบสอบถามไม่สามารถแคชได้เนื่องจากมีโครงสร้างแบบ nondeterministic (เช่น CURRENT_DATE) หรือเนื่องจากชุดผลลัพธ์มีขนาดใหญ่เกินกว่าที่จะจัดเก็บได้แบบสอบถามคิวที่ไม่สามารถลบได้ทั้งสองชนิดจะเพิ่มตัวแปรสถานะ Qcache_not_cached
  • เซิร์ฟเวอร์ไม่เคยเห็นคิวรีมาก่อนดังนั้นจึงไม่มีโอกาสแคชผลลัพธ์
  • ผลลัพธ์ของแบบสอบถามถูกแคชก่อนหน้านี้ แต่เซิร์ฟเวอร์ลบออก สิ่งนี้สามารถเกิดขึ้นได้เนื่องจากมีหน่วยความจำไม่เพียงพอที่จะเก็บไว้เพราะมีคนสั่งให้เซิร์ฟเวอร์ลบออกหรือเพราะมันไม่ถูกต้อง

และสาเหตุสำคัญของการแคชสูงที่ขาดหายไปโดยมีการสืบค้นที่ไม่สามารถสืบค้นได้บางส่วนอาจเป็น:

  • แคชแบบสอบถามยังไม่อุ่น นั่นคือเซิร์ฟเวอร์ไม่ได้มีโอกาสเติมแคชด้วยชุดผลลัพธ์
  • เซิร์ฟเวอร์กำลังดูข้อความค้นหาที่ไม่เคยเห็นมาก่อน หากคุณไม่มีการค้นหาซ้ำหลายครั้งสิ่งนี้สามารถเกิดขึ้นได้แม้ว่าแคชจะอุ่นขึ้นแล้ว
  • มีการตรวจสอบแคชจำนวนมาก

อัพเดท 2012-09-06 10:10 EDT

ค้นหาข้อมูลที่อัปเดตล่าสุดของคุณคุณquery_cache_limitตั้งค่าเป็น 1048576 (1M) สิ่งนี้ จำกัด ชุดผลลัพธ์ใด ๆ ที่ 1M หากคุณเรียกคืนสิ่งที่ใหญ่กว่านี้ก็จะไม่ถูกแคช ในขณะที่คุณquery_cache_sizeตั้งค่าไว้ที่ 104857600 (100M) การทำเช่นนี้จะช่วยให้ได้ผลลัพธ์ที่แคช 100 รายการในโลกที่สมบูรณ์แบบเท่านั้น หากคุณทำการค้นหาหลายร้อยแบบสอบถามการกระจายตัวของข้อมูลจะมาค่อนข้างเร็ว คุณมี 4096 (4K) เป็นชุดผลลัพธ์ขนาดต่ำสุด น่าเสียดายที่ mysql ไม่มีกลไกภายในสำหรับการจัดเรียงข้อมูลแคชแบบสอบถาม

หากคุณต้องมีแคชแบบสอบถามและคุณมี RAM มากคุณสามารถดำเนินการดังต่อไปนี้:

SET GLOBAL query_cache_size = 0;
SELECT SLEEP(60);
SET GLOBAL query_cache_size = 1024 * 1024 * 1024;

เพื่อล้างแคชแบบสอบถาม คุณสูญเสียผลลัพธ์ที่แคชทั้งหมดดังนั้นให้เรียกใช้บรรทัดเหล่านี้ระหว่างชั่วโมงที่มีการใช้งานน้อย

ฉันจะกำหนดสิ่งต่อไปนี้ด้วย:

  • query_cache_size = 1G
  • query_cache_limit = 8M

ที่เหลือ 23G of RAM ฉันจะเพิ่มดังต่อไปนี้:

  • innodb_buffer_pool_size = 12G
  • key_buffer_size = 4G

ที่เหลือ 7G นี่ควรจะเพียงพอสำหรับการเชื่อมต่อ OS และ DB

โปรดทราบว่าคีย์บัฟเฟอร์จะแคชเฉพาะหน้าดัชนี MyISAM เท่านั้นในขณะที่ InnoDB Buffer Pool แคชข้อมูลและดัชนี

อีกหนึ่งคำแนะนำ: อัพเกรดเป็น MySQL 5.5 เพื่อให้คุณสามารถกำหนดค่า InnoDB สำหรับหลาย CPU และหลายเธรดสำหรับอ่าน / เขียน I / O

ดูโพสต์ก่อนหน้าของฉันเกี่ยวกับการใช้ MySQL 5.5 ร่วมกับการเข้าถึง CPU หลายตัวสำหรับ InnoDB

อัพเดท 2012-09-06 14:56 EDT

วิธีการของฉันในการล้างแคชแบบสอบถามค่อนข้างมากเพราะมันจะเก็บข้อมูลที่แคชไว้และก่อให้เกิดเซ็กเมนต์ RAM ที่แตกต่างอย่างสิ้นเชิง ตามที่คุณได้ชี้ให้เห็นในความคิดเห็นของคุณFLUSH QUERY CACHE(ตามที่คุณแนะนำ) หรือRESET QUERY CACHEจะดีกว่า เพื่อความกระจ่างเมื่อฉันพูดว่า "ไม่มีกลไกภายใน" ฉันหมายความอย่างนั้น จำเป็นต้องมีการจัดเรียงข้อมูลและต้องดำเนินการด้วยตนเอง มันจะต้องมีการ crontab'd

ถ้าคุณทำ DML (INSERTs, UPDATEs, DELETEs) บน InnoDB บ่อยกว่า MyISAM ฉันจะบอกว่าจะลบแคชของคิวรีทั้งหมดซึ่งฉันได้กล่าวไว้ในตอนแรก


ขอบคุณสำหรับคำตอบ ฉันมีหนังสือเล่มนั้นและใช้มันอย่างกว้างขวาง ฉันทราบดีถึงสาเหตุที่คุณคิดถึงการทำแคช แต่เราได้ระบุว่าการทำให้แคชใช้ไม่ได้นั้นเป็นปัญหาสำคัญเนื่องจากมีความสัมพันธ์อย่างมากที่เราเห็นระหว่าง Com_select และ Qcache_inserts โอ้และฐานข้อมูลที่สงสัยมีส่วนผสมของ INNODB และ MyISAM
Craig Sefton

อัปเดตด้วยข้อมูลเพิ่มเติมที่คุณร้องขอ ขอบคุณ
Craig Sefton

ขอบคุณสำหรับการตอบกลับฉันรอที่เหลือ หนึ่งในสิ่งที่เราระบุคือประมาณ 18% ของการสืบค้นไม่ได้ถูกแคชดังนั้นขอขอบคุณคำแนะนำเกี่ยวกับการตั้งค่า น่าเสียดายที่ช่องนั้นไม่ได้ทุ่มเท แต่คำแนะนำของคุณควรช่วย การกระจายตัวของปัญหาก็เป็นปัญหาเช่นกัน ฉันยังคงกังวลเกี่ยวกับจำนวนของการทำให้เป็นโมฆะที่เราเห็น (ตรงข้ามกับข้อความค้นหาที่ไม่ได้เก็บไว้เลย) ดังนั้นยังคงไม่แน่ใจว่าค่าใช้จ่ายนั้นมีค่าหรือไม่ ซาบซึ้งในความเข้าใจของคุณขอบคุณมาก
Craig Sefton

เกี่ยวกับความคิดเห็นของคุณเกี่ยวกับ "mysql ไม่มีกลไกภายในสำหรับการจัดเรียงข้อมูลแคชแบบสอบถาม" คุณไม่สามารถเรียกใช้คำสั่งFLUSH QUERY CACHEเพื่อจัดเรียงข้อมูลได้หรือไม่ โปรดดู: dev.mysql.com/doc/refman/5.0/en/flush.html
Craig Sefton

อัปเดตคำตอบของฉัน ...
RolandoMySQLDBA

3

BAD: query_cache_size = 1G

ทำไม? เพราะจะต้องใช้ระยะเวลานานเท่าใด นั่นคือเมื่อมีการเขียนเกิดขึ้น 1GB ทั้งหมดจะถูกสแกนเพื่อค้นหาการอ้างอิงใด ๆ ไปยังตารางที่ได้รับการแก้ไข ยิ่ง QC ยิ่งใหญ่ก็ยิ่งช้า ฉันขอแนะนำให้มีขนาดไม่เกิน 50M เว้นแต่ว่าข้อมูลของคุณจะเปลี่ยนไปน้อยมาก

QC มีค่าใช้จ่ายทั้ง MyISAM และ InnoDB มันใช้ Mutex ระดับโลกและนำออกมาเร็วเกินไป mutex นี้เป็นเหตุผลหนึ่งที่ MySQL ไม่สามารถใช้ประโยชน์ได้มากกว่า 8 คอร์

SQL_NO_CACHE ไม่ถูกสังเกตจนกระทั่งหลังจาก Mutex ถูกล็อค! เกี่ยวกับการใช้งานเฉพาะสำหรับธงนั้นสำหรับการเปรียบเทียบ

บ่อยครั้งจะเป็นการดีกว่าถ้าให้แรมกับแคชอื่น


2

ฉันสามารถคิดกรณีที่สมบูรณ์แบบสำหรับมันและเราได้ทดสอบอย่างละเอียดและดำเนินการในการผลิต ... ฉันเรียกมันว่ากลยุทธ์การจัดกลุ่ม"ช่องทางที่รวดเร็ว" :

หากคุณแยกการอ่าน - เขียนด้วยพร็อกซีเช่น MaxScale หรือแอปพลิเคชันของคุณมีความสามารถคุณสามารถส่งการอ่านบางอย่างสำหรับตารางที่ไม่ค่อยถูกต้องเหล่านั้นไปยังทาสที่เปิดแคชแบบสอบถามไว้และส่วนที่เหลือไปยังทาสอื่น ๆ ปิด.

เราทำสิ่งนี้และจัดการการโทร 4M ต่อนาทีไปยังคลัสเตอร์ในระหว่างการทดสอบโหลดของเรา (ไม่ใช่มาตรฐาน ... ข้อตกลงจริง) เป็นผลลัพธ์ แอปพลิเคชันรอ master_pos_wait () สำหรับบางสิ่งดังนั้นจึงถูก throttled โดยเธรดการจำลองแบบและแม้ว่าเราจะเห็นสถานะของการรอการตรวจสอบความถูกต้อง Qcache ที่อัตราความเร็วสูงมากระดับ throughput เหล่านั้นจะสูงกว่าคลัสเตอร์ ความสามารถในการโดยไม่มี Qcache

วิธีนี้ใช้งานได้เนื่องจากไม่ค่อยมีสิ่งใดที่เกี่ยวข้องในแคชคิวรีขนาดเล็กบนเครื่องเหล่านั้นที่จะทำให้ใช้งานไม่ได้ กล่องเหล่านี้คือ "ช่องทางด่วน" ของเรา สำหรับแบบสอบถามที่เหลือที่แอปพลิเคชันทำพวกเขาไม่จำเป็นต้องโต้แย้งกับ Qcache ตั้งแต่ไปที่กล่องโดยไม่เปิด

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.