简体   繁体   English

如何正确基准化Python脚本连接到Redis所需的时间?

[英]How to correctly benchmark the time it takes for a Python script to connect to Redis?

Recently I was assigned the task to benchmark the time it takes for Python to connect to Redis. 最近,我被分配了一项任务,以测试Python连接到Redis所需的时间。 The purpose was to see whether there is any point in using connection pools over creating new connections. 目的是查看在创建新连接时使用连接池是否有任何意义。

I assumed the task to be fairly simple, I tried many cases, however, I'm constantly being told that my tests are completely wrong, so I do not know how to approach this. 我以为任务很简单,我尝试了很多情况,但是,我经常被告知我的测试是完全错误的,所以我不知道该怎么做。

Note: I'm relatively new to Python and I haven't gotten the grasp of many things concerning this language, so I don't have much experience. 注意: 我对Python还是比较陌生,我还没有掌握很多与此语言有关的知识,所以我没有太多经验。

My first try was the simplest way I could benchmark it that I could think of. 我的第一次尝试是我想到的最简单的基准测试方法。 This is my try with the script that creates a new connection every time: 这是我对每次创建新连接的脚本的尝试:

#!/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))

And to test the time it would take by using connection pools: 并使用连接池测试所需的时间:

#!/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))

I was told those tests are wrong. 有人告诉我这些测试是错误的。 So I thought that I'd need to close the connections manually first. 所以我认为我需要先手动关闭连接。 However, as I am using StrictRedis , I couldn't find a way (in the documentation) to manually close the connections, so I googled and found that StrictRedis.client_pool.disconnect() would be the solution. 但是,由于我正在使用StrictRedis ,因此(在文档中)找不到手动关闭连接的方法,因此我在Google上搜索并发现StrictRedis.client_pool.disconnect()将是解决方案。

So I wanted to check whether it really works and checked it in the following way: 因此,我想检查它是否真的有效,并通过以下方式进行检查:

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))

From which I get the following result: 从中我得到以下结果:

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

Which seemed odd, and to check whether client_list() really returns the correct thing I want it to, I ran a test with connections that can actually be closed (in the main() function): 这似乎很奇怪,并且要检查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())))

Which returns: 哪个返回:

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

So, it does work. 因此,它确实有效。 And because StrictRedis.connection_pool.disconnect() was not working, I just thought that StrictRedis connection has no way to be closed, it gets closed automatically. 而且由于StrictRedis.connection_pool.disconnect()无法正常工作,我只是以为StrictRedis连接无法关闭,它会自动关闭。

However, then I was then told that there is a way to close a StrictRedis connection and I have to do that. 但是,然后我被告知,有一种方法可以关闭StrictRedis连接,而我必须这样做。 Later, I was given the hint that I need to avoid using connection pools in the first test, and I saw in the source code that StrictRedis actually creates a connection pool for itself, though I don't really understand it. 后来,我得到提示,我需要在第一次测试中避免使用连接池,并且在源代码中我看到StrictRedis实际上为自己创建了一个连接池,尽管我不太了解。

Question: 题:
How to correctly benchmark the time it takes for the script to connect to Redis? 如何正确基准测试脚本连接到Redis所需的时间?

Update : 更新

I tried testing the connections via redis.Connection , since it doesn't actually use a connection pool (or at least I couldn't find information about it using one), and also to a redis server that is on another server in the local network: 我尝试通过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))

Now this was the test that I thought would be correct. 现在这是我认为正确的测试。 However, I am not sure about that, since each time I run the script, totally different results are yielded: 但是,我不确定,因为每次运行脚本时,都会产生完全不同的结果:

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

These tests show really weird results. 这些测试显示出非常奇怪的结果。 I restart redis-server each time before I run a test, now I'm on my knees begging for help as I have no idea what am I doing wrong and why is this happening. 每次运行测试之前,我每次都要重新启动redis-server ,但现在我跪下来寻求帮助,因为我不知道我在做什么错,为什么会这样。

Getting back to the original question.. 回到原来的问题..
Are those results normal, and why? 这些结果正常吗?为什么? Is this the correct way I should benchmark the connections, if not, how? 这是我应该对连接进行基准测试的正确方法吗?

Python version : 3.5 python版本 :3.5
Redis server version : 3.2.6 Redis服务器版本 :3.2.6

Thanks in advance. 提前致谢。

Speaking about Redis it is usually discussed to keep 1 shared connection or a connection pool. 说到Redis,通常讨论保留1个共享连接或连接池。 Opening and closing connections every time is dramatically expensive, just don't do this. 每次打开和关闭连接的成本都非常高,请不要这样做。 If you want to open and close connections every time, no need to measure, pool will win big time. 如果您想每次都打开和关闭连接,而无需测量,则池将赢得大量时间。

Regarding your test, it is hard to say if you're doing it right, because you're measuring a library - a black box. 关于您的测试,很难说您做得是否正确,因为您要测量的是一个黑匣子。 Who knows what it does under the hood. 谁知道它在引擎盖下做什么。 From here you have two ways: dig into library or measure not connection time, but performance on your app using one approach or another. 从这里开始,您有两种方法:深入研究库或不衡量连接时间,而是使用一种或另一种方法衡量应用程序的性能。 I'd suggest to measure doing useful operation with pool and without. 我建议衡量在有池和无池的情况下进行有用的操作。

But again, throw away an idea of opening and closing connections for every operation. 但是,再次,放弃了为每个操作打开和关闭连接的想法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM