배치 작업의 처리 방식별 성능을 비교하려고 여러 조합으로 돌리는 실험을 짰다. 조합마다 소요 시간과 산출물 크기를 재도록 만들어 두고 결과를 모았다. 그런데 어느 조합에서만 예상하지 못한 항목이 결과에 섞여 나왔다.
Table of contents
Open Table of contents
세운 가설과 배제
처음에는 두 가지를 의심했는데 하나는 실험 스크립트가 조합을 잘못 넘긴 것이고 다른 하나는 입력 자료가 조합마다 다른 것이었다. 둘 다 확인할 수 있는 종류라 각각 검사했다.
실행할 때 넘긴 argv를 그대로 찍어 보니 조합은 정확했다. 입력 자료를 md5sum으로 조합마다 비교했더니 전부 같았다. 두 가설이 배제되면서 원인이 실험 밖에 있다는 쪽으로 좁혀졌다.
원인 — 부모 환경에서 온 설정
env로 실행 환경을 찍어 보니 전역으로 걸린 설정이 하나 있었다. 실험에서는 그것을 쓰지 않도록 옵션을 줬는데도 자식 프로세스는 부모의 환경 변수를 그대로 물려받고 있었다.
옵션으로 다른 설정을 껐다고 해서 그 환경 변수까지 빠지는 것은 아니었다. 그 설정에 포함된 규칙이 실행에 개입해서 산출물을 바꾸고 있었다. 규칙이 걸리는 조건과 결과에 섞인 항목의 규모가 정확히 맞아떨어졌다.
조건에 따라 개입이 갈렸다
문제는 그 규칙이 모든 조합에서 발동하는 것이 아니라는 점이었다. 특정 조건의 조합에서만 걸려서 그 조합만 다른 처리를 거쳤다.
그러면 조합끼리의 비교 자체가 성립하지 않는다. 성능 차이로 보이는 것이 처리 방식의 차이가 아니라 규칙 개입 여부의 차이일 수 있다. 비교 실험에서는 비교하려는 것 말고 다른 것이 조합마다 달라지면 안 됐다.
격리와 실전 조건
순수한 비교를 하려면 그 환경 변수가 안 들어오는 자리가 필요했다. 그래서 env -i로 환경을 비우고 실험을 다시 돌렸다.
다만 운영에서 실제로 도는 상태는 그 설정이 걸린 쪽이다. 그래서 실전 조건에서 얼마나 걸리는지를 재려면 오히려 그대로 두는 것이 맞았다. 무엇을 재려는지에 따라 격리할지 말지가 갈렸다.
배제가 만든 확증
이 조사에서 결론을 세운 것은 앞의 두 가설을 배제한 과정이었다. 남은 후보 하나만으로는 그것이 원인이라고 말하기 약하다.
다른 가능성을 하나씩 지우고 나서 남았고 규모와 패턴까지 맞았기 때문에 확증이 됐다. 그리고 자식 프로세스가 부모의 환경 변수를 물려받는다는 것을 앞으로의 전제로 적어 두었다. 그 전제를 모르면 같은 종류의 실험이 계속 오염된다.
정리
- 자식 프로세스가 부모의 환경 변수를 그대로 물려받는다
- 옵션으로 다른 것을 꺼도 그 환경 변수는 안 빠진다
- 그 규칙이 실행에 개입해 산출물을 바꾼다
- 조건에 따라 개입 여부가 갈리면 비교가 성립하지 않는다
- 순수 비교에는
env -i로 비운 환경이 필요하다 - 실전 조건 측정에는 그대로 둔 상태가 맞다
- 다른 가설을 배제해야 남은 후보가 강해진다
- 자식이 부모의 환경 변수를 물려받는다는 것을 전제로 적는다