避免数据存储区争用

时间:2012-03-14 10:44:19

标签: python google-app-engine nosql google-cloud-datastore

我遇到了设计问题,我的应用程序有增长的流量,而且我有很多“交易冲突。正在重试......”。我不知道如何避免它们。

介绍: 此应用中的每位演员都可以访问另一位演员。

这是我的实际设计(它可能有错误,只是一个例子)

class Actor(object):
  name = db.StringProperty()

class ActorVisits(object):
  """Store a list of all actors has visited the parent of this kind

  Note: Has an ancestor an Actor
  """
  visits = db.ListProperty(db.Key)

class Visit(object):
  """A new visit by actor on the parent of this kind.
  Each time a same actor visits the parent of this kind, this kind is updated
  with the new datetime for the visit.

  Note: Has an ancestor an Actor
  """
  actor = db.ReferenceProperty(collection_name=Actor)
  visited_at = db.datetimeProperty()

这是一个用例的例子:

foo = Actor(name="foo")  
bar = Actor(name="bar")

db.put([foo, bar])

def trx():
  """Store a new visite from 'bar' to 'foo' """

  av = ActorVisits.get_bey_keys_name(key_name="v/foo", parent=foo)
  if av is None:
    av = ActorVisits(key_name="v/foo", parent=foo)

  v = Visit.get_bey_keys_name(key_name="v/foo/bar", parent=foo, actor=bar)
  if v is None:
    v = Visit(key_name="v/foo/bar", parent=foo, actor=bar)
  v.visited_at = datetime.datetime.utcnow()
  async = db.put_async(v)

  if not v.key() in av.visits:
    av.visits.append(v.key())
    av.put()

  async.get_result()

db.run_in_transaction(trx, bar, foo)

如果有人想让我更好地使这个模型。感谢

1 个答案:

答案 0 :(得分:2)

通过将Visits移出Actor的EntityGroup,使访问最终保持一致。如果每次访问都是根实体,则不会遇到任何写入速率问题,您可以轻松查询它们。

如果您不想创建大量的访问实体,只需更新一个实体,您可以通过将其基于Actor和访问者来确定访问确定性的关键字。

所以演员的Id为123, Vistor(另一位演员)拥有888的Id,

您创建了一个类型为Visit的键,其ID为“123_888”(无父级),您使用此键放置()访问,并更新时间,并覆盖之前的访问。你也可以在键上做一个get(),它会非常一致(如果你保持计数说)。

然后,您可以使用最终一致的查询构建ActorVisits。