2016-11-27 31 views
7

我正在運行python應用程序(flask + redis-py)與uwsgi + nginx和使用aws elasticache(redis 2.8.24)。我發現在高負載下(每秒500次請求/使用loader.io 30秒),我正在失去請求(對於這個測試,我只用了一個單個服務器沒有負載平衡器,1個uwsgi實例,4個進程,用於測試)。 stress testAWS Redis + uWSGI背後的NGINX - 高負載

我已經挖得更深一些,並發現這個負載下,一些要求ElastiCache是​​緩慢的。 例如:

  • 正常負荷:cache_set時間0.000654935836792
  • 重載:cache_set時間0.0122258663177 這不會發生的所有請求,只是隨機occurres ..

我的AWS ElastiCache基於cache.m4.xlarge(默認AWS配置設置)上的2個節點。 查看已連接在過去3小時目前的客戶: aws elasticache clients

我覺得這樣做沒有意義,因爲目前14臺服務器(其中8 XX RPS的高流量使用這個集羣),我希望看到更高的客戶利率。

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套接字網絡代理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的:24年2月8日

於是得出結論:

  1. 如果連接14臺服務器,每臺服務器有4個進程,並且每臺服務器都打開一個連接到redis集羣內的8個不同數據庫,那麼AWS客戶端的計數會很低
  2. 什麼導致請求響應時間爬升?
  3. 希望瞭解關於ElastiCache和/或uWSGI性能任何意見重載
+0

奧茲,你能找到解決辦法嗎?我面臨着完全相同的問題。從字面上看...... nginx + flask + uwsgi一直很好,但是因爲我在Elasticache中添加了redis,所以我在Elasticache中遇到了長時間運行查詢的問題。 – camelCase

回答

2

簡答下

所以,如果我是正確的,在我的情況下,問題不是Elasticache請求,但uWSGI內存使用情況。

長的答案

我已經安裝了uwsgitop與此設置:

### Stats 
### --- 
### disabled by default 
### To see stats run: uwsgitop /tmp/uwsgi_stats.socket 
### uwsgitop must be install (pip install uwsgitop) 
stats = /tmp/uwsgi_stats.socket 

這將暴露uwsgi統計信息uwsgitop。

然後,我使用​​以350-500個請求/秒對應用程序進行壓力測試。

我發現與我以前的配置是,uWSGI工作人員不斷增長使用的內存大小,直到內存窒息,然後CPU尖刺。需要重新產卵的新工人也要求cpu,這會導致服務器出現某種過載 - 這導致nginx超時並關閉這些連接。

所以我做了一些研究和配置修改,直到我設法得到下面的設置,目前管理約〜650rps的每個實例~13ms的響應時間,這對我很好。

*我使用的應用程序(仍然使用一些)醃dat文件,其中一些人重加載磁盤 - 我已經減少了磁盤的依賴性最小*

對於任何人誰可能會看到它的未來 - 如果您需要快速響應 - 儘可能將所有內容同步。爲前,用芹菜+ RabbitMQ的任何數據庫請求,如果可能的話

uWSGI配置:

listen = 128 
processes = 8 
threads = 2 
max-requests = 10000 
reload-on-as = 4095 
reload-mercy = 5 
#reload-on-rss = 1024 
limit-as = 8192 
cpu-affinity = 3 
thread-stacksize = 1024 
max-fd = 250000 
buffer-size = 30000 
thunder-lock = true 
vacuum = true 
enable-threads = true 
no-orphans = true 
die-on-term = true 

NGINX相關部分:

user nginx; 
worker_processes 4; 
worker_rlimit_nofile 20000; 
thread_pool my_threads threads=16; 
pid /run/nginx.pid; 

events { 
    accept_mutex off; 
    # determines how much clients will be served per worker 
    # max clients = worker_connections * worker_processes 
    # max clients is also limited by the number of socket connections available on the system (~64k) 
    worker_connections 19000; 

    # optmized to serve many clients with each thread, essential for linux -- for testing environment 
    use epoll; 

    # accept as many connections as possible, may flood worker connections if set too low -- for testing environment 
    multi_accept on; 
} 

http { 
    ... 
    aio      threads; 
    sendfile    on; 
    sendfile_max_chunk  512k; 
    tcp_nopush    on; 
    tcp_nodelay    on; 
    keepalive_timeout  5 5; 
    keepalive_requests  0; 
    types_hash_max_size  2048; 
    send_timeout   15; 
    ... 
} 

希望它能幫助!