MLOps - # 4 MinIO

jaewonnow_·2025년 9월 28일

MLOps

목록 보기
4/11
post-thumbnail

MySQL 까지 연결됨을 확인했음
그러나 MySQL로 Artifact Store를 대체할 수 없따,,
그 이유는 왜냐면

Artifact Store 저장소의 성격

1. 데이터의 성격 차이

구분파일(Artifacts)데이터(Metadata)
예시모델 바이너리(.pt, .onnx, .pkl), 체크포인트, 로그 파일, 이미지, 데이터 스냅샷학습 파라미터(lr=0.01), 실험 이름, metric(accuracy=0.92), 데이터셋 버전, 실행시간
단위대용량 blob (MB~GB, 심지어 TB 가능)구조화된 작은 값 (KB~MB 수준)
저장소 적합오브젝트 스토리지 (MinIO, S3, GCS)RDBMS (MySQL, Postgres, SQLite)
최적화 포인트읽기/쓰기 대역폭, 내구성, 확장성검색, 쿼리, 필터링, 관계형 조회
MLflow에서Artifact StoreTracking DB (Metadata Store)

Artifact = 모델 파일, 체크포인트, 로그, 이미지 등 → 보통 수 MB ~ 수 GB 이상 대용량 바이너리 파일

RDBMS = 행(row) 단위로 구조화된 데이터 저장에 최적화 → 대용량 바이너리(blob)를 대량으로 넣으면 성능/운영 비용 문제 발생

👉 즉, 파일(blob) 보관은 오브젝트 스토리지가 맞고, 메타데이터는 DB에 두는 게 맞다.

2. 성능 및 확장성

RDBMS에 파일 넣으면?

1. RDBMS 저장 방식

DB에 파일을 넣는 방법은 보통 BLOB(Binary Large Object) 타입을 쓴다.

이때 파일은 DB 테이블의 row 안에 저장되거나, 내부적으로 별도 스토리지에 저장 후 그 포인터를 row가 가리킨다.

즉, DB 입장에서는 “행 하나에 수십 MB~GB짜리 덩어리”가 들어가는 것.

2. 락(lock)이 생기는 이유

RDBMS는 트랜잭션 일관성(ACID)을 보장해야 함.

그래서 특정 row에 큰 blob을 쓰는 동안:

해당 row(심하면 페이지 전체)에 lock이 걸림 → 다른 트랜잭션은 대기해야 함.

blob이 크면 쓰기 작업 시간이 길어져 → 락 보유 시간이 길어짐 → 동시성 저하.

반대로 오브젝트 스토리지는 blob 저장 시 이런 트랜잭션 락이 거의 없음 → 그냥 파일 단위 append/write.

3. I/O 부하가 커지는 이유

DB는 인덱스 + 페이지 단위(보통 8KB~16KB)로 데이터를 관리.

그런데 blob 파일은 수십 MB~GB → 여러 페이지에 쪼개져 저장됨.

읽고 쓰려면 페이지 단위로 계속 I/O 발생 → 불필요한 부하 급증.

DB 캐시(buffer pool)에도 blob이 들어가려 하면서 → 인덱스/메타데이터 캐시까지 밀어내는 부작용.

4. 비용 문제

DB 스토리지는 보통 고성능 SSD, RAID, 백업/복제 포함 → GB당 비용이 비쌈.

파일 시스템이나 오브젝트 스토리지는 대용량/저렴한 스토리지 사용 가능.

오브젝트 스토리지(MinIO, S3 등)

1. Key-Value 기반 구조

오브젝트 스토리지는 파일이 아니라 Object(객체) 단위로 관리한다.

Key = 고유 식별자 (ex. s3://bucket/model/v1/model.pkl)

Value = 실제 데이터(blob)

Metadata = 생성일, 크기, 사용자 정의 태그 등

즉, “파일 경로 + 데이터”가 아닌, Key로 접근하는 거대한 분산 해시 테이블 같은 구조예요.

파일시스템처럼 디렉토리 트리 탐색이 없으니, 수십억 건도 성능 저하 없이 조회 가능.

2. 분산 스케일 아웃 설계

오브젝트 스토리지는 Scale-Out 아키텍처를 쓴다.

서버(NODE)를 수평으로 계속 늘려서 저장 용량/처리량을 확장 가능.

데이터는 자동으로 샤딩(Sharding) + 분산 배치.

예: MinIO는 4개 디스크가 있으면, 파일을 조각내서 각 디스크에 분산 저장.

3. Erasure Coding (삭제 코드)

S3/MinIO는 RAID 대신 Erasure Coding을 사용한다.

데이터를 여러 조각으로 나누고, 수학적으로 redundancy 블록을 추가한다.

일부 디스크가 고장나도, 수학적으로 재구성 가능.

RAID보다 효율적 (적은 공간으로 높은 내구성 제공)

덕분에 수십억 object도 안전하게 분산 저장 가능.

4. 메타데이터 관리 (Indexing Layer)

각 object의 key와 위치 정보는 메타데이터 DB(내부 key-value store)에 저장한다.

일반 파일시스템은 디렉토리 inode 구조라서 파일 수가 많아지면 성능이 떨어지는데,

오브젝트 스토리지는 key-value 인덱스로 관리하기 때문에 파일 수에 거의 제한이 없음.

AWS S3는 공식적으로 “object 수 무제한” 제공.

5. API 기반 접근

오브젝트 스토리지는 POSIX 파일시스템이 아니라 REST API/SDK로 접근합니다.

파일 오픈/락 같은 무거운 오퍼레이션이 없고,

PUT(Object 업로드)

GET(Object 다운로드)

DELETE(Object 삭제)

LIST(프리픽스 기반 조회)

이런 단순 API로 대량 처리를 효율화.

3. 운영 및 기능적 이유

오브젝트 스토리지는 버전 관리, 분산 복제, 내구성 기능이 내장
(스토리지 레벨에서 자동 백업 + 스냅샷 관리 기능)

예: S3는 11x9(99.999999999%) 내구성 제공

DB는 이런 기능이 없어서 직접 구현해야 함 → 비효율적


Artifact Store - MinIO

https://www.min.io/open-source/download?platform=linux&arch=amd64

뭘 다운받을지 헷갈려서 GPT좀 돌려 봤다.

Ubuntu 또는 Debian 계열의 리눅스를 사용 중이라면 → DEB 파일을 다운로드하세요.

CentOS, RHEL, Fedora 계열의 리눅스를 사용 중이라면 → RPM 파일을 다운로드하세요.

1. 전용 계정 생성

sudo useradd -r minio-user -s /sbin/nologin
sudo mkdir -p /home/ubuntu/mlflow_artifacts
sudo chown -R minio-user:minio-user /home/ubuntu/mlflow_artifacts

-r: 시스템 계정 (로그인 불가)

-s /sbin/nologin: 직접 로그인 막음

권한 위임: 데이터 디렉토리를 minio-user 전용으로

minIO 또한 데이터베이스와 유사한 스토리지 이므로 계정을 생성해주는 과정을 거친다.
DB 서버는 보통 사용자 이름과 비밀번호로 인증하지만, MinIO는 S3 호환 스토리지고, S3는 API를 통해 접근하기 때문에 Access Key와 Secret Key 쌍으로 인증한다.

아티팩트 스토어 저장할 디렉토리 파일을 만들고 minio가 읽을 수 있도록 권한을 준다.

🚦 2. 환경 변수 파일 생성

/etc/default/minio 파일을 만듭니다:

sudo nano /etc/default/minio

내용:

## MinIO 데이터 볼륨 (저장 경로)
MINIO_VOLUMES="/home/ubuntu/mlflow_artifacts"

## 콘솔 주소 (관리 UI)
MINIO_OPTS="--console-address :9001"

## 관리자 계정 (반드시 바꾸는 게 안전)
MINIO_ROOT_USER=minioadmin
MINIO_ROOT_PASSWORD=초기비밀번호123

🚦 3. systemd 서비스 유닛 파일

/etc/systemd/system/minio.service:

[Unit]
Description=MinIO Object Storage Server
Documentation=https://docs.min.io
Wants=network-online.target
After=network-online.target

[Service]
EnvironmentFile=/etc/default/minio
User=minio-user
Group=minio-user
ExecStart=/usr/local/bin/minio server $MINIO_OPTS $MINIO_VOLUMES

#보안/안정성 설정
PrivateTmp=true
ProtectSystem=full
ProtectHome=true
NoNewPrivileges=true
Restart=always
RestartSec=5s
LimitNOFILE=65536
TimeoutStopSec=30

[Install]
WantedBy=multi-user.target

이전 mlflow.service

아티팩트 경로가 home 의 로컬 아티팩트 파일에 저장되어있다.
이 부분 역시 바꿔준다.

mlflow server \
  --backend-store-uri mysql://mlflow:mlflow123@127.0.0.1/mlflow_db \
  --default-artifact-root s3://mlflow-artifacts/ \
  --host 0.0.0.0 --port 5000

앞으로 우리가 쓰게 될 버킷으로 바꿔준다

🚦 4. 서비스 실행

sudo systemctl daemon-reload
sudo systemctl enable minio
sudo systemctl start minio

서비스 파일로 만든 시스템 파일 재실행하면

상태 확인:

systemctl status minio

시스템 정상 실행 확인

🚦 5. 방화벽 & 접근

sudo ufw allow 9000/tcp
sudo ufw allow 9001/tcp

ufw로 서버(컴퓨터) 9000, 90001 포트 접근 제어


/

이미 Lightsail에서 9000, 9001 포트 열려 있음 → 외부 접속 가능

접속:

API: http://:9000 -> 관리자 계정

WebUI: http://:9001 -> 웹 UI

(.venv) ubuntu@ip-172-26-11-190:~/MLOps/projects/firstproject/MLOps$ python traininglogistic.py --experiment "Toss_ads Logistic"
INFO:__main__:MLflow Tracking Server 연결 테스트...
INFO:__main__:서버 주소: http://3.39.169.116:5000
INFO:__main__:
=== 실험 목록 ===
INFO:__main__:실험 ID: 7
INFO:__main__:실험명: Toss_ads Logistic
INFO:__main__:생성일: 1759127023464
INFO:__main__:--------------------------------------------------
INFO:__main__:실험 ID: 6
INFO:__main__:실험명: Test1
INFO:__main__:생성일: 1758608844499
INFO:__main__:--------------------------------------------------
INFO:__main__:로지스틱 회귀 모델 훈련 시작
2025/09/29 06:43:02 WARNING mlflow.models.model: `artifact_path` is deprecated. Please use `name` instead.
INFO:botocore.credentials:Found credentials from IAM Role: AmazonLightsailInstanceRole
🏃 View run LogisticRegression_20250929_064301 at: http://3.39.169.116:5000/#/experiments/7/runs/f7475cb9fb0b4d53b0bed0e30830abb5
🧪 View experiment at: http://3.39.169.116:5000/#/experiments/7
ERROR:__main__:❌ 오류 발생: Failed to upload /tmp/tmprl8a38x6/model/input_example.json to mlflow-artifacts/7/models/m-b716e4d498214cb48c540576aa8705b1/artifacts/input_example.json: An error occurred (AccessDenied) when calling the PutObject operation: Access Denied
ERROR:__main__:MLflow 서버가 실행 중인지 확인하세요.

MinIO Client를 직접 다운로드해서 다른 위치에 설치하면 됩니다:

wget https://dl.min.io/client/mc/release/linux-amd64/mc -O /usr/local/bin/mc
sudo chmod +x /usr/local/bin/mc

  1. 올바른 mc 확인
    /usr/local/bin/mc --help

여기서 Manage MinIO servers 라는 문구가 보이면 MinIO Client가 맞습니다.

  1. PATH 우선순위 조정

현재는 /usr/bin이 /usr/local/bin보다 먼저 잡혀서 Midnight Commander가 실행됨.
~/.bashrc에 다음을 추가해서 MinIO Client를 우선 사용하도록 바꿀 수 있다:

export PATH=/usr/local/bin:$PATH

이런식으로 환경변수에 aws_s3 계정으로 선언한 값들이 나와야한다

꼭 맞춰야 할 것 (Ubuntu 러너 기준)

패키지

pip install mlflow boto3 botocore s3fs

자격증명

AWS S3:

환경변수 또는 ~/.aws/credentials에 정확한 키 설정

AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, (임시키면 AWS_SESSION_TOKEN), AWS_DEFAULT_REGION

MinIO 등 S3 호환:

AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY

MLFLOW_S3_ENDPOINT_URL="https://" (필수)

AWS_DEFAULT_REGION="us-east-1" 같은 임의 값

네트워크

러너(Ubuntu)가 S3/MinIO 엔드포인트에 outbound 접근 가능

원격 MLflow Tracking 서버를 쓴다면 그 포트 접근 가능(기본 5000)

MLflow Tracking URI

코드에서 mlflow.set_tracking_uri("http://:5000")

버킷 권한

MLflow가 쓰는 버킷에 PutObject 권한

profile
0 to 100 Data Engineer

0개의 댓글