第一个数据存储区查询总是很慢

时间:2019-10-04 06:37:59

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

我有一个Python 3.7项目,该项目使用google.cloud.ndb库与数据存储区通信。

我注意到,实例启动时的第一个请求总是比后续请求慢一个数量级(几秒钟)。即使使用模拟数据存储在本地运行,也是如此。我已经验证了延迟是由于第一个ndb.Key(...).get()开始运行所致。大概是数据存储区连接需要一些时间来设置?

有人找到减少这种延迟的方法吗?

代码示例:

from flask import Flask
from google.cloud import ndb

import time

client = ndb.Client()

def ndb_wsgi_middleware(wsgi_app):
    def middleware(environ, start_response):
      with client.context():
        return wsgi_app(environ, start_response)
    return middleware

app = Flask(__name__)
app.wsgi_app = ndb_wsgi_middleware(app.wsgi_app)

@app.route('/main')
def main():
  now_ts = time.time()
  org = ndb.Key(Org, 1).get()
  print('Finished get in %f' % (time.time() - now_ts))
  return 'Does not exist' if org is None else 'Exists'

class Org(ndb.Model):
  pass

if __name__ == '__main__':
  app.run(host='0.0.0.0', port=8080, debug=True)

从浏览器获取2 localhost:8080/main后(使用命令gcloud beta emulators datastore start调出的本地数据存储模拟器)后的输出:

Finished get in 2.043116
127.0.0.1 - - [09/Oct/2019 22:41:49] "GET /main HTTP/1.1" 200 -
Finished get in 0.001995
127.0.0.1 - - [09/Oct/2019 22:41:56] "GET /main HTTP/1.1" 200 -

1 个答案:

答案 0 :(得分:0)

出现此行为的原因是,除非另有配置,否则所有App Engine应用程序都在空闲时关闭其实例。这意味着,如果他们收到新的请求,则他们必须花一些时间来回滚并做出响应,从而比原先的响应时间更长。这是设计使然,因为实例在运行时按分钟计费,从而避免占用资源并不必要地产生费用。

您可以使用warm-up requests避免这种情况,Automatic scaling是一种特殊的加载请求,可以在发出实时请求之前准备实例。

其他选择是使用模块在应用程序上设置Partitioner,并为最小空闲实例设置一个值。这意味着,如果您进行设置,则至少有一个实例将一直运行,从而避免了需要任何和所有加载请求。但是,由于这些实例处于恒定的运行状态,因此会产生额外的费用。