메모리 증설 포인트

EnoSoup·2021년 7월 26일
0

Linux

목록 보기
12/15
post-thumbnail

리눅스 서버 메모리 증설 포인트 확인 방법

# swap 영역 확인
	      total        used        free      shared  buff/cache   available
Mem:       16122556    14116980      218736         360     1786840     1735812
Swap:      20971516      768256    20203260

# swap영역은 물리 메모리 사용영역이 부족할 경우를 대비해 만들어 놓은 영역, 메모리 부족할 경우
# disk I/O 작업을 진행하기 때문에 메모리 작업과 비교했을 때 처리속도가 느려진다. swap영역을 사용 할
# 경우 시스템 성능 저하가 일어난다.
# 만일 해당 시스템이 swap 영역을 사용한다는 것 자체가 시스템 메모리 부족한 이유로 사용한다는 의미이기
# 때문에 어떤 프로세스가 메모리를 사용하는지 확인해 볼 필요가 있다.
# 해결책 : 서비스 용도가 아닌 관리 용도의 프로세스에 메모리 누수가 있어 메모리를 점유하려 하고, 그 과정
#        에서 swap 영역을 사용하고 있을 수도 있기 때문에 구별해서 해당 프로세스를 죽여 메모리 부족현상
#        으로 인한 성능저하를 해결할 수 있다.

1. proc 파일 시스템 smaps 파일확인
# 예제) mongodb-server
$ ps -ef | grep mongod
root      2070  2038 36  3월09 ?      2-20:44:38 mongod -f /etc/mongod.conf

$ sudo su cd /proc/2070/ && cat smaps | more
3a8206932000-3a8246932000 ---p 00000000 00:00 0
Size:            1048576 kB
KernelPageSize:        4 kB
MMUPageSize:           4 kB
Rss:                   0 kB
Pss:                   0 kB
Shared_Clean:          0 kB
Shared_Dirty:          0 kB
Private_Clean:         0 kB
Private_Dirty:         0 kB
Referenced:            0 kB
Anonymous:             0 kB
LazyFree:              0 kB
AnonHugePages:         0 kB
ShmemPmdMapped:        0 kB
Shared_Hugetlb:        0 kB
Private_Hugetlb:       0 kB
Swap:                  0 kB
SwapPss:               0 kB
Locked:                0 kB
ProtectionKey:         0
VmFlags: mr mw me sd
55921703e000-55921a801000 r-xp 00000000 103:04 620757098                 /usr/bin/mongod
Size:              57100 kB
KernelPageSize:        4 kB
MMUPageSize:           4 kB
Rss:               10992 kB

# 위 mongodb 프로세스는 Swap 영역을 사용하고 있는 것이 없다.
# 해당 프로세스의 논리적 메모리 "3a8206932000-3a8246932000" 사이에 있는 메모리 크기는 "1048576 kB" 이며,
# swap 영역에는 없다.

# 예제) mongodb-server docker 프로세스 확인
$ ps -ef | grep docker
root      2038 22020  0  3월09 ?      00:00:17 containerd-shim -namespace ...

$ cd /proc/22020/ && cat smaps | more
c000000000-c000200000 rw-p 00000000 00:00 0
Size:               2048 kB
KernelPageSize:        4 kB
MMUPageSize:           4 kB
Rss:                1168 kB
Pss:                1168 kB
Shared_Clean:          0 kB
Shared_Dirty:          0 kB
Private_Clean:         0 kB
Private_Dirty:      1168 kB
Referenced:         1160 kB
Anonymous:          1168 kB
LazyFree:              0 kB
AnonHugePages:         0 kB
ShmemPmdMapped:        0 kB
Shared_Hugetlb:        0 kB
Private_Hugetlb:       0 kB
Swap:                592 kB
SwapPss:             592 kB
Locked:                0 kB
ProtectionKey:         0
VmFlags: rd wr mr mw me ac sd
c000200000-c000a00000 rw-p 00000000 00:00 0
Size:               8192 kB
KernelPageSize:        4 kB
MMUPageSize:           4 kB
Rss:                3052 kB
Pss:                3052 kB

# 하지만 mongodb를 운영중인 docker 데몬을 보면 "592kB"가 swap 영역에 있다.

2. 전체 프로세스 swap 메모리 확인방법
# smem 유틸리티 설치
$ sudo amazon-linux-extras install epel
$ sudo yum -y install smem

# smem 조회
$ sudo smem -t
	PID User     Command                         Swap      USS      PSS      RSS
 7955 root     tail -f mongod.log.1 -n 200       92        4       17      196
 7954 root     sudo tail -f mongod.log.1 -     1140        4       21      252
 4262 root     /usr/sbin/acpid                   44       96      100      192
 1833 root     /usr/sbin/lvmetad -f             208      104      110      236
 3945 root     /sbin/agetty --keep-baud 11       36      108      119      232
 3944 root     /sbin/agetty --noclear tty1       36      112      123      236
 2955 libstoragemgmt /usr/bin/lsmd -d                  64      116      124      252
22338 rngd     /sbin/rngd -f --fill-waterm      848      120      130      284
 3045 root     /usr/sbin/gssproxy -D            400      128      135      264
 3833 root     /usr/sbin/atd -f                 112      128      137      288
 2855 rpc      /sbin/rpcbind -w                 404      160      172      344
 3641 root     /usr/libexec/postfix/master      960      180      195      396
 3644 postfix  qmgr -l -t unix -u               968      156      203      580
 2860 root     /usr/sbin/irqbalance --fore      172      208      234      532
 2713 root     /sbin/auditd                     288      264      288      524
32321 root     /usr/sbin/crond -n               508      196      300     1076
 3425 root     /sbin/dhclient -6 -nw -lf /     1852      184      331      752
 2939 chrony   /usr/sbin/chronyd                404      328      365      684
12978 root     /usr/sbin/sshd -D                932      112      411     1376
 3297 root     /sbin/dhclient -q -lf /var/     1816      356      521     1008
 2248 root     /usr/lib/systemd/systemd-ud      476      744      794     1152
 2867 dbus     /usr/bin/dbus-daemon --syst      408      760      840     1272
 2786 root     /usr/lib/systemd/systemd-lo      180      836      910     1324
 9885 ec2-user sshd: ec2-user@pts/0              68      232     1636     4436
21882 root     /usr/sbin/rsyslogd -n          74764      936     2382     4632
 2038 root     containerd-shim -namespace       568     2416     2416     2420
    1 root     /usr/lib/systemd/systemd --      352     2460     2568     3068
 9886 ec2-user -bash                              0     2272     2670     4276
 4587 postfix  pickup -l -t unix -u               0     2296     3311     6436
15765 root     sudo smem -t                       0     1808     3443     7456
 9868 root     sshd: ec2-user [priv               4      944     3532     8600
15664 root     /usr/bin/amazon-ssm-agent       5940     4564     4568     4636
22020 root     /usr/bin/containerd            14176     9664     9669     9776
15766 root     python /bin/smem -t                0     9668    10175    12008
14351 root     /usr/lib/systemd/systemd-jo      120     6752    10256    14972
15733 root     /usr/bin/ssm-agent-worker       9736    13768    13772    13852
17226 root     /usr/bin/dockerd -H fd:// -    28068    14132    14143    14296
23936 root     /usr/local/bin/mongodb_expo     1108    15692    15692    15696
29352 root     /opt/aws/amazon-cloudwatch-     3552    32376    32376    32380
 2070 root     mongod -f /etc/mongod.conf    588308 13799384 13799384 13799388
-------------------------------------------------------------------------------
   40 8                                      739112 13924768 13938573 13971780

# 마지막 줄이 전체 합계이며, "739112kB"가 swap에 사용된 것을 확인할 수가 있다.
# 제일 많이 사용중인 프로세스는 mongodb 메모리 사용량이 많을 것을 확인할 수 있다.

3. 버디시스템
# 커널은 버디 시스템을 통해서 메모리를 할당, 버디 시스템은 물리 메모리를 연속된 메모리 영역으로 관리한다.
# 버디시스템 구조
1개 4KB -> 4KB -> 4KB -> ...
2개 4KB+4KB -> 4KB+4KB -> 4KB+4KB -> ...
4개 4KB+4KB+4KB+4KB -> 4KB+4KB+4KB+4KB -> 4KB+4KB+4KB+4KB -> ...

# 버디시스템 현재상황 확인하기
$ sudo cat /proc/buddyinfo
Node 0, zone      DMA      1      0      0      1      2      1      1      0      1      1      3
Node 0, zone    DMA32  14777   3878   1162    164    138    112     43      8      2      0      0
Node 0, zone   Normal     76   8213    721    575    244     37      4      1      0      0      0

# 각각의 행은 2의 배수로 1, 2, 4개의 영역을 의미한다.
# 커널은 프로세스가 사용하는 메모리 중 Inactive 리스트에 있는 메모리를 골라서 swap영역으로 이동시킨다.
# 그 다음 해당 메모리 영역을 해제하고 다른 프로세스에 할당한다.
# 커널은 기본적으로 유휴 메모리가 있을 경우 캐시로 활용하려 하고, 메모리 사용 요청이 증가하면 캐시로
# 활용하고 있는 메모리를 재할당해서 프로세스에 할당하는 기본적인 동작 원리임.

4. vm.swappiness, vm.vfs_cache_pressure

# vm.swappiness : 커널이 얼마나 공격적으로 메모리 영역을 swap 영역으로 옮기는 것을 결정하는 파라미터
#                 기본값 : 60
# vm.vfs_cache_pressure : 캐시를 재할당 한다고 했을 때 페이지캐시를 더많이 재할당할지, inode 캐시를 재할당할지 결정한다.
#                         기본값 : 100
# 참고) dentry : 디렉터리 캐시 / inode : inode 캐시

4.1 vm.swappiness 설정값 확인
$ sudo sysctl -a | grep -i vm.swappiness
vm.swappiness = 60

# vm.swappiness 값이 작으면 : 캐시 메모리를 재할당
# vm.swappiness 값이 높으면 : 메모리 swap영역 사용

4.2 vm.vfs_cache_pressure 설정값 확인
$ sudo sysctl -a | grep -i vm.vfs_cache_pressure
vm.vfs_cache_pressure = 100

# vm.vfs_cache_pressure 값이 0이면 dentry와 inode 캐시를 반환하지 않아 시스템의 메모리 부족
# 현상을 일으킬 수 있기 때문에 0으로 설정하면 안된다.

# vm.vfs_cache_pressure 값의 변화에 따라 dentry, inode 캐시의 양이 변동되기 때문이므로 해당 값이
# 100 이상이 되면 미사용 중이 아닌 캐시들도 반환하기 때문에 성능저하가 발생할 수 있으므로, 해당 워크로드에
# 맞게 테스트 후 설정을 적용해야 한다.

5. 메모리 증설 포인트
# swap 영역의 사용은 현재 워크로드에 메모리가 부족하다는 것으로 알 수 있음.

5.1 운영 시스템이 swap을 사용한다면 대처방법
# 1. 메모리의 사용량이 선형적으로 증가하는 경우
#    이런 case는 보통 메모리 누수를 의심, 애플리케이션이 요청을 처리하고 요청처리가 끝나면 메모리를 해제
#    해야하는데, 제대로 해제되지 않으면 사용하는 메모리가 계속 늘어난다.

# 2. 순간적으로 메모리 사용량이 폭증하는 경우
#    평상시 메모리 사용은 일정하지만 순간적으로 요청이 증가하면 메모리 사용량이 폭증해서 swap을 사용하게 된다.
#    안정적인 서비스를 위해 사용한 메모리의 최대치를 계산해서 메모리를 증설
#    만약 서비스에 크게 영향을 끼치는 정도가 아니라면 swap을 사용

5.1.1 pmap 프로세스 메모리 영역별 크기 확인방법
# 예제) mongodb 서버 예제
# mongodb proc 확인 및 영역 확인
$ sudo pmap 2070
2070:   mongod -f /etc/mongod.conf
00003a8206932000 1048576K -----   [ anon ]
000055921703e000  57100K r-x-- mongod
000055921a802000    924K r---- mongod
000055921a8e9000    944K rw--- mongod
000055921a9d5000   3060K rw---   [ anon ]
000055921aeae000 14974352K rw---   [ anon ]
...

5.1.2 gdb 메모리 덤프 생성방법
# gdb 설치
$ sudo yum -y install gdb

# 메모리 덤프 할 논리주소 확인
$ sudo cat /proc/2070/smaps
7ffb558c9000-7ffb55b64000 r-xp 00000000 103:04 2067792041                /usr/lib/x86_64-linux-gnu/libcrypto.so.1.1
Size:               2668 kB
KernelPageSize:        4 kB
MMUPageSize:           4 kB
Rss:                 100 kB
Pss:                 100 kB
Shared_Clean:          0 kB
Shared_Dirty:          0 kB
Private_Clean:       100 kB
Private_Dirty:         0 kB
Referenced:           80 kB
Anonymous:             0 kB
LazyFree:              0 kB
AnonHugePages:         0 kB
ShmemPmdMapped:        0 kB
Shared_Hugetlb:        0 kB
Private_Hugetlb:       0 kB
Swap:                  0 kB
SwapPss:               0 kB
Locked:                0 kB
ProtectionKey:         0
VmFlags: rd ex mr mw me sd

# 메모리 덤프 생성
$ sudo gdb -p 2070
...
(gdb) dump memory /home/ec2-user/memory_dump 0x7ffb558c9000 0x7ffb55b64000
# smaps로 확인한 주소 앞에 "0x"를 붙혀 메모리 논리주소를 작성해서 생성한다.

# 메모리 덤프 읽기
$ sudo strings /home/ec2-user/memory_dump
ETLL
%%Hm
		CJAAQ
eeX=
==Ns
3--Jg
6yy_&
aaY8GG
G^]]V
11M|
uu\)
rUUT
9MMR
99Ov
...
...
profile
Cloud Engineer@Plateer. 클라우드 상에서 엔지니어링을 재미있게 하는 엔지니어입니다.

0개의 댓글