Post

처리대상 flag, 일배치, 재처리 관련 설계

상황 1.

1
2
거래원장_테이블 ------> 일배치_테이블
// 하루에 한번 [어제 있었던 거래+재처리 필요 거래]들을 대상으로 일배치를 돌린다.

‘재처리 필요 거래’를 처리하는 관점에서 크게 2가지 방법이 있다.
A. 거래원장_테이블에 update해서 처리 대상임을 표시하여 일배치에 포함시키는 방법
B. 일배치_테이블에 미리 적재하는 방법

A. 거래원장_테이블에 update해서 처리 대상임을 표시하는 방법

어제 있었던 거래 -> 생성하면서 처리 대상으로 표시
재처리 필요 거래 -> 재처리 필요해진 순간 처리 대상으로 표시하는 방법.
처리 대상 표시 방법은 [처리대상 flag를 두거나, 처리상태 code를 두거나, 처리일자 date]를 두는 방법으로 나뉜다.

A-1. 처리대상 flag를 두는 방법, 처리상태 code를 두는 방법

id처리상태
1REQUEST
2DONE
3(재처리필요)DONE->REQUEST
  • 재처리flag (또는 상태 code)만 변경하면 되니 제일 심플하고 간단해보이지만…
  • 단점이 있다. 재처리 flag=y만 잡아서 pagination 배치 처리 할 때, 배치 수행 중간에 y로 세팅되는 건이 생기면 그 항목이 끼어들면서 paging이 틀어져 처리 누락이나 PK 충돌 발생 가능성 있음.
    • 따라서 중간에 y로 세팅되더라도 paging이 틀어지지 않도록 하기 위해서, 보통은 flag를 y로 세팅하면서 동시에 기준시간도 업데이트하고, 배치 대상건을 특정 기준시간 이전인 항목만으로 격리 하게 된다.
    • 하지만 이렇게 대상건 판단 조건으로 기준시간 범위도 사용할거라면, 처리대상 flag를 두는게 그다지 의미가 없어진다. (기준시간 보면 되므로)
  • 다른 단점도 있다. 배치 종료하면서 flag를 n으로 업데이트하게 되니, 종료 후 처음부터 재수행해야 하는 case에서는 대상건들을 다시 y로 만들 Rollback 잡이 반드시 필요해진다.
  • 날짜로 끊을 수 없고 시간으로 끊어야만 하는 경우이면서, 이미 처리 완료된 항목이 다음 배치에서 조회되면 안되는 경우라면 처리대상 flag를 두는게 심플 할 수 있다.
    • e.g., 일 4회 호출되어야 하는 배치이면서 개별 항목에 대한 api call은 1번만 발생해야 한다면, 이전 배치 수행 시간~지금 배치 수행 시간 사이에 있는 항목들만 잡아서 처리해야 하는데, 배치 실패해서 수행 시간이 밀리고 재처리 하는 경우 등을 고려하면 시간으로 끊어 수행하는 것이 훨씬 편하다.

A-2. 처리일자 date를 두는 방법 👍

id처리일자
12023-03-25
22023-04-01
3(재처리필요)2023-03-29->2023-04-01
  • 상기했듯 배치 수행 중간에 추가된 대상건이 배치에 잡히는 것을 방지하기 위해서 어차피 ‘기준시간’을 사용하긴 해야한다.
  • 따라서 A유형 처리 방식 중에서는 처리일자 date를 사용하는 것이 제일 나아보인다.

B. 일배치_테이블에 미리 적재하는 방법

거래원장_테이블 id적재일자X일배치_테이블 id처리일자
12023-03-25X  
22023-04-01->2 (배치 수행 시 적재)2023-04-02
3(재처리필요)2023-03-29->3 (어드민 요청 시 미리적재)2023-04-02
  • 재처리 대상건은 어드민에서 ‘재처리’ 눌렀을 때 일배치_테이블에 미리 적재. 어제 있었던 거래는 일배치가 돌 때 적재하는 방식.
  • 이 방식도 단점이 있다. 오늘 일배치가 돌 때 적재 예정이었던 건을 ‘재처리’로 미리 적재하게 되면, PK 충돌 발생 가능성이 있음.
  • 그러면 ‘재처리’ 눌렀던 건들은 일배치 적재에서는 제외해야 하는데…
    • 일배치_테이블에 미리 적재되어 있는지 체크? => 꽤나 까다롭다.
    • 거래원장_테이블에서 처리대상 flag=n으로 만들기? => 이렇게 처리할거면 미리 적재가 아니라 일배치 적재 시 함께 적재되도록 표시하는 방식(A)이 나음.결국 방법 A가 된다.
  • 아니면 오늘 일배치 처리 예상 건인 경우, ‘재처리’ 요청을 불가능하게 만드는 방법도 있다.
    • 애초에 오늘 일배치 처리 예상 건이라는 건, 아직 처리 완료가 되지 않은 건이라는 의미이고,
    • 처리 완료가 되지 않은 건에 대한 재처리는 불가능하게 막아두는게 논리적으로 옳아보인다.

특정 건들은 지연처리 해야 하는 케이스?

A, B 방식 모두 사용 가능하다. A로 가는 경우 거래원장_테이블의 처리일자를 미래로 set. B로 가는 경우 일배치_테이블에 처리일자를 미래 날짜로 적재.

상황 2.

1
2
3
4
5
거래원장_테이블 ------> 일배치_테이블
// 하루에 한번 대상건들을 잡아 일배치를 돌린다. 대상건 조건은 아래와 같다.
1. 원장에 적재되어 있으며, 아직 처리완료되지 않았고, 선행 배치 처리가 완료된 항목
    (선행 배치 처리가 언제 완료될지는 개별 건마다 다름)
2. 처리완료되었으나 재처리 필요한 항목

이전 배치 처리가 언제 완료될지 모르고, 개별 건마다 완료 시점이 다르기 때문에 이런 경우 [처리대상 flag와 처리일자 date]를 모두 사용하는 것이 나을 수 있다.

  • 방법 1) [처리대상flag=y && 처리요청일자<=오늘 && 선행조건만족] 조건으로 잡아서 처리
  • 방법 2) [처리일자=오늘] 조건으로 모두 잡아서
    • [선행조건만족]인 항목들은 일배치_테이블에 insert 처리.
    • [not 선행조건만족]인 항목들은 거래원장_테이블에 처리일자++ update 처리.
  • 두 방법 모두 가능하다. 상황에 맞게 적용.
    • 방법1은 배치가 하루쯤 돌지 않아도 다음날 도는 배치에 누락된 대상건이 자동으로 포함 되지만, 방법 2는 반드시 매일매일 배치가 돌면서 처리일자를 +1 update 해주어야 누락이 발생하지 않는다.
    • 방법1은 처리요청일자를 범위 로 잡기 때문에 최대 몇개월 전까지만 탐색 할 것인지를 정해야 한다. 보통 파티션키로 세팅하는데, 이 범위를 벗어난 너무 오래전 항목에 대해 재처리 요청하는 경우, flag=y임에도 처리대상으로 포함되지 않게된다.
      • 운영하다 보면 이렇게 오래된 항목(e.g., 6개월 전)에 대한 재처리가 필요한 경우가 가끔 있어 꽤나 난감하다.
This post is licensed under CC BY 4.0 by the author.