我正在使用带有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()
Run Code Online (Sandbox Code Playgroud)
上面的代码应该运行20个线程,这些线程在执行命令时从max size 4的连接池获得连接.
连接发布后?
根据此代码(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)
Run Code Online (Sandbox Code Playgroud)
执行每个命令后,连接将被释放并返回池中
有人可以验证我已经理解了这个想法是正确的,上面的示例代码将如所描述的那样工作吗?
因为当我看到redis连接时,总有超过4个.
编辑:我刚刚在代码中注意到函数在finally之前有一个return语句.那最终的目的是什么呢?
正如 Matthew Scragg 提到的,finally 子句在测试结束时执行。在这种特殊情况下,它用于在完成连接后将连接释放回池,而不是使其保持打开状态。
至于无响应,请查看您的服务器正在做什么。您的 Redis 实例的内存限制是多少?您多久保存一次到磁盘?您是否在基于 Xen 的 VM(例如 AWS 实例)上运行?您是否正在运行复制,如果运行的话,有多少个从属设备,它们是否处于良好状态,或者它们是否经常要求完全重新同步数据?您的任何命令是否“保存”?
您可以使用命令行界面来回答其中一些问题。例如,
redis-cli info persistence
会告诉您有关保存到磁盘的过程的信息,redis-cli info memory
会告诉您有关内存消耗的信息。
当获取持久性信息时,您要专门查看rdb_last_bgsave_status
和rdb_last_bgsave_time_sec
。这些将告诉您上次保存是否成功以及花费了多长时间。花费的时间越长,遇到资源问题的可能性就越大,并且遇到可能表现为无响应的速度下降的可能性就越大。