실무에서 기획에 따라 개발하고 있던 중이었다. 다음은 그 요구사항이다.
이 원형 큐 커서를 관리하는 데이터를 RDBMS
테이블로 설계했다고 하자. 그러면 무엇이 문제일까?
사용자가 쉽게 접근할 수 있고, 많이 접근할 수 있는 데이터다. 또한 커서이기 때문에 갱신도 잦다.
현재 사용중인 DB
는 InnoDB
엔진을 사용하고 있다. 이 InnoDB
스토리지 엔진은 레코드 자체만을 잠그는 레코드 락을 갖고 있다. (참고로 InnoDB
엔진은 락 에스컬레이션은 없다고 한다.)
그런데, 해당 엔진은 레코드 자체가 아니라 인덱스의 레코드를 잠근다. 인덱스가 하나도 없는 테이블이라도 내부적으로 자동 생성된 클러스터 인덱스를 이용해 잠근다.
예를 들어, 커서 A,B,C가 있다고 하자. 인덱스가 커서 A에만 걸려있다고 하자. 만약 UPDATE
에서 WHERE
조건이 A,B,C에 있다고 하자. 그러면 A,B,C 인덱스가 없기 때문에 UPDATE
1건을 위해 모든 레코드가 다 잠긴다.
만약 인덱스가 하나도 없을 경우에는 테이블 풀 스캔하면서 UPDATE
를 작업하고 모든 레코드에 잠금이 걸린다.
그러면 반대로 커서 A,B,C에 전부 인덱스를 걸면 안되냐 할 수도 있다. 하지만 인덱스는 조회 성능을 높이기 위한 도구이지, 갱신이 잦은 데이터에 대해선 적합하지 않은 도구다. 왜냐하면 갱신이 잦은 데이터의 경우 인덱스가 매번 새로이 정렬해야 하기 때문에 해당 시간이 추가 소요된다. 특히 이러한 커서는 갱신이 매우 빈번할 게 뻔하므로 인덱스 자체가 좋지 않다.
커서 데이터는 굳이 영구적으로 저장할 필요가 없다. 돈과 관련된 데이터도 아니다.
여러가지 이유로 Redis Hash
를 사용하기로 했다.
사용자 ID를 기반으로 빈번한 읽기와 쓰기 작업이 예상된다. 또한 복잡한 트랜잭션이 필요하지 않은 데이터다. 그리고 커서 위치의 빠른 업데이트와 조회가 필요하다. 이러한 특성으로 조회 및 갱신 속도가 빠른 Redis
를 선택하였다.
영구적일 필요가 없는 데이터다. 이는 인메모리 특성을 가진 Redis
의 데이터 만료와 잘 어울리는 특성이다.
사용자 별로 커서 데이터들을 갖는다. 이는 (key = 사용자 Id, value = 커서 데이터들)이라는 Hash
자료구조를 활용하기 적합하다.
Redis
의 경우 이미 실무에서 AWS Elastic Cache
를 사용하기 때문에, 연결 작업이 매우 쉽다. 그에 따라 개발 작업 소요 기간을 줄일 수 있다.
RDBMS
도 실무에 들어가니 공부할 게 끝이 없다... 고려할 게 참 많아진다. 그리고 MySQL
, Redis
뿐만 아니라 다른 선택지들은 없는지 연구해볼 필요가 있겠다.RealMySQL 8.0
1권