제가 채팅서비스를 구현한 아키텍처의 구조는 다음과 같습니다.
기존 채팅서비스는
ChatMessage chatMessage = dynamoChatRepository.findById(chatId).orElseThrow(() -> new ApplicationException(ApplicationErrorType.CHAT_NOT_FOUND));
다음과 같은구조로 채팅방에 있는 모든 채팅을 읽어와서 service로직에서 정렬 및 필터처리를 수행하였습니다.
ISSUE
데이터가 쌓임에 따라 점점 데이터에 과부하가 발생하는 문제가 발생하였고, 어떻게 해결할 지 찾아보았습니다.
첫번째 해결방안
다음 그림처럼 20페이씩 읽어오고 이전페이지를 읽어오려면 "이전 메세지를 불러오기" 를 클릭하여 페이지네이션을 하는 방법이 있었습니다.
두번째 해결방안
react query를 사용하여 모든데이터를 읽어오는데 캐시를 이용하고, 데이터가 변경되는시점에만 다시 읽어 들이는 방식을 사용.
현재 environment 의 최적의 상황은?
우리는 react를 깊게 만져본 팀원이 없을 뿐더러 backend는 익숙한 상황이였다. 뿐만 아니라 aws는 공식문서가 잘 나와 있어
페이징쿼리를 작성하는데 있어서 어려움이 없을거라고 판단하였고, dynmodb에 글로벌인덱스를 설정하고 페이징처리를 하기로 결정하였다.
Map<String, AttributeValue> expressionAttributeValues = new HashMap<>();
expressionAttributeValues.put(":x", new AttributeValue().withN(roomId.toString()));
QueryRequest queryRequest = new QueryRequest()
.withTableName("chatting")
.withIndexName("roomId-createdAt-index")
.withKeyConditionExpression("roomId = :x")
.withExpressionAttributeValues(expressionAttributeValues)
.withScanIndexForward(false) // 내림차순 정렬
.withLimit(10);
queryRequest.setExclusiveStartKey(exclusiveStartKey);
QueryResult queryResult = amazonDynamoDB.query(queryRequest);
// query dynomdb결과값을 entity값으로 변환
List<ChatMessage> entityResult = queryResult.getItems().stream().map(
ChatMessage::new
).collect(Collectors.toList());
다음과 같은 방식으로 10페이지씩 페이징을 수행함으로 데이터가 많이 쌓여도 서버 및 클라이언트측면에서 과부하가 발생하지않는 로직으로 성능을 개선할 수 있었다.
dynmodb는 어떻게 페이지네이션을 수행할까 ?
QueryRequest를 사용하여 테이블명 ,인덱스, order by , limit,를 설정하여 요청을 하게되면 response값으로 LastEvaluatedKey값이 반환되게 되고 그 값을 다시 lastEvaluatedKey값으로 지정하여 요청을 보내게 되면 10페이지 이후의 값을 반환시켜준다.
Map<String, AttributeValue> lastEvaluatedKey = queryResult.getLastEvaluatedKey();
여기서 문제 dynmodb는 그럼 이전 데이터를 가져올 수 없을까요?
아쉽게도 dynamodb에서 지원하는 쿼리에서는 이전데이터를 가져올 수 없다. 그래서 오히려 채팅 페이지네이션을 하는데 있어서
매우 적합한 db인 것 같다. 자동으로 클러스터링도해주고 nosql key value형태로도 유지해주고 ? 성능적으로 매우 좋은 것 같다.
TMI:괜히 당근이 dynamodb를 이용하여 chatservice를 설계하는것이 아니다..
'AWS' 카테고리의 다른 글
nginx port 분리하여 blue/green 배포 (0) | 2023.10.04 |
---|---|
[Spring] 배포 서버의 도커 컨테이너에 크롤링 환경 구축하기 (0) | 2023.09.28 |
로드밸런싱 , 다중서버 oauth 401 error (1) | 2023.09.26 |
채팅서비스 sql vs nosql mongodb ? dynamodb ? (0) | 2023.09.10 |
aws codedeploy 블루/그린배포 중 오류 (0) | 2023.09.08 |