Home 로컬 캐시를 글로벌 캐시와 동기화할 수 있을까?
Post
Cancel

로컬 캐시를 글로벌 캐시와 동기화할 수 있을까?

글을 작성하게 된 계기


멀티 서버 상황에서 캐시를 갱신하는 방법에 대해 고민한 내용을 정리하기 위해 글을 작성하게 되었습니다.

구체적 기술을 예시로 들었지만, 다른 기술을 사용하는 경우에도 동일하게 적용할 수 있습니다.





1. 문제 상황


캐시를 사용할 때, 어려운 문제 중 하나는 동기화 입니다. 애초에 변하지 않는 데이터를 캐싱하는 게 가장 좋지만, 성능, 정책 등과 같은 이유로 어쩔 수 없이 변하는 데이터를 캐싱 해야 할 때가 있습니다. 이를 위해 각 애플리케이션 내부에 글로벌 캐시의 값을 저장해, 로컬 캐시(Local Cache) 를 사용한다고 가정해 보겠습니다. 만약 멀티 서버 구조에서 로컬 캐시를 갱신해야 한다면 어떤 방법을 사용할 수 있을까요?

image

예시를 들었지만, 로컬 캐시를 이렇게 사용하는 것이 좋은 방법은 아니라고 생각합니다.







2. 해결 방법


이를 해결하는 방법은 크게 오케스트레이션(Orchestration) 이 없는 경우와 있는 경우, 두 가지로 나눌 수 있습니다. 오케스트레이션은 중앙 관제 서버로, 다른 여러 서버를 통제하는 서버입니다.

In system administration, orchestration is the automated configuration, coordination, deployment, development, and management of computer systems and software.





2-1. 오케스트레이션이 없는 경우

먼저 오케스트레이션이 없는 경우, Redis의 Pub/SubRabbitMq의 Fanout 을 통해 로컬 캐시를 갱신할 수 있습니다. 즉, 아래와 같이 한 서버로 캐시 갱신을 요청했을 때, 브로드 캐스팅을 통해 각 서버의 로컬 캐시를 갱신하는 것입니다.

image






캐시를 갱신할 때는 뒤에서 앞으로 갱신해야 합니다. 즉, 안정적인 데이터를 먼저 갱신한 후, 불안정한 데이터를 갱신해야 합니다.

image






이는 별도의 오케스트레이션이 없기 때문에 별도의 서버 비용이 발생하지 않으며, 유지보수 비용이 적다는 장점이 있습니다. 하지만 서비스가 커지며 갱신할 데이터가 많아졌을 때 이를 체계적으로 관리하기 힘들어지며, 브로드 캐스팅 과정에서 일시적 데이터 불일치 가 발생할 수 있습니다.

  1. 장점: 별도의 서버 비용이 발생하지 않으며, 유지보수 비용이 적다.
  2. 단점: 서비스가 커졌을 때, 갱신할 데이터가 많을 때 체계적으로 관리하기 힘들다.






2-2. 오케스트레이션이 있는 경우

오케스트레이션이 있는 경우, 중앙 서버에서 각 서버의 로컬 캐시를 갱신할 수 있습니다. 캐시를 갱신할 때, 동기화 문제가 발생할 수 있으므로 항상 뒤에서부터 이를 갱신하도록 합니다.

image





이는 별도의 서버/유지 보수 비용이 발생하는 단점이 있지만 서비스가 커지고 갱신해야 할 데이터가 많아지더라도 체계적으로 관리할 수 있다는 장점이 있습니다.

  1. 장점: 서비스가 커지더라도 체계적으로 캐시를 관리할 수 있다.
  2. 단점: 추가적인 서버/유지보수 비용이 발생한다.







3. 한계


위 방식 또한 캐시가 갱신되는 순서 보장 이 힘들다는 한계가 있습니다. Redis의 Pub/Sub은 Fire-and-Forget 방식으로 캐시 갱신 유무를 파악하기 힘들며, RabbitMq 또한 메시지 추적 이 까다롭기 때문입니다.

근본적으로 서버는 언제 오토 스케일링 될 지 완벽히 예측할 수 없으며, 캐시 갱신 이벤트가 특정 시점에 누락되거나 처리되지 않을 가능성도 존재합니다.







4. 대안


사실 이 문제는 로컬 캐시만 사용하지 않으면 바로 해결됩니다. 즉, 글로벌 캐시만 사용해 문제를 해결하는 것이죠. 이 경우에도 시스템 규모 와 관리하는 캐시 수 에 따라 방법이 다를 것 같습니다.

  1. 작은 규모의 시스템
  2. 큰 규모의 시스템





4-1. 작은 규모의 시스템

작은 시스템이라면 글로벌 캐시만 사용 하며, 글로벌 캐시가 다운될 경우를 대비해 1차, 2차 캐시를 구축할 수 있습니다. 다음과 같이요.

image






이렇게 되면 글로벌 캐시만 사용하기 때문에 캐시 동기화 문제로부터 자유로울 수 있습니다. 단점으로는 글로벌 캐시가 다운될 경우, 레이턴시가 증가할 수도 있고, 별도로 2차 캐시를 구축해야 하기 때문에 서킷 브레이커와 같은 추가적인 장치를 설치해야 한다는 점입니다.

사실 작은 시스템이라면 1차, 2차 캐시를 구축할 필요가 없을 수도 있습니다.






4-2. 큰 규모 시스템

대규모 시스템이라면 중앙에 오케스트레이션을 둔 후, 실시간 데이터(RealTime Data) 인지, 일정 주기로 갱신되어도 될 캐시 인지를 구분해 갱신할 수 있습니다. 물론 큰 규모의 시스템이라도 관리할 할 캐시가 적은 경우, 별도의 시스템을 구축하지 않을 수도 있습니다.

image






이때, 실시간 정합성이 중요한지, 아닌지에 따라 한 번 더 구분하는 게 필요한데, 실시간 정합성이 중요한 데이터라면 즉시 갱신하고, 아니라면 일정 주기로 이를 갱신해도 괜찮습니다. 이 방식의 장점은 캐시를 더 세밀하게, 체계적으로 관리할 수 있다는 점이며, 단점은 추가적인 서버/유지보수 비용이 발생한다는 점입니다.

  1. 장점: 캐시를 세밀하게, 체계적으로 관리할 수 있다.
  2. 단점: 추가적인 서버/유지보수 비용이 발생한다.







5. 정리


캐싱을 할 때, 애초에 잘 변하는 데이터는 캐싱하지 않는 것이 좋습니다. 하지만 성능, 비즈니스 정책 때문에 글로벌 데이터를 로컬에 캐싱해야 할 때도 있는데요, 이를 갱신할 때, 어떤 방법이 있는지, 또 대안은 무엇이 있는지도 알고 있으면 좋을 것 같습니다.


This post is licensed under CC BY 4.0 by the author.

서비스 장애 대응과 롤백, 그 과정에서 배운점

개발을 시작하게 된 계기와 개발을 하는 이유