개발/기획-개발 flow

KBO 야구 중계 서비스를 만들기 위한 도메인 이해와 아키텍처 설계

inspire12 2024. 3. 19. 16:45

 

시어머니만 1000만명’ 티빙, 야구중계 쉽지 않지요? [김동영의 시선]

 

최근에 티빙이 KBO 인터넷 야구 중계권을(뉴미디어) 구입하면서 인터넷 중계와 하이라이트 영상들을 유료화했습니다.

 

그러나 유료로 전환되는데 비해 서비스 품질이 좋지 않다는 비난이 많이 있습니다. 

 

저는 2019년도부터 2022년까지 4시즌 정도 야구 중계 서비스를 개발, 운영해 봤는데요. 야구 중계라는 게 개발자 입장에서 생각보다 만만치 않은 부분이 있습니다. 

 

첫 번째로 야구 중계 데이터는 실시간이고 수기입니다.

기본적으로 기록원이 야구 경기를 보면서 손으로 입력해 전달하는 시스템입니다. (서비스를 하던 시점에선 데이터 계약이 독점이라 다른 모든 서비스도 같았다고 알고있습니다)

 

기록원도 사람이다 보니 잘못 입력할 수도 있고 실수로 누락하거나 중복으로 보낼 때도 있습니다. 

사람이 입력하다 보니 당연히 실수가 있을 수밖에 없지만 초창기엔 기록원의 실수로 인해 시스템이 불안해지고 원망도 많이 했습니다. 

그러나 구조적으로 어쩔수 없는 것이다 보니 시스템이 이런 데이터수정에 대해 안정성을 갖춰야 합니다. 즉 데이터 클리닝과 재입력에 따른 멱등성 작업과 재생성에 따른 롤백이벤트와 그에 따른 시나리오들을 만들어야 놔야 합니다. 

 

텍스트로 데이터를 전달받게 됩니다. 

아마 문장으로 데이터를 적어서 보내면 기록원 입장에선 확인하기도 쉽고 빠르게 전송할 수 있어서 그렇게 한 것 같습니다만 개발자 입장에서 텍스트를 파싱해서 데이터를 처리하는 게 생각보다 큰 부담입니다. 

텍스트를 파싱하다보니 초반에는 예상치 못한 복잡한 상황 혹은 드물게 나타나는 상황 때문에 파싱 오류가 나는 경우도 많았습니다. 주자 상황과 교체 상황 때문에 이런 복잡한 상황들을 표현할 템플릿이 없는 경우도 있었습니다. 그런 예상치 못한 케이스에 맞게 실시간으로 프로그램을 수정하거나 아예 해당 데이터를 무시하고 나중에 대응하는 식으로 데이터 디버깅 작업도 필요했습니다. 

 

수기이다 보니 동명이인에 대한 처리가 애매합니다. 

동명이인 한 이닝 동반 홈런 '이병규의 날'

 

텍스트 파싱인데 만약 동명이인이 있다면 심지어 그 동명이인이

같은 팀이고

둘다 타자, 혹은 둘 다 투수이며

같은 경기에 나오게 된다면

 

실제로 LG엔 큰 이병규 작은 이병규로 두 명이 있는 경우도 있었죠

이런 경우 운영자가 라인업에 어떤 순서에 나오는 이병규가 큰 이병규인지 작은 이병규인지를 세팅해야 합니다. 

그런데 선발이 아니라 중간에 대타로 나오게 된다면? 이런 경우에 만약 운영자가 놓치게 되면 데이터 오염과 시스템 결함으로 직결되게 됩니다. 

 

두 번째로 야구는 데이터 자체에 정정이 많습니다. 

 

기록원이 기록을 잘 적어 보냈어도 문제일 수 있습니다. 야구는 경기 중 번복되는 경우가 엄청 많습니다.

스트라이크가 볼이 되는 경우도 아웃이 세이브가 되는 경우도, 아웃이 실책이 될 수도 있습니다. 

선수 교체가 잘못 전달 되는 경우도 자주 있습니다. 투수 타자뿐 아니라 주자, 수비 교체에 따른 데이터 변경도 고려해야 합니다.

 

심지어 타자가 투수로 올라오는 경우도 있습니다. 

 

세 번째로 경기 상태, 일정 변경에 따른 변화입니다. 

야구 데이터는 정규 경기와 포스트시즌 경기, 시범 경기 기록이 다 따로 처리해야 합니다. 

그리고 비가 오고 황사가 심한 등 컨디션에 따라 경기 전, 중 취소되는 경우도 많습니다. 그런 경우 일정 변경에 자유로워야 합니다. 

경기 중계 아키텍처

다음은 경기 중계를 위한 아키텍처입니다. 

경기 타입: 시범 / 정규 / 올스타, 이벤트 / 플레이오프

경기 상태: 경기 전 / 경기 중 / 중단 / 경기 종료 / 경기 취소

수집할 데이터 

데이터를 받아오는 기준은 투구입니다. 야구에선 투구가 이루어져야 상황이 전개되기 때문입니다. (인플레이)

 

데이터는 경기 시작 / 중간 / 끝에 따라 다릅니다.

위에 경기 상태가 이를 의미합니다. 각 상태에 따라 주로 수집하는 데이터는 다음과 같습니다.

경기 전 

경기 일정

  • 시작 시간 변경 여부 
  • 경기 취소 여부 (우천, 황사 등)
  • 더블헤더

라인업 정보 

  • 1군 등록 선수
  • 홈팀 / 어웨이 타순
  • 홈팀 / 어웨이  수비위치
  • 홈팀 / 어웨이  선발투수

경기 중

  • 경기 시작 여부
  • 투구 정보 
  • 이닝 시작/종료
  • 타구 정보 (홈런, 안타, 파울 등) 
  • 주자 변경 정보 
  • 득점, 스코어보드
  • 아웃 정보 
  • 선수 교체
  • 인게임 데이터 처리 

경기 후 

  • 경기 종료 
  • 시즌 선수 데이터 업데이트
  • 시즌 팀 데이터 업데이트 
  • 랭킹 업데이트

이런 데이터 수집은 이벤트 별로 airflow 같은 스케줄러 배치 툴을 통해 주기적으로 수집을 합니다. 

데이터 수집시 고려할 점

경기 전

경기 전엔 라인업 데이터가 변화가 자주 있습니다. 경기 시작 전 꼭 체크를 해줘야 합니다. 

경기 중

경기 중 엔 데이터 변화에 따른 클리닝 후 재생성 과정이 필요합니다. 이닝이 지난 후 심지어 경기가 끝난 다음에 기록이 바뀌는 경우도 많기 때문에 이런 부분도 고려해야 합니다. 때문에 경기내부 데이터를 계산하는 부분이 필요합니다. 실시간 데이터를 시즌데이터에 바로 적용하게 되면 클리닝을 적용하는 범위가 너무 많아지고 부작용이 일어나기 쉬워 경기 내에 데이터는 따로 저장하고 유저에게 보여주는 게 좋습니다. 

 

데이터를 클리닝은 꽤 까다롭습니다. 야구는 투구 카운트를 기준으로 카운트 안에서 일어난 일들을 시퀀스별로 처리하고 이를 id로 처리합니다. 전체 id에 대한 데이터 변경이 여부를 판단하는 로직이 필요합니다.

그리고 변경이 감지되면 변경된 데이터로 기존 데이터를 지우고 재생성을 이벤트를 전파합니다. 그러면 해당 투구 이후부터 만들어졌던 데이터는 각 서비스별로 지우고 들어온 데이터를 기준으로 새로 만들게 됩니다. 

야구 데이터는 해봐야 경기당 300개 정도안으로 끝나기 때문에 계산이 크게 부담이 되진 않습니다. 

경기 후

경기가 끝나고 데이터가 정리되는 새벽에 반영하는 게 좋습니다. 특히 랭킹 같은 경우 배치 계산이 필요합니다. 

만약 경기 끝난 직 후 실시간으로 기록 변화를 반영하고 싶다면 전날까지 기록된 시즌 데이터와 인게임 데이터를 계산해서 보여주고 새벽 배치가 지난 후 시즌 데이터로 보여주는 게 좋습니다. 

 

마치며

티빙이 KBO로 진출하면서 저도 야구 중계 플랫폼을 운영했을 때의 기억이 많이 났습니다. 야구를 좋아하는 입장에서 큰 비용은 아니라 결제는 할 생각입니다. 그러나 처음 생각한 것보다 생각지 못한 변수들이 너무 많을 것이고 그 대비를 아직 미처 다 하지 못한 것 같아서 굉장히 걱정이 됩니다.  

제가 적은 건 단순히 문자 중계에 따른 경기 데이터 전파와 기록에 대한 부분을 적었지만 팀을 응원하는 응원방, 팀별 유저 처리, 영상 스트리밍 부분, 경기 채팅 그리고 하이라이트 생성 등 할 일이 되게 많습니다. 저는 초기에 운영팀 없이 11시 넘어서까지 경기를 보는 일이 잦았지만 티빙에 개발자 분들은 부디 문제없이 잘 운영하시길 기원하겠습니다.

반응형