이러한 관행을 사용하여 데이터의 전체 수명 주기 동안 신뢰할 수 있고 확장 가능하며 관찰 가능한 데이터를 구성하고 관리하십시오.
데이터를 구성하십시오
데이터 저장소를 줄이십시오
데이터 저장소는 데이터베이스의 테이블과 유사하게 작동합니다. 소량의 고정된 데이터 저장소 세트를 사용하고 그 안에서 레코드를 키로 구성하십시오. 예를 들어, 각 플레이어에 대한 데이터 저장소를 생성하는 대신 모든 플레이어의 프로필을 하나의 PlayerData 데이터 저장소에 저장하십시오.
플레이어당 하나 또는 몇 개의 키를 사용하십시오
데이터가 4 MB 객체 크기 제한 내에 들어갈 수 있을 때마다 각 플레이어의 지속적인 데이터를 하나의 키 아래에 저장하십시오. 예를 들어, PlayerData 데이터 저장소에서 User_123456과 같은 키를 사용하십시오. 이 패턴은 요청을 줄이고 관련 값을 원자적으로 업데이트할 수 있게 하며 롤백을 더 쉽게 이해할 수 있게 합니다.
플레이어의 데이터의 서로 다른 부분이 서로 다른 접근 패턴을 가지거나 키당 크기 또는 처리량 제한에 접근하는 경우, 레코드를 소수의 결정론적 키로 분할하십시오. 원자적으로 변경해야 하는 데이터는 동일한 키에 유지하십시오.
정적 키 패턴 및 접두사를 사용하십시오
안정적인 식별자와 정적 패턴에서 키 이름을 만드십시오. 예를 들어, User_{UserId}와 같은 형식입니다. 변경될 수 있는 표시 이름이나 다른 값을 사용하지 마십시오. 정적 패턴은 서버와 도구 전반에 걸쳐 키를 예측 가능하게 만듭니다. 데이터 저장소의 경우, 자동화된 잊혀질 권리 처리가 플레이어 데이터를 식별할 수 있게 합니다.
관련 키를 그룹화하기 위해 접두사를 사용하십시오. 예를 들어, 여러 캐릭터 프로필을 지원하는 경험은 User_123456/Profile/Warrior 및 User_123456/Profile/Mage를 사용할 수 있습니다. 그런 다음 User_123456/Profile을 ListKeysAsync()에 전달하여 해당 플레이어의 프로필을 나열할 수 있습니다.
스코프는 데이터 저장소를 세분화하는 또 다른 방법입니다. 스코프는 해당 데이터 저장소 인스턴스의 모든 키 앞에 문자열을 추가하며, 기본값은 global입니다.
데이터 저장소 모듈 평가
타사 데이터 저장소 모듈은 항상 옵션이며, 많은 경우 처음부터 시스템을 구축하는 것보다 선호될 수 있습니다. 하나를 채택하기 전에 소유권, 유지 관리 상태 및 기능 세트를 검토하십시오. 모듈 없이 데이터를 액세스하고 마이그레이션하는 방법을 이해하십시오.
요청을 줄이고 분산시키십시오
플레이어 데이터를 메모리에 버퍼링하십시오
세션 시작 시 플레이어의 데이터를 로드하고 게임 플레이를 위해 서버 로컬 복사본을 유지하십시오. 모든 변경 사항에 대해 데이터 저장소 요청을 보내는 대신 로컬 복사본을 업데이트하십시오. 플레이어가 떠날 때, 서버가 종료될 때, 구매 처리와 같은 중요한 체크포인트에서 주기적으로 저장하십시오. 요청 한도 내에 유지되고 세션 잠금 만료보다 짧은 주기적 저장 간격을 선택하십시오. 플레이어 데이터 및 구매 샘플은 180초를 사용합니다.
반복 요청을 분산시키십시오
모든 서버에서 동일한 일정으로 반복 요청을 시작하지 마십시오. 고정 주기 루프를 시작하기 전에 각 서버 또는 플레이어에 무작위 초기 오프셋을 할당하십시오. 정확한 주기가 필요하지 않은 폴링 또는 조정 루프의 경우 각 간격에 제한된 무작위 지터를 추가하십시오. 이러한 패턴은 요청을 시간에 따라 분산시키고 동기화된 트래픽 급증을 줄입니다.
일시적인 실패를 재시도하십시오
요청을 pcall()로 감싸고 일시적인 실패를 지수 백오프를 사용하여 재시도하십시오. 각 지연에 무작위 지터를 추가하여 서버가 동시에 재시도하지 않도록 하십시오. 지연 및 시도 횟수를 제한하고, 잘못된 요청이나 더 이상 유용한 결과를 제공할 수 없는 작업으로 인한 오류는 재시도하지 마십시오.
각 키에 대해 데이터 저장소 재시도를 순서대로 처리하십시오. 더 오래된 요청이 더 새로운 요청이 성공한 후 재시도하면 더 새로운 데이터를 덮어쓸 수 있습니다. 또한 결과가 불확실한 쓰기를 고려하십시오: 실패한 호출은 서버가 성공적인 응답을 받지 못했음을 의미하지만, 백엔드는 쓰기를 완료했을 수 있습니다. 자세한 내용은 데이터 저장소 오류 코드 및 한계 및 재시도를 참조하십시오.
SetAsync보다 UpdateAsync를 선호하십시오
쓰기 작업이 현재 값에 의존하거나 여러 서버가 동일한 키를 쓸 수 있는 경우 UpdateAsync()를 선호하십시오. UpdateAsync()는 쓰기 전에 최신 값을 콜백으로 읽어들여 손실된 업데이트를 줄입니다. SetAsync()는 먼저 읽지 않고 키를 덮어쓰며, 두 서버가 동시에 쓸 경우 불일치를 초래할 수 있습니다.
새 키를 생성하거나 이전 값에 의존하지 않는 값을 교체할 때 SetAsync()를 사용하십시오. 두 방법의 비교는 Set vs update를 참조하십시오.
핫 키를 샤딩하십시오
각 키에는 읽기 및 쓰기 처리량 제한이 있습니다. 하나의 논리적 레코드가 불필요한 요청을 줄인 후에도 이러한 한도에 지속적으로 도달하는 경우, 결정론적 키를 통해 샤딩하십시오. User_{UserId}_Inventory_{ShardId}와 같은 식별자에서 안정적인 샤드를 선택하여 모든 서버가 동일한 데이터를 동일한 샤드로 라우팅하도록 하십시오.
샤딩은 일관성을 유지하고 향후 마이그레이션을 수행하는 것을 더 복잡하게 만듭니다. 하나의 키에 맞고 처리량 한도 아래에 있는 데이터를 샤딩하지 마십시오.
운영 워크플로우 구축
사용 가능한 도구를 함께 사용하십시오:
- 관찰하십시오. 데이터 저장소 관찰 대시보드를 사용하여 요청, 응답 상태, 처리량 및 저장소를 추적하십시오. 팀이 지속적인 실패나 예상치 못한 성장에 대응할 수 있도록 중요한 데이터 저장소 메트릭에 대한 사용자 정의 경고를 구성하십시오. Creator Hub 알림은 저장소가 한도에 접근하거나 초과할 때 알려주며, 가이드 및 대시보드 링크를 포함합니다.
- 검사하십시오. 데이터 저장소 관리자를 사용하여 데이터 저장소, 키, 저장소 사용량 및 예상 비용을 검사하십시오. 경험에 데이터 저장소가 100개 이상 있는 경우, 데이터 저장소 목록은 크기 및 키 수를 표시하지 않습니다. 해당 메트릭을 위해 Open Cloud 또는 데이터 저장소 배치 프로세서를 사용하십시오.
- 복구하십시오. 개별 레코드에 대해 데이터 저장소 관리자를 사용하십시오. 반복 가능하거나 대규모 워크플로우를 위해 Open Cloud 데이터 저장소 API 또는 데이터 저장소 배치 프로세서를 사용하십시오.
- 의도적으로 확장하십시오. 먼저 불필요한 저장소와 요청을 줄이십시오. 정당한 사용량이 기본 할당량을 초과하는 경우, 확장 서비스를 평가하십시오.
Open Cloud와 게임 서버는 경험 수준의 요청 예산을 공유합니다. 운영 Open Cloud 스크립트의 속도를 제한하여 실시간 트래픽에 간섭하지 않도록 하십시오.
데이터 수명 주기 관리
모든 수정에 대해 새 키를 생성하는 대신 데이터 저장소 버전을 사용하십시오. 키의 최신 버전만 저장소 사용량에 포함되며, 버전을 사용하면 이전 값을 검사하거나 복원할 수 있습니다.
임시 및 빠르게 변경되는 데이터에 대해 메모리 저장소를 사용하십시오. 메모리 저장소 데이터는 자동으로 만료되며 지속적인 데이터 저장소 저장소에 추가되지 않습니다.
테스트가 끝나면 테스트 데이터를 삭제하고 만료된 이벤트나 사용 중지된 기능에 대한 데이터를 제거하십시오. 데이터 저장소를 삭제로 표시한 후에는 복원할 수 있는 30일의 버퍼가 있습니다. 이 30일이 지나면 Roblox는 데이터 저장소를 영구적으로 삭제합니다. 자세한 내용은 데이터 저장소 관리자를 참조하십시오.
잊혀질 권리 처리 설정
정적 데이터 저장소 및 키 패턴을 따르는 플레이어 데이터에 대해 자동화된 잊혀질 권리(RTBF) 처리를 구성하십시오. 자동화된 RTBF는 Roblox가 적격 요청을 처리할 때 삭제 템플릿을 적용하기 때문에 선호되는 워크플로우입니다.
자동화된 RTBF가 데이터 스키마를 지원하지 않는 경우, 삭제 권리 웹후크를 사용하여 사용자 정의 삭제 워크플로우를 실행하십시오. 두 워크플로우 모두 일치하는 모든 플레이어 데이터를 제거하는지 확인하십시오.