DB 쿼리 서버

3권에서 새로 도입된 네트웍 및 멀티플레이어 프로그로그래밍 섹션을 위한 게시판입니다.

Moderator: 류광

Locked
protian

캐쉬DB 에대해

Post by protian »

위에서 캐쉬DB를 Access 같은걸 쓰지 말라고 했는데..

캐쉬 DB 를 보통구현할때 어찌 쓰는지.. 궁금하네요

( 짧은 제생각엔 메모리확보를 많이해서 메모리에 읽어들인다고 생각하고 있지만... -- 메모리 캐쉬 DB )

그리고 로그온시 메인DB 에서 값을 캐쉬DB 로 읽어오고
플레이시는 캐쉬DB 를 변경사용하고
로그아웃시 캐쉬DB 값을 메인DB 에 저장한다고 하시고
서버가 죽을 경우 DB 에이전트에서 캐쉬DB 데이터를 메인 DB 에 저장한다고 말씀하시는데..

불의의 사고로 캐쉬 DB 를 관리하는 서버 ( 혹은 프로그램 ) 이 뻗어버리면 데이터가 다 날아가지 않을까요??

제생각엔 플레이중이라도 변경된 사항중 중요한것은 메인DB 에 일정 간격으로 업데이트 되어야 되지않을까요..



허접질문이었읍니다...

고수님들의 조언 부탁드립니다. :)2
nomoreid
Posts: 61
Joined: 2004-04-06 19:11
Location: S모사
Contact:

Re: 캐쉬DB 에대해

Post by nomoreid »

protian wrote:위에서 캐쉬DB를 Access 같은걸 쓰지 말라고 했는데..

캐쉬 DB 를 보통구현할때 어찌 쓰는지.. 궁금하네요

( 짧은 제생각엔 메모리확보를 많이해서 메모리에 읽어들인다고 생각하고 있지만... -- 메모리 캐쉬 DB )
제가 썼던 용어의 혼돈이 있었네요.

캐쉬 디비 - 시스템의 구조상에서 메인 디비의 캐쉬 역할을 하는 임시저장용 디비

메모리 디비 - 성능을 높히기 위해 메모리에 상주하는 디비 정확하게는 in memory Database.
꼭 성능때문이 아니라 하드디스크가 없는 embed system에서도 사용. (예: 셋톱박스,PDA)

물론 캐쉬디비로 메모리 디비를 쓸 수 있습니다. 제가 위에서 말씀드린 구조에서는 캐쉬 디비는
최대 동시접속자의 데이터만 처리하는 구조이기 때문에 캐쉬디비가 차지하는 최대 메모리 용량은
계산 가능합니다. 따라서 메모리만 허용된다면 게임서버와 같은 서버내에 존재할 수 있습니다.

메인의 백업으로 캐쉬디비를 쓰고 그 캐쉬디비를 메모리 디비로 쓴다는 아이디어는 이미 다른 곳에서
많이 쓰는 구조 입니다.

아래 제품이 그예입니다. (RDBMS와 연결되며 리얼타임으로 이벤트를 빠르게 처리해주는 일종의 미들웨어 입니다. M$제품군으로 따지면 MTS나 메시지큐 서버정도..)

http://www.timesten.com/products/TimesTen_5_0.html
timesten wrote: In-Memory Database Technology

At the heart of TimesTen's system is a relational data manager based upon in-memory database (IMDB) technology. IMDB technology embodies unique methods, algorithms, index and data structures optimized around the guarantee that the database is memory-resident. The goal of IMDB technology is performance - shorter response-times and greater throughput - achieved largely through more efficient CPU utilization. When an entire data manager is engineered this way, a 10:1 reduction in instructions can be accomplished (on average) compared to a traditional disk-based RDBMS accessing a fully-cached database.
저같은 경우는 캐쉬디비로 Mysql이나 기타 소스가 공개된 안정적인 DB를 고려하고 있습니다. 메모리디비까지는 고려하지 않고 있습니다만 디비의 성능이 요구되는 구조라면 고려해야겠죠.
protian wrote:
그리고 로그온시 메인DB 에서 값을 캐쉬DB 로 읽어오고
플레이시는 캐쉬DB 를 변경사용하고
로그아웃시 캐쉬DB 값을 메인DB 에 저장한다고 하시고
서버가 죽을 경우 DB 에이전트에서 캐쉬DB 데이터를 메인 DB 에 저장한다고 말씀하시는데..
불의의 사고로 캐쉬 DB 를 관리하는 서버 ( 혹은 프로그램 ) 이 뻗어버리면 데이터가 다 날아가지 않을까요??

제생각엔 플레이중이라도 변경된 사항중 중요한것은 메인DB 에 일정 간격으로 업데이트 되어야 되지않을까요..
물론 디비에이전트는 간단 하므로 어느정도 안정화 되면 업데이트가 거의 없으므로 죽는일은 없을 것입니다.
(그렇게 해야 하구요.)
하지만 그럼에도 불구 하고 죽었더라도 방법은 있습니다.

"디비에이전트가 죽었더라도 캐쉬디비는 죽은건 아니므로 데이터는 살아 있습니다."

따라서 다음과 같은 시나리오가 가능합니다.

우선 디비에이전트가 죽으면 게임 진행이 불가능한 상태 입니다. 일단 게임서버의 경우 자신에게 접속된 디비에이전트가 통신불능이라면 유저에게 이상이 있음을 알리고 대기 상태로 유저를 바꿔 두어야 겠죠. (해당 서버의 유저들은 세션관리서버의 유저 상태가 접속중이라는 상태가 되어 있으므로 클라이언트를 죽이고 재접속을 시도해도 다른서버가 정상적이라 할지라도 재접속되지 않습니다. )

그런 후 관리자는 캐쉬디비의 내용을 메인디비로 옮깁니다. 뭐 그전에 에이전트의 크래쉬 로그같은게 있다면 프로그래머에게 전달해 주어야겠지요. (프로그래머는 그날 해결할때까지 퇴근 못합니다. T_T)
그리고 해당 서버에 접속중인 유저에 리스타트 메시지를 날리고 에이전트와 서버를 리스타트 합니다.
(또는 이상태에서 게임이 재시작되게 합니다.)
서버가 다 뜨면 해당 서버에 접속했던 유저들의 접속중이라는 상태 플래그를 세션관리서버에서 해제해 줍니다.
그러면 다시 원상복귀 됩니다.

물론 이런것을 위한 툴이 따로 마련되어 있으면 더 좋겠지요. 관리자의 관리툴에 포함되어 있는 것이 좋겠지요.
또는 프로그래머가 수동으로도 할 수 있겠죠. 어짜피 디비니까요. DBDUMP떠서 메인디비에 넣어주고 update문 돌려서 수동으로 바꿔 줄 수 있습니다. (메인DB에 모든 쿼리가 몰리는 구조에선 서비스 중에 대량의 쿼리를 날리 거나 백업등을 하긴 힘들지만 캐쉬 디비를 쓰는 경우는 메인디비의 부하가 게임 진행에 영향을 주지 않으므로 가능 합니다.)

아직까지 저도 전의 삽질 경험 후에 얻은 아직 시나리오 단계의 구조 입니다. 더 괜찮은 아이디어나 보안점등이 있다면 환영입니다. ^^;
When you know the programmer, you see His code everywhere.
The opposite of living is not death, its the living dead. (>_<)乃
ljh6341
Posts: 28
Joined: 2005-12-21 14:44
Location: 세상 모든 게임 속에 소속되어 있습니다.

Re: DB 쿼리 서버

Post by ljh6341 »

imays wrote:일부 온라인 게임 프로젝트에서 DB 서버와 게임 서버 사이에 쿼리 서버를 자체 제작해서 배치해 둔다는 얘기를 들었습니다.

제 경험상 쿼리 서버의 필요성을 느끼지 못했는데요... 쿼리 서버의 효과는 무엇인가요?

서비스하는 게임의 성격에 따라 차이가 난다고 봅니다.

저희는 mmorpg를 서비스 하는데.. SQL DB와 게임 서버 사이에 DB Cache 서버(역시 용어가 다르죠. ^^;; )를 만들었습니다.

MS SQL DB를 사용하는데.. MEMORY DB와 틀리게 MSSQL과 같은 DISK DB는 DISK에 기록하는 시간이 역시 관건입니다.
(select가 주 업무인 금융권, 도서관, 학교등에서 사용하는 DB들은 최근 MAIN MEMORY DB를 많이 도입하고 있는 실정입니다. 하지만 게임 서비스를 위한 DB는 유저 데이터 저장이 가장 최우선 목적으므로 주로 DISK DB를 사용합니다. (물론 MAIN MEMORY DB 제품중에서도 DISK DB와 비슷한 기능으로 최적화한 제품도 있습니다.) )

실시간으로 유저 데이터 (저희 같은 경우는 캐릭터 정보 varbinary(4000), 친구리스트, 스킬 배치등에 varbinary(1024) 정도 됩니다.)를 저장하려면 SQL DB에 부하가 발생할 수도 있습니다. (한 2년 전에 테스트해서 어느 정도인지는 까먹고 있었습니다만... ^^ )

단순히 업데이트 뿐만 아니라 캐릭터 생성에 따른 삽입, 삭제, 캐릭터 리스트 불러오기등.. 다른 작업들도 많으니까요.

그래서 다른 분들처럼 Agent서버를 만들었는데, 처음 목적은 단순히 game server -> cache -> sql db 용이었습니다.
주로 일어나는 update는(실제로 측정결과 50%이상이 update였습니다. ) 결과값을 돌려줄 필요가 없어서 cache에 쌓아두고, cache 서버가 적절히 sql db로 업데이트만 했었죠. (동일한 유저의 update가 10초에 5번 정도 들어왔다면, 마지막 데이터만 적용하는 식으로..)

뭐.. 요기 까지가 말씀하신 쿼리 서버를 두는 목적중의 하나라고 생각합니다. 비싼 한대의 sql db를 좀 더 효율적으로 사용하는 방법이랄까요.

이 외에도 여러가지 활용도가 있습니다. 특히 select에 대한 효과를 많이 볼수 있는데요.

유저 리스트 검색, 유저 데이터 검색, 로그인 처리 등은 굳이 DB까지 가지않고 Cache 서버를 기동할 때 DB에서 싹 불러와서 Cache서버가 가지고 있습니다. 그리고 Cache서버에서 처리해서 돌려보내 주는거죠. 물론 처음 기동할 때 조금 느리긴 하지만 전혀 문제는 되지 않습니다. 불러온 데이터의 변경이 있을 경우 Cache 서버의 정보를 수정하고 SQL DB에 여유 있을 때 저장하면 지속적으로 데이터의 무결성도 보장할 수 있구요.
또 이런 데이터를 공유 메모리에 기록한다면 Process가 죽어도 다시 키면 유저 데이터 혹은 쿼리 정보들을 그대로 유지하여 데이터 손실을 막을 수 있습니다.

단점이라면.. ^^

Cache 서버의 Power가 나가면.. 윽!!!

물론 이런 경우를 대비해서 .. 쌓아두는 양을 조절합니다. ^^ 너무 많아지면.. 무리를 해서라도 SQL DB로 날려버려야죠. 저는 5초 정도를 여유로 잡아두는데.. 큰 무리 없었습니다.

우리가 보통 DB Cache 혹은 Agent 라고 부르는 서버는 아시다시피 Main Memory DB의 성격과 비슷합니다.

좀.. 삼천포로 빠졌는데.. 대략 이렇습니다.


전 처음에 물어볼 분이 주변에서 없어서 다른 분들 이야기 주워듣고 만들었는데.. 다른 분들은 정확하게 어떻게 구현하여 사용하시는지 궁금하기도 하네요.
-----------------------



땡겨줘.
Locked