App Engine 缓存与数据一致性
数据一致性:
NDB由于是具有最终一致性特点的分布式数据存储,因此在数据存储时需要进行恰当的数据建模。在同一个实体集里面,所有根实体(无 parent )的实体在 id 分配上保证不重复,具有相同 parent 的实体也保证不会出现重复 ID,换句话说 id 的相对唯一性是由 parent 决定的。同时,在使用 multi_get 时也必需是取同一 parent 的实体。
Ancestor 和按 id 查询时保证一致性,但是对整个实体集的查询不保证一致性,因为实体的写入分两个阶段,提交阶段和应用阶段,第一阶段中,CommitLog记录成功即认为写入成功,第二阶段更新索引,在索引更新前非Ancestor或 id 查询看不到结果,Ancestor 及 id 查询即使索引未更新也能返回正确结果。
因此要正确使用 Ancestor 查询,一个典型的场景:比如多个答案属于一个问题,即可指定答案的 parent 为问题,添加新问题后立即查询问题下的所有答案将总是能看到新答案,而使用索引的,针对全部回答的按时间排序的“最新答案”有可能看不到最新添加的答案(索引未更新)。
缓存部分:
在新的NDB数据存储中,GAE提代了两级缓存,1. InProcess 2. Memcache 一级缓存只作用于当前请求过程,2级缓存会在查询时自动缓存,并能在实体属体改动后自动失效。但无论命中哪种缓存,因为是按实体查询次数计费的,因此对计费无影响,真黑 ~~~
因此有必要在程序中设计一层自己的 In-process 缓存这样可以省钱。在考虑以实体的类型+id 作为缓存键值时还应该考虑 parent 节点,以避免键冲突的可能。