2

私はgeventを使用して、いくつかのredis処理を行い、結果をクライアントに返すサーバーを構築しています。でも出来は悪いです。いくつかの調査の結果、redis への接続は 1 つしかないことがわかりました。greenlet が 1 つだけ生成されているようです。これが私のプログラムです:

#!/usr/bin/env python
from gevent import monkey
monkey.patch_all()
import gevent
from gevent.wsgi import WSGIServer
from gevent.pool import Pool
import gevent.socket
from cgi import parse_qs, escape
import json
import redis

p = redis.ConnectionPool()

def app(environ, start_response):
    status = '200 OK'
    body = ''

    path = environ.get('PATH_INFO', '').lstrip('/')
    parameters = parse_qs(environ.get('QUERY_STRING', ''))

    r = redis.Redis(connection_pool=p)
    if path == 'top':
        l = r.zrevrange('online', 0, 50, True)
        body = json.dumps({'onlinetime':map(lambda (pid, online): {'pid':pid, 'onlinetime':online}, l)}) + '\n'

    headers = [
        ('Content-Type', 'text/html'),
        ('Content-Length', str(len(body))),
    ]

    print 'in_use_conn:', len(p._in_use_connections), 'created_connections:', p._created_connections
    start_response(status, headers)

    yield body

def main():
    pool = Pool(1000)
    WSGIServer(('', 7332), app, spawn=pool, log=None).serve_forever()

if __name__ == '__main__':
    main()

プログラムに何か問題がありますか? redis への接続が 1 つしかないのはなぜですか?

4

2 に答える 2

2

http://gehrcke.de/2013/01/highly-concurrent-connections-to-redis-with-gevent-and-redis-py/をご覧ください。

私は100%ではありませんが、あなたのモンキーパッチがうまくいっていますが、私はそれを次のように置き換えます:

import gevent
import redis.connection
redis.connection.socket = gevent.socket

gevent でサポートされている redis への接続を使用して、独自のプールを作成することもできます。

于 2013-10-01T13:18:51.373 に答える
1

redis への接続が 1 つしかないと思う理由は何ですか? 実際、私の小さなテストでは、サーバーが実際に多くの redis への接続を開いていることが示されています。

テストをより明確にするために、print ステートメントを少し変更しました。

print '%s' % parameters['index'], 'in_use_conn:', len(p._in_use_connections), 'created_connections:', p._created_connections, 'available_conn:', len(p._available_connections)

次に、このスクリプトを実行していくつかのリクエストを行います。

for i in {1..20}
do
    wget http://127.0.0.1:7332/top?index=$i > /dev/null 2>&1 &
done

そして、ここに私が得たものがあります:

['1'] in_use_conn: 1 created_connections: 2 available_conn: 1
['2'] in_use_conn: 4 created_connections: 5 available_conn: 1
['3'] in_use_conn: 3 created_connections: 5 available_conn: 2
['4'] in_use_conn: 5 created_connections: 6 available_conn: 1
['6'] in_use_conn: 4 created_connections: 6 available_conn: 2
['5'] in_use_conn: 3 created_connections: 6 available_conn: 3
['7'] in_use_conn: 2 created_connections: 6 available_conn: 4
['10'] in_use_conn: 1 created_connections: 6 available_conn: 5
['8'] in_use_conn: 0 created_connections: 6 available_conn: 6
['14'] in_use_conn: 10 created_connections: 11 available_conn: 1
['11'] in_use_conn: 9 created_connections: 11 available_conn: 2
['12'] in_use_conn: 8 created_connections: 11 available_conn: 3
['16'] in_use_conn: 7 created_connections: 11 available_conn: 4
['15'] in_use_conn: 6 created_connections: 11 available_conn: 5
['13'] in_use_conn: 5 created_connections: 11 available_conn: 6
['20'] in_use_conn: 4 created_connections: 11 available_conn: 7
['19'] in_use_conn: 3 created_connections: 11 available_conn: 8
['9'] in_use_conn: 2 created_connections: 11 available_conn: 9
['17'] in_use_conn: 1 created_connections: 11 available_conn: 10
['18'] in_use_conn: 0 created_connections: 11 available_conn: 11

ピーク時に 10 個の greenlet が同時に実行され、ソケットを待っていることがわかります。あなたのコードは私には完璧に見えます。「パフォーマンスが悪い」理由は別の話です。ソートされた「オンライン」のセットが大きすぎる可能性があります。または、ブロッキング クライアントを使用してサーバーをテストしている可能性が高く、その場合、redis への接続は 1 つしか表示されません。

于 2013-10-01T16:04:54.380 に答える