DEV Community

finaltype
finaltype

Posted on Originally published at finaltype.github.io

[260716] 끊긴 건 15초였는데, 피해는 4시간 45분이었다

와이파이가 잠깐 끊겼다가 조용히 반쪽짜리 연결로 남아있었던 사건과, 그 김에 다시 세운 "가장 싼 걸 가장 위험한 것에 의존시키지 말자"는 원칙

어제 예고했던 그 사고 이야기입니다. 원인을 다 파헤치는 데 하루가 꼬박 걸렸는데, 그만큼 배운 것도 많았습니다.

끊긴 건 15초, 피해는 4시간 45분

집 와이파이가 새벽에 잠깐(15초 정도) 끊겼습니다. 그런데 로그를 뜯어보니 실제 피해 시간은 4시간 45분이었습니다.

연결이 끊겼다가 같은 공유기에 다시 "접속 성공"은 했는데, 정작 인터넷이 실제로 되는 상태로는 못 돌아왔습니다. 겉보기엔 연결돼 있지만 데이터가 하나도 안 오가는, 반쪽짜리 연결 상태로 몇 시간을 그냥 있었던 겁니다. 그러다 새벽에 우연히 다른 무선 채널로 넘어가면서 그제서야 완전히 복구됐습니다.

더 놀라운 건, 운영체제는 이미 4분 만에 "지금 인터넷이 제대로 안 된다"는 걸 정확히 알고 있었다는 겁니다. 상태를 낮춰서 계속 표시하고 있었는데, 아무도 그 신호를 보고 있지 않았을 뿐입니다. 그래서 결론을 하나 새로 세웠습니다 — 문제가 있었는지 없었는지는 "그때 신호가 있었는가"가 아니라 "누가 그 신호를 실제로 읽었는가"로 갈린다는 겁니다.

이번 일로 밤사이 자동으로 돌아가던 작업 몇 개가 몇 시간씩 헛돌았습니다. 데이터를 놓친 작업들은 대부분 나중에 다시 받아오면 되는 것들이라 복구가 가능했지만, 복구가 아예 안 되는 작업 하나는 그날 몫을 접어야 했습니다.

재미있는 반전도 하나 있었습니다. "연결이 끊겼다"는 신호만 너무 믿으면 이번엔 반대 방향 실수가 나옵니다. 실제로 그렇게 짜여 있던 다른 자동화 하나가, 일시적 끊김을 "완전히 끊겼다"로 오판해서 무한히 재시도만 반복하는 사고를 낸 적도 있었습니다. 결국 "신호 하나만 보고 단정하지 말고, 실제로 확인해보고 판단하자"는 게 이번 사고 전체를 관통하는 교훈이었습니다.

가장 싼 작업을 가장 위험한 작업의 성공에 의존시키지 말자

같은 날 밤, 야간 자동 분석이 절반도 못 끝내고 멈추는 더 큰 사고가 겹쳤습니다. 원인은 세 가지가 한꺼번에 겹친 복합 사고였는데, 그 중 하나가 방금 얘기한 네트워크 문제였습니다.

이 사고를 계기로 오래 미뤄뒀던 설계 원칙 하나를 확정했습니다. 예전부터 "분석에 쓸 입력 데이터를 미리 다 얼려두고 나서 무거운 계산을 시작하자"는 아이디어가 있었는데, 그때는 "계산 도중에 얼려도 충분하다"고 판단해서 미뤄뒀습니다. 그런데 이번 사고로 그 판단이 틀렸다는 게 실제로 증명됐습니다.

생각해보면 당연한 얘기입니다. 입력 데이터를 준비하는 건 몇 분이면 끝나는 가벼운 작업이고, 그 다음 무거운 계산은 몇 시간씩 걸리면서 네트워크 문제 등 여러 변수에 노출됩니다.

그런데 그동안은 가벼운 작업의 결과가 무거운 작업이 끝까지 성공해야만 완성되는 구조였습니다. 제일 안전해야 할 것(입력 기록)이, 제일 위험한 것(몇 시간짜리 계산)이 성공해야만 완성되는 구조였던 셈입니다.

이번에 이 순서를 뒤집었습니다. 입력부터 먼저 확실히 저장해두고, 그 다음에 무거운 계산을 시작하도록 바꿨습니다.

여기서 일반화할 수 있는 원칙이 하나 나왔습니다. 데이터가 오래된 것과 데이터가 틀린 것은 다르게 취급해야 한다는 겁니다.

그냥 며칠 묵은 데이터로 어제와 비슷하게 판단하는 정도는 크게 위험하지 않습니다. 하지만 서로 다른 시점의 데이터가 뒤섞여서 겉보기엔 멀쩡한데 실제로는 앞뒤가 안 맞는 숫자가 나오는 건 훨씬 위험합니다. 전자는 계속 진행해도 되고, 후자는 무조건 멈춰야 합니다.

경보를 언제 울릴지에 대한 원칙도 다시 세웠습니다. "이 알림을 받은 사람이 지금 당장 할 수 있는 행동이 있는가?"가 기준입니다. 없으면 그건 급하게 알릴 일이 아니라 나중에 모아서 봐도 되는 일입니다.

그 밖에

  • 실계좌 주문 처리 로직에서도 중요한 걸 하나 확정했습니다. 주문 결과는 "성공"과 "실패" 두 가지만 있는 게 아니라, "결과를 알 수 없음"이라는 세 번째 상태가 있어야 한다는 겁니다. 응답을 아예 못 받은 경우를 그냥 "실패"로 뭉개버리면, 사람이 그 말을 믿고 수동으로 다시 주문을 넣었다가 실제로는 이미 처리된 주문이 두 번 나갈 위험이 있습니다. 이번에 이 세 번째 상태를 명시적으로 다루도록 고쳤습니다.
  • 예전에 만든 뉴스 심리 신호 관련 실험도 계속 다듬었습니다.

오늘 정리한 원칙 중 가장 마음에 드는 건 "위험한 작업에 안전한 걸 묶어두지 말자"는 겁니다. 당연한 말 같지만, 실제로 사고가 나기 전까진 그 결합이 문제라는 걸 몰랐습니다.

Top comments (0)