DB Cache 이론 및 이해
Last updated
Last updated
현재 ProudNet DB 시스템은 Windows 에서만 동작됩니다.
게임 데이터베이스는 트랜잭션 규모가 작은 대신, 많은 횟수의 접근이 있고 대부분의 데이터가 불러오기와 저장의 반복이라는 특징이 있는데, ProudNet 데이터베이스 시스템은 이 과정을 cache 하여 데이터베이스의 부하를 줄여줍니다.
게임 데이터베이스에 저장되는 데이터를 tree 단위로 다루며 이 tree 는 node들로 구성됩니다.
각 node들은 부모,자식 관계를 가지며 각 node는 이름-값 pair 즉, property field를 가집니다.
로딩하는 데이터 tree의 최상위 node인 root node의 table name과 child node들의 table name 은 서로 달라야 합니다.
DB cache 에서는 데이터를 독점 로딩하여 다루는 것이 기본 사용법이며, ProudNet DB 시스템에서는 다음과 같은 유형의 접근을 제공합니다.
경쟁 상태 를 피하기 위하기 위해 DB cache 시스템은 동일한 데이터를 1개의 DB cache client에서만 로딩하도록 허락하는데, 이를 독점적 불러오기(exclusive load)라고 부릅니다.
DB Cache System은 이미 한 DB Cache Client가 독점 중일 때 새로운 DB Cache Client가 독점 요청하면 이전의 DB Cache Client는 독점권 이양 요청을 받게 되고 이를 수락 또는 거부할 수 있습니다. 이 때 이전의 DB Cache Client가 데이터를 Unload하면 새로운 DB Cache Client가 독점권을 받게 됩니다.
일방적 데이터 변경하기를 할 경우 데이터는 DB cache의 메모리에 즉시 반영되고, 이 변경 사항은 좀 지나서 데이터베이스에 실제 기록 즉, 데이터 cache를 합니다. 일방적 데이터 변경하기 처리는 즉시 리턴되기 때문에 데이터를 변경하는 루틴에서 대기 시간이 발생되지 않습니다. 따라서 데이터 변경 후에 그 결과가 완료될 때까지 기다리는 과정이 불필요합니다.
아래 루틴처럼 unlock then lock 과정은 필요하지 않습니다.
일방적 데이터 변경하기 는 DB cache의 메모리에 무조건 적용되지만 데이터베이스에 DB Constraints를 설정한 레코드에 변경 사항이 반영되지 못할 수도 있습니다.
따라서 DB Constraints를 설정하지 않거나 설정하더라도 확실한 경우에만 쓰는 것이 좋습니다. 통상적인 온라인 게임에서 게이머와 월드 지역의 객체에 대한 데이터베이스 객체들은 일방적 데이터 변경하기 가 안전하게 사용될 수 있습니다.
요청 응답형 데이터 변경하기 는 요청 응답형으로, 일방적 데이터 변경하기와 반대로 동작합니다. DB cache client 는 요청 응답형 데이터 변경하기를 DB cache server 에 요청하고 이를 데이터베이스에 실제 기록하여 기록 성공 여부를 DB cache client 를 통해 확인됩니다.
요청 응답형 데이터 변경하기 는 진정한 의미의 cache 는 아니지만 실제 기록이 성공하기 전까지는 DB cache 에 변경사항을 반영하지 않아서 DB Constraints 로 인한 기록 실패 확률을 줄일 수 있습니다. 온라인 게임에서 중복된 이름을 금지하는 플레이어 캐릭터를 생성할 때 대표적으로 요청 응답형 데이터 변경하기를 사용합니다.
일방적 데이터 변경하기와 요청 응답형 데이터 변경하기는 독점적으로 로딩된 데이터에 한합니다.
하지만 이미 다른 DB cache client 에서 독점적 로딩된 데이터를 읽기 혹은 쓰기를 하고 싶을 때가 있습니다. 웹 서버에서 플레이어 캐릭터의 정보를 열람하거나, 유료 아이템 결제 서버에서 플레이어 캐릭터의 가방에 아이템을 추가 하거나 변경해야 할 때와 같이 운영 툴에서 로그온 중인 플레이어의 캐릭터 정보를 열람하거나 변경해야 하는 경우도 있습니다.
비독점적 데이터 접근하기는 이를 위한 기능입니다.
모든 비독점적 데이터 접근은 요청 응답형 데이터 변경하기 방식으로 작동하기 때문에 즉시 응답하지는 않으나 DB Constraints에 내성을 가집니다. 또한 비독점적으로 데이터를 변경하면 독점적 로딩을 한 DB cache client 에서는 다른 곳에 의해 데이터가 변경되었음을 통보받습니다.
DB cache가 로딩해서 다루고 있는 data tree의 데이터 상태는 DB에 있는 것보다 DB cache에 있는 것이 더 최신 상태를 유지합니다. 왜냐하면 데이터 기록이 DB cache에서 먼저 이루어진 후 DB에 뒤늦게 기록되기 때문입니다.
그러다 보니 DB cache가 다루는 data tree와 별개로 사용자가 DB에 직접 데이터를 기록하는 경우, DB에 있는 데이터가 잠깐 더 예전 상태이기 때문에 원하지 않는 오류가 발생할 수 있습니다.
이는 data race condition 과 비슷한 문제입니다.
ProudNet에서는 DB cache가 다루는 data tree를 DB에서 직접 다루려 할 때 data race condition을 피하기 위해 데이터 격리 기능(data isolation)을 제공하는데, 이는 DB를 직접 엑세스하더라도 data race condition이 발생하지 않도록 사용자가 원하는 data tree를 DB cache에서 사용권을 완전히 해제합니다.
사용법은 다음과 같습니다.
DB에서 직접 엑세스해야 하는 data tree에 대해 Proud.CDbCacheClient2.RequestIsolateData(X)를 통해 호출하면 X가 격리 처리되고, X가 이미 로딩되어 있는 경우 언로드도 됩니다.
Proud.IDbCacheClientDelegate2.OnDeisolateDataSuccess(X)가 콜백되면 안전하게 DB에 있는 X를 엑세스해도 됩니다.
X가 격리되어 있다면 DB cache는 X를 로드할 수 없습니다.
X에 대한 DB 엑세스를 모두 마쳤다면 격리 해제를 하기 위해 Proud.CDbCacheClient2.RequestDeisolateData()를 호출합니다.
접근유형 | 활용 예시 | Cache 여부 | 즉시 리턴 | 독점적 로딩 필요 여부 | 내부 처리 방식 |
---|---|---|---|---|---|
일방적 데이터 변경하기
게임 플레이 중 플레이어 캐릭터의 잦은 정보 변경
YES
YES
YES
메모리에 먼저 Cache 후 DB 에 후 write
요청 응답형 데이터 변경하기
고유 이름을 가진 플레이어 캐릭터 생성
NO
NO
YES
DB 에 write 후 성공하면 메모리에 Cache
비독점적 데이터 접근하기
유료 아이템을 웹 서버에서 구매하기
NO
NO
NO
DB 에 write 후 성공하면 메모리에 Cache