Education*
Devops
Architecture
F/B End
B.Chain
Basic
Others
CLOSE
Search For:
Search
BY TAGS
linux
HTTP
golang
flutter
java
fintech
개발환경
kubernetes
network
Docker
devops
database
tutorial
cli
분산시스템
www
블록체인
AWS
system admin
bigdata
보안
금융
msa
mysql
redis
Linux command
dns
javascript
CICD
VPC
FILESYSTEM
S3
NGINX
TCP/IP
ZOOKEEPER
NOSQL
IAC
CLOUD
TERRAFORM
logging
IT용어
Kafka
docker-compose
Dart
고객 상담을 위한 Chatting 서비스 아키텍처
Recommanded
Free
YOUTUBE Lecture:
<% selectedImage[1] %>
yundream
2024-05-01
2024-05-01
936
# 개요 가상의 회사 Joinc는 고객 상담을 위해서 Chating Service를 준비 하고있다. 프로덕트 관리자는 Chating Servier를 위해서 아래의 요구사항을 솔류션 아키텍트에게 전달했다. 1. 100만명의 활성사용자가 있다. 2. 읽기와 쓰기는 3:1 정도로 읽기가 더 많다. 3. 고객 별 상담 채널을 생성할 수 있어야 한다. 4. 상담자에게 메시지 알람이 가야 하며, 상담자는 쌓여있는 몇 건의 읽지 않은 메시지가 있는지 알아야 한다. 고객도 마찬가지로 몇 건의 읽지 않은 메시지가 있는지 알아야 한다. 5. 고객에게 마케팅 메시지와 같은 이벤트 메시지를 전달 할 수 있어야 한다. 이러한 요구사항을 처리하기 위한 아키텍처를 설계해보려 한다. # High-Level 데이터베이스 설계  모든 채팅은 chat_room을 기준으로 이루어진다. chat_room에 고객과 서비스 담당자가 참여를 하며, 주고 받는 메시지는 chat room에 쌓이는 구조다. 고객에게 마케팅 메시지를 발송 해야 할 수 있는데 chat_room으로 처리하면 어떨지 생각을 해보자. 마케팅용 chat_room을 만들고 타겟 고객을 chat_room에 초대하는 방식이다. 처음에는 chat_room 하나로 모든 것을 처리 할 수 있으려니 생각했으나 아래의 문제가 예상됐다. * 마케팅을 위한 타겟 고객이 10만명이라고 생각해보자. 10만명 유저를 Insert 할 것인가 ? 너무 비효율적이라고 생각했다. 이 문제는 고객 별 메시지 박스를 따로 만드는 방식으로 해결하기로 했다. # RDS의 요구사항 만족 여부 검토 메시지를 저장하기 위한 데이터베이스를 선택해보자. AWS는 다양한 종류의 SQL/NoSQL을 제공하는데, 대표적인 SQL 서비스인 **RDS**와 NoSQL의 대표주자 **DynamoDB**가 있다. 여기에서는 RDS 데이터베이스가 각 요구사항을 충족할 수 있을지를 검토한다. **Request Per Second** 메시지 처리 시스템에서 가장 중요한 요소는 RPS(Request Per Second), 초당 처리량일 것이다. 채팅 서비스의 경우 "사람"이 메시지를 입력하고 특정 사람이 메시지를 읽기 때문에, 웹 문서처럼 대량의 읽기/쓰기, 특히 대량의 읽기가 발생하지는 않을 것이다. 1. 사람이 메시지를 작성하는데에는 수십초가 걸릴 수 있다. 2. 고객 상담의 특성상 메시지는 특정 소수의 사람에게 전달되기 때문의 대량의 읽기가 발생하지는 않는다. 따라서 **RDS(MySQL, PostgreSQL)** 로도 대응이 가능할 것이다. **트래픽 증가 대응** RDS에서 트래픽 증가에 대응하는 일반적인 방법은 "**읽기 전용 복제본**"을 만드는 것이다. RDS는 최대 5개까지의 읽기 전용 복제본을 만들 수 있는데, 이를 통해서 늘어나는 읽기 요청을 처리 할 수 있다. 다만 상담 채널은 다른 문서 서비스에 비해서 읽기와 쓰기 요청이 비교적 큰차이가 나지 않는 특성이 있다. 예를 들어서 블로그 서비스를 한다면 쓰기와 읽기의 비율은 1:1000 이상의 차이가 날 것이다. 그러므로 상담 채널 서비스에서 트래픽이 문제가 생긴다면, "쓰기 증가"로 인한 문제가 생길 것이라는 걸 예상을 해야 한다. 쓰기 증가는 아래와 같이 해결 할 수 있을 것이다. 1. **수직확장(Scale up)**: 인스턴스의 사양을 높여서 해결한다. 단순하며 효과를 즉시 테스트 할 수 있으므로 가장 먼저 고려해볼 수 있다. 2. **수평확장(Scale out)**: 읽기 전용 복제본을 만든다. 3. **RDS Optimized Writes**: MySQL 같은 관계형 데이터베이스는 신뢰할 수 있는 데이터베이스 트랜잭션을 위한 ACID(원자성, 일관성, 격리성, 내구성)속성을 제공한다. MySQL은 **이중 쓰기 버퍼** 라는 기능을 이용해서 부분 페이지 쓰기 오류를 방지한다. 이 기능은 데이터에 대한 보호기능을 제공하지만 추가적인 쓰기 부하를 초래한다. **Amazon RDS Optimzed Writes** 기능을 활성화 해서 이중 쓰기 버퍼를 사용하지 않고 쓰기 성능을 높일 수 있다. 단 이 기능은 **AWS Nitro System**을 사용하는 DB 인스턴스 클래스에서 사용 할 수 있다. **피크타임 대응** 사람과의 채팅은 그 특성상 피크타임의 예측과 대응이 어렵지 않다. 하지만 마케팅 메시지의 경우에는 특정 시간에 수십만명의 사용자에게 메시지를 보내야할 수 있기 때문에 이에 대한 대비가 필요하다. RDS를 이용해서는 아래와 같이 처리해야 할 것이다. 1. 마케팅 팀에게 마케팅 일정과 용량을 전달 받는다. 2. RDS 인스턴스를 Scale Up 한다. 3. 마케팅 이벤트를 수행한다. 4. RDS 인스턴스를 Scale Down 한다. 프로세스가 복잡하고 오버 프로비저닝으로 인한 '비용 비효율'도 예측이 된다. 또한 특정 테이블의 부하가 다른 테이블에 영향을 줘서 전체 서비스가 불안정해 질 수도 있다. 이러한 문제는 다시 아래와 같이 해결 할 수 있을 것이다. * 이벤트 메시지를 저장하기 위한 별도의 데이터베이스를 만든다. 어쨋든 가능은 하지만 최적의 솔류션은 아닌 것 같다. # DynamoDB의 요구사항 만족 여부 검토 그래서 아래와 같이 해결하기로 했다. * chatting 서비스는 MySQL RDS로 처리한다. * 이벤트 메시지는 DynamoDB로 처리한다. 이제 DynamoDB가 "특정 시간에 대량의 메시지 발생"을 처리할 수 있는 솔류션인지 검토해보자. * DynamoDB는 **수평확장**에 강력한 데이터베이스다. DynamoDB에서는 데이터의 처리량과 용량을 증가시키기 위해서 데이터를 여러 **파티션**으로 분산한다. 여러 노드에 분산되어서 저장하고 처리하기 때문에, 데이터가 증가하더라도 안정적인 성능을 제공한다. * DynamoDB는 처리량에 따라서 자동으로 확장할 수 있다. 관리자가 수동으로 인프라를 증설하는 등의 작업을 할 필요가 없다. * DynamoDB는 온디맨드 모델을 제공하는데, 프로비저닝된 모델과 다르게 "필요한 만큼의 처리량을 요청"할 수가 있다. 이를 통해서 데이터베이스 성능을 자동으로 확장및 축소할 수 있다. 사용한 만큼만 요금을 지불하면 되므로 비용 효율적으로 사용 할 수 있다. 대량 이벤트 메시지의 경우 DynamoDB가 최적의 솔류션으로 판단되었다. 대략 아래와 같이 설계 할 수 있을 것이다.  DynamoDB의 메시지박스 테이블에 각 사용자에게 전달하는 마케팅 메시지를 저장한다. 문제는 "사용자가 읽지 않은 메시지의 갯수"를 확인하는 것이다. DynamoDB는 분산형 테이터베이스이기 때문에 여러 파티션의 결과를 수집해야만 집계작업을 수행하는 것이 가능하다. 가능은 하지만 성능적으로 손해를 볼 수 밖에 없다. RDS 처럼 **count** 연산을 사용 할 수가 없다. ```sql SELECT COUNT(*) FROM TABLE_NAME; ``` 이 문제는 사용자별로 읽지 않은 메시지를 카운트하기 위한 별도의 테이블을 만드는 것으로 해결 했다. 이 테이블은 두 개의 필드로 구성될 것이다. 1. user_id: 유저 id 2. unread: 유저가 읽지 않은 아이템의 카운트 사용자에게 새로운 메시지를 전달하면 **unread++** 연산을 하고, 사용자가 메시지를 읽으면 **unread--** 연산을 하는 식이다. # 서비스 아키텍처 서비스의 전체 아키텍처는 아래와 같다.  실시간 채팅은 NATS Cluster를 이용한다. [NATS Cluster](https://www.joinc.co.kr/w/CNCF_NATS)에 전달된 메시지는 Message Worker가 처리해서 DynamoDB에 저장한다. 사용자가 처음 로그인을 하게 되면 Message Badge에서 읽지 않은 메시지 갯수를 가져오고, 이전 채팅 메시지는 Message Box에서 읽게 된다. # 참고 * [RDS Optimized Writes for MySQL을 통한 쓰기 성능 개선](https://docs.aws.amazon.com/ko_kr/AmazonRDS/latest/UserGuide/rds-optimized-writes.html)
Recent Posts
MLOps with Joinc - Kubeflow 설치
Vertex Gemini 기반 AI 에이전트 개발 05. 첫 번째 LLM 애플리케이션 개발
LLama-3.2-Vision 테스트
Vertex Gemini 기반 AI 에이전트 개발 04. 프롬프트 엔지니어링
Vertex Gemini 기반 AI 에이전트 개발 03. Vertex AI Gemini 둘러보기
Vertex Gemini 기반 AI 에이전트 개발 02. 생성 AI에 대해서
Vertex Gemini 기반 AI 에이전트 개발 01. 소개
Vertex Gemini 기반 AI 에이전트 개발-소개
생성 AI 모델 Flux.1 설치 및 사용
GPT를 이용한 Reranker 테스트
Archive Posts
Tags
architecture
aws
cloud
Copyrights © -
Joinc
, All Rights Reserved.
Inherited From -
Yundream
Rebranded By -
Joonphil
Recent Posts
Archive Posts
Tags