2

これは私の完全なトレースです:

    Traceback (most recent call last):
  File "/home/server/backend/venv/lib/python3.4/site-packages/celery/app/trace.py", line 283, in trace_task
    uuid, retval, SUCCESS, request=task_request,
  File "/home/server/backend/venv/lib/python3.4/site-packages/celery/backends/base.py", line 256, in store_result
    request=request, **kwargs)
  File "/home/server/backend/venv/lib/python3.4/site-packages/celery/backends/base.py", line 490, in _store_result
    self.set(self.get_key_for_task(task_id), self.encode(meta))
  File "/home/server/backend/venv/lib/python3.4/site-packages/celery/backends/redis.py", line 160, in set
    return self.ensure(self._set, (key, value), **retry_policy)
  File "/home/server/backend/venv/lib/python3.4/site-packages/celery/backends/redis.py", line 149, in ensure
    **retry_policy
  File "/home/server/backend/venv/lib/python3.4/site-packages/kombu/utils/__init__.py", line 243, in retry_over_time
    return fun(*args, **kwargs)
  File "/home/server/backend/venv/lib/python3.4/site-packages/celery/backends/redis.py", line 169, in _set
    pipe.execute()
  File "/home/server/backend/venv/lib/python3.4/site-packages/redis/client.py", line 2593, in execute
    return execute(conn, stack, raise_on_error)
  File "/home/server/backend/venv/lib/python3.4/site-packages/redis/client.py", line 2447, in _execute_transaction
    connection.send_packed_command(all_cmds)
  File "/home/server/backend/venv/lib/python3.4/site-packages/redis/connection.py", line 532, in send_packed_command
    self.connect()
  File "/home/pserver/backend/venv/lib/python3.4/site-packages/redis/connection.py", line 436, in connect
    raise ConnectionError(self._error_message(e))
redis.exceptions.ConnectionError: Error 0 connecting to localhost:6379. Error.
[2016-09-21 10:47:18,814: WARNING/Worker-747] Data collector is not contactable. This can be because of a network issue or because of the data collector being restarted. In the event that contact cannot be made after a period of time then please report this problem to New Relic support for further investigation. The error raised was ConnectionError(ProtocolError('Connection aborted.', BlockingIOError(11, 'Resource temporarily unavailable')),).

私は実際に ConnectionError を検索しましたが、一致する問題はありませんでした。

私のプラットフォームはubuntu 14.04です。これは私の redis 設定の一部です。(redis.conf ファイル全体が必要な場合は共有できます。ちなみに、すべてのパラメーターは LIMITS セクションで閉じられています。)

# By default Redis listens for connections from all the network interfaces
# available on the server. It is possible to listen to just one or multiple
# interfaces using the "bind" configuration directive, followed by one or
# more IP addresses.
#
# Examples:
#
# bind 192.168.1.100 10.0.0.1
bind 127.0.0.1

# Specify the path for the unix socket that will be used to listen for
# incoming connections. There is no default, so Redis will not listen
# on a unix socket when not specified.
#
# unixsocket /var/run/redis/redis.sock
# unixsocketperm 755

# Close the connection after a client is idle for N seconds (0 to disable)
timeout 0

# TCP keepalive.
#
# If non-zero, use SO_KEEPALIVE to send TCP ACKs to clients in absence
# of communication. This is useful for two reasons:
#
# 1) Detect dead peers.
# 2) Take the connection alive from the point of view of network
#    equipment in the middle.
#
# On Linux, the specified value (in seconds) is the period used to send ACKs.
# Note that to close the connection the double of the time is needed.
# On other kernels the period depends on the kernel configuration.
#
# A reasonable value for this option is 60 seconds.
tcp-keepalive 60

これは私のミニ redis ラッパーです。

import redis

from django.conf import settings


REDIS_POOL = redis.ConnectionPool(host=settings.REDIS_HOST, port=settings.REDIS_PORT)


def get_redis_server():
    return redis.Redis(connection_pool=REDIS_POOL)

そして、これが私がそれを使用する方法です:

from redis_wrapper import get_redis_server

# view and task are working in different, indipendent processes

def sample_view(request):
    rs = get_redis_server()
    # some get-set stuff with redis



@shared_task
def sample_celery_task():
    rs = get_redis_server()
    # some get-set stuff with redis

パッケージのバージョン:

celery==3.1.18
django-celery==3.1.16
kombu==3.0.26
redis==2.10.3

問題はそれです。この接続エラーは、セロリ ワーカーを開始してからしばらくすると発生します。そして、最初にそのエラーが表示された後、すべてのタスクがこのエラーで終了し、すべてのセロリ ワーカーを再起動します。(興味深いことに、セロリの花もその問題のある時期に失敗します)

redis 接続プールの使用方法、または redis 構成、またはおそらくネットワークの問題が疑われます。理由についてのアイデアはありますか?私は何を間違っていますか?

(PS: 今日このエラーが表示されたら、redis-cli 情報の結果を追加します)

アップデート:

--maxtasksperchildパラメーターをワーカー スターター コマンドに追加することで、この問題を一時的に解決しました。私はそれを 200 に設定しました。もちろん、これはこの問題を解決するための適切な方法ではありません。これは単なる対症療法です。基本的に、ワーカー インスタンスを定期的に更新し (古いプロセスを閉じて、古いプロセスが 200 タスクに達したときに新しいプロセスを作成します)、グローバル redis プールと接続を更新します。そのため、グローバル redis 接続プールの使用方法に焦点を当てる必要があると思います。また、新しいアイデアやコメントを待っています。

下手な英語で申し訳ありませんが、よろしくお願いします。

4

1 に答える 1