자주 쿼리 캐시 무효화의 오버 헤드가 가치가 있습니까?


22

나는 현재 많은 데이터베이스에서 실행되는 많은 수의 INSERT, DELETE 및 UPDATE 문으로 인해 쿼리 캐시에서 많은 수의 무효화가 발생하는 MySQL 데이터베이스에서 작업하고 있습니다.

내가 결정하려고하는 것은 쿼리 캐시를 이러한 테이블에 대해 실행되는 SELECT 문에 사용할 수있는 이점이 있는지 여부입니다. 그들은 너무 빨리 무효화되기 때문에, 나에게 가장 좋은 것은이 테이블이있는 SELECT 문에서 SQL_NO_CACHE를 사용하는 것입니다.

빈번한 무효화의 오버 헤드가 가치가 있습니까?

편집 : 아래 @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 : OFF
  • 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을 다시 시작하십시오. 내가 왜 그렇게 제안하겠습니까? ???

쿼리 캐시는 항상 InnoDB와 충돌합니다. 수정이 다른 트랜잭션에 대한 반복 가능한 읽기에 영향을 미치지 않으면 InnoDB의 MVCC가 쿼리 캐시에서 쿼리를 제공 할 수 있다면 좋을 것입니다. 불행히도 InnoDB는 그렇게하지 않습니다. 분명히, 당신은 오히려 빨리 무효화되고 아마도 재사용되지 않는 많은 쿼리를 가지고 있습니다.

MySQL 4.0 미만의 InnoDB의 경우 트랜잭션에 대해 쿼리 캐시가 비활성화되었습니다. MySQL 4.1+의 경우, InnoDB는 테이블별로 쿼리 캐시에 대한 액세스를 허용 할 때 트래픽 경찰을 재생합니다.

귀하의 질문의 관점에서, 쿼리 캐시 제거의 정당화는 오버 헤드가 아니라 InnoDB가 그것을 관리하는 방법이라고 말합니다.

InnoDB가 쿼리 캐시와 상호 작용하는 방법에 대한 자세한 내용은 "고성능 MySQL (제 2 판)" 책 213-215 페이지를 참조하십시오 .

모든 데이터 또는 대부분의 데이터가 MyISAM 인 경우 SQL_NO_CACHE를 사용하는 원래 아이디어를 사용할 수 있습니다.

InnoDB와 MyISAM이 혼합 된 경우 캐시 미스가 얼마나 높은지에 따라 애플리케이션에 적합한 균형을 찾아야합니다. 실제로, 동일한 책의 209-210 페이지 는 캐시 누락에 대한 이유를 지적합니다.

  • 비 결정적 구조 (예 : CURRENT_DATE)를 포함하거나 결과 세트가 저장하기에 너무 커서 쿼리를 캐시 할 수 없습니다. 캐시 할 수없는 쿼리 유형 모두 Qcache_not_cached 상태 변수를 증가시킵니다.
  • 서버는 이전에 쿼리를 본 적이 없으므로 결과를 캐시 할 기회가 없었습니다.
  • 쿼리 결과는 이전에 캐시되었지만 서버에서 제거했습니다. 메모리를 확보하기에 메모리가 부족하거나 누군가 서버에 메모리를 제거하도록 지시했거나 무효화 되었기 때문에 이러한 상황이 발생할 수 있습니다.

캐시 할 수없는 쿼리가 거의없는 캐시 미스의 근본 원인은 다음과 같습니다.

  • 쿼리 캐시가 아직 준비되지 않았습니다. 서버가 캐시에 결과 세트를 채울 기회가 없었습니다.
  • 서버는 이전에는 보지 못한 쿼리를보고 있습니다. 반복되는 쿼리가 많지 않으면 캐시가 예열 된 후에도 발생할 수 있습니다.
  • 캐시 무효화가 많이 있습니다.

업데이트 2012-09-06 10:10 EDT

최신 업데이트 정보 query_cache_limit를보고 1048576 (1M)로 설정했습니다. 결과 집합을 1M로 제한합니다. 더 큰 것을 검색하면 캐시되지 않습니다. 당신이 한 있지만 query_cache_size104857600 (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

RAM은 23G입니다. 나는 다음을 제기 할 것이다 :

  • innodb_buffer_pool_size = 12G
  • key_buffer_size = 4G

그것은 7G를 떠난다. OS 및 DB 연결에 적합해야합니다.

키 버퍼는 MyISAM 인덱스 페이지 만 캐시하고 InnoDB 버퍼 풀은 데이터와 인덱스를 캐시합니다.

한 가지 더 권장 사항 : MySQL 5.5로 업그레이드하여 여러 CPU에 대해 InnoDB를 구성하고 읽기 / 쓰기 I / O에 대해 여러 스레드를 구성 할 수 있습니다.

InnoDB 용 다중 CPU 액세스와 함께 MySQL 5.5 사용에 대한 이전 게시물을 참조하십시오.

업데이트 2012-09-06 14:56 EDT

쿼리 캐시를 지우는 방법은 캐시 된 데이터를 호스 핑하고 완전히 다른 RAM 세그먼트를 형성하기 때문에 다소 극단적입니다. 당신이 당신의 의견에서 지적했듯이 FLUSH QUERY CACHE(당신이 제안한대로) 또는 심지어 RESET QUERY CACHE더 좋을 것입니다. 명확히하기 위해, "내부 메커니즘 없음"이라고 말했을 때, 나는 정확히 그 의미를 가졌습니다. 조각 모음이 필요하며 수동으로 수행해야합니다. crontab'd이어야 합니다.

MyISAM보다 InnoDB에서 DML (INSERT, UPDATE, DELETE)을 더 자주 수행한다면 쿼리 캐시를 완전히 제거한다고 말하고 싶습니다.


답변 주셔서 감사합니다. 나는 그 책을 가지고 있고 그것을 광범위하게 사용하고있다. 캐시 누락에 대해 설명하는 이유를 잘 알고 있지만 앞서 언급했듯이 Com_select와 Qcache_inserts 사이의 강력한 상관 관계로 인해 캐시 무효화가 주요 문제로 이미 식별되었습니다. 아, 그리고 문제의 DB에는 INNODB와 MyISAM이 혼합되어 있습니다.
Craig Sefton

요청한 추가 정보로 업데이트되었습니다. 감사.
Craig Sefton

답변 주셔서 감사합니다, 나는 나머지를 기대합니다. 우리가 확인한 것 중 하나는 약 18 %의 쿼리가 캐싱되지 않았기 때문에 설정에 대한 조언을 확실히 읽어보십시오. 불행히도 상자는 전용이 아니지만 권장 사항이 도움이 될 것입니다. 조각화도 분명히 문제입니다. 나는 여전히 우리 가보고있는 무효화의 수에 대해 정말로 걱정하고 있습니다 (전혀 캐시되지 않은 쿼리와는 대조적으로), 오버 헤드가 가치가 있는지 여부는 여전히 확실하지 않습니다. 당신의 통찰력을 정말로 고맙게 생각합니다. 대단히 감사합니다.
Craig Sefton

"mysql에는 쿼리 캐시 조각 모음을위한 내부 메커니즘이 없습니다"에 대한 의견과 관련하여 조각 모음 명령 FLUSH QUERY CACHE을 실행할 수 없습니까? dev.mysql.com/doc/refman/5.0/en/flush.html
크레이그 세프 턴

내 답변을 업데이트 ...
RolandoMySQLDBA

3

나쁨 : query_cache_size = 1G

왜? 세척 시간이 오래 걸리기 때문입니다. 즉, 일부 쓰기가 발생하면 수정 된 테이블에 대한 참조를 찾기 위해 전체 1GB가 스캔됩니다. QC가 클수록 속도는 느려집니다. 데이터가 거의 변하지 않는 한 50M 이하의 크기를 권장합니다.

QC는 MyISAM과 InnoDB 모두에 대한 오버 헤드입니다. 전역 Mutex를 꺼내고 너무 빨리 꺼냅니다. 이 뮤텍스는 MySQL이 약 8 개 이상의 코어를 효과적으로 사용할 수없는 이유 중 하나입니다.

SQL_NO_CACHE가 될 때까지 발견되지 않은 뮤텍스가 잠겨! 해당 플래그의 유일한 용도는 벤치마킹입니다.

RAM을 다른 캐시에 제공하는 것이 더 좋습니다.


2

완벽한 사례를 생각할 수 있으며 철저히 테스트하여 프로덕션 환경에서 실행했습니다. "고속 레인" 클러스터링 전략 이라고 합니다.

MaxScale과 같은 프록시를 사용하여 읽기 / 쓰기 분할을 수행하거나 응용 프로그램을 사용할 수있는 경우 쿼리 캐시가 켜져있는 슬레이브에만 거의 유효하지 않은 테이블에 대한 일부 읽기를 보내고 나머지는 다른 슬레이브에 보낼 수 있습니다 껐다.

결과적으로로드 테스트 (벤치 마크가 아닌 실제 거래) 동안 클러스터에 대한 분당 4M 호출을 처리합니다. 응용 프로그램은 master_pos_wait ()에서 몇 가지를 기다리므로 복제 스레드에 의해 조절되며 매우 높은 처리량에서 Qcache 무효화 대기 상태로 보았지만 처리량 수준은 클러스터보다 높음 Qcache없이 가능합니다.

무효화 할 머신의 작은 쿼리 캐시에는 관련성이 거의 없기 때문에 작동합니다 (이러한 쿼리는 자주 업데이트되지 않는 테이블에만 관련됨). 이 상자는 "빠른 차선"입니다. 응용 프로그램이 수행하는 나머지 쿼리의 경우 Qcache는 켜져 있지 않은 상태에서 상자로 이동하기 때문에 Qcache와 경쟁 할 필요가 없습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.