最近我被分配了一项任务,对Python连接到Redis所需的时间进行基准测试。目的是查看使用连接池而不是创建新连接是否有意义。
我认为任务相当简单,我尝试了很多案例,然而,我经常被告知我的测试完全错误,所以我不知道如何处理。
注意: 我对Python还比较陌生,而且我还没有掌握关于这种语言的很多东西,所以我没有太多经验
我的第一次尝试是我能想到的最简单的基准测试方法。这是我对每次创建新连接的脚本的尝试:
#!/usr/bin/env python3
import redis
import timeit
from datetime import datetime
def main():
connection = redis.StrictRedis(host='localhost', port=6379, db=0)
start_time = datetime.now()
timeit_results = timeit.timeit("main()", setup="from __main__ import main", number=5000)
time_taken = datetime.now() - start_time
print("Timeit results: {}".format(timeit_results))
print("Datetime results: {}".format(time_taken))
为了测试使用连接池所需的时间:
#!/usr/bin/env python3
import redis
import timeit
from datetime import datetime
pool = redis.ConnectionPool(host='localhost', port=6379, db=0)
def main():
connection = redis.StrictRedis(connection_pool=pool)
start_time = datetime.now()
timeit_results = timeit.timeit("main()", setup="from __main__ import main", number=5000)
time_taken = datetime.now() - start_time
print("Timeit results: {}".format(timeit_results))
print("Datetime results: {}".format(time_taken))
我被告知那些测试是错误的。所以我想我需要先手动关闭连接。然而,由于我使用StrictRedis
,我找不到手动关闭连接的方法(在文档中(,所以我在谷歌上搜索了一下,发现StrictRedis.client_pool.disconnect()
就是解决方案。
所以我想检查它是否真的有效,并通过以下方式进行检查:
interface = redis.StrictRedis(host='localhost', port=6379, db=0)
def main():
connection = redis.StrictRedis(host='localhost', port=6379, db=0)
connection.connection_pool.disconnect()
print("Open connections during test: {}".format(len(interface.client_list())))
start_time = datetime.now()
timeit_results = timeit.timeit("main()", setup="from __main__ import main", number=10)
time_taken = datetime.now() - start_time
print("Timeit results: {}".format(timeit_results))
print("Datetime results: {}".format(time_taken))
从中我得到以下结果:
Open connections during test: 2
Open connections during test: 3
Open connections during test: 4
Open connections during test: 5
Open connections during test: 6
Open connections during test: 7
Open connections during test: 8
Open connections during test: 9
Open connections during test: 10
Open connections during test: 11
这似乎很奇怪,为了检查client_list()
是否真的返回了我想要的正确内容,我对实际上可以关闭的连接进行了测试(在main()
函数中(:
connection = redis.Connection(host='localhost', port=6379, db=0)
connection.connect()
connection.disconnect()
print("Open connections during test: {}".format(len(interface.client_list())))
哪个返回:
Open connections during test: 1
Open connections during test: 1
Open connections during test: 1
Open connections during test: 1
Open connections during test: 1
Open connections during test: 1
Open connections during test: 1
Open connections during test: 1
Open connections during test: 1
Open connections during test: 1
所以,它确实有效。由于StrictRedis.connection_pool.disconnect()
不工作,我只是认为StrictRedis
连接无法关闭,它会自动关闭。
然而,后来我被告知有一种方法可以关闭StrictRedis
连接,我必须这样做。后来,我得到了在第一次测试中需要避免使用连接池的提示,我在源代码中看到StrictRedis
实际上为自己创建了一个连接池,尽管我并不真正理解它
问题:
如何正确地对脚本连接到Redis所需的时间进行基准测试?
更新:
我尝试通过redis.Connection
测试连接,因为它实际上没有使用连接池(或者至少我用连接池找不到有关它的信息(,也没有使用本地网络中另一台服务器上的redis服务器:
#!/usr/bin/env python3
import redis
from datetime import datetime
import timeit
test_num = 5000
def timefunc():
connection = redis.Connection(host='10.**.**.**', port=6379, db=0)
connection.connect()
connection.disconnect()
timeit_result = timeit.timeit("timefunc()", setup="from __main__ import timefunc", number=test_num)
print("Timeit result (total): {}".format(timeit_result))
print("Timeit result (average): {}".format(timeit_result / test_num))
现在这是我认为正确的测试。然而,我不确定,因为每次运行脚本时,都会产生完全不同的结果:
Test 1:
Timeit result (total): 3.4030799390748143
Timeit result (average): 0.0006806159878149628
Test 2:
Timeit result (total): 2.9527969888877124
Timeit result (average): 0.0005905593977775425
Test 3:
Timeit result (total): 6.543300905032083
Timeit result (average): 0.0013086601810064166
Test 4:
Timeit result (total): 21.31216992996633
Timeit result (average): 0.004262433985993266
Test 5:
Timeit result (total): 5.312907374929637
Timeit result (average): 0.0010625814749859273
这些测试显示出非常奇怪的结果。每次在进行测试之前,我都会重新启动redis-server
,现在我跪在地上乞求帮助,因为我不知道自己做错了什么,也不知道为什么会发生这种情况。
回到最初的问题
这些结果正常吗?为什么?这是我应该对连接进行基准测试的正确方式吗?如果不是,如何进行?
Python版本:3.5
Redis服务器版本:3.2.6
提前谢谢。
说到Redis,通常会讨论保留一个共享连接或连接池。每次打开和关闭连接都非常昂贵,只是不要这样做。如果你想每次都打开和关闭连接,无需测量,池将赢得巨大的时间。
关于你的测试,很难说你做得是否正确,因为你在测量一个库——一个黑盒。谁知道它在引擎盖下做什么。从这里开始,您有两种方法:挖掘库,或者不是测量连接时间,而是使用一种或另一种方法测量应用程序的性能。我建议测量有水池和没有水池的情况下做有用的操作。
但是,再次抛弃为每个操作打开和关闭连接的想法。