안녕하세요. LINE+ Redis 팀에서 DBA 업무를 담당하고 있는 김정훈입니다. 저희 팀은 이름 그대로 대표적인 키-값 저장소(key-value store)인 Redis를 연구하고 사내에 도입하고 있습니다. 또한 국가 및 법인을 불문하고 자체적으로 운영하고 있는 서비스를 제외한 LINE 관련 서비스에서 사용하는 모든 Redis에 대한 기술 지원을 담당하고 있습니다.
그동안 새로운 서비스가 생기고 기존 서비스도 성장하면서 Redis의 규모 또한 점차 커져 왔는데요. 이번 글에서는 2023년 한 해 동안 대규모 Redis를 운영하며 겪은 저희 팀만의 경험을 간략하게 나눠 보려고 합니다. 현재 저희가 운영하고 있는 Redis의 대략적인 규모와 함께 HA(high availability)를 어떻게 구성했는지 간단히 설명하고, 클라우드 리소스를 보다 효율적으로 사용하기 위해 진행했던 'Low Usage Project'를 소개하겠습니다.
Redis 운영 규모로는 아마 아시아 최대?
'대규모 Redis'라는 문구가 크게 와닿지 않으실 수도 있습니다. 아래는 작년 11월부터 금년 2월까지의 사용량 증가 추이를 보름 간격으로 나타낸 그래프입니다.
구체적인 수치를 공개할 수는 없지만, 확실한 것은 시간이 지나면서 전사에서 사용되는 Redis의 규모가 점점 커지고 있다는 것입니다. 사내 클라우드를 통해 제공되는 Redis도 있고, 일부 서비스는 DBA 작업 하에 VM이나 PM에 직접 설치해 운영하기도 합니다.
기존에도 확연히 많은 양의 Redis를 운영하고 있었기에 어쩌면 '아시아 최대 규모'이지 않을까 생각하고 있었습니다. 그러다 최근 Redis Enterprise의 엔지니어 분에게 중국의 어느 한 회사에서 엄청난 규모의 Redis를 운영하고 있다는 소식을 들으며 그 규모를 알 수 있었는데요. 놀랍게도 저희 규모가 그 규모를 상회했습니다. 그렇기 때문에 저희가 아마 아시아 최대 규모이지 않을까 추측하고 있습니다.
장애는 언제든지 발생할 수 있다
입사 초기 팀원들에게 자주 들었고, 지금도 뼈저리게 느끼고 있는 부분이 있습니다. 바로 장애는 언제든지 발생할 수 있다는 점입니다. 소프트웨어라면 개발 능력의 범주 안에서 직접 트러블슈팅이 가능합니다. 리소스를 많이 사용하는 부분이 있다면 로직을 개선하며 최적화하는 등이 그 예시일 것 같네요. 하지만 하드웨어의 경우에는 정말 무섭습니다. 하드웨어를 구성하는 다양한 부품(CPU, RAM 등) 중 어느 하나라도 문제가 생기면 PM 혹은 HV(hypervisor)에 서비스 아웃을 동반한 점검이 필요합니다. 심지어는 운영 도중 특정 벤더의 일부 부품 전체에서 문제가 발견돼 긴 시간 동안 서비스 아웃을 반복한 경험도 있습니다.
HA 구성 덕분에 안심할 수 있습니다! 아마도요
디스크 스토리지를 사용하는 타 DBMS와는 다르게 Redis는 인 메모리(in-memory) 데이터베이스입니다. 메모리는 휘발성 매체이기 때문에 Redis 프로세스가 종료된다면 데이터 유실을 각오해야 합니다.
이를 방지하기 위해 기본적으로 저희가 운영 중인 Redis는 '1 Primary - 1 Replica' 구조를 채택하고 있습니다. '더 많은 Replica 노드를 두면 훨씬 안전하고 편리하지 않을까?'라고 생각할 수 있지만, 각 구조에는 나름의 장단점이 있습니다. 아래 그림은 '1 Primary - 1 Replica' 구조와 '1 Primary - 2 Replica' 구조를 나타낸 그림입니다.
위 그림처럼 Replica 노드가 두 개인 경우 Primary 노드 에 문제가 발생했을 때 어느 Replica 노드가 Primary 노드가 될지를 결정하기 위한 추가 과정이 필요합니다. 물론 이 단점이 치명적인 단점은 아니더라도 Replica 노드 사이에서 발생할 충돌 가능성까지 고려해 '1 Primary - 1 Replica' 구조로 운영하고 있습니다. 의도한 것은 아니지만 이 구조는 Replica 노드를 최소화해 비용 측면에서의 최적화 또한 이룰 수 있었습니다.
이 상태에서 Primary 노드 하드웨어에 문제가 발생할 경우 기존 Replica 노드가 Primary 노드로 승격돼 문제없이 서비스를 운영할 수 있습니다. 하지만 하드웨어 문제가 해결되기 전까지는 Primary 노드 하나만 존재하게 돼 아직 다소 위험한 상태입니다.
Replica를 추가합니다, 그것이 Replica가 없다는 것이니까
Primary 노드만 남아 있는 경우 이 노드마저 다운되면 데이터 손실로 이어질 수 있기 때문에 고가용성을 유지하기 위해 '1 Primary' 상태를 방치하지는 않습니다. 해결책은 간단합니다. Replica 노드를 하나 더 추가하면 됩니다. 이에 대비해 팀 차원에서 고사양 장비를 몇 대씩 준비해 뒀고, 필요하면 서버를 추가로 발급받습니다. 이 서버들은 언제든 Redis를 실행할 준비가 돼 있으며, 서비스 아웃이 발견되는 즉시 Primary 노드만 남은 서비스에 임시 Replica 노드를 추가하는 작업을 진행합니다.
아래는 항상 '1 Primary - 1 Replica' 구조를 유지할 수 있도록 임시 Replica 노드를 추가하는 과정을 설명한 그림입니다.
그런데 놀랍게도 저희는 현재 클라우드 환경에서 관리되지 않는 PM의 경우 이 작업을 매번 수작업으로 진행하고 있습니다. 이런 상황이 자주 발생하지 않는다면 좋겠지만 실제로는 일주일에도 몇 번씩이나 때를 가리지 않고 발생합니다. 장애는 언제든지 발생할 수 있기 때문에 사내 각종 서비스의 무결점 운영을 위해 조금이라도 리스크가 있다면 사명감을 갖고 대응하고 있는데요. 그렇다면 클라우드 환경에서는 어떻게 작업하고 있을까요?
클라우드 환경에 오토 힐링 도입
앞서 이야기했듯 현재 운영하고 있는 Redis의 규모가 굉장히 크기 때문에 만약 클라우드 환경에서 관리하는 Redis까지 각 서버의 모든 점검 상황에서 위 대응을 반복해야 했다면 몸이 몇 백 개여도 모자랐을 것입니다. 매번 수작업을 하는 것은 불가능하고, 그렇다고 남은 서버 하나만 믿고 방치해 둘 수는 없는 노릇이었을 텐데요. 이를 해결하기 위해 사내 클라우드 환경에는 오토 힐링을 도입했습니다.
아래는 클라우드 환경에 도입한 오토 힐링이 작동하는 과정을 나타낸 그림입니다.
요지는 간단합니다. 서버 점검이 진행될 때 새로운 서버를 발급받아 추가하는 것입니다. 차이점이라고 하면 새롭게 추가된 서버가 반납되는 것이 아니라 점검 대상인 서버가 반납된다는 것입니다. 클라우드 환경이기 때문에 PM과는 달리 간단히 서버를 발급받고 교체할 수 있어서 자동화할 수 있었습니다.
서비스 아웃이 발생하는 경우에는 Redis 상태를 확인할 필요가 있기 때문에 야간에도 일어나서 확인해야 한다는 점은 변하지 않았습니다. 하지만 HA 구성을 유지하도록 자동화 프로세스를 구축한 것만으로도 공수를 크게 줄일 수 있었습니다.
호오, 사용량이 올라가는군요
좋은 서비스는 시간이 흐르면서 점점 사용하는 서버의 규모가 커지기 마련입니다. 그에 맞춰 사내 클라우드 서비스에도 다양한 기능을 추가하고 개선하며 안정성을 확보하고 있는데요. 클라우드 서비스는 개발자들이 사용하기 편리하다는 장점뿐 아니라 데이터베이스 관리자 측면에서의 장점도 굉장히 많습니다. 그중 저희가 꼽은 장점은 아래와 같습니다.
- 데이터베이스 수가 증가해도, 관리 공수가 정비례로 증가하지 않는다.
- (확장의 경우 타당한 스펙인지 검토하는 과정이 있긴 하지만) 확장 및 축소가 용이하다.
이와 같은 환경 하에 개발자는 손쉽게 '다수의 데이터베이스'를 제공받고, 저희는 손쉽게 '대규모 데이터베이스'를 제공할 수 있습니다. 그렇게 마치 전투력이 상승하듯 점점 더 많은 데이터베이스를 관리하면서 보다 많은 사용 사례를 발견하고 트러블 슈팅 사례를 남기며 더욱 견고하게 기술력을 다져 나가고 있었는데요. 어느 날 클라우드 환경에서도 전투력 측정기가 폭발할 수 있다는 것을 깨닫게 되었습니다.
Low Usage Project 기획 및 준비
클라우드 환경은 그 안에서는 여러 상황에 유연하게 대처할 수 있지만, 클라우드 자체의 물리적인 리소스가 부족한 상황에까지 유연하게 대처하기는 힘듭니다. 즉 물리 장비가 추가되지 않는 이상 수용량의 한계는 정해져 있고, 그 이상으로 서비스 를 제공하는 것은 어렵습니다.
사실 앞서 표현한 '전투력 측정기 폭발'은 조금 과장한 내용입니다. 서비스 제공에 무리가 있지는 않았습니다. 다만 생각 이상으로 사용량이 높았던 것은 사실입니다. 이에 대처하는 방법은 간단합니다. 사용량이 높으면 잘 사용하지 않는 리소스를 일부 반납하거나 축소하면 됩니다. 앞서 언급했듯 클라우드 서비스는 확장 및 축소가 용이하기 때문에 이를 실행하는 게 어렵지는 않습니다.
저희는 이를 프로젝트화해서 'Low Usage Project'라는 미사용 혹은 저사용 Redis 반납 캠페인을 시작했습니다. 이 글을 읽고 계신 분들 중 학창 시절에 AWS 등에서 서버를 발급받고 이용해 본 경험이 있는 분들이 많으실 텐데요. 발급받은 서버를 제때 반납하지 않아 보유 크레디트 이상의 비용이 청구된 경험이 있는 분도 계실 겁니다. 사내 클라우드도 마찬가지입니다. 사용하지 않음에도 방치하고 있다면 리소스를 낭비하고 있는 것입니다. 여기에 포커싱해 대규모 인프라 운영의 숙원과도 같은 과제인 '불필요한 비용과 리소스 낭비를 줄이자'라는 목표를 세우고 캠페인을 준비했습니다.
캠페인을 준비하면서 미사용 혹은 저사용을 판단하는 기준을 마련하거나 스케일인 혹은 스케일 다운 시 서비스에 영향이 있는지 판단하는 등 고려할 사항이 생각 이상으로 많았습니다. 아래는 그와 같은 고민이 남긴 흔적입니다.
그중에서도 가장 중요한 고민은 바로 '사용자가 원하는지'였는데요. 이제 각 고민을 어떻게 풀어나갔는지 간단히 살펴보겠습니다. 회고하며 글을 작성하는 지금이야 별것 아닌 것처럼 이야기할 수 있지만 당시에는 굉장히 괴로운 고민이었고 시행착오도 겪어야만 했습니다.
슈뢰딩거의 Redis: 사용할 수도 사용하지 않을 수도
Low Usage Project를 실행하면서 가장 먼저 만난 문제는 바로 '과연 이 Redis는 사용하고 있는 것일까?'를 판단하는 문제입니다. 이는 Redis에서 가장 중점적으로 보는 메모리 사용량만으로는 판별할 수 없는 문제입니다. 물론 익스포터를 이용해 각종 지표를 수집하고 있었기에 아래와 같이 명령어 발행 횟수 등 여러 지표를 확인할 수는 있었습니다.
문제는 지표만 충분했다는 점입니다. 명령어 발행 기록은 상대적으로 중요도가 낮아서 별도로 후가공하지 않고 있는 상태였습니다. 즉 지표 데이터베이스를 열어봐도 사용량을 식별할 수는 없었습니다. 그저 로(raw) 데이터만 존재했습니다.
하지만 데이터가 존재한다는 사실 자체에 감사하며 쉽게 사용량을 판단할 수 있도록 후가공을 진행했습니다. 최종적으로 각 서비스에 대해 최근 명령어 발행 횟수와 시스템 사용량을 토대로 내부적으로 저사용 판단 기준을 만들었는데요. 만든 뒤에는 향후 같은 과정을 반복하지 않도록 이를 체계화해 메모리 외에도 각종 지표를 추적 및 관리할 수 있도록 만들었습니다.
어? 그거 그렇게 하는 거 아닌데
미사용 Redis는 간단하게 정리할 수 있습니다. 사용 중인 리소스를 반납하기만 하면 되기 때문이죠. 하지만 저사용 Redis라면 이야기가 조금 달라집니다. 아래는 예시를 보여드리기 위해 Redis 설치 후 사용하지 않고 방치해 본 모습입니다.
위 예시는 다소 극단적인 예시였지만, 이와 비슷하게 서버 스펙에 비해 사용하는 메모리의 양이 현저히 낮은 서비스가 존재했습니다. 이런 경우 아래 두 가지 방법 중 하나 혹은 두 가지 모두를 사용해서 축소했습니다.
- 스케일 인: Redis 클러스터를 구성하는 샤드 수를 줄입니다.
- 스케일 다운: Redis를 구성하는 서버의 스펙을 줄입니다.
위 작업 과정에서 최우선으로 고려해야 할 사항은 '서비스에 중단이 없을 것'입니다. 다양한 서비스를 제공하기 위해 리소스를 확보하기 위한 작업에서 서비스 중단이 발생한다면 그야말로 주객전도가 되기 때문입니다.
물론 이에 대한 해결책도 준비돼 있었습니다. 앞서 HA 구성을 설명할 때 말씀드린 것처럼 확장 및 축소 중 언제라도 Redis 서버를 하나씩 더 추가할 수 있도록 설계했습니다. 이렇게 하면 작업 중 어느 하나의 물리 장비에 문제가 생겨도 Redis는 문제없이 가동할 수 있습니다.
하지만 이는 모두 클라이언트 설정이 잘 돼 있는 경우에만 가능한 해결책입니다. DNS 기반의 엔드포인트 설정, 혹은 Redis 클러스터의 구성 정보가 변경됐을 때 이를 정상적으로 식별할 수 있게 하는 Redis 클러스터 토폴로지 관련 옵션 설정 등 클라우드 환경에서 안전하게 사용하기 위해서는 사내 클라우드 설정 가이드의 모범 사례를 따라야만 합니다.
기존에도 주로 사용되는 클라이언트 라이브러리의 세부 설정에 대해서는 단순 조사를 넘어 그동안의 트러블 슈팅 사례를 토대로 가이드 문서를 제공하고 있었는데요. 캠페인을 준비하면서 더욱 다양한 설정 관련 가이드를 추가하고 보다 읽기 쉽게 정비했습니다. 상기한 오토 힐링의 작동도 클라이언트 설정에 의존하기 때문에 캠페인을 통해 향후 발생 가능한 장애도 미리 예방할 수 있었습니다.
'Users Rule', 그리고 'Perfect the Details'
자, 이제 마지막 고민이자 가장 중요한 고민이 하나 남았습니다. 바로 '사용자가 원하는지'입니다. Redis 운영 중 과거에도 몇 차례 캠페인을 진행했었는데요. 사내 메일로 다음과 같은 피드백을 받은 적이 있습니다.
각 사용자에게 커스텀해서 메일을 보낼 수 있는 시스템이라면 상세 정보를 확인할 수 있는 다이렉트 URL도 충분히 첨부할 수 있습니다. 세계적인 기업이니 만큼 사내 공지라고 하더라도 사소한 부분까지 신경 써서 더욱 수준 높은 결과를 이끌어 주셨으면 좋겠습니다.
피드백을 받고 그동안 업무 태도에 안일한 부분이 있었던 것은 아닌지 돌아봤습니다. 캠페인을 진행하면서 그 무엇보다 가장 중요한 것은 사용자의 참여인데도 이전 캠페인에서 저희는 다소 거친 정보만 제공했고, 어쩌면 이게 참여율 저조로 귀결될 수 있었습니다. 이전까지 이야기해 본 적 없는 사용자분이었지만 해당 메일은 제게 깨달음을 주었고, 이후 줄곧 제 중요 메일함에 남아있습니다.
LY의 Our Mission & Values 중 'Users Rule', 그중에서도 'Perfect the Details'를 다시 한번 되새기며 아주 사소한 부분까지 사용자를 위해 노력하기로 다짐했습니다. 피드백 받은 내용대로 URL을 제공할 뿐 아니라, 이를 넘어 사용자별로 맞춤형 대시보드를 제작하기로 했습니다. 제작 과정에서 중점적으로 고려한 내용은 아래와 같습니다.
- 왜 해야 하는가
- 무엇을 해야 하는가
- 어떻게 해야 하는가
- 한눈에, 직관적으로 확인할 수 있는가
그리고 이 내용은 이미 앞서 모두 다뤘던 내용입니다. 그렇습니다. 모두 빌드업이었습니다! 🙂
왜? | 후가공한 지표를 바탕으로, 귀하의 Redis가 미사용 및 저사용으로 판단되었습니다. |
---|---|
무엇을? | 미사용이라면 반납을, 저사용이라면 축소를 부탁드립니다. |
어떻게? | 가이드 문서를 참고하시고, 설정을 완료한 뒤 클라우드 UI를 통해 진행해 주세요. |
아래와 같이 최대한 간결하게 단일 페이지에서 모든 것을 해결할 수 있도록 구성했으며, 사용자뿐 아니라 저희도 사용량을 추적 및 관리하기 위해 관리자 대시보드도 구성했습니다.
이번 캠페인은 아무래도 대규모 Redis가 대상이었고, 배포 시기나 개발 관련 특정 이벤트를 피하는 등 개발자분들의 일정도 고려해 가며 진행했기 때문에 장기간으로 진행됐는데요. 깊이 고민한 결과를 녹여낸 덕분인지 많은 개발자분들이 캠페인에 참여해 주셨고, 덕분에 성황리에 마무리할 수 있었습니다. 아래는 23년 한 해 동안 Redis가 사용하고 있는 리소스 변화를 나타낸 그래프입니다(서비스 수가 아니에요!).
여기서 핵심은 서비스 수에는 거의 변화가 없었다는 점입니다. 오히려 서비스 삭제 속도가 서비스 생성 속도를 따라가지 못했습니다. 그럼에도 위와 같이 리소스 사용량이 꾸준히 낮아지는 것을 확인했고, 캠페인은 성공적 인 결과를 거두었습니다. 또한 공식 캠페인이 종료된 지금도 리소스를 효율적으로 사용하며 더욱 많은 Redis 서비스를 제공하기 위해 꾸준히 추적하며 관리하고 있습니다.
LY로 합병된 이후 운영 중인 Redis의 규모는 전체적으로 더욱더 커지고 있습니다. 규모가 커지면서 향후 해결해 나가야 할 과제 숫자도 비례해서 늘어가고 있는데요. 앞으로도 여러 도전을 거쳐 더욱 안정적이고 효율적인 서비스를 제공할 예정입니다. 이 자리를 빌려 사내 임직원분들께 많은 관심 부탁드립니다. 앞으로도 저희 Redis 서비스 잘 부탁드리겠습니다.
마치며
지나칠 정도로 큰 규모의 Redis를 다루는 것은 그 어디서도 경험할 수 없는 일이라고 생각합니다. 이런 경험을 처음 글로 쓰는 것이니 만큼 다루고 싶은 내용이 정말 많았는데요. 짧은 지면에 모두 풀어내기는 어려워 가장 중요하다고 생각한 HA 구성과 애정을 담은 프로젝트인 'Low Usage Project'를 주요 주제로 채택했습니다. 프로젝트의 경우에는 단순히 리소스를 효율적으로 사용하는 것을 넘어서 관리자 입장에서 여러 개선 사항도 적용할 수 있어서 큰 의미가 있었습니다. 이번 글에서 어쩔 수 없이 제외해야 했던 내용이나 기술적으로 조금 더 깊이 파고들어 다루고 싶었던 내용은 향후 시간이 될 때마다 꾸준히 작성할 예정이니 기대해 주세요. 🙂
한 가지 꼭 말씀드리고 싶은 부분은 이 글에서 소개한 내용을 전부 저 혼자서 진행한 것은 아니라는 것입니다. 이 자리를 빌려 의사 결정 과정에서 함께해 주며 협업을 통해 좋은 결과를 이끌어 주신 팀원분들께 진심으로 감사를 드립니다.
마지막으로, Redis를 사랑해 주세요. 이 글이 Redis에 애정을 가지고 있거나, 운영 업무를 하시는 모든 분들께 도움이 되기를 바랍니다. Love yourself, Love your Redis.