GeekCoders

[Redis] 레디스 운영 시 고려사항 본문

DB/Redis

[Redis] 레디스 운영 시 고려사항

알 수 없는 사용자 2015. 1. 22. 18:43

레디스는 다양한 환경에서 운용된다. 대표적으로 AWS 같은 클라우드 컴퓨팅 환경이나 IDC에 구축된 클러스터를 예로 들 수 있다. 이러한 환경에서 레디스 클러스터를 운영할 때 고려할 사항 중에서 설정과 하드웨어 관한 내용이다. 


1. 임계점 

스케일 업과 스케일 아웃은 모두 처리 능력을 향상시키는 방법이다. 스케일 업은 우수한 성능을 제공하는 푸품을 조합하여 강력한 장비 한 대를 구축한다. 하지만 결국 장치 한 대의 성능에는 한계가 분명하다. 반면 스케일 아웃의 경우 한계가 없다. 하지만 현실적으로 네트워크 대여폭 등에 의한 한계가 있다. 이와 같은 한계점을 임계점이라 한다.


CPU 임계점

레디스는 데이터 저장과 조회에 단일 스레드를 사용한다. 

멀티코어 시스템에서 성능을 최대한 끌어내기 위해서 인스턴스 여러 개를 실행하는 방안을 생각해 볼 수 있다. 예를 들어 8코어 시스템에서 레디스 인스턴스 8개를 실행하는 것이다. 

여러 개의 인스턴스를 운영시 메모리 대여폭의 임계점에 문제가 발생한다. 여러개의 인스턴스들이 동시에 명령을 처리할 경우 

레디스는 명령 처리를 위해 메모리에 접근하고, 조회된 데이터는 메모리 대여폭을 사용하여 데이터 버스를 통해서 해당 코어로 전송하게 된다. 즉 레디스 인스턴스가 메모리 대여폭을 나누어 사용하므로 병목현상이 발생한다. 

단일 시스템에서 다중 인스턴스를 실행하려면 메모리 대여폭이 충분해야 한다. 메모리 대여폭이 충분하다고 가정하면 코어 개수의 1/2 보다 작은 수의 인스턴스를 실행 하는 것이 가장 적당하다. 


메모리 크기 

레디스는 메모리에 데이터를 저장하기 때문에 레디스가 사용할 메모리의 크기를 지정하는 것은 성능과 가장 밀접한 관계가 있다.

redis.config의 maxmemory 설정값은 키를 위한 공간과 데이터를 위한 공간을 모두 포함한다. 즉, 레디스가 데이터를 저장하기 위한 부가적인 데이터의 크기도 포함하게 되는데, maxmemory 4GB를 지정했다면 실제로 저장 가능한 데이터의 크기는 4GB보다 작다. 레디스에 데이터가 계속 추가되어 물리 메모리를 모두 사용하게 된다면 운영체제는 애플리케이션이 시스템에 사용 가능한 물리 메모리보다 더 많은 메모리를 사용하려고 할 때 스왑 이라는 가상 메모리 공간을 하드디스크에 생성하여 사용하는데, 이를 스왑공간이라 부른다.  이때 스왑영역이 충분하지 않으면 운영체제는 메모리에서 동작 중인 프로세스를 제거하여 사용 가능한 메모리 영역을 확보하게 된다. 스왑영역을 사용하게 되면 레디스의 성능은 수백배까지 느려지게 된다. 


네트워크 

복제를 위한 마스터와, 슬레이브 간 데이터 전송과 네트워크 단절에 의한 데이터 동기화로 인해 네트워크에 부하가 발생할 수 있다. 마스터 노드에 쓰기 연산이 발생하면 마스터 노드는 연결된 슬레이브 노드에 레디스프로토콜을 사용하여 데이터를 전송한다. 키와 데이터의 크기에 해당하는 네트워크 대여폭을 사용하게 된다. 따라서 각 마스터는 쓰기 연산이 한번 발생할 때마다 복제를 위한 * slave갯수 만큼의 추가 트래픽이 발생하게 된다. 


2. 기타 고려사항


스냅샷

AWS와 같은 가상 환경에서 레디스를 서비스한다면 스냅샷 파일의 위치는 반드시 로컬 파일 시스템을 사용해야 한다. 레디스의 스냅샷 이벤트는 매우 빫은 시간에 매우 많은 디스크 입출력이 발생하는데, AWS의 EBS와 같은 외부 저장장치는 로컬 디스크에 비해서 스냅샷 파일을 기록하는 데 많은 시간이 소요된다. 이아 같은 이유로 스냅샷이 완료되기 전까지 레디스의 전체적인 성능도 같이 떨어지게 된다. 


마스터와 스냅샷

마스터 슬레이브 복제 구성에서 마스터 노드의 스냅샷 설정이 꺼져 있더라도, 새로운 슬레이브 노드가 마스터에 추가도면 마스터 노드는 스냅샷을 생성한다. 이와 같은 현상은 새로 추가돈 슬레이브 노드에 마스터 노드의 전체 데이터를 복제하나ㅡㄴ 데 필요한 레디스의 정상적인 동작이다. 

redis.config의 client-output-buffer-limit은 레디스 복제를 위해 스냅샷 데이터를 전송할 버퍼를 생성하는데, 이 버퍼의 크기가 지정된 크기보다 커지면 슬레이브의 연결을 강제로 끊게 된다. 이때 슬레이브는 마스터 노드와 여결이 끊어졌으므로 다시 마스터 서버로 접속을 시도하고, 접속 후에는 마스터 노드의 스냅샷이 생성되는 현상이 반복되게 된다. 


fork 함수

레디스는 AOF와 스냅샷을 위해서 fork 함수와 COW를 사용하여 백그라운드 저장 프로세스를 생성한다. fork 함수는 운영체제의 입장에서 매우 비싼 수행 비용이 필요하다. fork 함수를 수행하기 위해서 운영체제가 많은 리소스를 사용하게 되며, 단일 스레드로 동작하기 때문에fork 함수가 완료되기 전에는 다른 명령을 수행하지 못한다. 여기서 fork함수의 완료란 메인 프로세스에서 fork 함수가 수행되어 자식 프로세스의 생성이 완료되기까지의 시간을 말한다. 즉. 자식 프로세스가 데이터를 디스크에 저당하는 동안에는 모든 명령어가 문제없이 수행된다.


복제 구성

레디스의 복제를 구성할 때 하나의 마스터에 너무 많은 슬레이브를 구성하지 않도록 한다. 여기에는 두 가지 문제점이 존재하는데, 

첫 번째는 데이터를 복제하기 위한 네트워크 사용률이 데이터 서비스를 위한 네트워크 사용률보다 커지게 되어 매우 느린 응답시간을 보이게 된다. 이를 위해 복제를 위한 별도의 네트워크 카드를 설정하는 방법과 복제를 위한 별도의 스위치 허브를 사용하는 구성을 고려해야 한다. 

두 번째는 하나의 마스터 노드에 많은 슬레이브가 구성되면 각 슬레이브노드에서 요청되는 데이터 복제 요청에 응답하기 위하여 리소스 대부분을 사용하게 되어 쓰기 요청이 지연된다. 

'DB > Redis' 카테고리의 다른 글

[Redis] Password 설정  (0) 2016.08.04
[Redis] Master-Slave Replication  (0) 2015.01.26
[Redis] 레디스란 무엇인가  (0) 2015.01.22