Out of Memory 를 생성하는 테스트 어플리케이션

Out of Memory 현상을 확인하기 위해 아래와 같은 Flask 테스트 어플리케이션을 제작하였습니다.
코드는 Gen AI 의 도움을 받아 생성하였습니다.

Install

아래와 같은 방식으로 Python virtual environment 를 생성하고 pip 을 이용하여 Package 를 설치합니다.

[root@ip-172-31-14-46 ~]# python3 -m venv flask
[root@ip-172-31-14-46 ~]# source flask/bin/activate
(flask) [root@ip-172-31-14-46 ~]# pip install Flask psutil

아래와 같은 방법으로 소스를 추가합니다.

(flask) [root@ip-172-31-14-46 ~]# mkdir -p app/templates
(flask) [root@ip-172-31-14-46 ~]# vi app/app.py
(flask) [root@ip-172-31-14-46 ~]# vi app/templates/index.html

코드 상세 내역은 아래와 같습니다.

# cat app/app.py
from flask import Flask, render_template
import gc
import psutil

app = Flask(__name__)

@app.route('/')
def index():
    # 메모리 사용량 증가를 시뮬레이션하는 코드
    big_list = []
    for i in range(1000000):
        big_list.append([i] * 100)

    # 가비지 컬렉터 호출
    gc.collect()

    # 현재 메모리 사용량 출력
    memory_usage = psutil.Process().memory_info().rss / 1024 / 1024
    return render_template('index.html', memory_usage=memory_usage)

if __name__ == '__main__':
    app.run(host="0.0.0.0", debug=True)
# cat app/templates/index.html
<!DOCTYPE html>
<html>
<head>
    <title>Memory Usage Example</title>
</head>
<body>
    <h1>Current Memory Usage:  MB</h1>
</body>
</html>

Run

아래와 같은 방법으로 Flask App 을 시작합니다.

(flask) [root@ip-172-31-14-46 app]# python app.py
 * Serving Flask app 'app'
 * Debug mode: on
WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
 * Running on http://127.0.0.1:5000
Press CTRL+C to quit
 * Restarting with stat
 * Debugger is active!
 * Debugger PIN: 671-207-443

복수의 요청을 생성하기 위한 스크립트 구문은 아래와 같습니다.

for i in {1..100}
do 
curl localhost:5000 & 
done

Analysis

SAR 를 이용하여 메모리 사용량을 확인 하였습니다.

Linux 6.1.102-108.177.amzn2023.x86_64 (ip-172-31-14-46.ap-northeast-2.compute.internal)         09/02/24        _x86_64_        (4 CPU)
01:53:12      4224060   4217556   3381140     42.73      2168    206540   1452448     18.36     85592   3377924      3108
01:53:13      3737376   3731028   3860944     48.79      2168    206532   1633616     20.65     86160   3847620      3376
01:53:14      3514104   3507956   4076664     51.52      2168    206532   1772032     22.39     86752   4053420      3376
01:53:15      3169064   3163116   4413948     55.78      2168    206532   1920688     24.27     87188   4381104      3376
01:53:16      2652588   2646768   4922864     62.21      2168    206532   2106340     26.62     87588   4880428      3376
01:53:17      2437252   2431532   5123952     64.76      2168    206532   2352072     29.73     88160   5063012       296
01:53:18      2072308   2066744   5482052     69.28      2168    206532   2502520     31.63     88388   5410900         0
01:53:19      1509688   1504216   6044052     76.38      2168    206532   2581880     32.63     88788   5971272         0
01:53:20      1509688   1504216   6044028     76.38      2168    206532   2581880     32.63     88788   5971588         0
01:53:21      1400560   1395296   6145260     77.66      2168    206532   2704680     34.18     89188   6062772         0
01:53:22       786408    781252   6752340     85.34      2168    206532   2896008     36.60     89588   6659468         0
01:53:23       177820    172776   7353472     92.93      2168    206532   3096604     39.13     89988   7249352         8
01:53:24       158508     94756   7451868     94.18      1040    123804   3219404     40.69     48652   7298528        16
01:53:25       131352     32692   7542232     95.32        20     56332   3342332     42.24     20980   7349444        20

01:53:25    kbmemfree   kbavail kbmemused  %memused kbbuffers  kbcached  kbcommit   %commit  kbactive   kbinact   kbdirty
01:53:26       101108         0   7602924     96.08        20     26948   3358716     42.45     16864   7391152        20
01:53:28       103740         0   7619084     96.29         0      9488   3360508     42.47      7664   7399372         0
01:53:35       102504         0   7620380     96.31         0      9452   3360508     42.47      7964   7399200         0
01:53:40       100892         0   7621476     96.32         0      9968   3360764     42.47      7976   7401376         0    <<<---!!
01:53:44      5898940   5791436   1793056     22.66         0     40604   2401032     30.34     17640   1586532      4472    <<<---!!
01:53:45      6120816   6013576   1581748     19.99         0     41368   2144344     27.10     16924   1397056      4472
01:53:46      6234600   6127780   1474300     18.63         0     42252   2014212     25.46     16664   1301220      4472

위와 같이 %memused 가 96% 에서 사용량이 줄면서 kbavail 가 확보되는 것을 볼 수 있습니다.

Sep  2 01:53:42 ip-172-31-14-46 kernel: python invoked oom-killer: gfp_mask=0x140cca(GFP_HIGHUSER_MOVABLE|__GFP_COMP), order=0, oom_score_adj=0
Sep  2 01:53:44 ip-172-31-14-46 kernel: CPU: 2 PID: 2711 Comm: python Not tainted 6.1.102-108.177.amzn2023.x86_64 #1
Sep  2 01:53:44 ip-172-31-14-46 kernel: Hardware name: Amazon EC2 c5.xlarge/, BIOS 1.0 10/16/2017

messages 로그를 살펴보면 python 어플리케이션이 oom-killer 에 의하여 종료된 것을 볼 수 있습니다.

Containerization

테스트 환경 구축의 활용도를 높게 만들기 위해서 컨테이너 이미지 빌드 작업을 하였습니다.

FROM python:3.9-alpine

WORKDIR /app

COPY requirements.txt .
RUN apk add --no-cache gcc python3-dev musl-dev linux-headers \
    && pip install --no-cache-dir -r requirements.txt

COPY . .

CMD ["python", "app.py"]
# docker build -t oom-load-flask-app .
# docker run -d -p 5000:5000 --name oom-test han0495/oom-load-flask-app
c9d6c6fdc3b39cb62e285b843af84d4ec9fd0b16c4ed103a4c6519fcee15e2c7

# curl localhost:5000
<!DOCTYPE html>
<html>
<head>
    <title>Memory Usage Example</title>
</head>
<body>
    <h1>Current Memory Usage: 1105.00390625 MB</h1>
</body>
</html>

참고 문서

chhanz's profile image

chhanz

2024-09-02

Read more posts by this author