在 Firestore 模式下的 Datastore 中,處理存盤高寫入計數器(例如網站上的組態檔視圖)的推薦方法是使用分片/分布式計數器。
我遇到的問題是,使用分布式計數器,您需要選擇想要擁有的分片數量。這也在這里解決。例如,某些個人資料每秒獲得的瀏覽量可能比其他個人資料多得多(一個個人資料可能是名人,而另一個個人資料是普通人),因此需要更多的分片。
如果頁面每秒獲得大量視圖,有沒有辦法撰寫一個可以擴展其分片的分布式計數器?
我正在考慮檢測資料存盤爭用錯誤,然后在發生這種情況時添加更多分片。
我注意到 Cloud Firestore 有一個新的擴展,似乎可以滿足我的要求。但是,我沒有使用 Cloud Firestore,而是在 Firestore 模式下使用 Datastore - 本質上類似,但仍然不同。
uj5u.com熱心網友回復:
原始 Datastore 分布式計數器示例:
NUM_SHARDS = 20
class SimpleCounterShard(ndb.Model):
"""Shards for the counter"""
count = ndb.IntegerProperty(default=0)
def get_count():
"""Retrieve the value for a given sharded counter.
Returns:
Integer; the cumulative count of all sharded counters.
"""
total = 0
for counter in SimpleCounterShard.query():
total = counter.count
return total
@ndb.transactional
def increment():
"""Increment the value for a given sharded counter."""
shard_string_index = str(random.randint(0, NUM_SHARDS - 1))
counter = SimpleCounterShard.get_by_id(shard_string_index)
if counter is None:
counter = SimpleCounterShard(id=shard_string_index)
counter.count = 1
counter.put()
使用了固定數量的分片,但Firestore 示例使用單獨的物體來跟蹤分片數量。因此,您可以使用以下代碼更新上面的代碼:
class RootCounter(ndb.Model):
count = ndb.IntegerProperty(default=0)
num_shards = ndb.IntegerProperty(default=0)
def get_count(self):
if self.num_shards > 0:
return sum([e.count for e in SimpleCounterShard.query(parent=self.key)])
return count
def increment(self):
try:
self._increment()
except:
self.num_shards = 1
self.increment()
self.put()
@ndb.transactional(retries=1):
def _increment(self):
if self.num_shards > 0:
SimpleCounterShard.increment(parent=self.key, self.num_shards)
else:
self.count = 1
self.put()
自從 Datastore 模式的 Firestore 發布以來,重要的區別在于 Datastore 模式的 Firestore 具有很強的一致性,并且您可能沒有使用物體組。因此,查詢將給出準確的答案,并且分片計數器可以很好地適應具有根計數器的層次結構。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/507765.html
標籤:Google Cloud Collective 谷歌应用引擎 谷歌云平台 谷歌云火库 谷歌云数据存储 分片
