Là chi phí chung của việc vô hiệu hóa bộ đệm truy vấn thường xuyên có bao giờ đáng không?


22

Tôi hiện đang làm việc trên cơ sở dữ liệu MySQL, nơi chúng tôi đang thấy một số lượng lớn các lỗi không hợp lệ từ bộ đệm truy vấn, chủ yếu là do số lượng lớn các câu lệnh INSERT, DELETE và UPDATE đang được thực thi trên nhiều bảng.

Điều tôi đang cố gắng xác định là liệu có hay không có bất kỳ lợi ích nào khi cho phép sử dụng bộ đệm truy vấn được sử dụng cho các câu lệnh CHỌN đang được chạy trên các bảng này. Vì chúng bị vô hiệu hóa quá nhanh, nên đối với tôi, điều tốt nhất là chỉ sử dụng SQL_NO_CACHE trên các câu lệnh CHỌN với các bảng này.

Là chi phí vô hiệu thường xuyên bao giờ có giá trị nó?

Chỉnh sửa: Theo yêu cầu của người dùng @RolandoMySQLDBA bên dưới, đây là thông tin trên MyISAM và INNODB.

InnoDB

  • Kích thước dữ liệu: 177.414 GB
  • Kích thước chỉ mục: 114,792 GB
  • Kích thước bảng: 292,20 GB

MyISAM

  • Kích thước dữ liệu: 379.762 GB
  • Kích thước chỉ mục: 80.681 GB
  • Kích thước bảng: 460.443 GB

Thông tin bổ sung:

  • Phiên bản: 5.0,85
  • truy vấn_cache_limit: 1048576
  • truy vấn_cache_min_res_unit: 4096
  • truy vấn_cache_size: 104857600
  • query_cache_type: BẬT
  • query_cache_wlock_invalidate: TẮT
  • innodb_buffer_pool_size: 8841592832
  • 24GB RAM

2
dom.as/tech/query-cache-tuner tổng hợp nó khá độc đáo
Laurynas Biveinis

Hehe, rất sâu sắc.
Craig Sefton

Câu trả lời:


16

Bạn chỉ nên vô hiệu hóa bộ đệm truy vấn với

[mysqld]
query_cache_size = 0

và sau đó khởi động lại mysql. Tại sao tôi lại đề nghị như vậy ???

Cache truy vấn sẽ luôn đối đầu với InnoDB. Sẽ thật tuyệt nếu MVCC của InnoDB sẽ cho phép các truy vấn được cung cấp từ bộ đệm truy vấn nếu các sửa đổi không ảnh hưởng đến các lần đọc lặp lại cho các giao dịch khác. Thật không may, InnoDB không làm điều đó. Rõ ràng, bạn có rất nhiều truy vấn bị vô hiệu hóa khá nhanh và có thể không được sử dụng lại.

Đối với InnoDB trong MySQL 4.0, bộ đệm truy vấn đã bị vô hiệu hóa cho các giao dịch. Đối với MySQL 4.1+, InnoDB đóng vai trò cảnh sát giao thông khi cho phép truy cập vào bộ đệm truy vấn trên cơ sở mỗi bảng.

Từ góc độ câu hỏi của bạn, tôi sẽ nói rằng việc biện minh cho việc xóa bộ đệm truy vấn không phải là quá nhiều chi phí, mà là cách InnoDB quản lý nó.

Để biết thêm thông tin về cách InnoDB tương tác với bộ đệm truy vấn, vui lòng đọc trang 213-215 của cuốn sách "MySQL hiệu suất cao (Ấn bản thứ hai)" .

Nếu tất cả hoặc phần lớn dữ liệu của bạn là MyISAM, bạn có thể đi với ý tưởng ban đầu của mình về việc sử dụng SQL_NO_CACHE.

Nếu bạn có sự kết hợp của InnoDB và MyISAM, bạn sẽ phải tìm sự cân bằng phù hợp cho ứng dụng của mình dựa trên mức độ sai sót của bộ nhớ cache. Trên thực tế, các trang 209-210 của cùng một cuốn sách chỉ ra những lý do khiến bộ nhớ cache bị mất:

  • Truy vấn không được lưu trong bộ nhớ cache, bởi vì nó chứa cấu trúc không xác định (chẳng hạn như CURRENT_DATE) hoặc do tập kết quả của nó quá lớn để lưu trữ. Các loại truy vấn không thể kiểm soát được làm tăng biến trạng thái Qcache_not_cached.
  • Máy chủ chưa bao giờ thấy truy vấn trước đó, vì vậy nó không bao giờ có cơ hội lưu trữ kết quả của nó.
  • Kết quả của truy vấn đã được lưu trữ trước đó, nhưng máy chủ đã xóa nó. Điều này có thể xảy ra vì không có đủ bộ nhớ để giữ nó, bởi vì ai đó đã hướng dẫn máy chủ xóa nó hoặc vì nó không hợp lệ

và nguyên nhân gốc của lỗi bộ nhớ cache cao với một vài truy vấn không thể truy cập có thể là:

  • Bộ đệm truy vấn chưa ấm. Đó là máy chủ chưa có cơ hội lấp đầy bộ đệm với các tập kết quả.
  • Máy chủ đang nhìn thấy các truy vấn mà nó chưa từng thấy trước đây. Nếu bạn không có nhiều truy vấn lặp đi lặp lại, điều này có thể xảy ra ngay cả khi bộ đệm được làm nóng.
  • Có rất nhiều mất hiệu lực bộ nhớ cache.

CẬP NHẬT 2012-09-06 10:10 EDT

Nhìn thông tin cập nhật mới nhất của bạn, bạn đã query_cache_limitđặt thành 1048576 (1M). Điều này giới hạn bất kỳ kết quả nào được đặt thành 1M. Nếu bạn lấy bất cứ thứ gì lớn hơn, đơn giản là nó sẽ không được lưu trữ. Mặc dù bạn đã query_cache_sizeđặt thành 104857600 (100M), nhưng điều này chỉ cho phép 100 kết quả được lưu trong bộ nhớ cache trong một thế giới hoàn hảo. Nếu bạn thực hiện hàng trăm truy vấn, phân mảnh sẽ xuất hiện khá nhanh. Bạn cũng có 4096 (4K) làm tập kết quả kích thước tối thiểu. Thật không may, mysql không có cơ chế nội bộ để chống phân mảnh bộ đệm truy vấn.

Nếu bạn phải có bộ đệm truy vấn và bạn có rất nhiều RAM, bạn có thể thực hiện các thao tác sau:

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

để xóa bộ nhớ cache truy vấn. Bạn mất tất cả các kết quả được lưu trong bộ nhớ cache, vì vậy hãy chạy các dòng này trong giờ thấp điểm.

Tôi cũng sẽ chỉ định như sau:

  • truy vấn_cache_size = 1G
  • truy vấn_cache_limit = 8M

Điều đó để lại 23G RAM. Tôi sẽ nâng cao như sau:

  • innodb_buffer_pool_size = 12G
  • key_buffer_size = 4G

Rời đi 7G. Điều này là đủ cho các kết nối hệ điều hành và DB.

Hãy nhớ rằng bộ đệm chính chỉ lưu trữ các trang chỉ mục MyISAM, trong khi Bộ đệm InnoDB lưu trữ dữ liệu và chỉ mục.

Thêm một đề xuất nữa: nâng cấp lên MySQL 5.5 để bạn có thể định cấu hình InnoDB cho nhiều CPU và nhiều luồng để đọc / ghi I / O.

Xem các bài đăng trước đây của tôi về việc sử dụng MySQL 5.5 kết hợp với truy cập nhiều CPU cho InnoDB

CẬP NHẬT 2012-09-06 14:56 EDT

Phương pháp của tôi để xóa bộ đệm truy vấn khá cực đoan vì nó làm mất dữ liệu được lưu trong bộ nhớ cache và tạo thành một phân đoạn RAM hoàn toàn khác. Như bạn đã chỉ ra trong bình luận của bạn, FLUSH QUERY CACHE(như bạn đề xuất) hoặc thậm chí RESET QUERY CACHEsẽ tốt hơn. Để làm rõ, khi tôi nói "không có cơ chế nội bộ", tôi có nghĩa là chính xác điều đó. Chống phân mảnh là cần thiết và phải được thực hiện thủ công. Nó sẽ cần phải được crontab'd .

Nếu bạn thực hiện DML (CHERTN, CẬP NHẬT, XÓA) trên InnoDB thường xuyên hơn trên MyISAM, tôi sẽ nói xóa hoàn toàn bộ đệm truy vấn, như tôi đã nói lúc đầu.


Cảm ơn vì sự trả lời. Tôi có cuốn sách đó và đã được sử dụng rộng rãi; Tôi nhận thức rõ về các lý do bạn phác thảo cho lỗi bộ nhớ cache, nhưng như tôi đã đề cập, chúng tôi đã xác định tính không hợp lệ của bộ đệm là vấn đề chính do mối tương quan mạnh mẽ mà chúng ta thấy giữa Com_select và Qcache_inserts. Ồ, và DB trong câu hỏi có sự pha trộn của INNODB và MyISAM.
Craig Sefton

Cập nhật với thông tin bổ sung mà bạn yêu cầu. Cảm ơn.
Craig Sefton

Cảm ơn đã trả lời, tôi mong muốn phần còn lại. Một trong những điều chúng tôi đã xác định là khoảng 18% truy vấn không được lưu trong bộ nhớ cache, vì vậy chắc chắn đánh giá cao lời khuyên liên quan đến cài đặt. Thật không may, hộp không dành riêng, nhưng các khuyến nghị của bạn sẽ giúp ích. Phân mảnh chắc chắn là một vấn đề là tốt. Tôi vẫn thực sự lo lắng về số lượng vô hiệu mà chúng ta đang thấy (trái ngược với các truy vấn hoàn toàn không được lưu trong bộ nhớ cache), vì vậy vẫn không chắc chắn liệu chi phí có đáng hay không. Thực sự đánh giá cao cái nhìn sâu sắc của bạn, cảm ơn bạn rất nhiều.
Craig Sefton

Về nhận xét của bạn về "mysql không có cơ chế nội bộ để chống phân mảnh bộ đệm truy vấn", bạn có thể thực thi lệnh FLUSH QUERY CACHEđể chống phân mảnh không? Xem: dev.mysql.com/doc/refman/5.0/en/flush.html
Craig Sefton

Đã cập nhật câu trả lời của tôi ...
RolandoMySQLDBA

3

BAD: query_cache_size = 1G

Tại sao? Bởi vì một thời gian tuôn ra sẽ mất bao lâu. Đó là, khi một số ghi xảy ra, toàn bộ 1GB sẽ được quét để tìm bất kỳ tham chiếu nào đến bảng đã được sửa đổi. QC càng lớn, điều này càng chậm. Tôi khuyên bạn nên kích thước không quá 50M, trừ khi dữ liệu của bạn hiếm khi thay đổi.

QC là chi phí chung cho cả MyISAM và InnoDB. Nó lấy ra một Mutex toàn cầu, và đưa nó ra quá sớm. Mutex này là một lý do mà MySQL không thể sử dụng hiệu quả hơn 8 lõi.

SQL_NO_CACHE không được chú ý cho đến khi Mutex bị khóa! Về việc sử dụng duy nhất cho cờ đó là cho điểm chuẩn.

Thường thì tốt hơn là cung cấp RAM cho một số bộ đệm khác.


2

Tôi có thể nghĩ ra một trường hợp hoàn hảo cho nó, và chúng tôi đã thử nghiệm kỹ lưỡng và vận hành nó trong sản xuất ... Tôi gọi đó là chiến lược phân cụm "làn đường nhanh" :

Nếu bạn thực hiện phân tách đọc-ghi với proxy như MaxScale hoặc ứng dụng của bạn có khả năng, bạn có thể gửi một số lần đọc cho các bảng hiếm khi chỉ bị vô hiệu hóa cho các nô lệ được bật bộ đệm truy vấn và phần còn lại cho các nô lệ khác với nó tắt đi

Chúng tôi thực hiện điều này và xử lý các cuộc gọi 4 triệu mỗi phút đến cụm trong quá trình kiểm tra tải của chúng tôi (không phải là điểm chuẩn ... thỏa thuận thực sự). Ứng dụng chờ trên master_pose_wait () cho một số thứ, do đó, nó được điều chỉnh bởi luồng sao chép và mặc dù chúng tôi đã thấy nó với trạng thái chờ đợi vô hiệu hóa Qcache với thông lượng rất cao, các mức thông lượng đó cao hơn cả cụm có khả năng không có Qcache.

Điều này hoạt động vì hiếm khi có bất cứ điều gì có liên quan trong bộ đệm truy vấn nhỏ trên các máy đó để vô hiệu hóa (những truy vấn đó chỉ liên quan đến các bảng được cập nhật không thường xuyên). Những hộp này là "làn đường nhanh" của chúng tôi. Đối với phần còn lại của các truy vấn mà ứng dụng thực hiện, họ không phải tranh luận với Qcache vì họ truy cập vào các hộp mà không bật.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.