마이크로서비스는 프로세스를 독립적으로 실행하기 때문에 공통으로 접근해야 하는 공유 자원을 고려해야 합니다. 공유 자원을 처리하는 가장 쉬운 방법은 데이터베이스처럼 데이터를 저장하는 저장소를 공통으로 사용하는 것입니다. 그러나 이것은 데이터베이스에 부하가 집중될 경우 마이크로서비스를 아무리 분산 배치해도 부하를 감당할 수 없다는 치명적인 문제가 있습니다.
병목 현상을 발생시키는 공유 자원 접근 방식
마이크로서비스 아키텍처는 독립된 각 기능을 프로세스 레벨로 분리해서 장애와 부하에 효과적으로 대응할 수 있도록 설계한 아키텍처입니다. 하지만 프로세스가 분리되고 물리적으로 다른 머신에서 실행될 경우 공유 자원에 접근하기 어렵다는 단점이 있습니다.
마이크로서비스의 공유 자원 접근 이슈
이러한 문제를 해결하는 몇 가지 방법이 있습니다. 가장 직관적인 방법은 한쪽은 정보를 가지고 있고, 다른 한쪽은 질의를 하는 것입니다.
마이크로서비스 간 정보 공유 아이디어 1
우리가 만든 마이크로서비스 아키텍처는 Distributor가 모든 마이크로서비스의 접속 정보를 알고 있으므로 Distributor에서 정보를 받아 해당 마이크로서비스에 질의하면 됩니다. 요청하는 마이크로서비스는 별도의 소켓을 이용해 접속하고, 응답하는 마이크로서비스는 원래 동작하던 대로 API 호출에 응답하면 됩니다. 예를 들어 구매 관리 마이크로서비스가 상품 관리 마이크로서비스에 접속해 유효한 상품 정보를 질의하고, 구매 요청을 할 때는 유효한 상품 정보를 활용하는 방식을 생각해 볼 수 있습니다.
다른 방법은 특정 마이크로서비스가 공유 자원이 필요한 다른 모든 마이크로서비스에 변경 사항을 알려 주는 것입니다. 예를 들어 상품 관리 마이크로서비스에 상품 등록·삭제·변경 등 API를 호출하면, 구매 관리 마이크로서비스에 변경 사실을 알려 줍니다.
마이크로서비스 간 정보 공유 아이디어 2
이외에도 다양한 마이크로서비스 간의 구조적 배치로 데이터베이스에 부담을 주지 않고도 공유 자원 문제를 해결할 수 있습니다. 하지만 구현이 복잡하고 마이크로서비스 간에 의존성이 생기는 단점이 있습니다.
앞에서 설명했듯이 공유 자원 문제를 해결하는 가장 쉬운 구현 방법은 여러 마이크로서비스가 데이터베이스 하나에 접근하는 것입니다. 이때 발생하는 부하 문제를 해결할 수 있다면 공유 자원 처리에 대한 매우 좋은 해법이 될 수 있습니다.
이러한 관점에서 메모리 캐싱 시스템을 널리 활용하고 있습니다. 메모리 캐싱 시스템을 이용해 빈번하게 호출하지만 변경할 일은 적은 데이터를 별도의 메모리 캐싱 시스템에 저장해 놓고 데이터베이스에 질의하는 대신, 미리 저장해 둔 데이터를 이용하면 데이터베이스의 부하를 줄일 수 있습니다. 대표적인 메모리 캐싱 시스템으로 Memcached와 Redis가 있습니다. Memcached보다 상대적으로 다양한 기능을 제공하는 Redis 연동 방법을 알아보겠습니다.
Redis는 키-값 기반의 캐싱 기능 이외에도 다양한 기능을 제공합니다. 아주 간략하게 Redis 활용 사례를 알아봅시다. 자세한 내용은 공식 사이트(https://redis.io)에서 확인합니다.
Sorted Set 기능을 이용해 랭킹 서비스에 활용할 수 있습니다.