为什么boto dynamodb2的get_item速度不稳定且经常很糟糕?

4 投票
1 回答
737 浏览
提问于 2025-04-18 12:54

为什么我通过boto的get_item请求DynamoDB时速度这么慢,而且经常很慢?AWS控制台显示我的获取延迟最高达到了12.5毫秒,但我的请求根本没有接近这个速度。

我使用的环境是:
Python 2.7.5
AWS区域是us-west-1
boto版本是2.31.1
DynamoDB表的大小大约有18万条记录。

代码:

from boto.dynamodb2.fields import HashKey
from boto.dynamodb2.table import Table
from boto.dynamodb2.types import STRING
import boto.dynamodb2
import time

REGION = "us-west-1"
AWS_KEY = "xxxxx"
AWS_SECRET = "xxxxx"

start = time.time()
peeps = ("cefbdadf518f44da8a68e35b2321bb1f", "7e3a691df6134a4f83d381a5507cbb18")
connection = boto.dynamodb2.connect_to_region(REGION, aws_access_key_id=AWS_KEY, aws_secret_access_key=AWS_SECRET)
users = Table("users-test", schema=[HashKey("id", data_type=STRING)], connection=connection)
for peep in peeps:
    user = users.get_item(consistent=True, id=peep)
    print time.time() - start

结果:

(botot)➜  ~  python test2.py
0.056941986084
0.0681240558624
(botot)➜  ~  python test2.py
1.05709600449
1.06937909126
(botot)➜  ~  python test2.py
0.048614025116
0.0575139522552
(botot)➜  ~  python test2.py
0.0553398132324
0.064425945282
(botot)➜  ~  python test2.py
3.05251288414
3.06584000587
(botot)➜  ~  python test2.py
0.0579640865326
0.0699849128723
(botot)➜  ~  python test2.py
0.0530469417572
0.0628390312195
(botot)➜  ~  python test2.py
1.05059504509
1.05963993073
(botot)➜  ~  python test2.py
1.05139684677
1.0603158474

更新 2014-07-11 08:03 PST
我的实际使用场景是每次网页请求都要查找一个用户。正如@gamaat所说,DynamoDB的费用主要是在第一次查找时产生,因为这时会建立HTTPS连接。所以看起来如果我能在请求之间保持DynamoDB的连接并重复使用它,速度会更快。因此,我使用了werkzeug.contrib.cache.FileSystemCache来存储这个连接,但似乎它从来没有真正存储这个连接以供后续使用。其他值都能正常存储,就这个连接对象不行。有什么想法吗?如果这不是在请求之间存储连接的好方法,那还有什么好的方法呢?

更新 2014-07-11 15:30 PST
因为我使用supervisor和uwsgi来管理我的Flask应用,所以问题似乎在于如何在我的Flask应用中共享连接对象以供请求使用。

1 个回答

4

这个问题的解决方案让响应时间变得更快了(之前的平均响应时间大约是500毫秒,现在变成了大约50毫秒),主要做了两件事:

1) 把Boto DynamoDB的连接对象放在default_settings.py文件里,这样每次应用加载时,它只会加载一次到app.config["DYNDB_CONN"]里;

2) 配置uwsgi,让num_processes的值设置为-1,这样uwsgi就会始终保持num_processes - 1个进程在运行,如果负载需要的话,还可以再启动一个进程。

这样做的目的是为了减少uwsgi进程的重启次数,从而避免每次重启都要重新创建Boto DynamoDB的连接对象(这会产生HTTP连接的建立成本)。

撰写回答