Bla*_*way 7 python google-app-engine bigtable cpu-usage
我们在Google App Engine上有一个相当大的数据库 - 只有超过50,000个实体 - 我们希望从中清除过时的数据.计划是编写一个延迟任务来迭代我们不再需要的实体,并批量删除它们.
一个复杂因素是我们的实体也有我们想要清除的子实体 - 没问题,我们想; 我们只是查询这些实体的数据存储区,并将其与父项同时删除:
query = ParentKind.all()
query.count(100)
query.filter('bar =', 'foo')
to_delete = []
for entity in enumerate(query):
to_delete.append(entity)
to_delete.extend(ChildKindA.all().ancestor(entity).fetch(100))
to_delete.extend(ChildKindB.all().ancestor(entity).fetch(100))
db.delete(to_delete)
Run Code Online (Sandbox Code Playgroud)
我们限制自己一次删除100个ParentKind
实体; 每个人ParentKind
有大约40个孩子ChildKindA
和ChildKindB
实体 - 可能有4000个实体.
这在当时似乎是合理的,但是我们运行了一个批处理作为测试,结果查询运行了9秒 - 并且在可计算的CPU时间内花费了1933 秒来访问数据存储区.
这似乎相当苛刻 - 每个实体0.5个可计费秒! - 但我们并不完全确定我们做错了什么.它只是批量的大小吗?祖先的查询特别慢吗?或者,删除(实际上,所有数据存储访问)只是作为糖蜜缓慢?
我们将查询更改为keys_only
,虽然这样可以将运行一个批处理的时间缩短到4.5个实际秒,但CPU时间仍然需要大约1900秒.
接下来,我们将Appstats安装到我们的应用程序(感谢,kevpie)并运行一个较小的批次 - 10个父实体,总计约450个实体.这是更新的代码:
query = ParentKind.all(keys_only=True)
query.count(10)
query.filter('bar =', 'foo')
to_delete = []
for entity in enumerate(query):
to_delete.append(entity)
to_delete.extend(ChildKindA.all(keys_only=True).ancestor(entity).fetch(100))
to_delete.extend(ChildKindB.all(keys_only=True).ancestor(entity).fetch(100))
db.delete(to_delete)
Run Code Online (Sandbox Code Playgroud)
Appstats的结果:
service.call #RPCs real time api time
datastore_v3.RunQuery 22 352ms 555ms
datastore_v3.Delete 1 366ms 132825ms
taskqueue.BulkAdd 1 7ms 0ms
Run Code Online (Sandbox Code Playgroud)
这个Delete
电话是操作中最昂贵的一部分!
有没有解决的办法?尼克约翰逊提到使用批量删除处理程序是目前最快的删除方式,但理想情况下我们不希望删除所有类型的实体,只是那些匹配的实体,并且是我们初始bar = foo
查询的子代.
归档时间: |
|
查看次数: |
1566 次 |
最近记录: |