Firestore 분산 카운터

He SEO·2022년 7월 4일
0

분산 카운터

GCP Firestore는 단일 문서를 1초에 약 한 번만 업데이트가 가능하기 때문에 1초에 여러번 업데이트해야 한다면 분산 카운터 기능을 넣는 것이 좋다.

샤드

각 카운터는 샤드로 이루어진 하위 컬렉션을 갖는다.
컬렉션은 0 ~ (N-1)개의 문서를 생성하고 업데이트 시 하나의 문서에, 읽을 때는 모든 문서를 합산하여 읽는다.

초기화

num_shards 개수만큼의 문서를 생성한다.

const num_shards = 10;
function createCounter(ref) {
    var batch = db.batch();

    // Initialize the counter document
    batch.set(ref, { num_shards: num_shards });

    // Initialize each shard with count=0
    for (let i = 0; i < num_shards; i++) {
        const shardRef = ref.collection('shards').doc(i.toString());
        batch.set(shardRef, { count: 0 });
    }

    // Commit the write batch
    return batch.commit();
}

업데이트

0 ~ (num_shards-1) 중의 하나의 수를 가지고 와 해당 문서에 값을 업데이트 한다.

const num_shards = 10;
function incrementCounter(db, ref) {
    // Select a shard of the counter at random
    const shard_id = Math.floor(Math.random() * num_shards).toString();
    const shard_ref = ref.collection('shards').doc(shard_id);

    // Update count
    return shard_ref.update("count", firebase.firestore.FieldValue.increment(1));
}

가져오기

for문을 돌면서 해당 서브 콜렉션의 모든 문서의 값을 합산한다.

function getCount(ref) {
    // Sum the count of each shard in the subcollection
    return ref.collection('shards').get().then((snapshot) => {
        let total_count = 0;
        snapshot.forEach((doc) => {
            total_count += doc.data().count;
        });

        return total_count;
    });
}

고려 사항

  • 값을 가져올 때마다 n번의 읽기가 수행되어 비용이 증가할 수 있음
  • 샤드 수가 너무 작으면 쓰기 작업이 느려짐
  • 샤드 수가 너무 많으면 읽기가 느려지고 비용이 증가

참고 사이트

profile
BACKEND 개발 기록 중. 감사합니다 😘

0개의 댓글