Home 오케스트레이션의 역할과 책임은 어디까지 일까?
Post
Cancel

오케스트레이션의 역할과 책임은 어디까지 일까?


공공데이터로 ETL 토이 프로젝트를 하는 과정에서 오케스트레이션의 역할과 책임 에 대해 고민하게 되었고, 생각을 정리하기 위해 글을 작성하게 되었습니다.




1. 왜 이런 고민을 하게 되었을까?


ETL 파이프라인을 구성할 때, 데이터를 압축 해제한 후 저장하는 작업을 Airflow와 스프링 중 어디에서 할지 에 대해 고민이 들었습니다. 이전에 Dag에 비즈니스 로직을 최대한 넣지 말라는 글을 읽었기 때문에요. 그런데 이 과정에서 공공데이터를 압축 해제하고 데이터베이스에 저장하는 작업이 비즈니스 일까? 에 대한 의문이 들었습니다. 단순히 파일을 풀어 그대로 적재하는 것은 기술적 처리에 가깝기 때문이죠.

1
2
3
4
5
6
7
8
9
10
11
                                   파일 다운로드
                                        │
                                        ▼
                                     압축 해제
                                        │
                                        ▼
                                     DB 저장
                                        │
                                   ┌────┴────┐
                                   ▼         ▼
                                Airflow    Spring




물론 단순 INSERT만 있진 않았는데요. 변경된 내용이 있을 때, 변경 이력을 별도로 기록하는 로직이 포함되어 있었습니다. 이런 부분 때문에 비즈니스인지 아닌지 판단하기가 참 애매했죠.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
def upsert_policy(fee_id, new_rate):
    current = find_current_policy(fee_id)

    if current.rate == new_rate:
        return  # 변경 없음

    # 이전 상태 종료
    current.valid_to = now()
    save(current)

    # 새로운 상태 생성
    new_policy = Policy(
        fee_id=fee_id,
        rate=new_rate,
        valid_from=now()
    )
    save(new_policy)

    # 히스토리 기록
    save_history(
        fee_id=fee_id,
        old_rate=current.rate,
        new_rate=new_rate,
        changed_at=now()
    )





2. 오케스트레이션의 역할과 책임


Airflow의 역할과 책임은 오케스트레이션입니다. 오케스트레이션은 작업의 실행 흐름을 정의하고 통제하는 행위 로, 어떤 작업을 언제 실행할지, 어떤 작업이 선행되어야 하는지, 실패 시 재시도 여부를 어떻게 할지, 전체 파이프라인의 상태를 어떻게 관리할지에 대한 것입니다. 작업의 내부 구현 방식이나 데이터 처리 세부 로직은 책임 범위에 포함되지 않습니다.

In system administration, orchestration is the automated configuration, coordination, deployment, development, and management of computer systems and software.




즉, 내부에서 몇 개의 레코드를 처리했는지, 어떤 트랜잭션 전략을 사용했는지, 데이터 정합성이 어떻게 보장되는지는 오케스트레이션의 책임이 아닙니다. 오케스트레이션 계층은 결과를 관찰하고 다음 단계를 결정할 뿐입니다.

1
2
[ Orchestration Layer ]      ───────────────▶      [ Processing Layer ]
      (세부 작업 관리)                                      (세부 작업)




따라서 데이터 처리 로직, 대량 적재 전략, 변경 감지, 이력 관리 등은 신경 쓰지 않아야 합니다. 오케스트레이션이 처리 로직을 알게 되면 결합도가 높아지고, 처리 계층이 오케스트레이션 구조에 의존하면 유연성이 사라지기 때문입니다.

In computer software, business logic or domain logic is the part of the program that encodes the real-world business rules that determine how data can be created, stored, and changed. It is contrasted with the remainder of the software that might be concerned with lower-level details of managing a database or displaying the user interface, system infrastructure, or generally connecting various parts of the program.





3. 어디까지를 비즈니스 로직으로 봐야할까?


어디까지를 비즈니스로 볼 것인가? 는 결국 의미, 책임의 위치에 대한 문제인데요. 비즈니스란 데이터를 해석 하고, 판단과 상태 변화를 결정 하는 영역입니다. 반대로 파일을 내려받거나 압축을 풀고, 다른 스토리지로 복사하는 작업처럼 데이터의 내용을 이해하지 않고 수행되는 byte 단위 조작은 의미 해석이 없는 물리적 처리 에 가깝습니다. 이러한 영역은 비즈니스라기보다 인프라 또는 파이프라인 단계에 속합니다.

Business logic is the portion of an enterprise system which determines how data is transformed or calculated, and how it is routed to people or software.”




그러나 데이터를 해석하는 순간부터는 성격이 달라집니다. 변경 여부를 판단하고 상태를 종료하거나 새로 생성하는 로직이 개입되면, 그것은 단순 적재가 아니라 도메인 상태를 다루는 행위가 됩니다. 아래 항목 중 하나라도 해당한다면 그 영역은 비즈니스에 가깝습니다. 그때부터는 단순한 값이 아니라 의미와 규칙에 대한 책임을 다루기 때문입니다.

  • 데이터의 의미를 해석하는가
  • 조건에 따라 판단을 수행하는가
  • 상태를 변경하거나 관리하는가
  • 규칙이 바뀌면 함께 수정되어야 하는가




기존 데이터와 비교해 변경된 경우에만 반영하거나, 조건에 따라 이력을 남기도록 설계했다면 그것은 더 이상 단순 INSERT가 아닙니다. 데이터의 상태를 판단하고 관리하는 로직이 개입되는 순간, 그 영역은 비즈니스에 가깝습니다. 재처리 시 중복을 막거나, 특정 시점 기준 조회를 보장하는 요구 역시 상태와 규칙을 다루는 도메인 판단에 해당하기 때문입니다. 따라서 애플리케이션 로직으로 처리하는게 맞겠죠.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
@Service
class FeePolicyAdminService(
    private val feePolicyRepository: FeePolicyRepository,
    private val feePolicyHistoryRepository: FeePolicyHistoryRepository
) {

    @Transactional
    fun changeFeeRate(
        adminId: Long,
        feeId: Long,
        newFeeRate: BigDecimal
    ) {
        val policy = feePolicyRepository.findCurrentPolicyById(feeId)
            ?: throw FeeNotFoundException("수수료 정책이 존재하지 않습니다.")
        if (policy.feeRate == newFeeRate) {
            return
        }
        
        if(!policy.isChangeable(newFeeRate)) {
            return
        }

        policy.update(policy)
        
        // 상태를 추적하는 것도 비즈니스 로직
        feePolicyHistoryRepository.saveHistory(
            oldFeeRate = policy.feeRate,
            newFeeRate = newFeeRate,
            changedByAdminId = adminId,
            changedAt = LocalDateTime.now()
        )
    }
}




반대로 처리 규모나 성능과 같은 요소는 비즈니스가 아닙니다. 수백만 건을 청크로 나누어 적재하는 것, 인덱스를 일시적으로 제거하는 것, 병렬 처리 전략을 선택하는 것은 기술적 최적화입니다. 이는 처리 방식의 문제이지 데이터 의미의 문제는 아니기 때문입니다. 결국 비즈니스의 경계는 값을 어떻게 다룰 것인가? 가 아니라 그 값이 무엇을 의미하는가? 에서 결정됩니다. 값의 의미를 해석하고, 그 의미에 따라 상태를 정의하고, 규칙을 적용하는 영역이 비즈니스입니다.

  • 청크 사이즈를 1,000건으로 할지 10,000건으로 할지 결정하는 것
  • 배치를 단일 스레드로 돌릴지, 병렬로 나눌지 선택하는 것
  • 인덱스를 잠시 제거하고 적재 후 다시 생성하는 것
  • LOAD DATA INFILE을 사용할지, INSERT BULK를 사용할지 결정하는 것





4. 비즈니스 로직과 비즈니스 규칙


추가로 비즈니스 규칙비즈니스 로직 은 같은 말처럼 쓰이지만, 관점이 다릅니다. 이에 대해서도 간단히 살펴보죠.

  • 비즈니스 규칙
  • 비즈니스 로직



4-1. 비즈니스 규칙

비즈니스 규칙은 지켜야 할 기준입니다. 조직이 반드시 따라야 하는 정책이나 제약 조건을 선언적으로 정의합니다. 예를 들어 “수수료는 3%를 초과할 수 없다”, “유효 기간이 지난 정책은 적용될 수 없다”와 같은 문장은 규칙입니다. 이 문장은 절차를 설명하지 않으며, 단지 참이어야 하는 조건을 정의합니다.

  • 시스템이 반드시 지켜야 하는 제약과 기준을 정의
  • 변경되면 여러 로직과 화면, 배치에 광범위하게 영향을 미치는 정책 수준의 개념



4-2. 비즈니스 로직

반면 비즈니스 로직은 그 규칙을 시스템 안에서 실제로 동작하게 만드는 절차입니다. 수수료 변경 요청이 들어왔을 때 현재 값을 조회하고, 3% 초과 여부를 검증하고, 조건을 만족하면 상태를 변경하고, 변경 이력을 남기는 흐름 전체가 로직입니다. 즉, 규칙을 코드로 구현한 실행 과정입니다.

  • 규칙을 검사하고 판단하는 흐름을 포함
  • 조건 충족 여부에 따라 상태 변경, 저장, 이력 관리 등을 수행
  • 규칙을 실제 동작으로 구현하는 절차적 실행 과정





5. 정리


변경된 상태를 추적해야 하는 요구사항이 있었기 때문에 해당 로직은 스프링에서 처리하기로 했습니다. 단순 적재였다면 오케스트레이션 계층에 두어도 무방했겠지만, 상태를 판단하고 이력을 관리하는 순간 그것은 도메인 책임이기 때문입니다.


This post is licensed under CC BY 4.0 by the author.

MySQL의 시간 정밀도

원본 데이터는 언제 저장해야 할까?