현상

서비스 도중 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


to Top