ySQL5.1의 QueryCache가 멀티 코어 환경에 미치는 영향 조사

13981 단어 MySQL
2019.1.24 추기
ySQL이 느린 시스템은 결국 index를 사용하지 않는 업데이트 조회가 던져져 전체 스캐닝이 실행 중입니다.그럼에도 불구하고 CPU와 메모리는 거의 사용되지 않아 이해하기 어렵다...쿼리 1개, 스레드 1개로 CPU 활용도가 평균화됩니까?
2019.1.22 추기
비즈니스 환경에 적용되지만 늦어서 아쉽지만...
따라서 참고 정보로 보도된 것이다.
show processlist;에서 "Sending data"로 표시되는 update a.b ignore index(b) c.d 조회는 5개 정도의 2자리~3자리로 실행 중이며, SELECT 조회는 Lock 상태입니다.이유가 뭐야...교환이 없으니까 NUMA가 아니라...
MySQL5.1(MyISAM)을 사용하는 이전 시스템은 낮과 비교하면 매우 느리다.
요청부터 응답까지 60초면 됩니다. 항상 시간을 초과합니다.

ySQL 느린 시스템 - 운영 체제 조사


top와 vmstat을 통해 알게 된 것은 다음과 같다.
  • CPU16 스레드의 사용률은 평균 30% 정도이며 여유 있음
  • I/O Wait 및 네트워크 활용도 1비트 내외로 문제 없음
  • 로드 평균은 0.4로 낮지만 실행을 기다리는 프로세스 수는 4-8 사이를 배회한다
  • 하드웨어에 병목이 없다는 얘기다.
    고려할 수 있는 것은 소프트웨어가 멀티코어를 지원하지 않는다는 것입니까?버퍼 부족?
    index가 설정되지 않았습니다. 전체 스캐닝이 실행 중일 수 있습니다. 하지만 그때는 CPU가 모두 사용되지 않았습니까?

    ySQL 느린 시스템. - MySQL 조사.


    mysql에 로그인하여 showprocesslist 보기
  • 업데이트 조회가 수십 초 실행 중
  • select 조회 대기 잠금 해제
  • 이것은 무엇입니까?이렇게 생각하다가 Query Cache가 축소되지 않는다는 기사를 몇 편 발견했다.
    캐시를 검색하는 게 낫지 않을까요?
    쿼리 캐시 업데이트로 글로벌 잠금 해제
    예를 들어 사용자 행위력 등 파라미터를 포함하는 인용과 업데이트가 많은 테이블에 조회 캐시를 사용하면 가까스로 많은 핵심을 불러온 고성능 서버도 성능이 전혀 없다.
    전역 잠금이 설정된 상태에서 4개의 UPDATE를 던져도 하나씩 처리할 수 있고 SQL 하나는 하나의 스레드로 처리할 수 있습니다.
    따라서 멀티 코어 CPU를 탑재하더라도 단일 스레드와 동일한 성능으로 병렬 처리할 수 없습니다.
    제2회 ioDrive+MySQL 학습회 @ 외도 아버지 ioDrive의 세계에 오신 것을 환영합니다.
  • ioDrive의 부작용?ioDrive를 넣었기 때문에 기준을 잡으려고 했지만 성능이 전혀 없어서 CPU가 끊긴 것 같아요!용량: 1600% 기준: 최대 350%
  • 범인은query_cache,query_cache를 사용하지 않으면 프로세서가 최대값으로 실행됩니다
  • 그야말로 CPU가 막힌 느낌!!!
    ySQL – 간단한 업데이트가 느릴 때가 있습니다.
    showprocesslist를 몇 번 실행한 후에 이상한 녀석이 나타났다.
    이름도 "Waiting for query cache lock"!
    우리 집 쇼 프로세스에서는 찾을 수 없지만 의심스럽기 그지없어요...
    느린 시스템 my.cnf에는 QueryCacheSize 설정이 포함되어 있습니다.
    그렇다면QueryCache는 어느 정도까지 영향을 미칠지 정식 응용 전에 mysqlslap을 사용하여 검증하기로 했습니다.

    결과


    Query Cache는 효과가 있으면 굉장히 느려요!!!

    빠른 캐시 해제

    mysql> SET @@global.query_cache_size=0;
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> show variables like 'query%';
    +------------------------------+---------+
    | Variable_name                | Value   |
    +------------------------------+---------+
    | query_alloc_block_size       | 8192    |
    | query_cache_limit            | 1048576 |
    | query_cache_min_res_unit     | 4096    |
    | query_cache_size             | 0       |
    | query_cache_type             | ON      |
    | query_cache_wlock_invalidate | OFF     |
    | query_prealloc_size          | 8192    |
    +------------------------------+---------+
    7 rows in set (0.00 sec)
    
    [root@localhost ~]# ./slap2.sh 
    Benchmark
            Running for engine myisam
            Average number of seconds to run all queries: 2.336 seconds
            Minimum number of seconds to run all queries: 2.302 seconds
            Maximum number of seconds to run all queries: 2.358 seconds
            Number of clients running queries: 10
            Average number of queries per client: 10000
    

    기준 중의 showfull processlist를 보겠습니다.
    먼저 차트에서 0:00:02 시 INSERT 쿼리가 실행 중입니다.이곳의 CPU 사용률은 40퍼센트도 안 된다.
    2171        root    localhost       mysqlslap       Query   0       closing tables  INSERT INTO t1 VALUES (NULL,840098998,1711081283,898581402,408461159,1316988559,1222118486,276120047,1045280395,1270820277,1209004130,'QOPe8XYkIYviP1FTsAJh99xj88Av4zmMN30NQO7kwvIEoZjgcuEd43LCBN07MeTdhT07uzkiu2wiSXFwQLPMOmab9QbN440dQsdCsLueFjDbESXYhxu5bLYdf70k4t','LWlyiTBc8RBL2QhQqMFdRqqrJTzC535RZiH7CTjCwvZqDEGvcXOvEEmZcdlhYi8xHQ4LngZjR6ZgCiRo5sbJyLlarW8N5GLMaPjL5GwOEMwQ4O698hL6u6ZlSh9PpM','nGfMTdWQ1kgy2kM8lWhySc41DPaMqOcWgGk9tFRuz7sur62TScRxCOqHhPYNp8lLOWWHly4cxwWhvPAN1TC5l3MIKmi9vRMJpkTaiZ3YLZDGqNgjksgMn3g7pM8ciW','wXFHypq1LBQaSHp00ashwgccnHrwmPIioZrmNhnck6BCN0CFQxoEdGjGQa4CrNufwlQBI5o2Br7QrBaA8MOdX7uxZq9ODv42YM5qRtkXcrxKvNW3euZ9uJ6J9FkF2g','Ha2EGT00sckiwf5QajDzszIqISx2bzakZcypyyiqbIONpWqN5vFquZg4tezSdZC3A3k01QiSc7sPTahaTwGFTxJFRIjwsozurcmsuSDXR5wwfTN8PfFnSa2vtdkdPb','N8B9t6d6d53PtivGiCoxr8Xt4GNglgF8pRHaZvg2sjRdHEuzRaoIiB4eKJI5zQEgtXEIImCALfoemaT509NiLJDhWNmWp02iO9siv4l9cPnMr9RrIiPXueCO2rmrjh','Q7qAqdFbmjsQ5jROal6r90WLHO43FokZvQkd4r4iaw0XfRv551xEuJRBjY6qCrO790lDrhwHeoo9GjFLc4RWNuZ6IYwWFCeO4FevoQ4QEscMRjb4f2Q2x007Yoen18','35Nht3zpW6iyS9Z45CyY6vO63ouZRnhWlwCWz3JL91JW3kQ8wOY2Cw07kvgBaLiJ9mp8p1Wr2hDxQfyMvWH7RH6B4mNXzxq8jY9OZf7RKKHerFtnlAmCJtGGXXnXST','XB1gRQBbmOn32fIvI3xw8HpOZDvKcFp7Ijgl1jKn70qAf8xx4vtCCbSdgFpGWWFo5nP7Xeueelg9leypZjtdIL6ySv6qHMWN9wWYaOB41jDnLBSmuMF5bLvw82mQGH','pHDJqfbtbTco8qrcSlqciIpeEyY0OgH5xMGftjYSC1GKrzpBdfnJxdp3bD4rtDojcwETffqkgy4NylabPEmErcIIhE1RRh2vdGHGv70bxxyviPMzf96MdGgIWZlpEn')
    
    0:00:08에 여러 개의 SELECT 쿼리가 실행 중입니다.여기서 CPU를 다 썼어요!
    2182        root    localhost       mysqlslap       Query   0       Writing to net  SELECT intcol1,intcol2,intcol3,intcol4,intcol5,intcol6,intcol7,intcol8,intcol9,intcol10,charcol1,charcol2,charcol3,charcol4,charcol5,charcol6,charcol7,charcol8,charcol9,charcol10 FROM t1 WHERE id =  '70367'
    2183        root    localhost       mysqlslap       Query   0       statistics      SELECT intcol1,intcol2,intcol3,intcol4,intcol5,intcol6,intcol7,intcol8,intcol9,intcol10,charcol1,charcol2,charcol3,charcol4,charcol5,charcol6,charcol7,charcol8,charcol9,charcol10 FROM t1 WHERE id =  '83375'
    2184        root    localhost       mysqlslap       Query   0       Writing to net  SELECT intcol1,intcol2,intcol3,intcol4,intcol5,intcol6,intcol7,intcol8,intcol9,intcol10,charcol1,charcol2,charcol3,charcol4,charcol5,charcol6,charcol7,charcol8,charcol9,charcol10 FROM t1 WHERE id =  '1983'
    ...
    

    빠른 캐시 설정

    mysql> SET @@global.query_cache_size=128*1024*1024;
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> show variables like 'query%';
    +------------------------------+-----------+
    | Variable_name                | Value     |
    +------------------------------+-----------+
    | query_alloc_block_size       | 8192      |
    | query_cache_limit            | 1048576   |
    | query_cache_min_res_unit     | 4096      |
    | query_cache_size             | 134217728 |
    | query_cache_type             | ON        |
    | query_cache_wlock_invalidate | OFF       |
    | query_prealloc_size          | 8192      |
    +------------------------------+-----------+
    7 rows in set (0.00 sec)
    
     [root@localhost ~]# ./slap2.sh 
    Benchmark
            Running for engine myisam
            Average number of seconds to run all queries: 10.559 seconds
            Minimum number of seconds to run all queries: 10.488 seconds
            Maximum number of seconds to run all queries: 10.613 seconds
            Number of clients running queries: 10
            Average number of queries per client: 10000
    

    0:00:02의 INSERT 질의입니다.이것은 QC가 잘못되었을 때의 경향과 변화가 없다.
    2471        root    localhost       mysqlslap       Query   0       closing tables  INSERT INTO t1 VALUES (NULL,840098998,1711081283,898581402,408461159,1316988559,1222118486,276120047,1045280395,1270820277,1209004130,'QOPe8XYkIYviP1FTsAJh99xj88Av4zmMN30NQO7kwvIEoZjgcuEd43LCBN07MeTdhT07uzkiu2wiSXFwQLPMOmab9QbN440dQsdCsLueFjDbESXYhxu5bLYdf70k4t','LWlyiTBc8RBL2QhQqMFdRqqrJTzC535RZiH7CTjCwvZqDEGvcXOvEEmZcdlhYi8xHQ4LngZjR6ZgCiRo5sbJyLlarW8N5GLMaPjL5GwOEMwQ4O698hL6u6ZlSh9PpM','nGfMTdWQ1kgy2kM8lWhySc41DPaMqOcWgGk9tFRuz7sur62TScRxCOqHhPYNp8lLOWWHly4cxwWhvPAN1TC5l3MIKmi9vRMJpkTaiZ3YLZDGqNgjksgMn3g7pM8ciW','wXFHypq1LBQaSHp00ashwgccnHrwmPIioZrmNhnck6BCN0CFQxoEdGjGQa4CrNufwlQBI5o2Br7QrBaA8MOdX7uxZq9ODv42YM5qRtkXcrxKvNW3euZ9uJ6J9FkF2g','Ha2EGT00sckiwf5QajDzszIqISx2bzakZcypyyiqbIONpWqN5vFquZg4tezSdZC3A3k01QiSc7sPTahaTwGFTxJFRIjwsozurcmsuSDXR5wwfTN8PfFnSa2vtdkdPb','N8B9t6d6d53PtivGiCoxr8Xt4GNglgF8pRHaZvg2sjRdHEuzRaoIiB4eKJI5zQEgtXEIImCALfoemaT509NiLJDhWNmWp02iO9siv4l9cPnMr9RrIiPXueCO2rmrjh','Q7qAqdFbmjsQ5jROal6r90WLHO43FokZvQkd4r4iaw0XfRv551xEuJRBjY6qCrO790lDrhwHeoo9GjFLc4RWNuZ6IYwWFCeO4FevoQ4QEscMRjb4f2Q2x007Yoen18','35Nht3zpW6iyS9Z45CyY6vO63ouZRnhWlwCWz3JL91JW3kQ8wOY2Cw07kvgBaLiJ9mp8p1Wr2hDxQfyMvWH7RH6B4mNXzxq8jY9OZf7RKKHerFtnlAmCJtGGXXnXST','XB1gRQBbmOn32fIvI3xw8HpOZDvKcFp7Ijgl1jKn70qAf8xx4vtCCbSdgFpGWWFo5nP7Xeueelg9leypZjtdIL6ySv6qHMWN9wWYaOB41jDnLBSmuMF5bLvw82mQGH','pHDJqfbtbTco8qrcSlqciIpeEyY0OgH5xMGftjYSC1GKrzpBdfnJxdp3bD4rtDojcwETffqkgy4NylabPEmErcIIhE1RRh2vdGHGv70bxxyviPMzf96MdGgIWZlpEn')
    
    0:00:08 SELECT 조회CPU 사용률이 떨어지다니!
    2483        root    localhost       mysqlslap       Query   0       init    SELECT intcol1,intcol2,intcol3,intcol4,intcol5,intcol6,intcol7,intcol8,intcol9,intcol10,charcol1,charcol2,charcol3,charcol4,charcol5,charcol6,charcol7,charcol8,charcol9,charcol10 FROM t1 WHERE id =  '29930'
    2484        root    localhost       mysqlslap       Query   0       freeing items   SELECT intcol1,intcol2,intcol3,intcol4,intcol5,intcol6,intcol7,intcol8,intcol9,intcol10,charcol1,charcol2,charcol3,charcol4,charcol5,charcol6,charcol7,charcol8,charcol9,charcol10 FROM t1 WHERE id =  '63499'
    2485        root    localhost       mysqlslap       Query   0       NULL    SELECT intcol1,intcol2,intcol3,intcol4,intcol5,intcol6,intcol7,intcol8,intcol9,intcol10,charcol1,charcol2,charcol3,charcol4,charcol5,charcol6,charcol7,charcol8,charcol9,charcol10 FROM t1 WHERE id =  '16266'
    ...
    
    ※ 단, 느려지는 것은 auto-generate-sql-load-type=key의 경우입니다.다른 mixed와 write 등 조건에서 변화가 없습니다.아마도 MyISAM이 쓰기 클래스 조회를 실행할 때 표를 잠그기 때문일 것입니다.

    환경 확인


    ESXi6.0으로 제작된 VM
  • Intel(R) Core(TM) i5-2500S CPU @ 2.70GHz (4 cores)
  • MemTotal: 8062732 kB
  • Red Hat Enterprise Linux Server release 6.1 (Santiago)
  • mysql Ver 14.14 Distrib 5.1.52, for redhat-linux-gnu (x86_64) using readline 5.1
  • 검증 방법

  • MySQL 명령을 통해 QueryCacheSize를 0으로 설정(MySQL 기본값)
  • 셸스크립트를 통해 vmstat, showstats, showprocesslist
  • mysqlslap 실행, 종료 대기
  • MySQL 명령을 통해 QueryCacheSize를 128MB
  • 로 설정
  • 2 ~ 3
  • 도표는 상술한 시간적 기록을 같은 시간에 서로 성형한 후 Excel로 작성한 것이다.

    my.cnf

    [root@localhost ~]# cat /etc/my.cnf
    [mysqld]
    disable-innodb
    #query_cache_size=4M
    #performance_schema=on
    datadir=/var/lib/mysql
    socket=/var/lib/mysql/mysql.sock
    user=mysql
    # Disabling symbolic-links is recommended to prevent assorted security risks
    symbolic-links=0
    
    [mysqld_safe]
    log-error=/var/log/mysqld.log
    pid-file=/var/run/mysqld/mysqld.pid
    

    mysqlslap

    [root@localhost ~]# cat ./slap2.sh 
    mysqlslap \
     --no-defaults --auto-generate-sql --engine=myisam --auto-generate-sql-add-autoincrement \
     --host=localhost --port=3306 -u root \
     --number-int-cols=10 \
     --number-char-cols=10 \
     --iterations=10 \
     --concurrency=10 \
     --auto-generate-sql-write-number=100000 \
     --number-of-queries=100000 \
     --auto-generate-sql-load-type=key
    

    show status

    [root@localhost ~]# cat stats.sh 
    #!/bin/bash
    
    #mysql -u root show status;
    
    while :
    do 
      _line=`echo 'show status' | mysql -u root`
      _date=`date '+%Y/%m/%d %H:%M:%S'`
    
      echo "${_line}" | while read line
      do
          echo "${_date} $line"
      done
      sleep 1
    done
    
    실행 결과
    2019/01/21 00:24:04 Variable_name       Value
    2019/01/21 00:24:04 Aborted_clients     1
    2019/01/21 00:24:04 Aborted_connects    0
    2019/01/21 00:24:04 Binlog_cache_disk_use       0
    2019/01/21 00:24:04 Binlog_cache_use    0
    ...
    

    show processlist

    [root@localhost ~]# cat processlist.sh 
    #!/bin/bash
    
    #mysql -u root show full processlist;
    
    while :
    do 
      _line=`echo 'show full processlist' | mysql -u root`
      _date=`date '+%Y/%m/%d %H:%M:%S'`
    
      echo "${_line}" | while read line
      do
          echo "${_date} $line"
      done
      sleep 1
    done
    
    실행 결과
    2019/01/21 00:24:12 2181        root    localhost       NULL    Query   0       NULL    show full processlist
    2019/01/21 00:24:13 Id  User    Host    db      Command Time    State   Info
    2019/01/21 00:24:13 2171        root    localhost       mysqlslap       Sleep   1               NULL
    2019/01/21 00:24:13 2182        root    localhost       mysqlslap       Query   0       Writing to net  SELECT intcol1,intcol2,intcol3,intcol4,intcol5,intcol6,intcol7,intcol8,intcol9,intcol10,charcol1,charcol2,charcol3,charcol4,charcol5,charcol6,charcol7,charcol8,charcol9,charcol10 FROM t1 WHERE id =  '70367'
    ...
    

    vmstats

    vmstat -n 1 | gawk '{ print strftime("%Y/%m/%d %H:%M:%S"), $0 } { fflush() }' 
    
    실행 결과
    2019/01/21 00:23:58 procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu-----
    2019/01/21 00:23:58  r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
    2019/01/21 00:23:58  1  0      0 7480888  58500 201656    0    0     0     0   88   66  1  0 98  0  0   
    2019/01/21 00:23:59  0  0      0 7480244  58500 201660    0    0     0     0  148   90  0  0 100  0  0  
    2019/01/21 00:24:00  0  0      0 7480096  58500 201660    0    0     0     0  282  210  0  0 100  0  0  
    ...
    

    결론


    ySQL의 QueryCache는 기본적으로 사용됩니다.

    좋은 웹페이지 즐겨찾기