태풍이 헛소동으로 끝나던 밤: PM은 어떻게 태풍을 견디듯 가장 어두운 순간을 버티는가
먼저 사람을 좀 불편하게 할지도 모르는 말 한마디부터 하겠습니다: 당신이 평생 겪을 “가장 어두운 순간”의 절대다수는 이번 태풍과 똑같은 결말을 맞습니다——헛소동으로 끝나죠. 그리고 “헛소동으로 끝났다”는 이 말은 태풍 자체보다 더 확실하게 PM 하나를 죽입니다.
올해 제9호 태풍 ‘바웨이’가 어젯밤 남쪽으로 꺾였습니다. 저우산을 정면으로 때리지 않고, 태풍급으로 약해지면서 저장성 원링에서 푸젠성 샤푸 일대 해안으로 향했죠. 그래서 저우산과 푸퉈 쪽에서는, 7월 9일에 이미 멈춘 여객선, 취소된 항공편, 그리고 밤새 정박지에서 선자먼 서부두로 옮겨 놓은 그 수많은 어선이——지나고 보니 다 헛수고처럼 보입니다. 오늘 아침 벌써 단체방에는 “이럴 줄 알았으면 밤새 배를 옮길 필요 없었네”라는 말이 올라옵니다.
이 말에서 잠깐 멈춰 봅시다. 왜냐하면 이 일 전체에서 가장 곱씹어 볼 만한 지점이, 바로 이 “이럴 줄 알았으면 안 해도 됐는데”라는 말 속에 숨어 있으니까요.
지난 글에서 저는 푸퉈산 이야기를 하면서, 관세음보살한테 태풍을 막아 달라 빌지 말고 방파제를 쌓으라고 했습니다——“명중당하지 않은 것”을 신비로운 가호 덕으로 돌리지 마라, 그건 잘못된 귀인이다. 이번 글은 여기서 한 걸음 더 나갑니다: 방파제를 다 쌓았고, 경보가 진짜로 울린 그날 밤, 지휘하는 당신은 대체 무엇을 해야 하는가?
제 대답은 이렇습니다: 태풍을 견디는 건 한 가지 동작이 아니라, 이어지는 세 가지 동작입니다——태풍이 오기 전에는 준비를 다지고, 태풍 한복판에서는 비바람을 감당하고, 태풍이 지나간 뒤에는 쓰레기를 치운다. 이 세 가지는, 열 번 중 아홉 번이 헛소동으로 끝난다 해도, 하나도 빼놓을 수 없습니다. PM의 가장 어두운 순간은 딱 이렇게 버텨 내는 겁니다.
1. 태풍이 오기 전: 당신의 침착함은 전부 예전에 쟁여 둔 것이다
가장 어두운 순간에서 가장 사람을 속이는 것은 “침착함”입니다.
어떤 사람은 시스템이 한밤중에 무너지고, 데이터가 어긋나고, 사장 전화가 걸려 와도, 여전히 자리에 앉아 하나하나 일을 정리해 냅니다. 당신은 이게 타고난 멘탈이고 순간의 임기응변이라고 생각하겠죠. 아닙니다. 가장 어두운 순간의 침착함은 단 1그램도 그 자리에서 자라난 게 아닙니다. 전부 평소의 그 “태풍 없는 날들”에 조금씩 쟁여 둔 것입니다.
제품을 만들고 시스템을 만드는 사람에게 “쟁인다”는 건 아주 구체적인 것들입니다: 언제든 눌러 버릴 수 있는 롤백 스위치 하나; 먼저 1%의 트래픽만 내보내 시험해 보고, 100%의 사용자를 한꺼번에 물속에 밀어 넣지 않게 해 주는 점진적 배포 체계; 사용자가 욕하기 전에 어디서 피가 새는지 먼저 알려 주는 모니터링·알람 한 겹; 문서로 적어 놓고 실제로 훈련까지 해 본 대응 매뉴얼; 그리고 평소에 조금씩 모아 둔, 아직 쓸 때가 오지 않은 신뢰와 현금흐름의 완충 여유.
여기서 핵심어는 “실제로 훈련까지 해 본”입니다.
2017-01-31, GitLab에서 오늘날까지 두고두고 회자되는 사고가 하나 터졌습니다. 한 엔지니어가 심야에 잘못된 데이터베이스에 삭제 명령을 한 줄 쳤고, 프로덕션 DB의 데이터를 날려 버렸습니다. 데이터를 날린 것 자체는 세상의 끝이 아닙니다——정말로 모두의 등골을 서늘하게 한 건 그다음에 벌어진 일이었죠: 그들에게는 백업과 복제 메커니즘이 다섯 종류나 있었는데, 파고 들어가 보니 어느 하나도 진짜로 쓸 수 있는 게 없었습니다. 자동 pg_dump 백업은 설정 오류 하나 때문에 사실상 한 번도 성공적으로 돌아간 적이 없었고; 백업 실패 시 원래는 메일로 알람이 가야 했지만, 그 알람 메일들은 DMARC 설정 때문에 조용히 거부되어 아무도 받지 못했으며; Azure의 디스크 스냅샷은 있긴 했지만 복구에 18 hours 넘게 걸렸습니다. 결국 GitLab을 절벽 끝에서 끌어올린 건, 한 엔지니어가 사고 6 hours 전에 어쩌다 수동으로 찍어 둔 스냅샷 하나였습니다. 이 “어쩌다” 하나 덕분에, 그들은 겨우 6 hours 치 데이터만 잃었죠.
이 사건은 “준비를 다진다”는 말의 진짜 의미를 피가 뚝뚝 흐르는 채로 펼쳐 보여 줍니다: 당신은 방파제를 쌓았다고 여겼는데, 태풍이 오고 나서야 그게 그림으로 그려 놓은 것이었음을 깨닫는다. 백업 다섯 종류, 듣기엔 철옹성 같았지만, 어느 하나도 진지하게 검증되고 훈련된 적이 없었습니다. 훈련해 본 적 없는 대응 매뉴얼은 매뉴얼이 아니라 소원 빌기입니다. 문서에 적어 놓은 그 “우리는 완비된 재해 복구 방안을 갖추고 있습니다”라는 문장은, 태풍이 오기 전까지는 축복 한마디와 다를 게 없습니다.
한술 더 뜨는 방식은, 아예 태풍이 오기를 기다리지 않는 겁니다. Netflix는 “Chaos Monkey”라는 프로그램을 하나 키웁니다. 이 녀석의 매일 하는 일은, 프로덕션 환경에서, 하필 바람 한 점 없는 대낮을 골라, 지금 서비스 중인 머신 몇 대를 무작위로 꺼 버리는 것입니다. 자해처럼 들리지만, 사실은 가장 정직한 훈련입니다——진짜 태풍이 오고 나서야 방파제가 그림이었음을 발견하느니, 차라리 매일 미친 원숭이 한 마리를 서버실에 풀어 놓고, 아직 사고 안 난 시스템을 먼저 한 번 무너뜨려서, 대체 메꿔지는지 안 메꿔지는지 봐 버리는 겁니다. Chaos Monkey를 버텨 낼 수 있는 그런 침착함이라야 진짜 침착함입니다; 이렇게 시달려 본 적 없는 침착함은, 그저 운이 아직 다 떨어지지 않은 것일 뿐입니다.
그래서 첫 번째 층위의 “헛소동”이 바로 여기서 나옵니다: 당신이 쟁여 둔 그 롤백, 훈련, 백업의 절대다수는 평생 한 번도 쓸 일이 없습니다. 쓸 일이 없으면, 헛일 했다는 기분이 들죠. 하지만 관점을 바꿔 보면——당신이 보낸 그 평온한 날들은, 운이 좋아서가 아니라 준비가 사 온 것입니다. “헛되이 준비만 하는” 일을 한 번도 겪지 않은 사람은, 그저 아직 차례가 오지 않았을 뿐입니다.
2. 태풍 한복판: 당신이 맨 앞에 서서 비를 맞아야 한다
준비를 아무리 잘해 놨어도, 태풍이 진짜로 얼굴을 덮치는 그 순간은 여전히 아픕니다. 이때 시험받는 건 다른 것입니다: 감당.
위기 한복판에서, 지휘하는 사람이 절대로 해서는 안 되는 두 가지가 있습니다——도망, 그리고 책임 떠넘기기.
도망은 자기를 숨기고 바람이 지나가기를 기다리는 것; 책임 떠넘기기는 “누가 그 버튼을 눌렀느냐”를 다급하게 찾는 것입니다. 이 두 동작은 그 순간엔 당신을 조금 편하게 해 주지만, 동시에 가장 값비싼 것을 죽여 버립니다: 당신의 팀이 앞으로 나설 용기를 아직 낼 수 있는가. 감당은 쉽게 말해 이걸 거꾸로 하는 겁니다——맨 앞에 서서, 지금 이 순간 가장 어렵지만 반드시 당장 내려야 하는 결정을 내리는 것. 먼저 지혈부터: 롤백할 건 롤백하고, 내릴 건 내리고, 쳐낼 건 쳐내고, 잘못은 인정하고, 사용자에게 알릴 건 내일로 미루지 말고. 계산은, 당신이 먼저 떠안습니다.
역시 GitLab의 그날입니다. 그들은 오늘날 봐도 대단히 반직관적인 일을 하나 했습니다: 공개 생방송을 켜 놓고 데이터베이스를 복구한 것. 수천 명이 온라인으로 지켜보는 가운데, 데이터를 날린 추한 일과 다섯 겹 백업이 전부 무용지물이 된 밑천을, 조금씩 펼쳐 보이고 조금씩 고쳐 나갔습니다. 이건 쇼가 아닙니다. 이건 “감당”의 가장 단단한 형태입니다——내가 망쳤고, 모두가 보는 앞에서 그걸 고쳐 낸다, 나는 숨지 않는다. 한 회사가 감히 이렇게 할 수 있어야, 팀의 엔지니어들이 알게 됩니다: 여기서는 사고가 나면, 첫 반응이 고치는 것이지 숨기는 것이 아니라는 걸.
사고만 나면 먼저 회의를 열어 책임부터 추궁하는 곳과 대조해 보세요. 사고가 터지면 모두가 제일 먼저 하는 일은 어떻게 자기를 떼어 놓을지 궁리하는 것입니다. 로그부터 얼른 백업하고, 채팅 기록 얼른 캡처하고, “이 모듈은 제 담당 아닌데요”가 입에서 튀어나오죠. 감당의 반대말은 당황이 아니라 떠넘기기입니다. 책임을 아래로는 팀에게, 밖으로는 “운이 나빴다”에게 떠넘기는 사람에 대해, 바람이 멎은 뒤 모두가 기억하는 건 그가 뒤로 움츠러들던 그 뒷모습뿐입니다.
이 대목이 세 가지 중 가장 어렵습니다. 비를 맞는 건 진짜로 춥거든요. 새벽 세 시, 일은 아직 실마리가 없고, 모든 눈이 당신을 노려보는, 그 맛은 견디기 힘듭니다. 하지만 당신의 팀이 그 순간 보는 건, 당신이 당황하는지 아닌지, 정답을 갖고 있는지가 결코 아닙니다——그들이 보는 건, 불길이 가장 셀 때 당신이 앞으로 한 걸음 나섰는지, 뒤로 한 걸음 물러섰는지입니다. 가장 어두운 순간이 진짜로 저울질하는 건, 바로 이 한 걸음의 방향입니다.
3. 태풍이 지나간 뒤: 온 바닥의 쓰레기가 진짜 시험장이다
태풍이 지나가고 하늘이 갠 순간, 가장 위험한 방심도 함께 옵니다. 많은 사람이 비바람은 버텨 냈으면서, 결국 “치우기 귀찮아서”에서 죽습니다.
바람이 멎은 뒤 온 바닥의 난장판, 그게 진짜로 실력이 드러나는 곳입니다. 치운다는 건, 단지 판을 깔끔하게 정리하고 시스템을 다시 돌아가게 하는 것——그건 복구일 뿐입니다. 진짜 치우기는 이번의 아픔을, 다음번엔 다시 밟지 않을 규칙 한 줄로 바꾸는 것입니다: 회고는 메커니즘까지 파고들어야 하고, 이번의 교훈을 다음번에 자동으로 발효되는 검증 한 가지, 제거된 위험 요소 하나, 갱신된 대응 매뉴얼 한 부로 바꿔야 합니다.
Knight Capital이 바로 치우지 않아서 죽은 경우입니다. 2012-08-01 아침, 고빈도 매매를 하는 이 회사가 새 코드를 배포했는데, 엔지니어가 서버 8대에 수동으로 배포하다가 1대를 빠뜨렸습니다. 하필 그 서버에는, 진작에 폐기됐는데도 아무도 지우지 않은 옛 기능 코드 한 조각이 남아 있었죠. 코드네임 “Power Peg”. 새 코드가 그것과 같은 이름의 스위치를 재사용하는 바람에, 갱신 안 된 그 머신에서 무덤 속에 누워 있어야 할 이 죽은 코드가 깨어나, 시장에 미친 듯이 주문을 쏟아 내기 시작했습니다. 45 minutes 동안 약 ~397 million shares을 체결했고 154개 종목이 얽혔으며, 세전 손실 $440 million. 이 회사는 그해 연말에 바로 인수되어 사라졌습니다.
이 사슬이 얼마나 짧은지 보세요: 진작에 지웠어야 하는데 지우기 귀찮았던 폐코드 한 조각에, 검증 없이 머신 한 대를 빠뜨린 배포 한 번이 더해져, 회사 하나를 통째로 죽였습니다. 이게 “치우지 않음”의 극단입니다——쓰레기는 시스템 안에 남아 있어도 저절로 사라지지 않습니다. 그저 조용히, 그것을 불붙일 불씨 하나를 기다릴 뿐입니다.
다시 GitLab을 돌아봅시다. 똑같이 치명적일 수 있었던 사고인데, 그들은 사후에 거의 자학에 가까울 만큼 공개적인 회고 보고서를 썼습니다. 다섯 겹 백업의 한 겹 한 겹이 어떻게 실패했는지 하나하나 명확히 나열하고, 그다음 한 조목씩 고쳐 나갔죠. 한쪽은 쓰레기를 면역력으로 쓸어 담았고, 한쪽은 쓰레기를 제자리에 남겨 두고 터지기를 기다렸습니다. 두 회사가 오늘날 각각 어떤 모습인지는, 당신도 아시죠.
치우기에는 또 유독 거꾸로 하기 쉬운 지점이 하나 있습니다: 메커니즘을 쓸어라, 사람을 쓸지 마라. 회고의 목적은 “다음번에 이 구덩이가 자동으로 메꿔지게” 하는 것이지, 재수 없게 버튼을 잘못 누른 그 사람을 색출하는 게 아닙니다. 일단 사람을 색출하기 시작하면, 모두가 배우는 첫 번째는 다음에 사고 나면 먼저 숨기는 것입니다; 당신이 메커니즘만 고치고 누구인지 묻지 않아야, 다들 가장 빠른 순간에 문제를 소리쳐 낼 용기를 냅니다. 이 “일을 따지되 사람을 따지지 않는” 회고는, 원래 인터넷 업계가 발명한 게 아니라 항공업에서 자라난 것입니다: 비행기 한 대가 추락하면, 조사팀의 전부의 목적은 같은 기종의 비행기가 앞으로 하늘에서 떨어지지 않게 하는 것이지, 그 조종사를 치욕의 기둥에 못 박는 게 아닙니다——왜냐하면 사람을 못 박기 시작하는 순간, 다음번에 실수한 승무원은 숨기기를 택할 것이고, 숨기면 다음 비행기는 더 참혹하게 떨어질 테니까요. Google은 나중에 이걸 자기네 SRE 핸드북에 써 넣으며 이름을 붙였습니다. “blameless postmortem”이라고. GitLab의 그 데이터를 날린 엔지니어는 공개 처형당하지 않았습니다. 이건 마음이 약해서가 아니라 정신이 맑아서입니다——한 번 아팠다고 성장이 아니라, 그 아픔을 다시는 반복하지 않을 규칙 한 줄로 바꿔야 성장입니다.
4. 다시 그 “이럴 줄 알았으면 밤새 옮길 필요 없었네”로
이제 다시 서두로, 오늘 아침의 그 “이럴 줄 알았으면 밤새 배를 옮길 필요 없었네”로 돌아가 봅시다.
이 말은 사실 지난 글에 나온 그 잘못된 귀인의 거울상입니다. 지난번에 사람들은 “평안”을 관세음보살의 가호 덕으로 돌렸고; 이번에 사람들은 “평안”을 “원래부터 사고 날 리 없었다”는 것으로 돌립니다. 한쪽은 공을 보살에게 적어 넣고, 한쪽은 공을 운에게 적어 넣습니다——둘 다 슬그머니, 당신을 대신해 다음번의 준비를 취소해 버립니다.
하지만 진실은 이렇습니다: 절대다수의 “헛소동으로 끝났다”는, 바로 준비가 성공한 모습입니다. 어떤 조직이 지난 몇 년 동안 단 한 번도 “헛수고 한판”을 겪은 적이 없다면, 가능성은 둘뿐입니다——자기를 속이고 있거나(요행 한 번 한 번을 전부 “우리 시스템은 문제없다”로 여기며), 아니면 이미 진짜로 한 번 뒤집혀서 피의 수업료를 치른 것이거나. Knight Capital은 “헛소동으로 끝난” 적이 없었습니다. 배포 전 사고가 안 난 매 순간을 전부 “프로세스에 흠이 없다”로 읽었기 때문이죠. 그렇게 읽어 나가다 그 45 minutes에 다다랐습니다.
태풍 ‘바웨이’가 이번엔 남쪽으로 갔으니, 저우산은 십중팔구 무사히 지나갈 겁니다. 하지만 그 어민들을 오늘 밤 잠들게 하는 건, 태풍이 마음을 바꾼 그 잠깐의 변덕이 아니라, 어젯밤 밤새 정박지에서 옮겨 놓은 그 배들입니다.
다음번 가장 어두운 순간이 정면으로 내리꽂힐지 아닐지는, 당신이 정할 수 없습니다. 당신이 정할 수 있는 건, 태풍을 견디는 사람이 결코 빼놓지 않는 그 세 가지뿐입니다: 태풍이 오기 전에는 방파제를 종이 위에 그리지 말고 진짜로 파도를 막을 수 있게 쌓고; 태풍 한복판에서는 대열의 맨 앞에 서서 그 비를 맞고; 태풍이 지나간 뒤에는 온 바닥의 쓰레기를 깨끗이 쓸어, 앞으로 다시 반복하지 않을 규칙 한 줄로 쓸어 담는 것. 이 세 가지를 온전히 해내면, 남들은 당신더러 운이 좋다고 할 겁니다; 이 세 가지에서 게으름을 피우면, Knight Capital의 그 45 minutes은, 조만간 당신 차례가 됩니다.
토론