Casey가 AWS 장애를 분석합니다 | The Standup

TThe PrimeTime
컴퓨터/소프트웨어경영/리더십AI/미래기술

Transcript

00:00:00이번 스탠드업 에피소드는 케이시가 인트로를 맡기 때문에 특별할 거예요.
00:00:05케이시, 오늘은 무슨 얘기를 할 건가요?
00:00:07안녕하세요 여러분, 스탠드업에 오신 걸 환영합니다.
00:00:09최근 뭔가에 따르면 스포티파이에서 45, 6번째로 좋은 기술 팟캐스트라고 하더군요.
00:00:12사실이에요.
00:00:13아무튼, 죄송합니다.
00:00:14오늘 스탠드업에서는 제가 다루고 싶은 주제가 있어요.
00:00:1610월에 발생한 AWS 장애에 대해 이야기할 건데요, 사실 더 큰 주제를 다루고 싶어서 이걸 꺼낸 거예요.
00:00:20바로 실제로 뭔가를 이해하는 것과 이해한다고 말하는 것의 차이에 대해서요..
00:00:29특히 프로그래밍 경력 초기에 있는 사람들에게 자주 일어나는 일 중 하나인데요,
00:00:32예를 들어 주니어 프로그래머거나 막 입문한 경우 말이죠.
00:00:34저도 분명히 그랬는데, 뭔가를 안다는 인상을 주고 싶잖아요, 그렇죠?
00:00:37무슨 일이 벌어지는지 모른다는 걸 들키고 싶지 않은 거죠.
00:00:40그래서 외부적인 압박이 많이 있어요.
00:00:41실제로 있든 없든, 뭔가를 이해했다고 말해야 할 것 같거나 이해한 척해야 할 것 같은 느낌을 받게 되죠.
00:00:46사실은 좀 애매하거나 완전히 이해하지 못했는데도 말이에요..
00:00:49그리고 본인 잘못이 아니더라도,
00:00:51예를 들어 설명이 제대로 안 됐거나 중요한 정보가 빠져 있었더라도,
00:00:57여전히 그걸 알고 있었던 것처럼 행동해야 한다는 압박을 느끼게 되죠,
00:01:03그렇죠?
00:01:03그게 더 똑똑해 보이게 하거나, 최소한 주니어처럼 보이지 않게 해주니까요.
00:01:09그래서 제가 나이를 먹고 프로그래밍 경험을 더 쌓으면서 발견한 것 중 하나는,
00:01:16요즘엔 거의 과하다 싶을 정도로 설명을 요청한다는 거예요.
00:01:20멍청해 보이는 것에 대해 전혀 신경 쓰지 않아요..
00:01:26"잠깐만요, 다시 설명해 주세요.
00:01:33그 부분은 이해 못 했어요.
00:01:38그게 무슨 뜻이에요?" 또는 "그 용어는 무슨 의미예요?" 같은 식으로 물어봐요?
00:01:54이제는 그런 걸 별로 신경 쓰지 않거든요.?
00:02:03그렇게 걱정하지 않아요.
00:02:04그리고 실제로 알고 싶어요.
00:02:06왜냐하면 뭔가를 안다고 생각했거나 아는 척했다가 나중에 큰 낭패를 본 경험이 너무 많거든요..
00:02:12그래서 진짜 알고 싶어요.
00:02:13버그에 대한 설명이 있거나 성능 저하의 원인을 안다고 생각할 때, 항상 머릿속 한편으로는 이렇게 생각해요.
00:02:16'내가 진짜 근본 원인까지 파고들지 않았다면, 다른 뭔가일 수도 있어.
00:02:18진짜 원인이 아직 숨어 있을 수도 있는데 내가 끝까지 파보지 않아서 모르는 거일 수도 있지.
00:02:20그냥 편하니까 넘어가는 거 아닐까.'.
00:02:22진짜로 알고 싶어요.
00:02:23버그에 대한 설명이 있거나 성능 저하의 원인을 안다고 생각할 때도,
00:02:29항상 머릿속 한편에서는 '정말 이게 근본 원인까지 파고든 건지,
00:02:35아니면 진짜 원인이 아직 어딘가에 숨어 있는 건 아닐까.
00:02:39끝까지 살펴보지 않아서 모르는 건 아닐까.
00:02:43그냥 편하니까 넘어가려는 건 아닐까'라고 생각해요..
00:02:48제가 DynamoDB 장애에 대해 이야기하고 싶었던 이유는 최근에 주목할 만한 대규모 장애들이 연달아 발생했기 때문입니다.
00:02:57구글을 먹통으로 만든 큰 장애가 있었는데, 알고 보니 필드가 비어있는 경우를 처리하지 않은 게 원인이었죠.
00:03:04그러니까 프로그래밍 방식이,
00:03:06JSON을 불러오는데 JSON에 아무것도 없으면 널 포인터를 역참조하거나 뭐 그런 식이었던 거죠.
00:03:13말 그대로 그런 거였어요.
00:03:15그리고 CrowdStrike 장애도 있었는데, 블루스크린으로 전 세계를 먹통으로 만들었죠.
00:03:21그들은 정말 훌륭한 설명을 제공했는데,
00:03:24특정 배열 크기 조정 방식을 사용하는데 규칙이 너무 많아서 배열이 오버플로우됐다는 거였어요.
00:03:31이런 것들은 RCA, 즉 근본 원인 분석이라고 부르는 걸 제공했을 때 꽤 괜찮았습니다.
00:03:37왜 시스템이 다운됐는지 설명했을 때요.
00:03:39제가 그걸 읽었을 때 머릿속에 미해결 질문이 많이 남지 않았어요.
00:03:44문제가 된 코드 라인을 정확히 알지는 못했을 수도 있어요.
00:03:48실제 코드 조각을 공개하지 않았을 수도 있으니까요.
00:03:52하지만 충분한 정보를 줘서 저는 '아,
00:03:54누군가 이 코드를 어떻게 작성했는지 이해하겠고,
00:03:58그들이 저지른 멍청한 짓도 이해하겠다'는 생각이 들었습니다.
00:04:02그러니까 저런 짓은 하지 말라는 거죠.
00:04:05이해합니다.
00:04:05그리고 전 완전히 납득했어요..
00:04:10DynamoDB 장애의 경우는, 이 팟캐스트에서 다뤄졌잖아요?
00:04:15우리가 그 얘기했을 때, 기타 센터에 있던 그 사람이요.
00:04:20펍에서 누가 얘기하는 걸 우연히 들었다고 했던 거요..
00:04:24놀랍습니다.
00:04:25여기 찾기 어려운 프로그래머를 봅니다.
00:04:27대부분의 시간을 혼자, 종종 어둠 속에서 작업하는 단순한 생명체입니다.
00:04:31하지만 이게 뭔가요?
00:04:32인터넷에서 누군가 틀린 말을 하고 있네요.
00:04:35우리의 코더가 행동에 돌입합니다.
00:04:37분당 120단어의 최고 속도에 도달하다가 라이트 모드 웹사이트가 번쩍입니다..
00:04:42이 코드 애호가들의 천적이 우리 친구를 기절시킵니다.
00:04:45추격은 중단됐습니다.
00:04:46다음 기회에 잡아야겠네요.
00:04:47컴퓨터 앞에 있지 않을 때, 그들은 몇 시간이고 조잡한 기호들을 그리며 시간을 보낼 수 있습니다.
00:04:52그들이 화이트보드라고 부르는 것이죠.
00:04:54연구자들은 수천 개의 방언을 발견했으며, 단일 사무실에서만 십여 개 이상이 사용되는 경우도 있습니다.
00:04:59하지만 아직 어떤 언어학자도 그 목적이 무엇인지 해독하지 못했습니다..
00:05:03허영심 많은 생명체들입니다.
00:05:05그들의 신체는 수천 년에 걸쳐 진화하여 온라인에서 자신을 보면서 특이한 자세로 앉을 수 있게 되었습니다.
00:05:11이것은 종종 몇 시간 동안 지속되며 코드 리뷰를 기다리고 있다는 핑계를 댑니다.
00:05:17하지만 왜 그렇게 활동이 없는지 추궁당하면...
00:05:20그리고 마침내, 거의 아무것도 이루지 못한 긴 하루가 끝나고, 우리의 키보드 전사는 잠잘 준비를 합니다.
00:05:26빠르게 읽고는 불을 끕니다..
00:05:29잘 자, 작은 코더야.
00:05:30그래서 제가 밤에 어떻게 그렇게 잘 자냐고요?
00:05:33Sentry가 버그들을 박살내는 걸 도와주거든요.
00:05:36그리고 저는 겨울에 죽는 사우스다코타의 작고 귀여운 벌레들 말하는 게 아닙니다.
00:05:41크고 사나운 정글 벌레들을 말하는 겁니다.
00:05:44그리고 저는 그 어떤 것도 무섭지 않아요.
00:05:47그냥, 하지만 저는 Sentry의 Seer로 그 버그들을 박살낼 수 있습니다.
00:05:52그래서 저는 그것에 대해 좀 더 의욕이 생겨서 가서 보기로 했죠.
00:05:57그들이 얼마나 많은 정보를 게시했는지요.
00:05:59그리고 이미 어느 정도 읽었는데, 나중에 그들이 RCA를 게시한 요약본이 있었고 매우 모호했어요.
00:06:06RCA는 실제로 많은 것을 설명하지 않았습니다.
00:06:09그러다가 그들이 12월 re:Invent에서 전체 프레젠테이션을 게시한 걸 알아챘어요.
00:06:15아니면 re:Invent가 12월이었는지는 모르겠지만,
00:06:19비디오는 12월에 올라왔는데 이 장애를 다룬 re:Invent 프레젠테이션이었습니다..
00:06:26그래서 그걸 다 봤습니다.
00:06:28전체 RCA를 다 읽고 전체 프레젠테이션을 다 본 후에도, 여전히 이런 생각이 들더라고요.
00:06:35여기서 실제 버그에 대한 설명이 보이지 않는다고요.
00:06:39실제 버그가 뭐였는지 알아내려고 노력했는데 전혀 설명되지 않았어요..
00:06:45그래서 제가 하고 싶었던 건 그냥 그것에 대해 이야기하고,
00:06:48왜 그들이 버그가 무엇인지 제대로 설명하지 않았다고 생각하는지 짚어보면서,
00:06:52사람들이 그냥 '아,
00:06:53알겠어.
00:06:53버그가 뭔지 알았어'라고 넘어가서는 안 된다는 예시로 삼는 거였어요.
00:06:57사람들이 제게 답글을 달면서 '아,
00:06:59제가 버그가 뭔지 설명해드릴게요'라고 하고는 똑같은 얘기만 반복하더라고요.
00:07:02전 '그게 버그가 아니에요'라고 하는데 말이죠.
00:07:05그래서 모두가 '나는 이해했어'라고 말하도록 유도되는 거예요.
00:07:08읽었으니까요.
00:07:09하지만 아니에요.
00:07:10실제 버그가 뭐였는지 말해주지 못한다면, 우린 아직 끝난 게 아닌 거죠..
00:07:14좀 더 완전한 설명이 있어야 한다는 거죠.
00:07:16그래서 제가 말하는 게 다 합리적으로 들리나요?
00:07:19네.
00:07:19우선, 말씀드리고 싶은 건, 저는 케이시가 말하는 걸 정확히 알았어요..
00:07:23처음부터요, 맞죠.
00:07:25바로요.
00:07:25당신은 '알겠어요, 당신이 말하는 거 정확히 알아요.
00:07:30제 쪽에서 질문 없어요.
00:07:32막히는 거 없어요.
00:07:34다들 감사합니다.
00:07:35전 좋아요'라고 하는 것 같았어요..
00:07:39내일 봐요.
00:07:39아무 문제없어요.
00:07:40그냥 말하고 싶은 건,
00:07:42저는 Spotify에서 들을 때 팟캐스트에서 케이시가 말하는 걸 듣는 게 정말 좋아요.
00:07:47그리고 지금 당장도요.
00:07:49한 시간 동안 당신 얘기 들을 수 있을 것 같아요.
00:07:52Spotify 언급도 정말 좋네요.
00:07:54제가 막 말하려던 참이었어요.
00:07:56특히 Spotify에서 들으면 음질이 엄청나다고요.
00:07:59보너스 추가분도 받잖아요, 맞죠?
00:08:01실제 에피소드 전후의 모든 잡담을 다 들을 수 있어요.
00:08:04우리가 Spotify에 더 길고 긴 버전을 올리기 시작했거든요.
00:08:08더 많은 추가분이 들어간 버전이요.
00:08:10네.
00:08:11본론에서 벗어난 얘기는 덜하지만, Spotify에는 좀 더 잡담이 많아요.
00:08:15왜냐하면 라이브 청중들은 잡담을 듣거든요..
00:08:19여기 들어와서요.
00:08:20트래시와 그의 포켓몬 중독에 대해서도 듣게 되죠.
00:08:23당신은 아마 모를 거예요.
00:08:24왜냐하면 YouTube에서 이걸 듣고 있으니까요, 그렇죠?
00:08:27재미있는 얘기들을 다 듣지 못하는 거예요.
00:08:29YouTube 영상의 처음 10분으로는 꽤 팔기 어려운 내용이죠.
00:08:32YouTube 영상으로는 정말 힘든 판매죠.
00:08:34'나는 내가 이해도 못하는 걸 네 명이 얘기하는 걸 볼 거야.
00:08:37그리고 그게 다이나모 DB라고 불리는 거래'가 되는 거니까요.
00:08:40맞아요..
00:08:41팟캐스트를 시작하는 김에 아담을 소개해야 할 것 같은데요. 아, 그러네요. 아주 좋은 지적이에요.
00:08:45전혀 안 했네요. 안녕하세요. 오늘 팟캐스트에 나오신 이유를 좀 말씀해주세요.
00:08:50왜냐하면 제가 TJ네 집에 있거든요.
00:08:53첫 번째 이유,
00:08:541번 이유는 TJ가 자기 집에 방문하는 모든 사람에게 팟캐스트에 나올 것을 요구하기 때문이죠.
00:09:02몇 번은 좀 어색했죠.
00:09:03네.
00:09:04맞아요.
00:09:04당신은 정말 누구세요??
00:09:07AWS 히어로라는 것 외에요. 저는 그것도 아니에요. AWS 히어로가 아니었어요. 알겠어요.
00:09:13슈퍼히어로 그룹에서 쫓겨났다고요. 그게 어떻게 작동하는 거예요? 그냥 갱신이 안 되는 건가요?
00:09:18저는 한 번만 히어로였고 그들이 결정한 거죠.
00:09:20'아, 당신은...' 돈 내는 건가요.
00:09:22히어로가 되려면 돈을 내야 하나요?.
00:09:24아니요, 아니에요.
00:09:25그냥 저는 더 이상 그것에 대해 신경 쓰지 않았어요.
00:09:28전혀 얘기 안 했거든요.
00:09:29그래서 그들이 '어쩌면 그는 더 이상 히어로가 아닐지도 몰라.
00:09:32이제 그는 빌런이야'라고 한 거죠.
00:09:34케이시는 마치 살인 미스터리의 일부처럼 보이네요.
00:09:36거기 서 있는 게.
00:09:37오 이런.
00:09:37우리가 곧 뭘 보게 될 거냐면, 어, 뭐더라?
00:09:40닉 힐.
00:09:40보드에다 전부 그림 그리는 그 사람이요.
00:09:42그리고 나타나잖아요.
00:09:43케이시 무라토리.
00:09:44당신이 생각하는 사람이 그 사람이죠.
00:09:46무라토리.
00:09:46무라토리인가요, 아니면 무라토리인가요?
00:09:48오 세상에.
00:09:49곧 시각자료 쓰실 거죠?
00:09:50그래서 제가 이게 최고의 팟캐스트라고 하는 거예요..
00:09:54말 그대로 이게 참여하기에 최고의 팟캐스트예요.
00:09:57어, 우리 가족은 무라토리라고 발음해요.
00:10:00마치 거기에 Y가 있는 것처럼, 무라토리라고요.
00:10:03하지만 맞는 발음이에요.
00:10:05별로 말이 안 되는 게, 이탈리아어거든요.
00:10:08이탈리아 이름이에요.
00:10:09그리고 이탈리아어로는 무라토리나 무라토리일 거예요..
00:10:13말이 안 되죠.
00:10:14그래서 왜 무라...
00:10:16가 된 건지 전혀 모르겠어요.
00:10:18이탈리아계 미국인 같은, 이민자들 사이에서 일어난 일인 것 같아요.
00:10:23모르겠어요.
00:10:24좋아요.
00:10:24그래서 기본적으로 그들이 말한 건 이거예요..
00:10:28그들은 API 엔드포인트라고 부르는 것들을 가지고 있는데, 그걸 그렇게 부르죠.
00:10:34그리고 이것들은 도메인 주소입니다.
00:10:37DNS에서 찾아볼 때, DynamoDB 요청을 어디로 보내야 할지 알기 위해 찾게 될 이름이죠.
00:10:44그리고 이것들은 아마 이렇게 생겼을 겁니다..
00:10:47그리고 Adam이 아마 확인해줄 수 있을 거예요. 왜냐하면 그는 영웅이거나, 영웅이었으니까요.
00:10:53이것들은 마치, 아 뒤에 있네요.
00:10:55네.
00:10:56우리가 몇 초 뒤처져 있어요.
00:10:58리버에서 비디오가 사라졌거든요.
00:11:00아, 됐네요.
00:11:01그래서 이것들은 dynamodb.use-east-1.api.aws 같은 형태로 생겼습니다.
00:11:07그리고 IPv6를 사용하는지 IPv4를 사용하는지에 따라 달라지는 것 같아요.
00:11:12상황에 따라 다른 이름을 가지거나, 특정한 것을 사용하는지에 따라서요.
00:11:16정부 기관은 다른 것을 사용한다고 언급했던 것 같고요.
00:11:20그래서 이 이름들은 기본적으로 애플리케이션에 하드코딩하는 이름들입니다.
00:11:24DynamoDB로 뭔가를 해야 할 때, 이걸 요청하는 식이죠.
00:11:28이게 말이 되나요.
00:11:30그리고 맞게 들리나요.
00:11:31Adam, 왜냐하면 저는 AWS 관련 것들을 사용하지 않거든요.
00:11:35네?
00:11:36네?
00:11:36네.
00:11:37맞아요..
00:11:38그래서, 당신은 이런 것을 요청하게 되고 완벽하게 전송하게 됩니다.
00:11:42제 말은, 그가 무슨 말을 하는지 알겠어요.
00:11:45네.
00:11:46그러면 그게 어딘가로 리디렉션될 거예요.
00:11:49왜냐하면 분명히 전 우주의 모든 DynamoDB 트래픽을 처리할 단일 머신 같은 건 없을 테니까요.
00:11:56여기서 볼 수 있듯이 지역별로 세분화한다고 해도, 어느 지역을 선택해야 하는 것 같아요.
00:12:02추측하건대, 메인 주소로 보내는 게 아니라 지역 주소로 보내는 거죠.
00:12:07아니면 알아서 처리해줄 메인 주소가 있을 수도 있고요.
00:12:11잘 모르겠어요..
00:12:13어쨌든,
00:12:13어느 시점에서 이것과 통신하게 되는데,
00:12:16이것은 기본적으로 로드 밸런싱 체계 같은 것을 가리켜야 합니다.
00:12:21그래서 이것은 기본적으로 그들이 DNS 트리라고 부르는 것을 가리켜야 하죠..
00:12:27비록 그들이 트리의 특성에 대해 전혀 설명하지는 않았지만요.
00:12:31오히려 그냥 가중치 배열 같은 것처럼 들렸어요.
00:12:34여기 여러 머신들이 있고, 로드 밸런싱을 위해 우리가 설정한 가중치에 따라 그 머신들을 선택하는 거죠.
00:12:41그래서 머신이 뒤처지면 가중치를 낮게 설정하고, 머신이 비어 있는 것 같으면 가중치를 높게 설정하는 식이죠.
00:12:48그래서 그들은 그걸 트리라고 불렀어요.
00:12:50그래서 트리라고 가정하는 건데, 트리 부분이 뭔지는 설명하지 않았어요.
00:12:55하지만 이 이름은 가리켜야 합니다.
00:12:57잠깐만 끼어들어도 될까요??
00:13:00그런데, 실제로 누군가가 그 트리로 L6 승진을 받았다고 하더라고요.
00:13:03그래서 다음번에는 그 트리가 뭔지 알아보셔야 할 것 같아요.
00:13:06왜냐하면 그게 누군가에게는 정말 중요했던 거니까요.
00:13:09좋아요.
00:13:09패킷도 있었고 엔지니어들도 있었죠.
00:13:11동의해요.
00:13:11트리는 아마 중요할 거예요.
00:13:13단지 버그에는 중요하지 않았을 뿐이죠.
00:13:15그리고 그것조차도, 그래서 제 말은 그들이 트리를 설명할 필요가 없었다는 거예요..
00:13:19그래서 그들이 트리가 뭔지 건너뛴 건 괜찮다고 봐요. 하지만 저도 간단한 질문이 하나 있어요.
00:13:25네.
00:13:26그게 근본 원인 분석(root cause analysis)이라서 트리라고 부르는 건가요, 아니면 아닌가요??
00:13:29더 이상 농담은 안 돼요.
00:13:31너무 주제에서 벗어났어요.
00:13:33죄송해요.
00:13:33죄송해요.
00:13:34어쨌든, 이것은 그걸 가리켜야 합니다..
00:13:37그리고 이런 DNS 항목들의 로드 밸런싱 방식이 있는데,
00:13:41발표에서 이것을 설명한 방식은 plan145.dynamodb.ddb.aws 같은 걸 사용한다는 거예요.
00:13:49이게 그 트리의 루트인데, 근본 원인 분석이 아니라 이 트리 구조에서 루트라는 말이에요.
00:13:55여기에는 로드 밸런싱을 가능하게 하는 여러 레코드들의 최상위 레코드가 포함되어 있죠.
00:14:01그리고 Route 53이 이런 로드 밸런싱 기능을 가지고 있을 거라고 추측해요.
00:14:07발표 내용을 읽으면서 유추한 건데,
00:14:09그들이 직접적으로 말하진 않았지만,
00:14:12Route 53이 자체 DNS 시스템이고 이걸 통해 모든 걸 처리하는데,
00:14:17여기에 로드 밸런싱이 어떻게 작동해야 하는지 설정해두면 그게 가능해지는 것 같아요.
00:14:23그러면 일종의 무작위 방식과 가중치 같은 걸 기반으로 올바른 머신을 선택하는 거죠.
00:14:29그런데 그들이 말한 건,
00:14:31실제로 존재하는 이 이름이나 이런 식의 트리 같은 게 있는데,
00:14:35이 이름은 발표용으로만 사용한 거라는 거예요.
00:14:38실제로는 plan145 같은 사람이 읽을 수 있는 이름을 사용하지 않았대요.
00:14:44실제로는 뭔가를 해시한 값이었다고 해요.
00:14:46그러니까 실제로는 0aFE129a 같은 게 들어가 있었을 거예요.
00:14:51그래서 실제로 가서 보면 사람이 읽을 수 있는 이름은 보이지 않았을 거예요.
00:14:56적어도 그 당시에는요.
00:14:58plan145 같은 건 안 보이고 그냥 해시값만 보였을 거예요.
00:15:03그래서 아이디어는 이런 거죠.
00:15:05사용자가 이걸 사용하려고 하면 이 이름을 쿼리하고,
00:15:08Route 53이 여기로 연결해주는데,
00:15:11이게 일종의 로드 밸런싱 트리고 Route 53이 이걸 사용해서 당신이 가야 할 곳으로 보내주는 거예요.
00:15:18결국엔 실제로 트래픽을 보낼 수 있는 머신을 알려주는 거죠.
00:15:23근데 또 그들은 그런 부분을 설명하지 않아서 그게 어떻게 작동하는지는 전혀 모르겠어요.
00:15:29Route 53을 만져본 적도 사용해본 적도 없어서 모르겠지만, 어쨌든 그렇게 된다고 가정하죠.
00:15:36이 버그하고는 상관없으니까요..
00:15:41AWS 전문가가 있으니까 혼란스러우면 Adam한테 물어보면 되죠.
00:15:46더 많은 인사이트를 줄 수도 있을 거예요.
00:15:49그래요, 해보세요..
00:15:50Route 53에는 트래픽을 분할하는 여러 가지 방법이 있어요.
00:15:53그래서 네, 가중치 방식도 그 중 하나고, 그들이 설명한 게 그런 것 같네요..
00:15:57어떻게든 이런 레코드들을 그렇게 설정해놨는데, 어떻게 했는지는 말 안 했어요.
00:16:01하지만 뭔가 트리 형식으로 그걸 했죠.
00:16:04제 추측으로는 트리에 가중치가 있는 것 같아요.
00:16:06최상위에 몇 개의 가중치가 있고 거기서 더 많은 가중치로 분기되는 식으로요.
00:16:11레코드가 많으니까 그게 처리하기 더 쉬웠을 거예요..
00:16:14누가 알겠어요. 어쨌든 모르겠어요. 요점은 이게 정상적으로 일어나야 하는 일이라는 거죠.
00:16:20이제,
00:16:20실제로는 해시 코드였을 텐데 여기서 plan145라고 부르는 이유는,
00:16:26상상하시겠지만 로드 밸런싱이 계속 지속되어야 하기 때문이에요.
00:16:31DynamoDB 머신들이 항상 뭔가를 하고 있으니까요.
00:16:35과부하가 더 걸리기도 하고, 머신이 다운되거나 크래시되거나 누가 알겠어요, 그렇죠??
00:16:43오프라인으로 전환될 수도 있고, 새로운 용량이 추가될 수도 있습니다.
00:16:48그래서 이런 것들은 항상, 정말 항상 업데이트되어야 합니다.
00:16:53그래서 여러분이 연결하는 이 메인 API 엔드포인트는 그것이 가리키는 트리를 지속적으로 조정해야 합니다.
00:17:01그래서 그들이 하는 방식은 또 다른 트리, 즉 이동할 트리를 만드는 겁니다.
00:17:08예를 들어, 플랜 146 같은 걸 만드는 거죠.
00:17:11그리고 여기에 전체 트리를 만듭니다.
00:17:14그런 다음 준비가 되면,
00:17:16이 트리가 완성되면,
00:17:18이 레코드를 가져와서 저것을 가리키는 대신 이것을 가리키도록 하는 겁니다.
00:17:24즉, 새로운 것을 만들고, 그냥 그 이름을 바꿔서 이것으로 옮기는 거죠.
00:17:30그런데 어떤 이유로, 이 이유는 실제로 설명되지 않았는데요..
00:17:36그들이 그 프로세스를 설정한 방식은 두 개의 조각으로 나누는 것입니다.
00:17:41기본적으로 새로운 트리가 어떻게 생겨야 하는지 파악하는 플래너(planner)라는 것이 있습니다.
00:17:47그래서 플래너라고 불리는 어떤 머신이 있다고 상상할 수 있습니다.
00:17:52그게 실제 머신인지 아니면 다른 것들을 실행하는 어떤 머신에서 실행되는 프로세스일 뿐인지는 모르겠습니다.
00:17:59하지만 플래너라고 불리는 무언가가 있습니다.
00:18:01그리고 제가 파악한 바로는, 단 하나만 있습니다.
00:18:05즉, 우리가 전환할 새로운 플랜이 어떻게 생겨야 하는지 파악하는 플래너가 하나 있다는 뜻입니다..
00:18:13그리고 이것은 계속 작동합니다.
00:18:15그래서 플랜 145를 생성하고,
00:18:17그 다음 플랜 146을 생성하고,
00:18:20그 다음 147,
00:18:21148,
00:18:229,
00:18:2210,
00:18:23뭐 그런 식으로 계속되는 거죠?
00:18:25그리고 영원히 플랜을 계속 내놓습니다.
00:18:28그게 그것의 일이니까요.
00:18:30그런데 실제로는 그것들을 생성하지 않는 것 같습니다.
00:18:34그것의 일은 Route 53에 실제로 만드는 게 아닙니다.
00:18:38누군가가 Route 53에 넣는다면 그것들이 어떻게 될지 파악하는 것이 일입니다.
00:18:44그런 다음 세 개의 인액터(enactor)가 있습니다..
00:18:50이 인액터들은 플래너로부터 플랜을 받아서 Route 53에 넣습니다.
00:19:06이해가 되나요?
00:19:07자, 제가 발음을 이해한 바로는 플래너 하나, 인액터 세 개입니다.
00:19:11왜 이렇게 되어 있는지에 대한 설명은 없었습니다.
00:19:15그들은 인액터가 세 개인 이유는 장애 허용(fault tolerant)을 위해서라고 했습니다.
00:19:20즉, 그 중 하나가 다운되거나 하는 경우를 대비해서요.
00:19:24하지만 그렇다면 왜 플래너도 세 개가 필요하지 않은지는 설명하지 않았습니다.
00:19:29왜냐하면 플래너가 다운되면 인액터들이 실행할 것이 없거든요.
00:19:32그래서 별로 말이 안 됐습니다.
00:19:34그래서 왜 이 구조가 이렇게 생겼는지에 대한 설명이 발표에 없었습니다.
00:19:39이것이 이렇게 생긴 것이 버그와 크게 관련이 있는 것은 아니지만,
00:19:43나중에 보겠지만 어느 정도는 관련이 있습니다.
00:19:46그래서 저는 그들이 이것을 정당화하지 않았다는 사실에 약간 이상하다고 느꼈지만, 괜찮습니다.
00:19:51아무튼 이해가 되길 바랍니다.
00:19:53우리는 플래너가 하나 있습니다.
00:19:55인액터가 세 개 있습니다.
00:19:57인액터들은 모두 이 플랜을 실행하려고 합니다.
00:19:59자,
00:20:00여기서 일어나는 일은,
00:20:01다시 말하지만,
00:20:02그들이 발표에서 말한 유일한 것은 "추론하기 더 쉽게 만든다"는 것이었습니다.
00:20:07이것이 유일한 정보였습니다.
00:20:09그들은 추론하기 더 쉽게 만든다고 말했습니다.
00:20:12추론하기 더 쉽게 만들기 때문에, 이 인액터들은 직렬화(serialization)를 사용합니다.
00:20:18그래서 그들이 그냥 레코드를 만들려고 하고,
00:20:20레코드가 이미 있으면 그냥 만들지 않는 것이 아니라,
00:20:24다시 말해서,
00:20:24세 사람이 실행되고 있습니다..
00:20:29우리 모두 이 최상위 레코드, plan146.ddb.aws를 만들고 싶어 합니다, 맞죠?
00:20:36우리 모두 그걸 하려고 노력하고 있어요.
00:20:39우리 중 한 명이 먼저 해요.
00:20:41다음 사람이 하려고 하면 이미 거기에 있거나 뭐 그런 거죠?
00:20:44우리 모두 같은 레코드를 만들려고 하는 거예요.
00:20:48그래서 이론적으로는 세 사람이 계획의 어떤 부분을 처리하려고 하든 무작위로 마구 두드려도 이론적으로는 다 잘 작동해야 하는 거죠?
00:20:56그리고 발표자가 직접적으로 말하지는 않았지만, 제가 방금 말한 것에 동의할 것 같다는 느낌을 받았어요.
00:21:03즉, 그들이 그냥 임의로 실행하게 해도 괜찮았을 거라는 거죠.
00:21:07하지만 그는 추론하기 쉽게 만들기 위해 직렬화를 사용한다고 말했어요.
00:21:11그 의미는 이 실행자들이 그렇게 마구 두드리는 대신,
00:21:15업데이트하려는 엔드포인트에 대한 락을 획득하려고 시도한다는 거예요.
00:21:19다시 말해서,
00:21:20이 사람이 이것들 중 하나를 업데이트하려고 한다면,
00:21:23그리고 제가 받은 느낌은 이것을 업데이트하려고 한다면이었는데,
00:21:27이것을 업데이트하려고 한다면일 수도 있고,
00:21:30아니면 둘 다일 수도 있었어요.
00:21:32제 기억이 맞다면 락킹이 정확히 어디에서 발생하는지 100% 명확하게 말하지는 않았어요.
00:21:38하지만 락킹은 그들이 "좋아, DNS 레코드인 락을 만들 거야"라고 하면서 발생해요.
00:21:44그리고 Route 53이 원자적이라는 개념을 가지고 있다는 사실을 이용해서,
00:21:49즉 두 가지를 할 수 있는데 둘 다 성공하지 않으면 둘 중 어느 것도 하지 않는다는 거죠.
00:21:55그들은 기본적으로 Route 53을 통해 락을 거는 락킹 시스템을 만들었어요.
00:22:00그래서 Route 53의 DNS 레코드가 실제로 락 레코드인 거죠, 이해가 되나요??
00:22:08빠른 질문 해도 될까요?
00:22:10네.
00:22:11직렬화를 통해 이걸 한다고 하셨는데요?
00:22:14무슨 뜻인지 잘 이해가 안 가요.
00:22:16직렬화는 한 메모리에서 다른 메모리 표현으로 변환하는 거라고 생각했거든요.
00:22:22죄송해요, 다른 직렬화예요.
00:22:24네, 그것도 직렬화예요.
00:22:26이 경우에는 말 그대로 시간적 직렬화를 의미하는데,
00:22:30이 실행자들이 임의로 동작하는 게 아니라 어떤 순서로 행동을 조직화할 수 있는 방법을 원했다는 거예요.
00:22:38그리고 그들이 그렇게 한 방법이 락킹이었어요.
00:22:42그래서 일어나는 일은,
00:22:43이 사람이 하려는 일을 그냥 하는 대신,
00:22:46예를 들어 "좋아,
00:22:48이거 끝냈으니까 이 녀석을 계획 146에 연결할 거야"라고 하는 대신,
00:22:53이것에 대한 락을 획득하려고 시도하는 거죠?
00:22:57그리고 락을 얻지 못하면 변경하지 않아요.
00:23:00그래서 이 실행자들 중 한 명만 주어진 시간에 이것을 업데이트하는 과정에 있을 수 있어요.
00:23:07이해되나요?
00:23:08음.
00:23:09다시 말하지만, 그들이 정확히 왜 그렇게 하려고 했는지는 설명되지 않았어요.
00:23:15그냥 추론하기 쉽게 만든다고 말하고 거기서 끝났어요.
00:23:19그래서 왜 그들이 이게 개선이라고 생각했는지 모르겠어요.
00:23:23그리고 재미있게도, 이게 결국 버그를 발견하게 만들었어요.
00:23:28그래서 개선이 아니었죠.
00:23:29어쩌면 오히려 나빴을 거예요.
00:23:32그래서 Casey, 그들이 좋은 이유가 없다는 거예요?
00:23:36실행자들을 거의 한 번에 하나씩 실행하게 만들겠다고 하는데, 왜 실행자가 세 개나 있나요?
00:23:43이해가 안 가요.
00:23:44왜 하나만 두지 않나요?
00:23:46그냥 말하지 않았어요.
00:23:48우리는 이유를 몰라요.
00:23:50그리고 정확히 설명하지도 않았어요.
00:23:52세 개의 동시 실행자가 있는데 대한 설명을 정말 듣지 못했어요.
00:23:57그들이 다운될 수 있을 거라고 예상하는데, 그래서 세 개가 있는 거죠..
00:24:07맞아요. 하지만 락을 걸잖아요. 그럼 이 녀석이 락을 걸고 다운되면 어떻게 되나요?
00:24:13그러니까, 그것에 대한 설명도 들은 적이 없어요.
00:24:17그래서 이게 저한테는 정말 혼란스러웠죠.
00:24:19여기서 우리가 논의하는 내용의 일부로 불평하는 건 아니에요.
00:24:23왜냐하면 저한테 중요한 사안은 아니거든요.
00:24:26하지만 발표 자체로서는 정말 궁금한 게 많았어요.
00:24:29솔직히 왜 이런 걸 했는지 전혀 이해가 안 되더라고요.
00:24:33맞죠.
00:24:33그리고 아마 그건 다시 말하지만, 제가 AWS 서비스를 안 쓰기 때문일 수도 있어요.
00:24:39Route 53 같은 걸 정기적으로 사용하는 사람이라면 이런 것들 중 일부가 당연하게 느껴질 수도 있겠죠.
00:24:46아, 락에 타임아웃을 설정할 수 있기 때문이구나, 뭐 그런 식으로요.
00:24:50모르겠어요.
00:24:51그렇죠.
00:24:51어쨌든, 그래서 그들은 그렇게 하고 있었고요.
00:24:54결과적으로 어떤 일이 벌어지냐면,
00:24:57이 버그를 발견하게 된 계기가 된 일인데요,
00:24:59이 실행자들이 락을 얻지 못하면 그냥 백오프를 하는 거예요.
00:25:03맞죠?
00:25:04기본적으로 그냥 괜찮아, 좀 기다렸다가 다시 시도할게, 이런 식이죠.
00:25:08그래서 실행자, 이 실행자가 락을 얻으려고 하는데 다른 누군가가 이미 락을 갖고 있어요.
00:25:14그래서 잠깐 기다렸다가 락을 다시 얻으려고 시도하죠.
00:25:17그런 일이 벌어지는 거예요.
00:25:19맞죠.
00:25:20그리고 그들이 말하길, 병리학적 케이스라고 표현했는데요, 실행자 중 하나가 어떤 플랜을 실행했어요.
00:25:26그 플랜이 꽤 오래된 거였다고 해봅시다.
00:25:29그들이 예시로 110을 사용했던 것 같아요.
00:25:32그래서 플랜 110을 실행했죠.
00:25:34그리고 API가 제 110을 가리키도록 설정해야 한다고 생각하는 거예요.
00:25:38dynamodb.use.one인가 뭔가 그런 걸 업데이트하기 위해 락을 얻으려고 시도하는데,
00:25:44다른 누군가가 플랜 111 같은 걸 실행하고 있어서 실패하는 거죠.
00:25:49아니면 플랜 109일 수도 있고, 이전 플랜일 수도 있고요.
00:25:53그래서 다른 실행자들이 그걸 하고 있어요.
00:25:55이 실행자는 할 수가 없죠.
00:25:57백오프하는 거예요.
00:25:58맞죠..
00:26:02그리고 기억하세요, 여기 이 실행자는 110에 있어요. 시도하고 있고, 정말로 실행하고 싶어 하죠.
00:26:07다시 시도해요.
00:26:08다른 누군가가 락을 갖고 있네요.
00:26:10또 시도해요, 여전히 잠겨있어요.
00:26:12이 사람은 110에 붙어서 필사적으로 실행하려고 하는데 할 수가 없어요.
00:26:16명백히 이게 너무 많이 반복됐고,
00:26:18그 사이에 다른 실행자들과 플래너는 계속 새 플랜을 만들어내고 있는 거예요.
00:26:22맞죠..
00:26:23다른 실행자들은 145나 146 정도까지 올라가서 110보다 훨씬 앞선 플랜들을 실행하고 있어요.
00:26:30맞죠.
00:26:30그리고 이 친구는 여전히 멈춰있죠.
00:26:33운이 없게도 락을 한 번도 못 얻어서요.
00:26:36맞죠.
00:26:36마침내,
00:26:37플랜 145가 이미 다른 실행자에 의해 실행되고 가리켜지고 그런 일들이 다 일어난 후에야,
00:26:43플랜 110,
00:26:44이 실행자가 여전히 시도하다가 마침내 락을 얻게 돼요.
00:26:48그러니까, 그렇죠.
00:26:49그래서 그가 말하는 거예요, 좋아, 이제 우리는 110을 가리키고 있어.
00:26:54그렇죠.
00:26:55맞죠..
00:26:58그래서 이제 엄청 오래된 낡은 플랜을 가리키고 있는 건데, 사실 이게 문제가 되지는 않아야 해요. 맞죠.
00:27:03왜냐하면 결국 다음번에 어떤 실행자가 뭔가를 갖게 되면, 그건 훨씬 나중 플랜일 테니까요.
00:27:07그냥 플랜 146이나 147이나 148 뭐 그런 걸 실행하겠죠.
00:27:11그리고 이걸 다시 가리키면 우리는 다시 새 플랜으로 돌아가요.
00:27:14그래서 모두가 몇 분 동안 나쁜 로드 밸런싱을 겪겠지만, 그 다음엔 괜찮아질 거예요.
00:27:18맞죠.
00:27:19실제로 적어도 몇 분 동안은 나쁜 로드 밸런싱을 겪긴 했어요..
00:27:22맞죠. 네. 사실이에요. 근데 그것보다 훨씬 더 심각했어요. 그게 일어났어야 했던 일이죠. 맞죠.
00:27:30그러니까 그들도 이렇게 작동할 거라고 예상했다는 거죠.
00:27:34알겠어요.
00:27:35문제는 이것들이, 그들은 또한 Route 53이 이 모든 레코드들로 막히는 걸 원하지 않았어요.
00:27:42왜냐하면 그냥 놔두면, 결국 석 달 후에는 Route 53에 약 80억 개의 레코드를 쌓아놓게 되니까요.
00:27:50몇 분마다 이 큰 가중치 트리 같은 걸 넣는 거잖아요.
00:27:54그들은 생각했죠, 좋아, 어느 시점에서는 이 플랜들을 정리해야 해..
00:28:00그래서 enactor들은 특정 시간보다 오래된 플랜도 찾습니다.
00:28:04그리고 특정 시간보다 오래되면 삭제하죠.
00:28:07그래서 일어난 일은, 플랜 110을 가리키게 된 겁니다.
00:28:11이 enactor가 마침내 락을 획득합니다.
00:28:14110을 가리키죠.
00:28:15다른 enactor는 "오, 와우, 110이라니, 엄청 오래됐네.
00:28:20이거 제거해야겠다"라고 생각하고 삭제합니다.
00:28:23그러니까 이제 DynamoDB us-east-1.api.aws가 해결될 수 없는 레코드를 가리키게 된 겁니다.
00:28:30맞죠.
00:28:31실제로는 플랜 110처럼 보이지 않고 OAFE129A 같은 해시값,
00:28:36점,
00:28:36그리고 DDB.aws 이런 식으로 보일 겁니다.
00:28:39하지만 그 이름을 가리키고 있는데, 그 이름을 조회하면 아무것도 나오지 않습니다..
00:28:46그래서 그 시점에 일어나는 일은,
00:28:48데이터를 보낼 엔드포인트를 가져오려는 모든 사람들이 기본적으로 해결할 수 없는 이름을 받게 되는 겁니다.
00:28:54맞죠.
00:28:55그리고 Route 53에서 그런 일이 발생하면 정확히 무슨 일이 일어나는지는 잘 모르겠지만,
00:29:00기본적으로 사용할 수 없거나 IP 대신 횡설수설하는 값을 받게 될 겁니다.
00:29:04누가 알겠어요.
00:29:05하지만 어떤 값이든, 실제로 사용하려고 시도하면 응답을 받을 수 없을 겁니다.
00:29:09맞죠..
00:29:10흥미롭네요.
00:29:11이게 AWS가 Rust를 충분히 사용하지 않아서 그런 건가요?
00:29:15명백하게 use-after-free 버그잖아요.
00:29:18그래서 Rust를 사용했으면 해결됐을 거라고 생각하시나요?
00:29:21Route 53을 완전히 Rust로 다시 작성했다면, 분명히 이런 문제들은 없었을 거라고요.
00:29:27아니요,
00:29:28구체적으로 말하면,
00:29:29프레젠테이션에서 언급했던 걸로 기억하는데,
00:29:31Rust에 대한 얘기는 아니었지만 구체적으로 무슨 일이 일어나는지 설명했었습니다.
00:29:37이것 또는 저것을 조회하면,
00:29:38어느 쪽을 말하는 건지 정확히 기억은 안 나지만,
00:29:41레코드를 찾을 수 없다는 응답을 받게 된다고 했던 것 같습니다.
00:29:45그게 최종 결과예요.
00:29:47이것을 조회하든 저것을 조회하든, 확실하지는 않지만, 그냥 레코드를 찾을 수 없다는 응답을 받게 됩니다.
00:29:53그게 그 API를 호출하려고 할 때 받게 되는 응답이었죠.
00:29:57그래서 DynamoDB를 사용하기 위해 어떤 라이브러리를 사용하든, 그냥 "야, 레코드 못 찾았어.
00:30:03미안"이라고 할 겁니다.
00:30:05맞죠.
00:30:05그래서 인터넷에 있는 누구에게나 물어보면, 다들 "응, 버그를 설명했어.
00:30:10그게 버그야.
00:30:10race condition이 있었다는 거지"라고 합니다.
00:30:14모두가, race condition이라고 말하는 순간 모두의 뇌가 멈춰버립니다.
00:30:19"오, 알겠어, race condition이었구나.
00:30:22끝"이라고 하죠.
00:30:23볼 것 없다는 식으로요.
00:30:25맞죠?
00:30:25그래서 다들 "race condition이야.
00:30:28설명했잖아"라고 하는데, 아니에요, 설명 안 했어요.
00:30:31왜냐하면 여기서 무슨 일이 일어날지 생각해보면,
00:30:34바로 직후에 모두가 이걸 받게 되고,
00:30:37새로운 enactor가 그냥 새로운 걸 enact할 겁니다.
00:30:40맞죠?
00:30:41그래서 진짜 버그는, 왜 그게 일어나지 않았냐는 겁니다.
00:30:44제가 보고 싶었던 진짜 RCA는 왜 다음 actor가 와서 고치지 않았냐는 거예요.
00:30:50다른 것도 얘기해볼까요?
00:30:51이것도 버그 아닌가요?
00:30:52즉시 삭제되어야 할 정도로 오래된 레코드를 왜 쓰는 거죠?
00:30:56음, 그건 이 녀석이 꽤 오래 전에 썼기 때문이었어요.
00:30:59그리고 그건...
00:31:00음, 만약 왜 더 나은 코드로 actor를 작성하지 않았냐고 묻는 거라면, 네, 그것도 괜찮은 질문이네요..
00:31:11좋아요, 맞네요.
00:31:12즉시 삭제되어야 할 것으로 업데이트하는 건, 그게 바로 문제인 것 같은데요.
00:31:17훨씬 이전에 뭔가 잘못한 거잖아요.
00:31:19네,
00:31:20이것의 이론적 구조를 실제로 고치지는 못하더라도,
00:31:23이 녀석이 락 대기에서 백오프를 마친 후에 간단한 체크를 하나 하는 게 좋을 것 같아요.
00:31:29삭제 코드를 실행한다면 자기가 삭제할 만한 값으로 설정하려고 하는 건 아닌지 확인하는 것이 아마 좋은 안전 조치일 겁니다.
00:31:37하지만 네, 100% 동의합니다.
00:31:39좋아요, 하지만 enactor가 그 레코드를 얻으려고 정말, 정말 열심히 일했어요.
00:31:45오랫동안 기다렸죠.
00:31:46오, 포켓몬 카드를 가질 거예요..
00:31:49누가 기다렸든. 그러니 그냥 레코드를 쓰게 놔두세요. 좋아요. 그래서, 그래서 그것에 대해 듣고 싶네요.
00:31:56안타깝게도, 발표 자료를 보면, RCA를 봐도, 그 내용이 어디에도 없습니다.
00:32:03발표 자료에는 적어도 12초짜리 아주 작은 부분이 하나 있는데,
00:32:10거기서 버그가 대략 어디에 있을지 언급하긴 합니다.
00:32:15그래서 그게 뭔지 설명해드리겠습니다.
00:32:19명백히 이런 일이 함께 발생하는데,
00:32:22DynamoDB us-east-1을 사용할 때,
00:32:27그걸 플랜에 연결하면서 동시에 다른 작업도 수행합니다.
00:32:32그 작업은 롤백을 설정하는 겁니다..
00:32:40DD인 것 같은데요. DDB.rollback.AWS였나요? 정확히 기억이 안 나네요.
00:32:49롤백 레코드가 있습니다.
00:32:50그 레코드를 이전 플랜이 무엇이었든 그것으로 설정합니다.
00:32:55만약 여기서 145를 가리키고 있었는데,
00:32:57이제 110을 가리키려고 한다면,
00:33:00이 옛날 작업자가,
00:33:01저는 110으로 이동하고 있어요,
00:33:04라고 하면서 설정을 시도하는 거죠.
00:33:06현재 이 이름이 무엇이었든 가져와서, 그 이름을 이동시킵니다.
00:33:11플랜 145였을 텐데, 그걸 이동시켜서 롤백 주소가 이전 플랜을 가리키도록 합니다..
00:33:18맞습니다. 그리고 이건 그냥 디버깅용입니다. 또는, 기본적으로 운영자의 편의를 위한 거죠, 그렇죠?
00:33:24이전 플랜으로 롤백하고 싶거나 뭐 그런 경우를 위한 거죠.
00:33:28또는 이전 플랜이 뭐였는지 알고 싶으면 여기서 볼 수 있는 거고요, 맞죠?
00:33:32그게 그들이 장애에 대해 말한 방식의 첫 번째 부분입니다.
00:33:36여기서 한 가지 지적하고 싶은 게 있는데, 이것도 저한테는 전혀 이해가 안 갔어요.
00:33:41왜냐하면 제 생각엔,
00:33:42좋아요,
00:33:43이것들이 1분마다 업데이트된다고 말씀하시는 건데,
00:33:46그런 걸 하나 가지고 있는 게 무슨 소용이에요?
00:33:48로그인할 때쯤이면 이미 롤백하려던 것에서 새로운 것으로 업데이트됐을 텐데,
00:33:53그게 실제로는 원하지 않는 플랜이잖아요.
00:33:55모든 게 다운됐으니까요, 맞죠?
00:33:57그러니까, 맞죠?
00:33:58이건 원하지 않는 거예요.
00:34:00그냥 이름들을 리스트로 가지고 있어야 해요.
00:34:02그래야 12시 30분에 뭐였지?
00:34:04저거였어, 이렇게 할 수 있잖아요, 맞죠?
00:34:07그래서 이건 저한테 전혀 말이 안 됐어요.
00:34:09왜 이게 좋을 수 있는지 정말 전혀 모르겠어요, 맞죠?
00:34:12실제로 원하는 일을 할 것 같지 않았거든요.
00:34:15원하는 건 특정 시점을 표시해서,
00:34:17오후 1시로 돌아가야 해,
00:34:19그 이후로 모든 게 엉망이 됐으니까,
00:34:21이렇게 할 수 있는 거잖아요,
00:34:22맞죠??
00:34:26어쨌든, 그래서 저한테는 말이 안 됐어요.
00:34:29하지만 다시 말하지만, 버그와 정확히 관련된 건 아니니까.
00:34:32그래서 왜 그런지 묻지 않았어요.
00:34:34그냥, 좋아요, 그게 해야 하는 일이군요.
00:34:36그리고 한 버전만 롤백할 수 있다는 거죠, 그렇게 말씀하시는 거죠.
00:34:40네, 다른 트리들은 존재하는데도 말이죠.
00:34:42그러니까 이름만 알면 쉽게 할 수 있는 건데.
00:34:44그래서 이건 그냥 거의 확실히 신경 쓰지 않을 것에 사람이 읽을 수 있는 이름을 붙이는 거예요.
00:34:50맞습니다.
00:34:50하지만 그들은 정말 그렇게 많은 걸 저장할 수 없어요..
00:34:54Casey,
00:34:54제 생각엔 그들이 정말로,
00:34:56모르겠어요,
00:34:57Adam,
00:34:57이런 식으로,
00:34:58거기엔 확장성이 많지 않아요,
00:35:00맞죠?
00:35:00많은 라인들이니까요.
00:35:02제가 했다면, 그냥 이걸 타임스탬프로 만들었을 거예요.
00:35:05그게 원하는 거라면요, 맞죠?
00:35:07저라면, 플래너가 언제, 또는 이 사람이 이걸 언제 가리켰는지를 말했을 거예요.
00:35:12락을 얻었을 때, 이 이름을 타임스탬프로 바꾸고, 이걸 하나의 원자적 작업으로 업데이트하는 거죠.
00:35:18그러면 오후 1시로 롤백하고 싶으면,
00:35:20타임스탬프를 가진 것 중에서,
00:35:22가장 이른 타임스탬프를 찾으면 되는 거예요,
00:35:25그 시간 이후가 아닌 거요..
00:35:28그리고 그게 그 시간에 실행되고 있던 거예요.
00:35:30제가 했을 방법이 그거예요.
00:35:31맞습니다.
00:35:31하지만 모르겠어요.
00:35:32그래서 왜 이렇게 했는지 전혀 모르겠어요.
00:35:34그들이 한 대로 했네요.
00:35:34저는, 아시겠지만, 완벽하게 말이 될 수도 있어요.
00:35:36다시 말하지만, 저는 그들의 시스템에 대해 아무것도 몰라요.
00:35:39이 모든 것들이, 완벽하게 말이 돼요..
00:35:41그래서 제가 정말로, 제가 말하는 건 이해가 안 간다는 거예요. 나쁜 아이디어가 아닐 수도 있어요, 맞죠?
00:35:45시스템의 나머지 부분을 이해한다면 좋은 아이디어일 수도 있어요.
00:35:49어쨌든,
00:35:50그래서 그들이 말하는 건,
00:35:51이게 우리가 얻는 전부인데,
00:35:53이 작업은,
00:35:54롤백을 이전 플랜을 가리키도록 설정하는 거,
00:35:56즉 이 경우에는 실제로는 어떤 경우에는 더 새로운 거였을 수도 있어요,
00:36:01맞죠?
00:36:01그래서 실제로는 이전에 가리키던 플랜이 아니에요.
00:36:04더 오래된 것일 수도 있고, 더 새로운 것일 수도 있죠.
00:36:08그 활동을 하는 거예요..
00:36:11만약 그 플랜이 더 이상 존재하지 않는다면,
00:36:14즉 이렇게 삭제된 것처럼 말이죠,
00:36:16그러면 enactor가 영구적으로 멈춥니다.
00:36:19그래서 매번, 일단 dynamodb.usc가 그것인 상태가 되면, 맞죠.
00:36:25우리가 여기서 말한 일련의 단계들을 전부 수행합니다?
00:36:28이 플랜이 삭제되는 거죠..
00:36:31그래서 이제 이건 유효하지 않은, 해석 불가능한 이름을 가리키고 있게 됩니다.
00:36:34plan dash 110, 실제로는 어떤 16진수 코드인데, 우리는 그걸 더 이상 해석할 수 없습니다.
00:36:39뭐였든 간에, 더 이상 해석할 수 없어요..
00:36:41그 상태가 참이 되면,
00:36:43다음에 enactor가 와서 새로운 플랜을 가리키게 하려고 시도할 때,
00:36:48그게 어떤 새 플랜이든 간에,
00:36:50실제로 여기까지 와서 롤백을 설정하려고 할 때 영구적으로 크래시가 납니다.
00:36:56따라서 세 개의 enactor 모두 이제 멈추게 됩니다.
00:37:00왜냐하면 결국 세 개 모두 새로운 플랜을 실행하려고 시도할 것이고,
00:37:05먼저 롤백을 이전 플랜이 뭐였든 그걸 가리키도록 설정하려고 하다가,
00:37:10거기 플랜이 없다는 걸 발견하게 됩니다.
00:37:14그리고 그게 명백히 그냥 하드 크래시인 거죠.
00:37:17오, 그거 미친 거 아니에요.
00:37:19저는 세 개의 enactor가 중복성을 제공하기 위한 거라고 생각했는데.
00:37:25다시 말하지만, 이게 제가 온라인에서 답글 다는 사람들한테 짜증나는 이유입니다.
00:37:31그들은 레이스 컨디션이었다고 하는데, 레이스 컨디션이 아니었어요.
00:37:36이것에 레이스 컨디션이 필요한 게 아닙니다.
00:37:39레이스 컨디션은 단지 이 이름이 해석 불가능하게 된 이유일 뿐이에요.
00:37:45하지만 이걸 잘못 작성한 코드가 없었다면, 그냥 작동했을 겁니다..
00:37:52전혀 몰랐을 겁니다.
00:37:53DynamoDB가 1분 정도 순간적으로 다운되는 정도였을 텐데,
00:37:57가끔 DynamoDB가 1분 정도 다운되는 일이 있을 거라고 추측합니다.
00:38:02그건 글로벌 뉴스가 아니죠..
00:38:04글로벌 뉴스가 된 건 영구적으로 다운시킨 것이고, 그게 여기서 일어난 일입니다.
00:38:09그리고 실제 사람이 와서 이걸 파악하고,
00:38:11리셋하고,
00:38:11이 enactor들을 다시 작동시킬 때까지는 그냥 사라진 겁니다.
00:38:15영구적으로 다운된 거죠.
00:38:16그러니까 잠재적으로 몇 시간이요.
00:38:18그리고 이 경우에는 연쇄 장애를 일으킬 만큼 충분히 길었던 것 같습니다.
00:38:22그런 일은 절대 없었을 겁니다.
00:38:24그냥 순간적인 다운이었을 거예요.
00:38:25일부 사람들이 순간적으로 해석 불가능한 이름이나 레코드 없음을 받았다면, 그냥 다시 시도했을 겁니다.
00:38:31보통 DNS의 경우, 그건 마치 휴대폰이 터널을 지나간 것 같은 거예요.
00:38:35그게 전부였을 겁니다..
00:38:37그래서 저는 여기 코드가 어떻게 생겼는지 알고 싶어요.
00:38:41이게 유효한 이름이 아니었다면,
00:38:43시작할 때조차 그렇지 않았을 텐데,
00:38:45즉 이 시스템을 시작하고 운영자가 미리 설정하지 않았다면,
00:38:49아무것도 가리키지 않았을 겁니다.
00:38:52그게 시작할 것이라고 생각할 기본 케이스입니다.
00:38:55그러니까 이걸 하려고 한다면, 그 케이스를 처리할 거라고 생각할 텐데요.
00:39:00왜냐하면 롤백 주소는 그냥 아무것도 가리키지 않을 수 있으니까요.
00:39:05그냥 이게 뭐든 가져가세요.
00:39:06아무것도 아니면, 롤백 주소를 아무것도 아닌 것으로 설정하세요..
00:39:12끝.
00:39:12그러니까 그들이 이 코드를 작성한 방식에 뭔가 정말 이상한 게 있습니다.
00:39:17그리고 그게 RCA에 있었어야 할 내용입니다.
00:39:20제게는 그게 전체 버그예요.
00:39:21이건 그냥 우리가 이걸 아무것도 가리키지 않게 만든 과정의 배경일 뿐입니다.
00:39:26누군가가 실수로 이 레코드를 삭제했다면 같은 버그가 발생했을 겁니다.
00:39:30어떤 운영자가 그냥, 앗, 젠장, 아무것도 아닌 것으로 설정했다고 하면요..
00:39:35발표에 따르면 이 똑같은 버그가 발생했을 겁니다.
00:39:38그러니까 근본 원인은 레이스 컨디션이 아닙니다.
00:39:41레이스 컨디션은 부차적인 겁니다.
00:39:43이해되세요?
00:39:44간단한 질문인데요.
00:39:45저는 진지하게 이걸 생각해보고 있어서요.
00:39:47그러니까 그건 롤백을 설정하는 것이 아마도 메모리가 잔뜩 있는 어떤 struct 같은 게 전달되었다고 가정하고,
00:39:54어떤 종류의 접근을 시도하는 거겠죠.
00:39:56폭발하는 거죠.
00:39:57아니면 이게 같은 스타일의 버그라고 생각하세요?
00:40:00Cloudflare를 다운시킨 그 한 줄처럼, 그냥 거기 있다고 가정하고 unwrap하는 거요..
00:40:07Rust로 되어 있습니다. 메모리 안전한 Rust죠. Unwrap하고, 폭발하는 겁니다.
00:40:13정말 모르겠어요.
00:40:14제 머릿속으로는,
00:40:15사람들이 자주 하는 행동 중에 제가 항상 '왜 저렇게 하지?'라고 생각하는 게 뭘까 생각했는데,
00:40:22그건 그냥 그들이 프로그래밍을 배운 방식이기 때문이죠?
00:40:26그래서 에러 상황에 예외를 던지는 걸 좋아하는 언어 중 하나로 작성했다면,
00:40:31이게 딱 그런 사례가 될 거라고 생각했어요.
00:40:34예를 들어, 이 항목이 가리키는 DNS 레코드를 가져오려고 했는데요..
00:40:40정상적인 프로그래밍 환경이라면, 아무도 거기서 예외를 던지지 않아요.
00:40:45아무것도 받지 못하면 그냥 아무것도 반환하지 않죠.
00:40:48그러면 사람이 ddb.robot.js를 설정할 때 그냥 아무것도 없는 걸로 설정하는데,
00:40:54그게 올바른 동작이에요.
00:40:55말 그대로 '아무것도 없음'이라는 값이 이 플로우를 통해 올바르게 흘러가는 거죠.
00:41:00그런데 핵심 기반 서비스이니까,
00:41:02장애 허용적으로 작성하려고 한다고 가정하면,
00:41:05예외를 던지는 것 같은 건 절대 하지 않을 거예요.
00:41:08그래서 제 머릿속으론,
00:41:10여기서 이 레코드를 요청하면 어떤 라이브러리 호출 같은 걸 쓰는데 레코드가 없을 때 예외를 던지는 거죠.
00:41:16그래서 예외가 던져지고 액터가 종료된 거예요.
00:41:19그게 제 추측이에요.
00:41:21완전히 틀릴 수도 있어요.
00:41:22그냥 막 추측한 거니까요.
00:41:24하지만 그래서 RCA를 보고 싶은 거예요.
00:41:26뭐였을까요.
00:41:27Trash가 얘기한 것일 수도 있어요.
00:41:30Prime이 얘기한 것일 수도 있고요?
00:41:32제가 방금 말한 것일 수도 있죠.
00:41:34뭐든 될 수 있어요.
00:41:35그리고 알고 싶어요.
00:41:37왜냐하면 거기에 진짜 교훈이 있을 테니까요.
00:41:39이 경쟁 상태를 피하는 건 완전히 중요하지 않아요.
00:41:43이 경쟁 상태는 거기 있었을 수 있고,
00:41:45일 년에 한 번 5초 정도 이상한 장애를 피하려고 결국 고치는 게 중요했지만,
00:41:50사실 우리가 가장 배우고 싶은 건 아니에요.
00:41:53우리가 가장 배우고 싶은 건 '이런 걸 작성하지 마라'인데, 이게 뭔지조차 모르잖아요.
00:41:58그럼 어떻게 작성하지 않죠.
00:42:00그래서 이게 나쁜 RCA였다고 생각하는 거예요.
00:42:03이해되나요?
00:42:04네.
00:42:04네?
00:42:05좋아요.
00:42:05AWS 대부분이 뭘로 작성됐죠, Adam?.
00:42:11Java였어요.
00:42:12방금 채팅에서 누가 Scala라고 했어요.
00:42:16AWS에서 7년 일했다는데 대부분 Scala로 작성됐다고 하더라고요.
00:42:21음, 그건 기술적으로 Java에 단계만 더한 거죠.
00:42:25그리고 그 말이 그들을 끝없이 화나게 할 거예요.
00:42:29그래서 저는 여기까지예요..
00:42:34이건 제가 설명을 본 것 같지 않다고 느낀 경우였어요.
00:42:37그리고 사실 듣는 게 중요하다고 생각해요.
00:42:39왜냐하면 이 여름 이 문제의 밑바닥엔 나쁜 프로그래밍 관행이 있었거든요.
00:42:43그게 뭔지 알고 싶어요.
00:42:44특히 저 같은 사람들한테 도움이 되니까요.
00:42:47지금은 아키텍처 교육을 많이 하진 않지만, 언젠가는 하고 싶거든요.
00:42:50나쁜 아키텍처가 정말 많다고 생각하니까요.
00:42:53그래서 이런 것들에 주의를 기울이려고 노력해요.
00:42:55사람들이 어떤 종류의 아키텍처 실수를 하고 있을까?
00:42:58그리고 이것도 그 중 하나였을 거라고 확신해요.
00:43:01맞죠.
00:43:01그래서 알고 싶어요.
00:43:02알고 싶다고요..
00:43:04네.
00:43:05제 생각에 최소한 기대하는 건,
00:43:07왜 전체가 터졌는지 보여주는 간단하고 재현 가능한 예시 하나 정도는 있어야 한다는 거예요.
00:43:13작은 코드 스니펫 같은 거요.
00:43:15그리고 이건 아까 당신이 언급한 건데, 우리가 이런 종류의 문제에 접근하는 방식이잖아요.
00:43:20누군가의 코드를 리뷰하다가 이상해 보이는 걸 발견하면,
00:43:24저는 항상 제 샌드박스를 만들어서 제 이론을 검증하려고 최선을 다해요.
00:43:28그리고 실제로 코드를 보여주면서 이게 왜 아마 잘못됐는지, 간단하고 재현 가능한 단계를 제시하는 거죠.
00:43:35그런 걸 기대하는 거예요.
00:43:36그리고 그렇게 해야 제가 진정으로 이해할 수 있어요.
00:43:40많은 사람들이, 당신 말처럼, 뭔가 이상해 보이는 걸 발견하지만 왜 이상한지 모르잖아요.
00:43:46하지만 거기서 멈출 수 없어요.
00:43:48실제로 구축해보고 이해해야 하는 거죠.
00:43:50그게 제가 기대하는 거예요.
00:43:52그리고 아까 말했듯이,
00:43:53크라우드스트라이크랑 구글 장애 사례가 더 나았던 게,
00:43:56그냥 여기서 널 포인터 역참조였다거나,
00:43:5920개만 있을 거라고 생각했는데 설정 파일에 21개를 넣어서 배열 범위를 벗어났다고 말해줬잖아요.
00:44:05그러면 어떤 종류의 코드가 그런 문제를 일으키는지 정확히 알 수 있는 거죠.
00:44:10게다가,
00:44:11더 나아가서,
00:44:11아까 했던 얘기와 관련해서,
00:44:13제가 아는 한,
00:44:14Rust로 프로그래밍하는 모든 사람들은 가끔 이런 걸 봤을 때 "Rust로 작성했으면 이런 일 안 일어났을 텐데"라고 말하려고만 하는 것 같아요.
00:44:23근데 그런 얘기조차 할 수 있는 정보를 안 준 거예요..
00:44:29솔직히 그 사람들은 어쨌든 그런 말 했을 가능성이 높지만, 정보는 안 줬죠.
00:44:34그래서 RCA에서 지켜야 할 규칙 중 하나는,
00:44:37Rust 신봉자들이 원한다면 Rust로 작성했으면 방지할 수 있었을 거라고 올바르게 말할 수 있을 만큼 충분한 정보를 제공해야 한다는 거예요..
00:44:46그런데 이번 건, 그런 정보가 없어요. Rust로 방지할 수 있었을지 모르는 거죠.
00:44:51전혀 모르죠.
00:44:52아마 방지 못했을 수도 있지만 모르는 거예요.
00:44:55뭐, 케이시, 꽤 확률이 높긴 해요.
00:44:58왜냐하면 아마 출시조차 안 했을 테니까요.
00:45:01그러니까 방지한 거죠..
00:45:03맞아요. 액터가 하나도 없었을 거예요. 세트 액터를 설계하고 있었을 테니까요.
00:45:09CloudFlare도 이런 거 정말 잘해요.
00:45:12들어가서 많은 코드 라인을 보여주고 이게 정확히 무슨 일이 일어난 건지 설명하죠.
00:45:18문제가 위쪽에 있더라도, 이전의 모든 조건들 때문에 이 라인에서 폭발한 거라고요.
00:45:23제가 unwrap으로 Rust를 놀린 건데, 사실 진짜 문제는 아니었지만요.
00:45:28어쨌든 이런 모든 일들이 일어나는 거잖아요.
00:45:31그래서 CloudFlare는 정말 잘해요.
00:45:34AWS가 이번 건에서 이렇게 형편없이 한 게 놀라워요.
00:45:38그리고 또 다른 건, 이제 저를 불필요하게 의심스럽게 만드는 거죠, 그렇죠??
00:45:44이걸 읽으면서 생각했어요.
00:45:45뭔가 숨기는 거 아니야?
00:45:46버그가 뭔지 정말로 파악하지 못한 거 아니야?
00:45:48경쟁 상태(race condition)에 대해 온갖 얘기를 늘어놨지만,
00:45:52당신이 직접 설명한 내용만 봐도 경쟁 상태는 사실 중요하지 않았다는 걸 알 수 있어요.
00:45:56그건 그냥 레코드가 아무것도 아닌 값으로 설정되게 만든 계기일 뿐이지, 그게 뭐 그리 중요해요?
00:46:01그런 건 RCA에 '왜 이 버그가 다른 때가 아니라 지금 발생했는지'를 설명하는 부분으로 넣기에는 좋을지 몰라도,
00:46:06그게 버그 자체는 아니잖아요.
00:46:08그래서 이상하게 느껴져요.
00:46:09RCA에서 정작 버그에 대해서는 얘기하지 않으면 의심스러워지는 거예요.
00:46:12그럴 필요도 없는데 말이죠.
00:46:13실제로 찾아냈다면 그냥 말해주면 되고, 그러면 찾았다는 걸 알 수 있으니까요.
00:46:17그래서 이것도 일종의 신뢰 향상 효과가 있다고 봐요.
00:46:20외부에서 지켜보는 사람들, 이 DynamoDB라는 게 믿을 만한지 알고 싶어 하는 사람들에게 말이죠.
00:46:25버그를 실제로 찾아낸 것처럼 보이면 조금 더 신뢰가 생기지만,
00:46:28버그가 뭔지 전혀 모르는 것처럼 보이거나 버그를 이해하지 못한 것 같으면 오히려 더 걱정되는 거죠.
00:46:32그래서 이것도 RCA에서 이렇게 써야 하는 또 다른 이유라고 생각해요..
00:46:37고객들에게 신뢰를 주는 거죠. 어쩌면 그래서 Adam을 AWS 히어로에서 해고한 걸지도 몰라요.
00:46:43어쩌면 다 연결되어 있을지도. 그럴 수도 있지. 그가 이런 더러운 비밀을 폭로하는 걸 원하지 않았던 거야.
00:46:48그래.
00:46:48너무 많이 알아버렸어.
00:46:50너무 많이 알았던 거야.
00:46:51기타 샵(guitar shop) 얘기를 3분 정도로 간단히 요약해줄 수 있어?
00:46:56그게 뭘 드러냈는지 말이야.
00:46:57기억을 더듬어보려고 하는데,
00:46:59단일 장애점(single point of failure)인 어떤 사람이 관련되어 있었고 이번 장애 때도 자리에 없었다는 것 같은데.
00:47:06그래서 두 가지를 어떻게 조합해야 할지 모르겠어.
00:47:09물론 우리는 전혀 알 수 없죠.
00:47:11둘 중 어느 쪽이 진실을 말하고 있는지도 모르는 거예요.
00:47:14RCA가 너무 엉망이어서 맞는 내용인지 아닌지도 모르겠지만,
00:47:18어쨌든 비밀번호는 wishbone 12였던 것 같아요..
00:47:22바로 그거야. 항상 날 죽이려고 하네. 내 기억으로는 그래.
00:47:26그래,
00:47:27그 얘기는 설정을 복사하도록 설계된 뭔가가 있었는데,
00:47:31그게 통제 불능 상태가 되어서 멈출 수가 없었다는 거였어요.
00:47:35그냥 완전히 잘못된 방식으로 설정을 복사하고 있었고, 고치거나 수리해야 하는 상황이었던 거죠.
00:47:42우리가 더 이상의 정보를 갖고 있지 않은 이유는 그게 우연히 엿듣게 된 대화였기 때문이에요.
00:47:50그럼 이게 이번 내용과 일치하나요?
00:47:52음, 조금은 그래요.
00:47:54그 enactor들이 설정 복사를 실행할 만한 것처럼 들리긴 하니까요.
00:47:59하지만 다른 한편으로는, 이건 머신을 위한 설정이 아니에요.
00:48:04DNS 엔트리는 DNS 엔트리일 뿐이죠.
00:48:07진짜 설정은 아니에요.
00:48:08그래서 두 이야기가 그렇게 잘 들어맞지는 않는다고 봐요..
00:48:14그래서 이 RCA가 좀 더 믿을 만했으면 좋겠다고 바랐던 또 다른 이유가 있어요.
00:48:19그 이야기가 거짓이라는 걸 확실히 알고 싶었거든요.
00:48:21하지만 이 RCA가 너무 형편없어서 여전히 잘 모르겠어요.
00:48:25만약에, 만약에 그 사람이 설정을 복사하려고 만든 도구가 말 그대로 그 enactor라면 어떨까요?
00:48:30그냥 그걸 프로덕션화한 거고, 그 사람이...
00:48:33그리고 7년 동안 바꾸지 않은 거예요.
00:48:35그게 제가 점들을 연결해본 방식이에요.
00:48:37그 사람이 이렇게 말하는 거죠.
00:48:39'여러분,
00:48:40저는 그걸 제 로컬 환경에서 테스트하려고 만든 건데,
00:48:43여러분은 그냥 enactor 세 개를 만들어서 프로덕션에 나란히 배치하기로 결정했네요.
00:48:48도대체 어떻게 이런 일이...' 모르겠어요, 어떻게 이렇게 된 거죠?.
00:48:53대안적인 질문이 있어요.
00:48:54그래요.
00:48:54아니면 롤백이 문제였을까요?
00:48:56왜냐하면 그게 "자, 여기 이전 버전이 있어요"라고 복사하는 작업을 했거든요.
00:49:00맞죠.
00:49:01그래서 이전 버전을 복사하는데,
00:49:02그러다가 null 문제가 발생하고,
00:49:04스크립트가 전혀 예상하지 못했거나 제어를 벗어나서 계속해서 반복적으로 덮어쓰기 시작하는 거죠.
00:49:10그래서 아무것도 할 수 없게 되는 거예요.
00:49:12모르겠어요.
00:49:12제가 아는 건,
00:49:13제가 파악한 바로는 그들의 설명만을 바탕으로 했을 때,
00:49:16그들이 제공한 정보만으로는 여전히 경쟁 조건이 관련이 있다고 생각하지 않아요.
00:49:21왜냐하면 다시 말하지만,
00:49:22Route 53 엔드포인트에 대한 우연한 업데이트만으로도 세 개의 액터 모두 즉시 다운되었을 거거든요.
00:49:28그들의 설명에 따르면,
00:49:29액터들을 멈추는 데 필요한 건 엔드포인트가 해석 불가능한 이름을 가리키기만 하면 되는 거예요.
00:49:34그게 전부라고요.
00:49:35그래서 만약 그게 정말이라면, 문자 그대로 운영자의 오타만으로도 이 모든 게 다운될 수 있었던 거죠.
00:49:40경쟁 조건 같은 건 필요 없었어요.
00:49:42맞죠.
00:49:43그래서 다시 말하지만,
00:49:44RCA는 실제 버그가 무엇이었는지에 대해 저를 납득시키는 데 제대로 된 역할을 하지 못했어요.
00:49:49왜냐하면 RCA 전체에서 버그라고 말했던 이 경쟁 조건과 관련 없이도 똑같은 상황을 유발할 수 있는 방법들이 너무 많이 떠오르거든요.
00:49:57하지만 저는 그게 버그라고 생각하지 않아요.
00:49:59아무튼 Casey, 이 놀라운 발표를 해주셔서 감사합니다.
00:50:02저는 사실 진심으로 그린우드...
00:50:04질투에 찬 분노를 느끼고 있어요.
00:50:06당신이 사용한 그 필기 도구가 뭔지 궁금해서요.
00:50:08당신이 사용하는 걸 어떻게 설정하는지 알아내야겠어요.
00:50:11정말 환상적이네요..
00:50:15시청해주신 모든 분들께 감사드립니다.
00:50:16저는, 음, 라이브로 보신 분들은 사전 잡담과 아마도 사후 잡담도 조금 즐기셨기를 바랍니다.
00:50:21확장 버전과 메인 스토리에 포함되지 않은 재미있는 대화들을 듣고 싶으시다면,
00:50:25Spotify로 가서 전체 팟캐스트를 들어보세요.
00:50:27거기서는 우리가 그냥 떠들어대는데, 뭐 트래시가 먹는 것과 간식 같은 것들에 대해서요.
00:50:31이름은 'More Yapping,
00:50:33More Yapping Again'이고,
00:50:35Casey,
00:50:35TJ,
00:50:36그리고 Trash도 나와요..
00:50:42내 화면의 에러들, 터미널 커피, 그리고 꿈을 살아가는 중.

Key Takeaway

단순한 경쟁 상태를 넘어, 근본적인 코드 결함과 예외 처리 미비가 어떻게 대규모 AWS 장애를 영구적인 시스템 중단으로 확장시켰는지 분석하고 기술적 진실 추구의 중요성을 강조합니다.

Highlights

실제로 이해하는 것과 이해한 척하는 것 사이의 기술적 차이 및 주니어 개발자가 느끼는 압박

AWS DynamoDB 장애의 공식 근본 원인 분석(RCA)에 대한 비판적 접근

DNS 로드 밸런싱을 위한 플래너(Planner)와 인액터(Enactor) 구조의 작동 방식

경쟁 상태(Race Condition)가 발생하여 해석 불가능한 DNS 레코드가 생성된 과정

롤백 레코드 설정 시 발생한 하드 크래시가 전체 시스템 다운으로 이어진 메커니즘

기술적 투명성과 신뢰 구축을 위한 상세한 사후 분석 보고서의 중요성

Java 및 Scala 등 AWS 내부 구현 언어와 관련된 업계 관행 및 아키텍처 실수

Timeline

도입 및 기술적 이해의 본질

케이시는 이번 에피소드에서 단순히 AWS 장애를 분석하는 것을 넘어, 지식에 대한 솔직함이라는 더 큰 주제를 다룹니다. 특히 경력 초기의 주니어 개발자들이 무지함을 들키지 않기 위해 이해한 척해야 한다는 외부적 압박을 느끼는 현상을 지적합니다. 그는 나이가 들고 경험이 쌓이면서 오히려 멍청해 보이는 것을 두려워하지 않고 근본 원인을 알 때까지 집요하게 질문하는 태도를 갖게 되었다고 고백합니다. 이러한 태도는 버그의 진짜 원인이 숨어 있을 가능성을 항상 염두에 두는 프로페셔널한 자세로 연결됩니다. 결국 이 섹션은 기술적 문제를 다룰 때 '편의상 넘어가는 것'이 얼마나 위험한지를 강조하며 분석의 서막을 엽니다.

주요 기술 장애 사례 비교

최근 발생한 대규모 IT 장애 사례인 구글의 널 포인터 역참조 문제와 크라우드스트라이크의 배열 오버플로우 사건을 언급하며 논의를 확장합니다. 이들 사례는 근본 원인 분석(RCA)이 명확하여 코드가 어떻게 작성되었고 어떤 실수가 있었는지 외부 엔지니어도 충분히 납득할 수 있는 수준이었습니다. 반면 AWS DynamoDB 장애의 공식 보고서는 매우 모호하며 실제 버그의 핵심을 설명하지 못한다고 비판합니다. 케이시는 re:Invent 프레젠테이션까지 모두 시청했음에도 불구하고 여전히 해결되지 않은 의문점이 많다는 사실을 발견합니다. 이 과정은 대중이 단순히 '버그가 있었다'는 말에 설득되지 말고 더 깊은 설명을 요구해야 함을 시사합니다.

AWS 팟캐스트 게스트 소개 및 잡담

팟캐스트의 분위기를 환기하며 AWS 히어로였던 아담을 소개하고 팟캐스트의 여러 플랫폼 특징에 대해 이야기합니다. 스포티파이 버전에서는 유튜브보다 더 많은 잡담과 비하인드 스토리가 포함되어 음질과 내용 면에서 차별화된다는 점을 홍보합니다. 아담은 자신이 더 이상 AWS 히어로가 아닌 이유를 농담 섞인 어조로 설명하며 케이시의 분석 방식에 흥미를 보입니다. 케이시의 성인 '무라토리' 발음과 관련된 이탈리아계 미국인 배경에 대한 소소한 이야기도 나누며 긴장을 완화합니다. 이 구간은 기술적 분석 사이에서 시청자들과의 유대감을 형성하고 커뮤니티의 즐거움을 공유하는 역할을 합니다.

DynamoDB DNS 로드 밸런싱 구조

본격적으로 DynamoDB의 API 엔드포인트와 DNS 트리 구조에 대한 기술적 설명을 시작합니다. 사용자가 요청을 보내는 주소는 Route 53을 통해 여러 머신으로 분산되며, 이를 위해 가중치 기반의 로드 밸런싱 체계를 사용합니다. 케이시는 이 구조를 '트리'라고 부르지만 실제로는 가중치 배열에 가까운 형태일 것이라고 추측하며 화이트보드에 시각 자료를 그립니다. 여기서 해시값으로 구성된 실제 레코드 이름들이 사용자에게는 보이지 않는 내부적인 방식으로 관리된다는 점을 짚어줍니다. 아담은 Route 53이 트래픽을 분할하는 다양한 방식을 보충 설명하며 케이시의 분석에 전문성을 더합니다.

플래너와 인액터의 작동 메커니즘

로드 밸런싱 상태를 최신화하기 위해 '플래너(Planner)'와 '인액터(Enactor)'라는 두 가지 컴포넌트가 존재함을 설명합니다. 단일 플래너는 새로운 로드 밸런싱 계획을 생성하고, 세 개의 인액터는 이 계획을 받아 Route 53에 실제로 레코드를 생성하는 역할을 수행합니다. AWS는 추론을 쉽게 만들기 위해 인액터들이 DNS 레코드를 '락(Lock)'으로 사용하는 직렬화 방식을 채택했다고 주장합니다. 케이시는 중복성을 위해 세 개의 인액터를 두면서도 굳이 락을 걸어 한 번에 하나만 실행되게 만든 설계의 모순점을 지적합니다. 이 섹션은 시스템의 아키텍처적 결정이 나중에 발생할 버그의 배경이 되었음을 암시합니다.

장애의 발생: 경쟁 상태와 유효하지 않은 레코드

특정 인액터가 락 획득에 실패하여 오래된 플랜(예: 110번)에 머물러 있는 동안 다른 인액터들이 최신 플랜(예: 145번)으로 업데이트를 진행한 상황을 묘사합니다. 마침내 락을 얻은 인액터가 아주 낡은 110번 플랜을 다시 가리키게 되었는데, 그 시점에 이미 다른 프로세스가 110번 레코드를 삭제해버린 것이 문제의 핵심입니다. 이로 인해 DNS 요청은 해석 불가능한 이름을 가리키게 되고 서비스가 불능 상태에 빠지게 됩니다. 케이시는 이를 Rust의 'use-after-free' 버그와 유사한 논리적 오류라고 비유하며 왜 오래된 레코드를 검증 없이 그대로 썼는지 질문합니다. 많은 사람들이 이를 단순히 '경쟁 상태'라고 부르며 분석을 멈추는 현상을 비판적으로 바라봅니다.

치명적 결함: 롤백 설정과 하드 크래시

서비스가 일시적 장애를 넘어 영구적 다운타임으로 이어진 결정적 이유는 롤백 레코드 설정 과정에서의 하드 크래시 때문입니다. 인액터는 새로운 플랜을 적용할 때 이전 상태를 저장하기 위해 롤백 주소를 설정하는데, 가리켜야 할 이전 레코드가 이미 삭제되어 존재하지 않자 프로세스가 폭발해버린 것입니다. 결과적으로 세 개의 인액터가 모두 동일한 지점에서 크래시를 일으켜 작동을 멈추었고, 사람이 수동으로 개입할 때까지 시스템은 복구되지 않았습니다. 케이시는 예외 처리가 제대로 되었다면 5초 정도의 순간적인 끊김으로 끝났을 일이 나쁜 코딩 관행 때문에 글로벌 뉴스가 되었다고 지적합니다.

RCA의 품질과 기술적 교훈

마지막으로 AWS가 제공한 RCA가 왜 형편없는지 정리하며, 엔지니어들이 진정으로 배워야 할 교훈은 '경쟁 상태를 피해라'가 아니라 '이런 식의 방어적이지 못한 코드를 짜지 마라'임을 강조합니다. Cloudflare처럼 실제 코드 라인을 보여주며 투명하게 설명하는 것이 고객의 신뢰를 얻는 길이라고 조언합니다. 또한 AWS 내부에서 사용되는 Java나 Scala 같은 언어적 특성과 아키텍처 실수가 어떻게 결합되었는지에 대한 호기심을 드러냅니다. 영상은 시청자들에게 스포티파이에서 더 깊은 대화를 나눌 것을 권장하며, 완벽한 이해를 위해 끝까지 파고드는 엔지니어의 자세를 독려하며 마무리됩니다. 향후 아키텍처 교육에 대한 의지를 보이며 기술 커뮤니티의 발전을 기원합니다.

Community Posts

View all posts