Page History
...
상태관리 객체를 만드는 가장 큰 단점은 구현의 난이도에 있습니다있습
니다.
성능 트레이드오프
장점
- 로컬 상태 관리로 요청 처리 속도가 빨라짐.
- 네트워크 비용 감소와 높은 동시성 처리.
- 읽기와 쓰기의 독립적 최적화.
- 데이터베이스 성능 의존을 줄일수 있음
...
draw.io Board Diagram | ||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
- Hello Count 를 질의하기위해 영속장치를 접근할 필요없이 , 인메모리(상태프로그래밍) 에서 정확한 값을 바로 응답할수 있습니다.
- Redis에 마지막 값을 항상 유지함으로 ~ 업데이트 또는 장애복구시 Actor가 초기화될시 마지막값으로 상태를 복원해 시작할수 있습니다.
- 마지막 상태값 유지를 위해, 꼭 Redis일 필요없으며, 인메모리 기능을 이미 가지고 있기때문에 RDB에 단지 마지막 값을 유지할수도 있습니다.
- 이 모델은 Read를 위해 매번 RDB 조회할 필요가 없으며, Read의 책임있는 DB를 인메모리가 아닌 다른곳에 위임할수도 있습니다.
- 이벤트의 변화를 Kafka에 기록해둠으로 누군가는 이것을 소비해 시계열 기반 분석 기능을 작성할수도 있습니다. ( 이벤트 소싱패턴 활용한 다양한 기능을 구현 )
위 방식이 전통적인 CRUD 보다 분명 복잡하고 고려해야할 사항들은 더 있을수 있으며 위 방식을 단지 CRUD방식으로 풀어서 비교해보겠습니다.
전통적인 RDB를 이용한 CRUD 방식
Code Block | ||
---|---|---|
| ||
CREATE TABLE user_state ( user_id VARCHAR(255) PRIMARY KEY, state ENUM('HAPPY', 'ANGRY') NOT NULL, hello_count BIGINT NOT NULL, hello_total_count BIGINT NOT NULL ); DELIMITER // CREATE PROCEDURE increment_hello_count( IN p_user_id VARCHAR(255), IN p_amount BIGINT ) BEGIN UPDATE user_state SET hello_count = hello_count + p_amount WHERE user_id = p_user_id AND state = 'HAPPY'; END // DELIMITER ; DELIMITER // CREATE PROCEDURE get_user_state( IN p_user_id VARCHAR(255) ) BEGIN SELECT state, hello_count, hello_total_count FROM user_state WHERE user_id = p_user_id; END // DELIMITER ; |
전통적인 DB에서 쓰기와 읽기를 분리한다고 했을때 이것이 CQRS라고 생각하면 큰 착각이다. 우선 DB의 Read성능을 높이기위해 확장하는것은 DB1개를 더 두는것이기때문에 아주 값비싼 확장방식이다.
더욱이 사용자의 1카운트를 증가하기위해 Update또는 Create만 발생하는것이 아니라~ 기존 값을 확인(Read)한후 증가하기때문에 Read와 Write(Update)비용이 증가함과 동시에 동시성 처리를 위해
사용자단위로 LockFree하지 않은 방식이 사용되었습니다.
CRUD가 항상 단점이 있는것은 아니며 다음과 CQRS대비 장단점이 존재합니다.
장점: CRUD
- 데이터 영속성: RDB는 내구성 있는 저장소를 제공하여 애플리케이션이 충돌하더라도 데이터가 손실되지 않습니다.
- ACID 트랜잭션: RDB는 원자성, 일관성, 고립성, 내구성을 지원하여 신뢰할 수 있는 트랜잭션을 보장합니다.
- 유연한 쿼리: SQL을 사용하여 복잡한 쿼리와 조인을 수행할 수 있어 데이터 검색 및 조작이 용이합니다.
- 확장성: RDB는 대용량 데이터셋을 처리할 수 있으며 샤딩과 복제를 통해 수평 확장을 지원합니다.
- 백업 및 복구: RDB는 데이터 백업 및 복구를 위한 내장 메커니즘을 가지고 있습니다.
단점: CQRS
- 지연 시간: RDB 작업은 디스크 I/O 및 네트워크 지연을 수반하므로 메모리 내 작업에 비해 느릴 수 있습니다.
- 동시성: 높은 동시성을 처리하는 것은 도전적일 수 있으며, 병목 현상을 피하기 위해 신중한 트랜잭션 관리가 필요합니다.
- 복잡성: 스키마 관리, 인덱스 최적화 및 쿼리 최적화는 애플리케이션에 복잡성을 추가할 수 있습니다.
- 오버헤드: RDB는 ACID 속성을 유지하고 데이터 무결성을 보장하기 위해 오버헤드를 도입합니다.
- 확장성: RDB는 확장 가능하지만, 분산 메모리 내 액터 시스템의 선형 확장성을 따라가지 못할 수 있습니다.