Datastore에서 확대/축소 및 조회 및 즉시 반영이 가능한 카운터

Datastore 모드의 Firestore에서는 1초에 한 번 이상 업데이트되지 않는 솔리드로 설계하는 것이 좋습니다.공식 문서
따라서 Datastore는 카운터가 있는 솔리드를 설계하기 어렵습니다.
예를 들어 mish에서 애니메이션의 재생 수, 평론 수, 페이지 보기 수 등 계수기를 실시했지만 디자인의 난이도가 상당히 높기 때문에 어떻게 실시해야 하는지를 정리했다.
오픈소스로 재활용이 가능하니 가능하면 사용해 보세요.창고.

분산 계수기


상기 제한을 피하고 계수기를 실현하는 모델로 분산계수기라는 디자인 방법이 있다.
const datastore = new Datastore();

const increment = async (id: string) => {
  const key = datastore.key(["Counter", `${id}-${Math.floor(Math.random() * 100)}`]);

  const transaction = datastore.transaction();
  const [entity] = await transaction.get(key);
  datastore.update({
    key,
    data: { id, count: (entity?.count ?? 0) + 1 },
  });
  await transaction.commit();
};

const getCount = async (id: string) => {
  const [distributedCounters] = await datastore.createQuery("Counter").filter("id", "=", id).run();

  return distributedCounters.reduce<number>((previous, entity) => previous + entity.count, 0);
};
이 예에서 하나의 id를 위해 100개의 실체를 준비했다.이렇게 되면 업데이트 처리가 분산돼 1초에 100회 정도의 업데이트를 견딜 수 있다.
!
이 코드를 직접 사용하지 마세요.
키의 값이 연속되어 있기 때문에 핫스팟 발생합니다.
또한 동작 검증이 수행되지 않았습니다.

과제.


이 방차 계수기도 충분한 상황이 있지만 계수기의 값으로 조회하려는 경우는 충분하지 않다.
const getRanking = async () => {
  const [entities] = await datastore.createQuery("Counter").order("count", { descending: true }).run();

  return entities;
};
이런 코드를 썼어도 분산된 계수기에 대한 검색은 엉망진창인 값만 얻을 수 있다.

통계 분산 계수기


분포식 계수기의 과제를 해결하기 위해서는 합계 계수기를 다른 실체에 넣어야 한다.
몇 가지 통계 방법을 고려할 수 있다.

매일 전체 카운터 합계


바로 떠오르는 것은 하루가 끝날 때 모든 계수기를 조회하고 통계하는 방법이지만 문제점도 바로 떠오른다.
  • 최악의 날은 통계의 반영을 기다려야 한다
  • 합계가 하루 이상 걸리면 가까워진다
  • 합계 ID에 플래그를 세워 일정 시간마다 합계합니다.


    업데이트된 ID의 경우 Memcached 등 KVS 설정 로고를 활용해 몇 분 간격으로 로고가 나타나는 ID만 집계할 수 있다는 점도 문제다.
  • 로고가 세워진 동시에 합계를 진행하는 경우 데이터store의 업데이트 결과는 조회에 반영되지 않을 수 있습니다
  • 거래를 사용하면 어느 정도 피할 수 있지만 거래 충돌이 자주 발생한다
  • 확장성은 판매되는 데이터 스토어를 사용하지만 KVS의 확장성에 주의해야 한다
  • 반영에 있어서 몇 분 기다려야 하는데 즉각적인 반영이라고 할 수 없다
  • 그럼 어떡하지?


    이런 과제들을 해결하기 위해 하는 것은여기.이다.
    이 창고는 다음과 같은 동작을 실현했다.
  • 카운터 increament를 사용할 때 클라우드 Tasks에서 작업 만들기
  • CloudTasks 호출 후 총 서비스
  • 호출된 서비스는 클라우드 Tasks에서 받은 키를 바탕으로 합계
  • 이상의 설치를 통해 합계를 몇 초의 지연으로 반영할 수 있다.
    이렇게 되면 increament 때마다 임무가 만들어지지만 1시에는 수행시간이 있고 Datastore 안에 로고가 세워져 있어 임무를 수행하기 전에는 임무를 만들지 않는다.이 하지 않는 시간은 통계가 넘어가지 않도록 이윤을 챙겼다.
    CloudTasks는 1초에 500회 퀘스트를 완성할 수 있습니다 여분의 작업을 하지 않았기 때문에 1초에 2천500개의 아이디 인크레이션을 할 수 있다.또 이렇게 모자라면 대열 분산을 늘려 규모를 줄일 수도 있다.

    시험을 준비하다

  • 이 창고는mish의 생산에서 운용되어 현재 문제없이 운영되고 있다.PR을 환영합니다.
  • Google이 시작하기 위해 마련한 기술 세션에서 논의한 결과 아직 적절한 방법이 없다고 합니다.
  • 현재 node의 데이터store 클라이언트 라이브러리에서 excludeFrom Indexes를 가져올 수 없습니다.따라서 0.0.6 버전에서는 통계가 실행되면 모든 속성이 인덱스됩니다.버전 0.0.7에서 fork 클라이언트 라이브러리를 통해 독립적으로 실시하여 방법을 강구한다.Issue근데 반응이 없어서...가능하면 댓글을 달아주세요.🚀근데 눌러주세요.
  • Datastore는 이런 디자인을 매우 좋아한다. 뒤에서 이동하는 실례를 의식하지 않아도 좋은 확장성을 얻을 수 있고 축소하지 않을 수 없다.최소한 공식적인 최선의 실천이라도 준비해 주시겠습니까?
  • 좋은 웹페이지 즐겨찾기