LabHub
배우기 러닝패스 코스

CI/CD 파이프라인 · 캐시 열쇠 설계 · 이론

캐시는 열쇠를 어떻게 짓느냐가 전부다

LabHub 에서 이어서 보기

한 줄 요약

캐시가 지켜야 할 규칙은 하나다. 캐시를 지워도 같은 산출물이 나와야 한다. 캐시는 시간만 줄이는 장치이고, 결과를 바꾸는 순간 그것은 캐시가 아니라 숨은 입력이다. 그 규칙을 지키게 만드는 것이 열쇠 설계다.

왜 이게 필요했나

캐시를 붙이는 동기는 언제나 속도다. 그런데 열쇠를 대충 지으면 두 방향으로 다 진다. 열쇠가 너무 촘촘하면 아무것도 맞지 않아 캐시가 있으나 마나 하고, 열쇠가 너무 헐거우면 낡은 내용으로 통과하는 빌드가 나온다. 뒤쪽이 훨씬 나쁘다. 실패해야 할 것이 성공하기 때문이고, 그 실패는 캐시가 만료된 몇 주 뒤 엉뚱한 사람의 변경에서 터진다.

GitLab 문서는 이 성질을 아주 분명하게 적어 둔다. "캐싱은 최적화이지 언제나 동작한다고 보장되는 것은 아니다. 필요한 작업마다 캐시된 파일을 다시 만들어야 할 수도 있다." 즉 캐시가 없어도 되는 구조여야 한다. 작업이 캐시의 존재를 전제로 하면 그것은 캐시가 아니라 의존성이다.

열쇠에 무엇을 넣는가

열쇠는 "이 내용을 재사용해도 되는 조건" 을 문자열로 적은 것이다. 그래서 결과에 영향을 주는 것이 모두 들어가야 한다.

GitHub Actions 문서의 표준형이 이 모양을 그대로 담고 있다.

- uses: actions/cache@v4  with:    path: ~/.npm    key: npm-${{ runner.os }}-${{ hashFiles('**/package-lock.json') }}    restore-keys: |      npm-${{ runner.os }}-

GitLab 은 같은 일을 cache:key:files 로 한다. 특정 파일의 내용에 연결된 열쇠를 만들어 주는 기능이다.

접두 대체가 주는 것과 뺏는 것

restore-keys 는 정확히 맞는 열쇠가 없을 때 접두사로 시작하는 열쇠 를 찾는다. 공식 문서는 순서대로 훑으며, 부분 일치가 여럿이면 가장 최근에 만들어진 캐시 를 돌려준다고 적는다.

이득은 분명하다. 잠금 파일을 한 줄 고쳤다고 의존성을 전부 새로 받지 않고, 예전 것을 깔고 앉아 차이만 받는다. 위험도 같은 자리에 있다. 접두 대체로 받아 온 내용은 지금 잠금 파일과 일치한다는 보장이 없다. 그래서 접두 대체는 "다시 계산해도 결과가 같은 것" 에만 쓴다. 내려받기 캐시는 안전하고, 컴파일 산출물을 검사 없이 재사용하는 것은 위험하다. 열쇠가 완전히 맞았을 때만 단계를 건너뛰고, 접두 일치일 때는 내용을 채운 뒤 정상 절차를 다시 돌리는 것 이 안전한 형태다.

또 하나. GitHub Actions 의 캐시 항목은 한 번 만들어지면 내용을 바꿀 수 없다. 문서는 기존 캐시의 내용을 변경할 수 없으며 새 열쇠로 새 캐시를 만들라고 적는다. 그래서 "열쇠를 그대로 두고 내용만 고치면 되겠지" 는 통하지 않는다.

캐시와 산출물은 다른 물건이다

GitLab 문서의 구분이 가장 간결하다. 캐시는 인터넷에서 내려받는 의존성 같은 것에 쓰고, 산출물(artifact)은 단계 사이로 중간 결과를 넘기는 데 쓴다. 캐시는 러너 기계에 남고, 산출물은 서버에 저장되어 내려받을 수 있다.

판단 기준은 하나다. 없어져도 되는가. 없어지면 시간만 더 드는 것은 캐시다. 없어지면 다음 단계가 아예 못 도는 것은 산출물이다. 시험 보고서와 커버리지 결과를 캐시에 넣어 두는 파이프라인을 가끔 보는데, 캐시는 축출될 수 있으므로 실패한 그 순간의 증거가 사라진다.

범위와 오염

캐시는 신뢰 경계이기도 하다. 아무 브랜치나 캐시를 저장하게 두면, 그 브랜치에 밀어 넣을 수 있는 사람은 누구나 이후 빌드의 결과에 손을 댈 수 있다. 그래서 플랫폼들이 범위를 좁게 잡아 둔다.

한도와 축출도 알아 둘 값이다. GitHub Actions 는 저장소당 기본 10GB 이고, 7일 넘게 쓰이지 않은 항목을 지우며, 공간이 필요하면 마지막 접근 시각이 오래된 것부터 지운다. 그래서 열쇠를 커밋 단위로 잘게 쪼개면 캐시끼리 서로를 밀어내 적중률이 오히려 떨어진다.

현장에서 만나는 모습

참고

다음 실습에서 할 것

캐시 관리자를 셸로 직접 만든다. 잠금 파일 해시와 도구 판, 운영체제를 이어 붙여 열쇠를 짓고, 그 열쇠로 저장하고 꺼내는 스크립트를 쓴다. 그런 다음 잠금 파일을 한 줄 고쳐 열쇠가 저절로 달라지는지 확인하고, 접두 대체로 옛 내용을 받은 뒤 그대로 통과시키면 어떤 일이 벌어지는지 를 반례로 만들어 본다. 마지막에는 캐시를 비운 채 다시 돌려 산출물 해시가 같은지 대조하는 검사와, 적중률을 세어 보고하는 단계를 붙인다.