2016-03-05 241 views
0

我有一個以RabbitMQ作爲代理的基於Celery的任務隊列。我每天處理大約100封郵件。我沒有設置後端。Celery和RabbitMQ最終因內存耗盡而停止

我開始任務主這樣的:

broker = os.environ.get('AMQP_HOST', None) 
app = Celery(broker=broker) 
server = QueueServer((default_http_host, default_http_port), app) 

...我開始喜歡這個工人:

broker = os.environ.get('AMQP_HOST', None) 
app = Celery('worker', broker=broker) 
app.conf.update(
    CELERYD_CONCURRENCY = 1, 
    CELERYD_PREFETCH_MULTIPLIER = 1, 
    CELERY_ACKS_LATE = True, 
) 

服務器正常運行了相當一段時間,但經過約兩幾個星期它突然停止。我已經跟蹤停止下來的RabbitMQ不再接收由於內存耗盡消息:

Feb 25 02:01:39 render-mq-1 docker/e654ac167b10[2189]: vm_memory_high_watermark set. Memory used:252239992 allowed:249239961 
Feb 25 02:01:39 render-mq-1 docker/e654ac167b10[2189]: =WARNING REPORT==== 25-Feb-2016::02:01:39 === 
Feb 25 02:01:39 render-mq-1 docker/e654ac167b10[2189]: memory resource limit alarm set on node [email protected] 
Feb 25 02:01:39 render-mq-1 docker/e654ac167b10[2189]: ********************************************************** 
Feb 25 02:01:39 render-mq-1 docker/e654ac167b10[2189]: *** Publishers will be blocked until this alarm clears *** 
Feb 25 02:01:39 render-mq-1 docker/e654ac167b10[2189]: ********************************************************** 

問題是我無法弄清楚需要進行不同的配置如何防止這種疲憊。顯然某處沒有被清除,但我不明白。

例如,約8天后,rabbitmqctl狀態顯示我:

{memory,[{total,138588744}, 
     {connection_readers,1081984}, 
     {connection_writers,353792}, 
     {connection_channels,1103992}, 
     {connection_other,2249320}, 
     {queue_procs,428528}, 
     {queue_slave_procs,0}, 
     {plugins,0}, 
     {other_proc,13555000}, 
     {mnesia,74832}, 
     {mgmt_db,0}, 
     {msg_index,43243768}, 
     {other_ets,7874864}, 
     {binary,42401472}, 
     {code,16699615}, 
     {atom,654217}, 
     {other_system,8867360}]}, 

...當它第一次開始了它要低得多:

{memory,[{total,51076896}, 
     {connection_readers,205816}, 
     {connection_writers,86624}, 
     {connection_channels,314512}, 
     {connection_other,371808}, 
     {queue_procs,318032}, 
     {queue_slave_procs,0}, 
     {plugins,0}, 
     {other_proc,14315600}, 
     {mnesia,74832}, 
     {mgmt_db,0}, 
     {msg_index,2115976}, 
     {other_ets,1057008}, 
     {binary,6284328}, 
     {code,16699615}, 
     {atom,654217}, 
     {other_system,8578528}]}, 

...即使所有隊列爲空(除一個作業目前正在處理):

[email protected]:/# rabbitmqctl list_queues -q name memory messages messages_ready messages_unacknowledged 
celery 61152 1 0 1 
[email protected] 117632 0 0 0 
[email protected] 70448 0 0 0 
celeryev.17c02213-ecb2-4419-8e5a-f5ff682ea4b4 76240 0 0 0 
celeryev.5f59e936-44d7-4098-aa72-45555f846f83 27088 0 0 0 
celeryev.d63dbc9e-c769-4a75-a533-a06bc4fe08d7 50184 0 0 0 

我不知所措弄清楚如何到FI找出內存消耗的原因。任何幫助將不勝感激。

+0

看來你的隊列(S)(或交換機)正在進入流動狀態。您能否檢查一下 - 它在rabbitmq Web UI中可見 – cantSleepNow

+0

此特定服務器沒有安裝或配置W​​eb UI。有沒有簡單的方法來使用rabbitmqctl或其他命令行工具來查找這些信息?另外,從閱讀[理解流量控制](http://www.rabbitmq.com/blog/2014/04/14/finding-bottlenecks-with-rabbitmq-3-3/),我不確定這是什麼因爲描述意味着服務器無法跟上傳入的連接,但請求從來沒有超過每分鐘3-4次。 – seawolf

+0

我不知道命令行...是的,流意味着發行商對於服務器來說太快了,這也可以解釋爲消費者在處理消息時速度太慢,但最終似乎只有出版商纔會這樣做。 https://www.rabbitmq.com/memory.html – cantSleepNow

回答

1

日誌說,你用252239992個字節,大約是250MB,這是沒有這麼高。 你在這臺機器上有多少內存,以及rabbitmq的vm_memory_high_watermark值是多少? (你可以通過運行rabbitmqctl eval "vm_memory_monitor:get_vm_memory_high_watermark()."來檢查它) 也許你應該只是增加水印。

另一種選擇,可以讓你所有的隊列lazyhttps://www.rabbitmq.com/lazy-queues.html

+0

我相當確信這不是問題。問題不在於內存中的任務過多,而是內存逐漸消耗,即使隊列在絕大多數時間都是空的。 – seawolf

+0

當前水印是默認的,在600MB盒子上的系統RAM的40%。如果真的是正確的答案,我可以將這個門檻提高一些,我擔心的是內存使用的持續增長將達到我設定的任何標準,並且我會在不同的門檻再次遇到同樣的問題。我想找到增長的根本原因(如果可能的話),然後*然後*適當設置閾值。 – seawolf

+0

根據您的內存使用情況,大部分內存由'message_index'和'binary'使用。這意味着消息尚未被垃圾收集,而已經從隊列中刪除。 如果你的信息少於4KB,你可以設置'queue_index_embed_msgs_below'爲較低的值,以便將所有消息發送到message_store而不是message_index(以提高垃圾收集率),並啓用較高的延遲隊列以在內存中存儲較少的消息。 反正256MB的內存對於RabbitMQ來說操作起來是相當小的。 –

0

您似乎沒有生成大量的消息,因此2GB內存消耗看起來奇怪地很高。但是你可以嘗試得到的RabbitMQ刪除舊郵件 - 在您的芹菜配置設置

CELERY_DEFAULT_DELIVERY_MODE = 'transient' 
+0

這應該在排隊任務的端點上,還是在使用端點的端點上,或者兩者都在?它看起來是發件人特定的,但只是想確保。 – seawolf

+0

在[使用瞬態隊列](http://docs.celeryproject.org/en/latest/userguide/optimizing.html)閱讀本文後,它看起來像是將消息保存到磁盤而不是將它們保存在內存中,但是一旦它們完成,它們不會被從磁盤上刪除嗎?另外,似乎保存到磁盤不應該消耗越來越大的內存部分? – seawolf