我试图围绕争用以及它如何应用于Application Engine堆栈。
我有一个像这样构建的模型
class Events(db.Model):
#Owner Identification Number
owner_id = db.StringProperty(required=True)
#Authentication Token
auth_token = db.StringProperty(required=True)
#generic, b, c, d, ...
driver = db.StringProperty(required=True)
#Start Time and Date
tStart = db.DateTimeProperty(auto_now=True)
#Define whether the event is active or inactive
active = db.BooleanProperty(default=False)
#Payload store, this will store each payload block sent or pulled
payloads = db.StringListProperty(indexed=False)
此模型包含多个事件,每个事件都有一个所有者和一个有效负载,事件的所有者将在其事件中写入有效负载,而许多其他事件将从事件中读取,这是一种转录堆栈。 / p>
我的问题是争论,我是否会受到影响,如果是这样的话,我该怎样才能进行重组以防止它发生。
谢谢。
答案 0 :(得分:2)
我也是Google App Engine的新手。所以基本上避免争用实际上是在询问如何增加写入吞吐量。我能想到的解决方案是:
https://developers.google.com/appengine/articles/sharding_counters
https://developers.google.com/appengine/articles/scaling/contention
还有其他想法吗?我也想知道!
答案 1 :(得分:1)
在您的情况下,适用的限制是实体写入/更新限制,即每秒每个实体(或实体组)写入/更新1次。
读取没有限制。
使用memcache缓存读取仍然是个好主意,以降低成本并缩短响应时间。如果您使用Python NDB,那么caching is enabled by default。
解决方案:恕我直言,提高写入吞吐量并同时进行读取的良好解决方案是backends。它们(大多数)总是在可以用作共享内存的实例上。因此,您可以在进行并发读取时批量写入(并通过任务队列刷新)。
注意:实例每天大约重启一次,因此您无法将它们视为可靠的存储 - 您可以将它们用作智能缓存,同时异步(通过后端线程或任务队列)事务更新实体数据存储。
答案 2 :(得分:1)
我认为您的模型没有任何问题:
Events
实体不会支付任何竞争税,因为从您的言论和示例来看,只是在任何实体组之外的根实体。答案 3 :(得分:1)
在App Engine中,事件的每个实例都被读/写为整个对象。您会担心每个事件实例的争用。如果您必须经常更新单个事件实例,则可能需要担心争用。如果您更新不同的实例,则无需担心。
我不确定你的争论究竟是什么意思。您可能指的是a)事务完整性或b)有限的写性能。尽管你确实遇到了最终一致性问题,但你应该对阅读性能没有任何问题。
a)如果在更新Event实例后必须读取正确的数据,则需要按键使用数据存储区get()请求。 query()请求可能会返回旧数据。
b)如果您担心写入性能,则需要以某种方式将实体拆分为多个实体。您可能考虑为每个事件设置多个Payload实体,例如:
class Payload(db.Model):
event = db.ReferenceProperty(Events)
payload = db.StringProperty()
通过这种方式,您可以单独编写每个有效负载,但由于需要对其进行索引,因此需要稍微更加昂贵,因此需要按事件查询它们才能获取它们。您可能希望将Event设置为祖先,以便您可以使用祖先查询进行一致查询。