현상
서비스 도중 swap을 사용하여 서비스 지연발생
원인
OS상 numa가 활성화 되어 있으나 mysql에서는 사용하지 않도록 설정되어, node간 균등하지 않게 memory를 사용함.
memory를 많이 사용한 node에서 memory가 부족하다고 판단하여 swap을 사용하여 처리 지연 발생
분석
swap 사용 유무 체크
3.4G swap 사용중
~]# free -h total used free shared buff/cache available Mem: 62G 53G 3.6G 3.1G 4.9G 4.7G Swap: 4.0G 3.4G 645M |
OS numa 사용 확인
numa를 사용하는 경우 node 0, node 1 두개로 표현됨
아래 경우는 OS상 numa를 사용하는 형태
node 0 free : 208MB
node 1 free : 3123MB
~]# numactl --hardware available: 2 nodes (0-1) node 0 cpus: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 node 0 size: 32436 MB node 0 free: 208 MB node 1 cpus: 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 node 1 size: 32767 MB node 1 free: 3123 MB node distances: node 0 1 0: 10 21 1: 21 10 |
numa 메모리 실제 사용량 확인
Active(anon)이 App에서 할당하여 사용하는 메모리
아래는 20G, 15G로 불균현 확인됨
node 0 : 20G 사용중 8G Free
node 1 : 15G 사용중 8G Free
~]# numastat -cm
Per-node system memory usage (in MBs): Node 0 Node 1 Total ------ ------ ----- MemTotal 32436 32768 65204 MemFree 8271 8287 16558 MemUsed 24165 24481 48646 Active 20294 16002 36296 Inactive 2359 7289 9648 Active(anon) 20275 15289 35564 Inactive(anon) 2338 6588 8926 Active(file) 19 713 732 Inactive(file) 21 701 723 Unevictable 0 0 0 Mlocked 0 0 0 Dirty 0 0 0 Writeback 0 0 0 FilePages 126 5531 5657 Mapped 1 114 115 AnonPages 22528 17760 40288 Shmem 1 3205 3206 KernelStack 7 38 46 PageTables 43 69 112 NFS_Unstable 0 0 0 Bounce 0 0 0 WritebackTmp 0 0 0 Slab 206 210 416 SReclaimable 144 66 210 SUnreclaim 62 144 206 AnonHugePages 2 0 2 HugePages_Total 0 0 0 HugePages_Free 0 0 0 HugePages_Surp 0 0 0 |
mysqld에서 사용하는 numa 메모리 확인
mysql pid 확인 --> mysql
node 0 : 22G
node 1 : 17G
~]# ps -ef | grep mysql mysql 50416 1 0 Mar03 ? 00:00:00 ~~~/mysql/bin/mysqld_safe --defaults-file=~~~/my.cnf --pid-file=~~~mysql.pid mysql 51489 50416 7 Mar03 ? 11-03:43:53 ~~~/mysql/bin/mysqld --defaults-file=~~~/my.cnf --basedir=~~~/mysql --datadir=~~~/data/ ~~~~~~( 실행 옵션 )~~~~~~~~~
~]# numastat 51489
Per-node process memory usage (in MBs) for PID 51489 (mysqld) Node 0 Node 1 Total --------------- --------------- --------------- Huge 0.00 0.00 0.00 Heap 9.57 13.82 23.39 Stack 0.00 0.02 0.02 Private 22322.57 17031.40 39353.97 ---------------- --------------- --------------- --------------- Total 22332.15 17045.23 39377.38 |
node별 메모리 사용량 확인
node0은 local_node사용이 높고
node1은 other_node사용이 높음
~]# numastat node0 node1 numa_hit 3671867451 16116171368 numa_miss 47375279 12004935107 numa_foreign 12004935107 47375279 interleave_hit 20488 19934 local_node 3671943494 16124076268 other_node 47299236 11997030207 |
MySQL numa 설정 확인
innodb_numa_interleave OFF 로 설정되어 있지 않음
만약 ON으로 변경 시, mysql 재시작 필요
mysql> show variables like '%numa%'; +------------------------+-------+ | Variable_name | Value | +------------------------+-------+ | innodb_numa_interleave | OFF | +------------------------+-------+ 1 row in set (0.00 sec) |
OS numa policy 확인
default 청잭으로 numa 사용중 ( default 정책의 경우 app이 설치된 node를 우선적으로 할당하는 구조 )
cpu는 64개
~]# numactl --show policy: default preferred node: current physcpubind: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 cpubind: 0 1 nodebind: 0 1 membind: 0 1 |
numa 정책 옵션 설정
bind : 특정 node 에서 메모리를 할당 받도록 강제하는 정책
preferred : 특정 node 에서 메모리를 먼저 할당 받도록 하는 정책, 해당 node 메모리가 부족할 경우 다른 node 에서 할당
interleave : 여러 node 에서 균등하게 할당받도록 하는 정책
Option
|
Descriptions
|
--membind=nodes, -m nodes
|
지정된 노드에 있는 메모리만 할당
해당 노드 메모리가 모두 차면 swap이 발생한다.
|
--cpunodebind=nodes, -N nodes
|
지정된 노드에 있는 CPU에서만 프로세스가 돌아가도록 설정
메모리 할당도 해당 노드해서만 이루어진다. 메모리의 지역성으로 성능이 올라갈 수 있지만, 반대쪽 노드의 CPU를 잘 활용하지 못하는 단점이 있다.
membind 보다 장점은 더이상 지정된 노드에 메모리가 없으면 다른 노드의 메모리를 활용한다는 점이다.
|
--physcpubind=cpus, -C cpus
|
cpunodebind 와 다른점은 노드를 지정하지 않고 CPU 번호를 지정한다.
즉 node0, node1에 있는 CPU들을 지정할 수 있다.
|
--preferred=node
|
지정된 노드에 있는 메모리를 우선적으로 할당
membind와 차이점은 지정된 노드의 메모리가 차면 다른 노드의 메모리를 활용한다. 상황에 따라서는 cpunodebind 와 다르지 않게 동작할 수도 있다.
|
--interleave=nodes, -i nodes
|
지정된 여러 노드에서 공평하게 메모리를 할당 (라운드로빈)
all 로 하면 모든 노드로 분배된다.
|
예제) numactl --physcpubind=+0-4,8-12 myapplic arguments Run myapplic on cpus 0-4 and 8-12 of the current cpuset. numactl --interleave=all bigdatabase arguments Run big database with its memory interleaved on all CPUs. numactl --cpubind=0 --membind=0,1 process Run process on node 0 with memory allocated on node 0 and 1. numactl --cpubind=0 --membind=0,1 -- process -l Run process as above, but with an option (-l) that would be confused with a numactl option. numactl --preferred=1 numactl --show Set preferred node 1 and show the resulting state. numactl --interleave=all --shmkeyfile /tmp/shmkey Interleave all of the sysv shared memory region specified by /tmp/shmkey over all nodes. numactl --offset=1G --length=1G --membind=1 --file /dev/shm/A --touch Bind the second gigabyte in the tmpfs file /dev/shm/A to node 1. numactl --localalloc /dev/shm/file Reset the policy for the shared memory file file to the default localalloc policy. |
대응
1. OS와 MySQL 둘다 numa를 사용하거나, 사용하지 않도록 설정을 맞추어줌
>> OS 설정 변경을 위해서는 장비 재시작, MySQL 설정 변경을 위해서는 DB 재시작이 필요함.
서비스 도중이라, 이후 점검시 진행
2. OS 물리 메모리 free공간을 확보.
>> 배치량이 많지 않아, MySQL memory buffer pool을 줄여 물리 메모리 공간 확보
3. numa 사용으로 불균등하게 메모리가 사용되어 swap이 발생함.
cpu와 memory를 효율적으로 사용하지 못하겠지만 최대한 swap을 사용하지 않도록 하기 위해 아래 설정을 실행
numactl --interleave=all mysqld
참고
https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=sory1008&logNo=221222077917