--- kind: REFERENCE slug: verify-the-injection-landed-separately-from-the-result title: 예측을 먼저 적고, 주입이 걸렸는지 결과와 따로 확인하고, 대조군 없이 귀속하지 않는다 topic: when-the-measurement-lies topicName: 주입이 걸렸는지 무엇으로 아는가 project: keycloak-session-store status: 게시 전 sourceRevision: cdac9b8178391311d8eca1ebc6cac15bb62d79af source: - final/document.md#결국-지키려던-것은-무엇이었나 - final/document.md#문제를-어렵게-만든-제약-주입이-먹지-않는다 - final/document.md#결정이-지켜지는지-확인하는-방법-대조군-없이는 evidence: - ../../../final/evidence/raw/a1-jgroups-transport-block__07-cluster-size.txt - ../../../final/evidence/raw/a6-latency-injection__03-flannel-injection.txt - ../../../final/evidence/raw/a8-rolling-restart__01-restart-availability.txt - ../../../final/evidence/raw/d4-certificate-renewal__05-control-no-injection.txt - ../../../final/evidence/raw/d4-certificate-renewal__08-inflight-artifact.txt --- # 예측을 먼저 적고, 주입이 걸렸는지 결과와 따로 확인하고, 대조군 없이 귀속하지 않는다 상태를 일부러 망가뜨리는 실험은 예측을 먼저 적고, 주입이 걸렸는지 결과와 따로 확인하고, 대조군 없이 귀속하지 않는다. 이 실험대가 위반 사례로 적은 둘은 전부 대조군 규칙이다 — A-6 의 −41% 대조군과 A-8 의 표본 9개다. ## 관계 - **주입이 아홉 번 조용히 실패했고 전부 아무 일도 없는 것처럼 보였다** 두 번째 규칙이 이 아홉 건에서 나왔다. 아홉 건은 규칙을 세우게 만든 실패이고, 규칙을 세운 뒤의 위반 사례가 아니다. - **실패 76 건이 서버 탓이 아니었다 — 대조군이 오보를 막았다** 세 번째 규칙을 지켜서 오보를 막은 가장 최근 실험이다. 대조군과 같은 순간의 폴링이 없었으면 측정 장치의 아티팩트가 서버 장애로 기록됐다. - **up 지표는 살아 있지만 쓸모없는 상태를 보지 못한다** A-2 에서 장애가 실제로 일어나는 동안 이 지표는 1 이었다. 주입이 걸린 것을 확인해도 관측 도구가 그 상태를 보여 주지 않는 경우가 남는다. ## 목적 주입 실험의 결과는 세 자리에서 틀릴 수 있다. 첫째, 무엇을 예상했는지를 결과를 본 뒤에 적으면 예측과 결과의 차이가 사라진다. 둘째, 주입이 걸리지 않으면 관측에 아무 변화도 나타나지 않아 영향이 없는 경우와 구별되지 않는다. 셋째, 평시 값을 모르면 변화가 주입 탓인지 다른 이유인지 가를 수 없다. 뒤의 두 자리에서 실제로 문제가 났다 — 주입은 아홉 번 조용히 실패했고, 대조군 규칙은 두 번 어겼다. 첫째 자리를 어긴 사례는 이 실험대의 기록에 없다. 그 기록은 세 번째가 가장 자주 어겨졌고 치른 값도 가장 컸다고 적는데, 그 문장은 세 규칙의 위반 횟수를 견준 수치가 아니라 기록을 쓴 사람의 판단이다. 숫자로는 세 번째 규칙을 어긴 사례 둘만 남아 있다. ## 규칙 ### 1. 예측을 먼저 적는다 주입하기 전에 무엇이 일어날 것으로 보는지 적어 둔다. 결과를 보고 나면 무엇을 예상했는지 정직하게 쓸 수 없다. 이 실험대가 그 예측을 적어 둔 곳은 A-0 의 「9. 다음 실험에 대한 예측」이다. A-0 이 평시를 재고 난 직후, 아직 아무것도 주입하기 전에 쓴 표이고, 뒤따르는 절들의 「맞다 / 틀렸다」는 전부 그 표와의 대조다. 표 앞에는 「예측이 빗나가면 그것이야말로 배울 거리다」라고 적혀 있다. 표에 적힌 실험 번호는 옛 로드맵의 것이라 지금 번호와 어긋난다. 당시의 `B-5` 가 최종 B-3 이고 `A-3 노드 상실` 이 최종 A-4 인데, 번호를 고쳐 적지 않고 원문 그대로 두었다 — 예측을 언제 썼는지가 번호에 남아 있기 때문이다. 틀린 예측은 지우지 않고 남긴다. 이 실험대에서 빗나간 예측은 다섯이다. B-4 에서는 nginx 가 동명 헤더를 덮어쓸 것으로 봤지만 덮어쓰지 않았고, A-7 에서는 refresh 의 500 이 REVOKED_TOKEN 때문이라고 봤지만 CLIENT_SCOPE_CLIENT 였다. 그중 A-1 의 예측이 틀리지 않았다면 A-0 의 인과 설명이 잘못된 채로 남았을 것이다. A-2 의 up 이 1 이던 것은 그 다섯에 들어가지 않는다. 원본 가이드가 그 줄의 예측 칸을 비워 두고 「관측의 함정」이라고 적었으므로, 미리 적어 둔 예측이 빗나간 것이 아니라 예측한 적 없이 튀어나온 관측이다. 이 규칙을 어긴 사례는 이 실험대의 기록에 적혀 있지 않다. ### 2. 주입이 걸렸는지를 결과와 따로 확인한다 「아무 일도 없었다」는 「영향이 없다」와 구별되지 않는다. 주입 뒤에는 대상이 실제로 그 상태인지를 확인하는 단계를 하나 더 둔다. 보는 값은 결과가 아니라 상태다 — cluster_size, 워커 PID(프로세스 식별 번호), conntrack 표, 패킷 카운터. 주입 명령이 오류 없이 끝난 것은 걸렸다는 뜻이 아니다. NetworkPolicy 로 7800 을 막았을 때 ESTABLISHED 연결은 conntrack 때문에 규칙 평가를 건너뛰었고, cluster_size 는 25분간 2 로 남았다. 명령 자체는 정상 종료했다. 실패한 주입이 깨끗한 결과를 내기도 한다. A-3 은 DB 를 세 번 죽여 두 번 실패했는데, 그 두 번이 모두 「유실 0건」을 냈다. 무엇을 보면 걸린 것인지 신호를 미리 정해 두지 않았다면 첫 번째 결과를 그대로 답으로 적었을 것이고 결론은 정반대가 됐을 것이다. 재현 가이드 26편이 이 규칙을 절 구조로 갖고 있다. 편마다 주입 전에 평시를 잡는 절이 먼저 오고, 주입 다음에 「주입 검증」 절이 따로 서고, 그 뒤에 관찰과 복구가 온다. 이 규칙의 근거인 아홉 번의 실패는 규칙을 세우기 전에 일어났다. 규칙을 세운 뒤에 이 규칙을 어긴 사례는 따로 적혀 있지 않다. ### 3. 대조군 없이 귀속하지 않는다 평시를 모르면 이상을 해석할 수 없다. 주입 중에 비200 이 한 번 나왔을 때 평시 오류율을 모르면 그것이 주입 탓인지 알 수 없으므로, D-4 에서는 주입 전에 900건을 재서 오류가 0 이라는 것부터 확인했다. 대조군이 변하지 않는다고 가정하지 않는다. A-6 에서는 지연을 주입하지 않은 노드 쪽이 오히려 빨라졌다. 이 실험대가 어긴 사례로 적은 둘이 전부 이 규칙에 걸려 있다. D-4 의 in-flight 76건은 반대로 읽어야 한다 — 거기서는 대조군이 있어서 오보를 막았다. ## 적용 조건 - 상태를 일부러 망가뜨리고 그 영향을 재는 실험 전부에 걸린다. - 이 실험대가 적용 범위로 말하는 곳은 아홉 번의 실패 이후 이 실험대에서 돌린 실험까지다. 다른 실험실이나 다른 프로젝트까지 넓힌 근거는 이 실험대의 기록에 없다. - 주입 명령이 오류 없이 끝났을 때도 두 번째 규칙이 걸린다. 종료 코드는 대상의 상태를 말해 주지 않는다. - 대조군은 주입한 뒤가 아니라 주입 전에 잰다. 주입 뒤에 잰 값에는 이미 주입의 영향이 섞여 있다. ## 예외 - 주입 없이 평시를 관측하는 측정에는 첫 두 규칙이 걸리지 않는다. 망가뜨릴 대상이 없으므로 예측과 주입 확인이 성립하지 않는다. - 대조군 규칙은 평시 관측에도 걸린다. 무엇을 재든 그 값이 평소 값인지 아닌지를 가르려면 비교할 구간이 필요하다. ## 예시 - A-6 지연 주입 : 지연을 넣지 않은 대조군 노드가 70 ms 에서 41 ms 로 빨라졌는데(−41%) 해설 문서는 처음에 영향 없음이라고 적었다. JIT(just-in-time 컴파일) 워밍업이나 캐시처럼 주입과 무관한 변동이었고, 자릿수가 달라 결론 자체는 유지됐다. 나중에 고쳤다. - A-8 롤링 재시작 : 5초 간격 표본 9개로 무중단을 주장했다. 고친 문장은 「5초 해상도에서 끊김이 관측되지 않았다」다. 뒤에 1초 간격에 3초 타임아웃으로 D-2 롤백 전환을 재자 파드가 바뀌는 순간 요청 하나가 3초를 넘겼다. - D-4 in-flight 감시 : 76건이 실패했다. 그대로 적었으면 「갱신 중 대규모 요청 실패」라는 오보가 됐을 것이다. 같은 순간의 폴링은 49건 전부 200 이었고, 실패한 76건은 연결수 0 에 소요 시간 50µs 였고 재현이 0/100 이었다. - A-1 전송 차단 : 주입을 넣은 뒤 cluster_size 를 따로 읽었고, 25분간 2 로 남아 있는 것을 보고 주입이 걸리지 않았다고 판정했다.