Backend.GameData.Get 에 관련하여 문의 드립니다.

안녕하세요, 뒤끝 Backend.GameData.Get 관련하여 동작 방식 문의드립니다.

현재 게임 내에서 친구 추천 기능을 구현하면서 다음과 같이 유저 메타 테이블에서
레벨 구간으로 필터링한 뒤, 최대 100명의 유저를 조회하고 있습니다.

public void SuggestedFriend(Action done)
{
    if (suggesetObjects.Count > 0)
        return;

    finalSuggeset.Clear();

    Where where = new Where();

    int myTheme = GetTheme(GameController.Instance.UserInfo.UserLevelTotal);

    int startLevel = ThemeStart(myTheme - seatchRange);
    int endLevel = ThemeEnd(myTheme + seatchRange);

    where.Greater("player_level", startLevel);
    where.Less("player_level", endLevel); // 이부분은 이렇게 사용하면 안되는건 인지 하고 수정하였습니다

    int maxtheme = JsonDataHandler.Instance.GetThemeMaxNum(GameController.Instance.UserInfo.UserSeason);

    var bro = Backend.GameData.Get(MetaTable, where, 100); // 최대 100명 조회

    if (!bro.IsSuccess())
    {
        Debug.Log(bro);
        return;
    }

    if (bro.GetReturnValuetoJSON()["rows"].Count <= 0)
    {
        Debug.Log(bro);
        return;
    }

    Dictionary<string, string> list = new Dictionary<string, string>();

    for (int i = 0; i < bro.Rows().Count; ++i)
    {
        var inDate    = bro.Rows()[i]["owner_inDate"]["S"].ToString();
        var nickname  = bro.Rows()[i]["nickname"]["S"].ToString();
        var friendCode = bro.Rows()[i]["friend_code"]["S"].ToString();

        // 과거에는 여기에서 Add를 사용했습니다.
        // list.Add(inDate, nickname);
        list.TryAdd(inDate, nickname);
    }

    list = ShuffleDictionary(list);
    ...
}

발생했던 문제

위 코드에서 처음에는 TryAdd가 아니라 Dictionary.Add 를 사용하고 있었고,
실서비스 로그에서 다음과 같은 형태의 예외가 발생했습니다.

System.ArgumentException: An item with the same key has already been added. Key: owner_inDate

즉, 동일한 owner_inDate 값을 가진 row가 두 번 이상 반환되어 Dictionary.Add 에서 중복 key 예외가 발생했습니다.

코드 상으로는 owner_inDate 를 “유저 1명당 1개 row” 라는 전제로 사용하고 있었기 때문에,
Backend.GameData.Get(MetaTable, where, 100) 결과에 동일 owner_inDate 가 여러 개 포함될 수 있다고는 예상하지 못했습니다.

현재는 TryAdd 로 수정하여 예외는 더 이상 발생하지 않지만,
문제를 분석하는 과정에서 한 가지 특이한 점이 있어 확인을 부탁드리고자 합니다.

기종별 발생 빈도 편차

위 예외가 발생한 유저들을 집계해 보았을 때,
전체 유저 중 Galaxy A15 / A16 계열 기종에서 해당 예외 발생 비율이 유난히 높게 나타났습니다.

  • 무작위 200명 정도를 샘플링했을 때
    → 특정 기종(A15, A16)의 비중이 비정상적으로 높게 나타남
  • 코드 상으로는 단순히 GameData.Get(MetaTable, where, 100)Rows() 를 순회하는 구조이고,
    기종별로 분기하거나 다른 조건을 쓰는 코드는 없습니다.

에러 자체는 저희가 Add 를 사용한 쪽의 문제라는 것은 인지하고 있으나,
“왜 특정 기종에서만 유달리 중복 key(동일 owner_inDate)가 많이 나오는가?”
라는 부분이 궁금해서 아래 내용을 확인 요청드립니다.

확인 요청 드리고 싶은 사항

  1. Backend.GameData.Get 으로 조회할 때
    동일 테이블 / 동일 where 조건 / 동일 limit(예: 100)으로 호출하더라도,
    2.여러 row에 동일한 owner_inDate 값이 포함되어 반환될 수 있는지*
    (예: 한 유저가 같은 테이블에 여러 row를 갖는 구조라면 가능할 것 같은데,
    MetaTable 성격 상 “유저당 1 row” 라는 전제에서 설계되어 있어서요.)
  2. Backend.GameData.Get 결과가
    요청을 보낸 단말 환경(휴대폰 기종, OS, 네트워크 환경 등)에 따라
    반환되는 row의 우선순위나 구성에 차이가 날 수 있는지
  • 예: 특정 샤딩/캐싱 정책이나 내부 정렬 방식으로 인해
    동일 조건에서 일부 유저군이 더 자주 선택될 가능성이 있는지
  • 동일 where 조건/limit으로 여러 번 호출 시,
    어떤 기준으로 row가 선택/정렬되는지(예: createdAt 오름차순, 내림차순, 랜덤 등)
  1. 혹시 GameData.Get 이 내부적으로
    요청 단말의 어떤 값(예: gamer_id, owner_inDate 등)에 따라
    조회 범위 혹은 우선순위가 달라질 수 있는 로직
    이 있는지 여부

정리하면,
저희 코드에서 Add 사용으로 인한 예외는 수정하였으나,
특정 기종에서 동일 owner_inDate 중복이 유독 많이 관측되는 현상이 단순 우연인지,
혹은 Backend.GameData.Get 의 내부 동작(정렬/샘플링/캐시 등)과 관련이 있을 수 있는지
확인 받고 싶습니다.

확인 부탁드립니다.
감사합니다.

안녕하세요 개발자님,
문의해주신 내용과 관련하여 해당 현상이 발생한 프로젝트 정보가 확인되지 않아 정확한 문제 상황 확인 및 안내에 어려움이 있습니다.
기본적으로 Backend.GameData.Get 함수는 요청한 단말기의 기종, OS, 네트워크 환경에 따라 조회 결과의 구성이나 우선순위를 변경하지 않으며, DB에 저장된 데이터를 있는 그대로 반환합니다.
문의 시 기본 양식에 맞춰 프로젝트 정보 및 sdk 정보등을 포함하여 문의해주시기 바랍니다.

더불어 친구 추천의 경우 where절 조건을 통해 테이블 데이터를 기반으로 유저를 검색 조회하기보다는 랜덤조회 기능을 활용하시는 방법을 추천드립니다.
Where절을 통해 특정 조건을 만족하는 유저를 검색할 경우 기본적으로 가장 최근 삽입된 row부터 조건에 맞는 유저를 모두 찾을때까지 데이터를 순차적으로 조회하게되며 그 과정에서 높은 DB 처리량이 발생하게 됩니다.
이에 랜덤조회 기능을 통해 친구를 추천하도록 하는 방법으로 구현하시는 것을 추천드립니다.