MinIO의 주요 작업

MinIO는 고성능 오픈소스 객체 저장소 시스템으로, Amazon S3 API와 호환됩니다. Java 애플리케이션에서 MinIO 공식 SDK인 MinIO Java SDK를 사용하여 MinIO 서비스를 조작할 수 있으며, 파일 업로드, 다운로드, 삭제, 객체 목록 조회 등 일반적인 기능을 수행할 수 있습니다.

  1. 의존성 추가 (Maven)

<dependency>
    <groupId>io.minio</groupId>
    <artifactId>minio</artifactId>
    <version>8.5.12</version> <!-- 최신 버전 사용 권장 -->
</dependency>

주의: MinIO Java SDK 8.x 버전부터 API는 OkHttp + Retrofit을 사용하며, 모든 메서드는 비동기 비블록 방식(CompletableFuture 반환)입니다. 단, .get() 메서드나 동기 메서드를 통해 동기 호출도 가능합니다.

  1. MinIO 클라이언트 초기화

import io.minio.MinioClient;

MinioClient client = MinioClient.builder()
    .endpoint("http://localhost:9000") // MinIO 서버 주소
    .credentials("ACCESS_KEY", "SECRET_KEY") // 인증 키
    .build();

HTTPS 사용 시, 인증서가 유효해야 하며 테스트 환경에서는 모든 인증서를 신뢰하도록 설정할 수 있습니다.

  1. 주요 작업 예제

1. 버킷 생성

boolean exists = client.bucketExists(BucketExistsArgs.builder().bucket("sample-bucket").build());
if (!exists) {
    client.makeBucket(MakeBucketArgs.builder().bucket("sample-bucket").build());
}

2. 로컬 파일 업로드

client.uploadObject(
    UploadObjectArgs.builder()
        .bucket("sample-bucket")
        .object("test.txt")
        .filename("/path/to/file.txt")
        .build()
);

3. InputStream으로 업로드 (웹 업로드용)

InputStream stream = new FileInputStream("/path/to/image.png");
client.putObject(
    PutObjectArgs.builder()
        .bucket("sample-bucket")
        .object("image.png")
        .stream(stream, stream.available(), -1)
        .contentType("image/png")
        .build()
);
stream.close();

주의: -1은 크기 모름을 의미하며, MinIO는 자동으로 분할 업로드합니다. 크기가 알려진 경우 실제 바이트 수를 전달하여 성능 향상 가능.

4. 파일 다운로드

client.downloadObject(
    DownloadObjectArgs.builder()
        .bucket("sample-bucket")
        .object("test.txt")
        .filename("/tmp/downloaded.txt")
        .build()
);

5. 객체를 InputStream으로 가져오기

InputStream stream = client.getObject(
    GetObjectArgs.builder()
        .bucket("sample-bucket")
        .object("test.txt")
        .build()
);
String content = new String(stream.readAllBytes(), StandardCharsets.UTF_8);
stream.close();

6. 버킷 내 객체 목록 조회

ListObjectsArgs args = ListObjectsArgs.builder()
    .bucket("sample-bucket")
    .prefix("") // 선택적 접두사 필터
    .recursive(true) // 하위 디렉토리 포함 여부
    .build();

Iterable<Result<Item>> results = client.listObjects(args);
for (Result<Item> result : results) {
    Item item = result.get();
    System.out.println(item.objectName() + " (" + item.size() + " bytes)");
}

7. 객체 삭제

client.removeObject(
    RemoveObjectArgs.builder()
        .bucket("sample-bucket")
        .object("test.txt")
        .build()
);

8. 여러 객체 삭제 (배치 처리)

List<DeleteObject> items = Arrays.asList(
    new DeleteObject("data1.txt"),
    new DeleteObject("data2.txt")
);

Iterable<Result<DeleteError>> errors = client.removeObjects(
    RemoveObjectsArgs.builder()
        .bucket("sample-bucket")
        .objects(items)
        .build()
);

for (Result<DeleteError> error : errors) {
    DeleteError err = error.get();
    System.err.println("삭제 실패: " + err.objectName() + " - " + err.message());
}

9. 사전 서명 URL 생성

String url = client.getPresignedObjectUrl(
    GetPresignedObjectUrlArgs.builder()
        .method(Method.GET)
        .bucket("sample-bucket")
        .object("secure-file.doc")
        .expiry(60 * 60) // 1시간 유효
        .build()
);
System.out.println("다운로드 링크: " + url);

  1. 예외 처리

MinIO SDK는 ErrorResponseException, InsufficientDataException, InternalException, InvalidKeyException, IOException 등을 발생시킵니다.

일관된 처리를 위해 다음과 같이 예외를 잡는 것이 좋습니다:

try {
    // MinIO 작업
} catch (ErrorResponseException e) {
    System.err.println("서버 오류: " + e.errorResponse().message());
} catch (Exception e) {
    e.printStackTrace();
}

  1. 전체 예제: 업로드 및 다운로드 링크 생성

import io.minio.*;
import io.minio.http.Method;
import java.nio.file.Paths;

public class MinioSample {
    public static void main(String[] args) throws Exception {
        MinioClient client = MinioClient.builder()
            .endpoint("http://localhost:9000")
            .credentials("minioadmin", "minioadmin")
            .build();

        String bucket = "storage-bucket";
        String fileName = "sample.txt";
        String filePath = "/tmp/sample.txt";

        // 버킷 생성
        if (!client.bucketExists(BucketExistsArgs.builder().bucket(bucket).build())) {
            client.makeBucket(MakeBucketArgs.builder().bucket(bucket).build());
        }

        // 파일 업로드
        client.uploadObject(
            UploadObjectArgs.builder()
                .bucket(bucket)
                .object(fileName)
                .filename(filePath)
                .build()
        );

        // 사전 서명 URL 생성
        String url = client.getPresignedObjectUrl(
            GetPresignedObjectUrlArgs.builder()
                .method(Method.GET)
                .bucket(bucket)
                .object(fileName)
                .expiry(3600)
                .build()
        );

        System.out.println("파일 업로드 완료. 다운로드 링크: " + url);
    }
}

  1. 주의사항

  1. 스레드 안전성: MinioClient는 스레드 안전하며, 전역 싱글톤으로 사용 가능합니다.
  2. 대용량 파일 업로드: SDK가 자동으로 멀티파트 업로드를 처리합니다.
  3. HTTPS 설정: 실제 환경에서는 HTTPS를 활성화하고 유효한 인증서를 사용해야 합니다.
  4. 권한 관리: 애플리케이션용 별도의 Access Key를 생성하고, MinIO의 IAM 정책을 통해 권한을 제한하는 것이 좋습니다.
  5. 버전 호환성: MinIO 서버와 Java SDK 버전을 최신으로 유지하여 호환성을 확보하세요.

추가 고급 기능(객체 메타데이터 설정, 라이프사이클 관리, 이벤트 알림 등)에 대해서는 공식 문서를 참고하세요: 👉 https://min.io/docs/minio/linux/developers/java/MinIO-Java-SDK.html

태그: MinIO Java SDK 객체 저장소 S3 API 보안 설정

7월 21일 20:45에 게시됨