2010년 12월 30일 목요일

아래 글은 
---------------------------------------------------------------------------------
System에 장애가 발생 했을 시, 문제를 잘 파악하는게 중요한 Point가 되고,
장애의 원인을 정확하게 파악하고 있다면, 무엇을, 누가, 어떻게 해야 하는지가 명확 해 집니다.
그렇지 못하다면, 인적, 금전적 Resource가 낭비되는 건 당연하구요.
System 상에서 장애 원인을 파악하기 어려운 부분 중의 하나가 Memory인데, 이는 OS 관련 문제 중
20% ~ 30%를 차지하고 있을 정도죠. Memory Trouble은 어려 복잡한 문제가 혼합되어 일어나는데
그 문제는 Application, Middle-Ware, OS, Hardware와 관련되어 더욱더 해결하기 어려워지죠.
일단 Memory를 확인 하기 위한 Command부터 숙지 할 필요가 있을 듯 하네요.
대표적으로 free, vmstat, sar, top, ps가 되죠.
우선,
free : 간단하게 메모리를 파악할 수 있으나, 보기 애매한 부분이 있죠.
vmstat : Memory 상황 및 CPU 사용률도 같이 파악 할 수 있으나, Option이 다양하지 않아 특정
Period에 고부하가 발생 했을 시에는 적합하지 않을 수 있어요.
sar : 위 나열된 Command 중에 가장 취득정보가 많으나,  약간 부적절한 부분도 있어 Memory 감시
관점에서는 vmstat보다 좀 떨어집니다.
top : real time으로 볼수 있는 tool인데, 여러가지 기능이 있고 Log 기록도 가능하죠
( - b batch mode 시)
ps : top과 같이 real time으로 볼 수 있는 tool이고, 여러 Option이 있는데 습관에 따라 쓰는 것 만
쓰게 된다는 예를 들면 "ps ax", "ps aux", "ps -elf" 등이죠.

그럼,  실제 사용 시를 확인 해 볼까요?
# free
             total       used       free     shared    buffers     cached
Mem:       4046504    3453500     593004          0     111468    1755760
-/+ buffers/cache:    1586272    2460232
Swap:      4192912    1178400    3014512

각 부분의 의미를 간단하게 설명 하자면
[Mem] total : Total Physical Memory size
[Mem] used : Total Physical Memory size - Free memory size
[Mem] free : 현재 사용되고 있지 않은 여유 Memory
[Mem] shared : 항상 0이고, 현재 사용되고 있지 않음.
[Mem] buffers : File등의 Meta data를 Cache하고 있는 Physical Memory size
[Mem] cached : File의 Real Data를 Cache하고 있는 Physical Memory size
[-/+ buffers/cache] used- : buffers, cached를 포함하고 있지 않은 used size
[-/+ buffers/cache] free+ : buffers, cached를 포함한 free size
[Swap] total : Total Swap size
[Swap] used : Total Swap size - Free size
[Swap] free : 사용하고 있지 않은 Swap size

여기서 [Mem] Free는 “남아있는 Memory Size”가 아닌, 어떠한 용도로도 사용되고 있지 않은
Physical Memory Size
라고 생각하면 되고, 이는 [Mem] Free가 적다  -> 남아 있는 Memory size가
적다 -> 이용가능한 Memory size가 부족하다와 같은 발생을 막기 위함입니다. 따라서, 단순하게
Physical Memory를 추가해도 언젠가는 [Mem] Free가 이전과 같아 지지요.
결론적으로 System 전체의 Memory 사용량의 감시는 [Mem] Free을 판단 기준으로 하는 것이 아니라,
사용가능한 Physical Memory Size로 계산 할 필요가 있죠.
System의 이용가능한 Memory size의 계산은 Linux의 Page Cache에 대해서 이해 할 필요가 있는데,
Linux는 HDD등의 Storage에 저장되어 있는 Data에 대해서 Read / Write 시에 확보 했던 Memory를
Page Cache라는 형태로 보존 합니다.
CPU는 Storage의 Data를 직접 Read 할 수 없어서 Storage Data는 우선 Memory에 Load를 합니다.
이렇게 Read한 Data를 Page Cache로서 재이용합니다. 일단 Load 해 두면 Page Cache는 Read/Write를
Storage에서 Read 해 올 필요가 없으므로 고속처리가 가능하죠.
Page Cache는 새로 Storage Data를 Read/Write로 인해 Memory를 추가 할 필요가 없는 한, Memory를 release
하지 않으므로, 일반적으로 System이 가동하고 있는 것 만으로도 [Mem] Free는 Page Cache로서 계속 활용되고
어느 정도까지 계속 줄어들게 되죠. 서버마다 다르긴 한데, 어떤 건 150MB까지 또 어떤건 202MB 제 경험상
동일한 Application이 계속 돌고 추가 되지 않는 한 항상 같은 Free Memory size를 유지하게 됩니다. 따라서,
[Mem] Free가 50MB가 계속 유지된다고 해서 반드시 걱정 할 필요가 없는 거지요.
이 Page Cache는 사용중이 아닌 Storage와 Data Sync 되어 있으면 바로 Release 할 수 있고, Page Cache에 대한
Write가 있을 경우엔 일시적으로 Unsynchronized 상태가 되지만, Storage와의 Sync는 정기적으로 이루어지고 있어
시간이 지나면 Release 가능한 상태가 됩니다. 즉, Page Cache는 “System이 다른 용도로 재이용 가능한” Memory를
포함하고 있죠. 
이용 가능한 Physical Memory Size를 free command를 통해 계산 하는 방법
 free command에도 어느정도는 Page Cache를 의식하여 개량되어 있고, 그것이 used – 와 free +입니다.
Buffers와 Cached는 Page Cache이고, 정확하게는 Buffers는 Cached에 SwapCached를 추가한 것이 Page Cache의
Total이지만, free command에서는 SwapCached가 표현되지 않죠. 그림을 보면, Buffers와 Cached를 합친 것을
used에서 뺀(used-), free를 더한 (free+)로 보다 현실적인 Physical Memory size와 이용가능한
Physical Memory size를 출력하고 있죠. 따라서, 이 두 수치를 참고하면 됩니다.
그렇다고 해서, System이 이용가능한 Memory size를 파악하기엔 부족하죠. 앞에서, Page Cache를 다른 용도로
재이용하기에는 “Storage와 Sync하고 있음”이라는 조건이 있었죠. Buffers와 cached에는 당연히 “Storage와 Unsynchronized” Page Cache가 포함되어 있죠. 그래서, free+는 실제 이용가능한 Memory size보다 좀 더 부풀려져
있게 되고, 아래와 같이 표현 가능하죠.
free < 실제 사용가능한 Memory size < free+

Physical Memory Status 확인 방법
그럼, Storage와의 Sync 정보까지 포함한 Memory 사용상태 감시를 위해서는 Active와 Inactive를 감시하면
됩니다.
Active와 Inactive는 vmstat -a 나 cat /proc/meminfo를 통해 취득 가능하죠.
# vmstat -a
procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu------
 r  b   swpd   free  inact active   si   so    bi    bo   in   cs us sy id wa st
 0  0 1178400 534328 805388 2502796    0    0   161   159    0    0  7  2 89  1  0

$ cat /proc/meminfo
MemTotal:      4046504 kB
MemFree:        424364 kB
Buffers:        117508 kB
Cached:        1845500 kB
SwapCached:     726764 kB
Active:        2610468 kB
Inactive:       803068 kB
HighTotal:           0 kB
HighFree:            0 kB
LowTotal:      4046504 kB
LowFree:        424364 kB
SwapTotal:     4192912 kB
SwapFree:      3014512 kB
Dirty:            9800 kB
Writeback:           0 kB
AnonPages:     1448396 kB
Mapped:          24508 kB
Slab:           152152 kB
PageTables:      27492 kB
NFS_Unstable:        0 kB
Bounce:              0 kB
CommitLimit:   6216164 kB
Committed_AS:  4136824 kB
VmallocTotal: 34359738367 kB
VmallocUsed:    264576 kB
VmallocChunk: 34359473651 kB
HugePages_Total:     0
HugePages_Free:      0
HugePages_Rsvd:      0
Hugepagesize:     2048 kB

Active는 Page Cache나 Anonymous Page 중 최근 이용 했거나 아직 Storage와 Unsynchronized인 Release 할 수
없는 Page이고, Inactive는 Page Cache나 Anonymous Page 중 마지막으로 Access 된 이후 어느 정도 시간이 지나
Storage와의 Sync가 완료되어 바로 Release 할 수 있는 Page이죠. 따라서, /proc/meminfo의 MemFree와 Inactive를
더한 것이 정확한 이용 가능 Memory size가 됩니다.
아참 여기서 Anonymous Page란 주로 User Process가 이용하고 있는 Page로, ps 등으로 취득가능한 RSS로
표시되는 값입니다. 실제, Shared Memory가 Page Cache에 포함되어 있거나 해서, 정확하게 파악하는 것은
상당히 번거로운 일이죠.
실제 이용 가능한 Memory size ≒MemFree + Inactive

Additional information : Kernel Tuning to control the Page Cache
Page Cache가 항상 남아있어 이를 Release 하고 싶은 경우 drop_caches 를 사용하면 되죠. drop caches는
지금 사용되고 있지 않은 Storage와 Unsynchronized Page Cache나 Slab Cache를 MemFree로 Release 합니다.
즉, MemFree ≒ 이용 가능한 Memory가 되죠.
아참 여기서 Slab Cache란 Directory의 Meta Data 정보를 수용하는 dentry나 File의 Meta Data 정보를 수용하는
inode구조체등을 Cache하고 있는 Kernel내의 Memory 영역입니다. 이는 Page Cache와 별도로 Kernel 안에
확보되어 있고, Storage와 Sync되어 있으면 Release도 언제든지 가능합니다.
아래는 사용방법 입니다.
1. Default 상태로

# echo 0 > /proc/sys/vm/drop_caches

2. Page Cache만 Release

# echo 1 > /proc/sys/vm/drop_caches

3. Slab Cache를 Release

# echo 2 > /proc/sys/vm/drop_caches

4. Page Cache와 Slab Cache를 Release

# echo 3 > /proc/sys/vm/drop_caches
위 drop_caches에 설정 한 parameter는 지속되지 않으므로 필요에 따라 실행해야 합니다.

댓글 없음:

댓글 쓰기