【发布时间】:2017-04-11 10:10:20
【问题描述】:
我正在使用 uwsgi + nginx 并使用 aws elasticache (redis 2.8.24) 运行 python 应用程序 (flask + redis-py)。
在尝试改善我的应用程序响应时间时,我注意到在高负载下(每秒 500 个请求/使用 loader.io 持续 30 秒)我丢失了请求(对于这个测试,我只使用了一个没有负载均衡器的服务器,1 个 uwsgi 实例,4 个进程,专门用于测试)。
我挖得更深了,发现在这种负载下,对 ElastiCache 的一些请求很慢。 例如:
- 正常加载:cache_set时间0.000654935836792
- 重载:cache_set时间0.0122258663177 并非所有请求都会发生这种情况,只是随机发生..
我的 AWS ElastiCache 基于 cache.m4.xlarge 上的 2 个节点(默认 AWS 配置设置)。 查看过去 3 小时内连接的当前客户端:
我认为这没有意义,因为目前有 14 台服务器(其中 8 台具有 XX RPS 的高流量使用此集群),我希望看到更高的客户端率。 p>
uWSGI 配置(版本 2.0.5.1)
processes = 4
enable-threads = true
threads = 20
vacuum = true
die-on-term = true
harakiri = 10
max-requests = 5000
thread-stacksize = 2048
thunder-lock = true
max-fd = 150000
# currently disabled for testing
#cheaper-algo = spare2
#cheaper = 2
#cheaper-initial = 2
#workers = 4
#cheaper-step = 1
Nginx 只是一个使用 unix socket 的 uWSGI 网络代理。
这就是我打开与 redis 的连接的方式:
rdb = [
redis.StrictRedis(host='server-endpoint', port=6379, db=0),
redis.StrictRedis(host='server-endpoint', port=6379, db=1)
]
这就是我设置值的方式,例如:
def cache_set(key, subkey, val, db, cache_timeout=DEFAULT_TIMEOUT):
t = time.time()
merged_key = key + ':' + subkey
res = rdb[db].set(merged_key, val, cache_timeout)
print 'cache_set time ' + str(time.time() - t)
return res
cache_set('prefix', 'key_name', 'my glorious value', 0, 20)
这就是我获得价值的方式:
def cache_get(key, subkey, db, _eval=False):
t = time.time()
merged_key = key + ':' + subkey
val = rdb[db].get(merged_key)
if _eval:
if val:
val = eval(val)
else: # None
val = 0
print 'cache_get time ' + str(time.time() - t)
return val
cache_get('prefix', 'key_name', 0)
版本:
- uWSGI:2.0.5.1
- 烧瓶:0.11.1
- redis-py: 2.10.5
- Redis:2.8.24
所以结论:
- 如果连接了 14 台服务器,每台服务器有 4 个进程,并且每台服务器都打开与 redis 集群中 8 个不同数据库的连接,那么为什么 AWS 客户端数量很少
- 是什么导致请求响应时间攀升?
- 如果有任何关于 ElastiCache 和/或 uWSGI 在高负载下的性能的建议,我们将不胜感激
【问题讨论】:
-
Orz,你找到解决方案了吗?我面临着完全相同的问题。从字面上看...nginx+flask+uwsgi 一直很好,但是自从我在 Elasticache 上添加了 redis 后,我遇到了 Elasticache 中长时间运行查询的问题。
标签: python amazon-web-services redis uwsgi redis-py