kill

minio, hadoop-s3

영구우 2025. 5. 16. 14:58

Hadoop-S3 (S3A) 정리

1. 정의
    **Hadoop-S3(S3A)**는 Hadoop이 Amazon S3 또는 MinIO 같은 S3 호환 오브젝트 스토리지에 접근할 수 있게 해주는 파일 시스템 커넥터

2. 주요 구성 요소
hadoop-aws.jar                 Hadoop이 S3A를 인식하도록 하는 커넥터
aws-java-sdk-bundle.jar  AWS S3 API를 사용하기 위한 Java SDK
core-site.xml                     S3A 설정을 명시하는 Hadoop 설정 파일 (endpoint, 키 등)

3. 작동 방식
    - 내부적으로 s3a:// 스킴을 사용해 오브젝트 스토리지(S3/MinIO)에 접근
    - HDFS처럼 다룰 수 있도록 추상화
    - 예: hadoop fs -ls s3a://my-bucket/

4. MinIO와 Hadoop-S3의 관계
기본 관계  MinIO는 S3A의 backend로 동작 가능
역할          Hadoop-S3 커넥터가 MinIO에 s3a://를 통해 접근
설정 방법  core-site.xml 또는 Spark 설정에 MinIO endpoint, access key, secret key를 넣으면 연동
사용 예     Iceberg, Spark, Presto 등이 s3a://my-bucket/... 경로를 통해 MinIO의 데이터를 읽고 쓰기

[Iceberg or Spark or Presto]
         |
         | (fs.s3a.impl)
         v
[Hadoop S3A 커넥터 (hadoop-aws + aws-sdk)]
         |
         v
[MinIO 서버 (S3 호환 스토리지)]

5. Hadoop-s3 만으로 충분 한 경우
    - Spark, Iceberg 등에서 단순히 MinIO를 스토리지로만 쓸 경우
    - hadoop fs 명령이나 HDFS 클러스터가 필요 없는 경우
    - 이럴 때는 Hadoop을 설치할 필요 없이 필요한 JAR만 넣고 설정만 적용하면 충분

6. core-site.xml 확인
    - MinIO 설정은 /home/본인계정/hadoop-conf/core-site.xml
<configuration>
  <property>
    <name>fs.s3a.access.key</name>
    <value>minioadmin</value>
  </property>
  <property>
    <name>fs.s3a.secret.key</name>
    <value>minioadmin</value>
  </property>
  <property>
    <name>fs.s3a.endpoint</name>
    <value>http://localhost:9000</value>
  </property>
  <property>
    <name>fs.s3a.path.style.access</name>
    <value>true</value>
  </property>
  <property>
    <name>fs.s3a.impl</name>
    <value>org.apache.hadoop.fs.s3a.S3AFileSystem</value>
  </property>
</configuration>

7. 프로젝트 구조 생성
~/hadoop/
├── minio-s3a-maven/
│   ├── pom.xml
│   └── src/
│       └── main/
│           └── java/
│               └── com/
│                   └── example/
│                       └── minio/
│                           └── MinioTest.java
    $ mkdir -p ~/hadoop/minio-s3a-maven/src/main/java/com/example/minio
    $ cd ~/hadoop/minio-s3a-maven

8. pom.xml 생성
    $ cat <<EOF > pom.xml
<dependencies>
  <!-- Hadoop AWS -->
  <dependency>
    <groupId>org.apache.hadoop</groupId>
    <artifactId>hadoop-aws</artifactId>
    <version>3.3.6</version>
    <exclusions>
      <exclusion>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-log4j12</artifactId>
      </exclusion>
    </exclusions>
  </dependency>

  <!-- Hadoop Common -->
  <dependency>
    <groupId>org.apache.hadoop</groupId>
    <artifactId>hadoop-common</artifactId>
    <version>3.3.6</version>
    <exclusions>
      <!-- 여기서도 log4j 관련 바인딩 제거 -->
      <exclusion>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-reload4j</artifactId>
      </exclusion>
      <exclusion>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-log4j12</artifactId>
      </exclusion>
    </exclusions>
  </dependency>

  <!-- AWS SDK -->
  <dependency>
    <groupId>com.amazonaws</groupId>
    <artifactId>aws-java-sdk-bundle</artifactId>
    <version>1.12.367</version>
  </dependency>

  <!-- SLF4J API -->
  <dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>1.7.36</version>
  </dependency>

  <!-- SLF4J 바인딩: simple만 유지 -->
  <dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-simple</artifactId>
    <version>1.7.36</version>
  </dependency>
</dependencies>
EOF

9. Java 코드 생성
$ cat <<EOF > src/main/java/com/example/minio/MinioTest.java
package com.example.minio;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.fs.RemoteIterator;
import org.apache.hadoop.fs.LocatedFileStatus;

import java.net.URI;

public class MinioTest {
    public static void main(String[] args) throws Exception {
        Configuration conf = new Configuration();
        conf.addResource(new Path("/home/본인계정/hadoop-conf/core-site.xml"));

        FileSystem fs = FileSystem.get(new URI("s3a://my-bucket"), conf);
        RemoteIterator<LocatedFileStatus> files = fs.listFiles(new Path("s3a://my-bucket/"), false);

        while (files.hasNext()) {
            LocatedFileStatus fileStatus = files.next();
            System.out.println(fileStatus.getPath());
        }
    }
}
EOF

10. 빌드
    $ cd ~/hadoop/minio-s3a-maven
    $ mvn clean package

11. 실행( 파일 목록 화면에 뿌리기 )
    $ java -cp "target/minio-s3a-test-1.0-SNAPSHOT.jar:$(cat cp.txt)" com.example.minio.MinioTest

12. 업로드 셈플 파일 만들기
    $ echo "Hello hadoop-s3 to minIo!!" > ~/hadoopToMinioTest.txt

13. MinioUpload.java
    $ nano src/main/java/com/example/minio/MinioUpload.java
package com.example.minio;

// Hadoop 설정 및 파일 시스템 관련 클래스 임포트
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FSDataOutputStream;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;

import java.io.FileInputStream;
import java.io.InputStream;
import java.net.URI;

public class MinioUpload {
    public static void main(String[] args) throws Exception {
        // 로컬에서 업로드할 파일 경로 (절대경로 사용)
        String localFile = "/home/ubuntu/sample.txt";

        // MinIO의 업로드 대상 경로 (s3a 프로토콜 사용)
        String s3aPath = "s3a://my-bucket/uploaded-sample.txt";

        // core-site.xml 로딩하여 Hadoop 설정 객체 생성
        Configuration conf = new Configuration();
        conf.addResource(new Path("/home/ubuntu/hadoop-conf/core-site.xml"));

        // Hadoop FileSystem 객체 생성 (s3a 프로토콜에 맞는 구현체로 초기화)
        FileSystem fs = FileSystem.get(new URI(s3aPath), conf);

        // Hadoop 대상 경로 객체 생성
        Path destPath = new Path(s3aPath);

        // try-with-resources 문법으로 파일 스트림 열기
        try (
            // 로컬 파일을 읽기 위한 InputStream
            InputStream in = new FileInputStream(localFile);
            // MinIO(S3A)에 쓸 Hadoop OutputStream 생성 (덮어쓰기 허용)
            FSDataOutputStream out = fs.create(destPath, true)
        ) {
            // 버퍼를 사용하여 데이터를 읽고 씀 (4KB 단위)
            byte[] buffer = new byte[4096];
            int bytesRead;

            // in.read(): 버퍼 크기만큼 로컬 파일에서 읽고, out.write()로 S3A에 씀
            while ((bytesRead = in.read(buffer)) > 0) {
                out.write(buffer, 0, bytesRead);
            }
        }

        // 업로드 완료 메시지 출력
        System.out.println("업로드 완료 → " + s3aPath);
    }

}
13. 빌드/실행
    $ mvn clean package
    $ mvn dependency:build-classpath -Dmdep.outputFile=cp.txt

    $ java -cp "target/minio-s3a-test-1.0-SNAPSHOT.jar:$(cat cp.txt)" com.example.minio.MinioUploadTest

14. 파일 삭제
    14.1. FileSystem.delete(Path, recursive)
        fs.delete(new Path("s3a://my-bucket/삭제할파일이름"), false);
        - 첫 번째 인자: 삭제할 S3A 경로
        - 두 번째 인자: 디렉토리일 경우 true로 주면 하위 파일까지 재귀 삭제
            → 지금은 단일 파일이므로 false
    14.2. MinioDelete.java
        $ nano src/main/java/com/example/minio/MinioDelete.java
package com.example.minio;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;

import java.net.URI;

public class MinioDelete {
    public static void main(String[] args) throws Exception {
        // 삭제할 파일의 S3A 경로
        String s3aPath = "s3a://my-bucket/uploaded-sample.txt";

        // core-site.xml 기반 설정 로딩
        Configuration conf = new Configuration();
        conf.addResource(new Path("/home/본인계정/hadoop-conf/core-site.xml"));

        // S3A용 FileSystem 객체 생성
        FileSystem fs = FileSystem.get(new URI(s3aPath), conf);
        Path target = new Path(s3aPath);

        // 파일 삭제 시도
        boolean success = fs.delete(target, false);

        if (success) {
            System.out.println("삭제 완료 ::: " + s3aPath);
        } else {
            System.out.println("삭제 실패 또는 파일 없음 ::: " + s3aPath);
        }
    }
}
    14.3. 빌드/실행
        $ mvn clean package
        $ mvn dependency:build-classpath -Dmdep.outputFile=cp.txt
        $ java -cp "target/minio-s3a-test-1.0-SNAPSHOT.jar:$(cat cp.txt)" com.example.minio.MinioDelete

'kill' 카테고리의 다른 글

apache/hive:3.1.3 기반 Docker 환경 구성  (11) 2025.05.26
minio, hadoop-s3, iceberg, stremPark, hive  (29) 2025.05.20
minio, hadoop  (6) 2025.05.15
Kafka (Helm 기반) 제거 스크립트  (2) 2025.05.14
Kafka 설치 - Bitnami Helm Chart  (20) 2025.05.14