Java - 대용량 데이터 적재 로직 설계시 유념할 사항

 작성해야하는 로직이 대용량의 데이터를 특정 DB에 적재하는 로직을 설계해야 한다면

대용량의 데이터를 한번에 적재하는 것보단 데이터를 일정기준으로 끊어서 적재하는 것이 바람직하다.

 

 

1. 메모리 자원의 효율적 관리

 한꺼번에 적재하게되면 적재해야할 데이터들을 Insert를 실행하기 전까지는 변수에 담고 있어야하기 때문에

데이터의 양이 방대하면 방대할수록 너무나 많은 데이터를 변수에 담고 있기 때문에

메모리 자원을 너무 많이 점유할 수 있다.

 

  따라서 일정기준을 두어서 데이터를 분할하여 Insert를 실행하고 데이터를 담고 있는 변수를 비워주고

다음 분할량을 넣고 Insert하는 식으로해서 JVM에서 Heap 메모리나 Static 메모리 자원 등을

너무 많이 점유하지 않도록 해야한다.

 

(예제 코드)

import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;

public class MybatisBulkInsertExample {

    public static void main(String[] args) {
        SqlSessionFactory sqlSessionFactory = ...

        try (SqlSession session = sqlSessionFactory.openSession()) {
            List<Map<String, Object>> dataList = new ArrayList<>();

            for (int i = 0; i < 10000; i++) { // 대용량 데이터 삽입
                Map<String, Object> param = new HashMap<>();
                param.put("column1", "value" + i);
                param.put("column2", i);
                dataList.add(param);

                if (dataList.size() == 1000) {
                    session.insert("myMapper.bulkInsertMyTable", dataList);
                    session.commit();
                    dataList.clear();
                }
            }

            if (!dataList.isEmpty()) { // 마지막으로 남은 데이터들 처리
                session.insert("myMapper.bulkInsertMyTable", dataList);
                session.commit();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

 

 

 

2. 예외 상황에 대한 유연한 대처

  적재하다가 예외가 발생하여 적재가 이루어지지 않는다면 처음부터 다시 적재해야하는 사태가 발생할 수 있다.

만약에 끊어서 적재하면 끊어진 시점의 Data 부분만 재적재를 하는 배치 프로세스를 따로돌리면 해당 문제에 대응할 수 있겠지만 한꺼번에 적재한다면 이러한 대응이 불가능하다.

 

 

3. 적재 성능 향상

  데이터를 작은 단위로 나누어 순차적으로 적재하면, DB의 I/O 부하를 분산시킬 수 있다. 이는 특히, 대용량 데이터를 처리할 때 DB 서버에 과도한 부하를 주지 않으며, 전체 적재 작업의 속도를 향상시킬 수 있기 때문이다.

  또한, 일부 DBMS는 병렬 처리 기능을 지원하여, 데이터를 분할 적재함으로써 적재 작업의 병렬 실행이 가능해져 전체적인 성능이 향상될 수 있다.