如何减少 Google App Engine 数据存储延迟?

2022-09-04 22:12:01

通过appstats,我可以看到我的数据存储查询大约需要125毫秒(api和cpu组合),但在执行查询之前通常存在很长的延迟(例如,长达12000毫秒)。

我可以看到我来自数据存储的延迟与我的查询无关(例如,相同的查询/数据具有截然不同的延迟),因此我假设这是应用程序引擎的调度问题。

其他人是否看到同样的问题?

有没有办法减少延迟(例如管理控制台设置)?

这是来自appstats的屏幕截图。此 servlet 具有很少的 CPU 处理。它执行 getObjectByID,然后执行数据存储查询。该查询具有 OR 运算符,因此应用引擎将其转换为 3 个查询。

appstats screenshot.如您所见,在执行第一个 getObjectByID 之前需要 6000 毫秒。在获取操作之前没有处理(获取 pm 除外)。我认为这 6000 毫秒的延迟可能是由于实例预热造成的,因此我将空闲实例增加到 2 以防止任何预热。

然后,在 getObjectByID 和查询之间大约 1000 毫秒有第二个延迟。获取和查询之间有零行代码。该代码仅采用 getObjectByID 的结果,并将数据用作查询的一部分。

总计为 8097 毫秒,但我的数据存储操作(以及 99.99% 的 servlet)仅为 514 毫秒(45 毫秒 api),尽管每次运行 servlet 时这些数字都会发生变化。这是另一个 appstats 屏幕截图,它针对相同的数据在同一 servlet 上运行。enter image description here

这是我的java代码的基础知识。出于安全目的,我不得不删除一些细节。

user = pm.getObjectById(User.class, userKey);           
//build queryBuilder.append(...
final Query query = pm.newQuery(UserAccount.class,queryBuilder.toString());
query.setOrdering("rating descending");
query.executeWithArray(args); 

编辑:使用Pingdom,我可以看到GAE延迟从450ms到7,399ms不等,或1,644%的差异!这是有两个空闲实例,站点上没有用户。enter image description here


答案 1

我在我的一些应用程序中观察到非常相似的延迟(在7000-10000ms范围内)。我不认为大部分问题(那6000ms)在于你的代码。

在我的观察中,这个问题与AppEngine启动一个新实例有关。设置最小空闲实例可能有助于缓解,但它不会解决它(我尝试了多达2个空闲实例),因为基本上即使你有N个空闲实例,应用程序引擎也会更喜欢旋转动态实例,即使单个请求进来,并且在疯狂的流量高峰时会“保存”空闲的实例。这是非常违反直觉的,因为您希望它使用已经存在的实例,并为将来的请求启动动态实例。

无论如何,根据我的经验,这个问题(10000ms延迟)在任何非零负载量下很少发生,许多人不得不每隔几分钟恢复到ping(可能是cron作业)的一些king(可能是cron作业)(过去工作5分钟,但最近实例死得更快,所以它更像是每2分钟一次ping),以保持动态实例,以便在没有其他人在场时访问站点的用户提供服务。这种ping并不理想,因为它会蚕食您的免费配额(每5分钟ping一次会消耗掉一半以上的配额),但到目前为止,我真的还没有找到更好的选择。

回顾一下,总的来说,我发现应用程序引擎在负载下非常棒,但是当您在网站上只有很少(1-3)用户时,它就不出色了。


答案 2

Appstats 仅在您进行 GAE API/RPC 调用时帮助诊断性能问题。

对于关系图,“空白”时间花在实例上运行代码上。这不会是安排时间。

您极有可能猜测最初的延迟可能是由于实例预热造成的。它可能是正在执行的框架代码。我无法猜测Get和Query之间的延迟。可能是有 0 行代码,但您在 Query 中调用了某个需要时间处理的函数。

如果不了解语言,框架或实际代码,没有人能够帮助您。

您需要自行添加某种性能跟踪才能诊断此问题。执行此操作的最简单(但不是高度准确)方法是在代码执行时添加计时器并记录计时器值。


推荐