redis-py
redis-py copied to clipboard
redis.hgetall() Python multithreading is not executing concurrently with multiple redis servers
Redis Server version - 7.0.11 (latest)
Description: Running multiple Redis standalone servers (ports: 7000, 7002, 7004). Using multi-threading to read from multiple servers concurrently. Hence, number of threads = 3.
Issue - Python's avg time for hgetall(key)
using 3 threads = 3 * avg time for the single thread execution.
With Java, it's working as expected. With below benchmark code and output, it's visible that python avg time (for hgetall(key)
) = 90ms and java avg time(for hgetall(key)
) = 28 ms for the same key with 3 threads(for 3 server concurrent read)
Java -
jedis verson - 4.4.1
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import java.util.Arrays;
import static java.lang.System.nanoTime;
class ThreadedRedisRead implements Runnable {
int port;
public ThreadedRedisRead(int port) {
this.port = port;
}
public void run() {
System.out.println("thread is running...");
JedisPool pool = new JedisPool("localhost", port);
int numOfIterations = 100;
long[] res = new long[numOfIterations];
for (int i = 0; i < numOfIterations; i++) {
try (Jedis jedis = pool.getResource()) {
res[i] = read_data(jedis);
}
}
System.out.println("avg = " + Arrays.stream(res).sum() / numOfIterations);
System.out.println("max = " + Arrays.stream(res).max().getAsLong());
System.out.println("min = " + Arrays.stream(res).min().getAsLong());
// Prints: {name=John, surname=Smith, company=Redis, age=29}
}
public static long read_data(Jedis jedis) {
long start = nanoTime();
jedis.hgetAll("seller-1");
return (nanoTime() - start) / 1000000;
}
}
public class Main {
public static void main(String[] args) throws InterruptedException {
Thread thread1 = new Thread(new ThreadedRedisRead(7000));
thread1.start();
Thread thread2 = new Thread(new ThreadedRedisRead(7002));
thread2.start();
Thread thread3 = new Thread(new ThreadedRedisRead(7004));
thread3.start();
thread1.join();
thread2.join();
thread3.join();
System.out.println("Hello world!");
}
}
Output
thread is running...
thread is running...
thread is running...
avg = 28
max = 172
min = 16
avg = 28
max = 139
min = 17
avg = 28
max = 138
min = 17
Hello world!
Python version - 3.9.6
redis-py version - 4.5.5
import time
from threading import Thread
import redis
def threaded_function(arg):
def read_data(connection_obj, key):
start = time.time_ns()
connection_obj.hgetall(key)
end = time.time_ns() - start
return end / 1000000
print("thread started "+str(arg))
redis_pool = redis.ConnectionPool(host='127.0.0.1', port=int(arg), db=0)
res = []
for i in range(100):
connection_object = redis.Redis(connection_pool=redis_pool)
res.append(read_data(connection_object, "seller-1"))
print("avg", sum(res) / len(res))
print("max", max(res))
print("min", min(res))
if __name__ == "__main__":
thread1 = Thread(target = threaded_function, args = (7000, ))
thread1.start()
thread2 = Thread(target = threaded_function, args = (7002, ))
thread2.start()
thread3 = Thread(target = threaded_function, args = (7004, ))
thread3.start()
thread1.join()
thread2.join()
thread3.join()
print("thread finished...exiting")
Output -
thread started 7000
thread started 7002
thread started 7004
avg 87.73813000000001
max 104.335
min 75.594
avg 87.86647999999992
max 110.966
min 71.124
avg 91.26289000000004
max 118.033
min 30.482
thread finished...exiting