5

我正在使用带有 python 的 Redis 服务器。

我的应用程序是多线程的(我每个进程使用 20 - 32 个线程),而且我还在不同的机器上运行该应用程序。

我注意到有时 Redis cpu 使用率为 100% 并且 Redis 服务器变得无响应/缓慢。

我想为每个应用程序使用 1 个总共 4 个连接的连接池。例如,如果我最多在 20 台机器上运行我的应用程序,则应该有 20*4 = 80 个到 redis 服务器的连接。

POOL = redis.ConnectionPool(max_connections=4, host='192.168.1.1', db=1, port=6379)
R_SERVER = redis.Redis(connection_pool=POOL)

class Worker(Thread):

    def __init__(self):
        self.start()

    def run(self):
        while True:
            key = R_SERVER.randomkey()
            if not key: break
            value = R_SERVER.get(key)


    def _do_something(self, value):
        # do something with value
        pass

if __name__ = '__main__':
    num_threads = 20
    workers = [Worker() for _ in range(num_threads)]
    for w in workers:
       w.join()

当执行命令时,上面的代码应该运行从最大大小为 4 的连接池中获取连接的 20 个线程。

什么时候释放连接?

根据此代码(https://github.com/andymccurdy/redis-py/blob/master/redis/client.py):

    #### COMMAND EXECUTION AND PROTOCOL PARSING ####
def execute_command(self, *args, **options):
    "Execute a command and return a parsed response"
    pool = self.connection_pool
    command_name = args[0]
    connection = pool.get_connection(command_name, **options)
    try:
        connection.send_command(*args)
        return self.parse_response(connection, command_name, **options)
    except ConnectionError:
        connection.disconnect()
        connection.send_command(*args)
        return self.parse_response(connection, command_name, **options)
    finally:
        pool.release(connection)

每条命令执行完毕后,连接被释放并回到池中

有人可以验证我是否正确理解了这个想法并且上面的示例代码将按描述工作吗?

因为当我看到redis连接时,总是有4个以上。

编辑:我刚刚在代码中注意到该函数在 finally 之前有一个 return 语句。那么finally的目的是什么?

4

2 回答 2

0

正如 Matthew Scragg 提到的,finally 子句在测试结束时执行。在这种特殊情况下,它用于在完成连接后将连接释放回池,而不是让它保持打开状态。

至于无响应,请查看您的服务器在做什么。您的 Redis 实例的内存限制是多少?您多久保存一次磁盘?您是否在基于 Xen 的 VM(例如 AWS 实例)上运行?您是否正在运行复制,如果有,有多少从属服务器,它们是否处于良好状态,或者它们是否经常要求完全重新同步数据?您的任何命令是否“保存”?

您可以使用命令行界面回答其中一些问题。例如 redis-cli info persistence会告诉你有关保存到磁盘的过程的信息,redis-cli info memory会告诉你有关你的内存消耗的信息。

在获取持久性信息时,您要专门查看rdb_last_bgsave_statusrdb_last_bgsave_time_sec。这些将告诉您上次保存是否成功以及花费了多长时间。花费的时间越长,您遇到资源问题的可能性就越大,并且您遇到可能表现为无响应的减速的可能性就越大。

于 2014-07-21T15:56:42.957 回答
0

尽管在它之前有一个 return 语句,但最终块将始终运行。你可以看看 redis-py/connection.py , pool.release(connection) 只把连接放到可用连接池中,所以连接仍然存在。关于 redis 服务器 cpu 的使用,您的应用程序将始终发送请求并且没有中断或睡眠,所以它只是使用越来越多的 cpu,而不是内存。并且 cpu 使用与打开的文件数无关。

于 2017-02-08T03:02:58.457 回答