redis / redis

Redis is an in-memory database that persists on disk. The data model is key-value, but many different kind of values are supported: Strings, Lists, Sets, Sorted Sets, Hashes, Streams, HyperLogLogs, Bitmaps.
http://redis.io
Other
66.82k stars 23.78k forks source link

[NEW] Add io_uring support to redis #9441

Open HanGuangyu opened 3 years ago

HanGuangyu commented 3 years ago

The problem/use-case that the io_uring addresses

The use of io_uring can improve the performance of redis on Linux compared to using epoll.

Description of the feature

io_uring is a powerful new asynchronous I/O API for Linux by Jens Axboe from Facebook. And it has been added to Linux kernel since 5.1 version. For more details about io_uring, we can see Lord of the io_uring.

Additional information

This work is a POC(Proof of Concept) cooperate by alibaba team of Anolis community and Uniontech Software Technology Co., Ltd. We have experimentally added io_uring support to redis and gotten good performance improvement in testes. If this work can be approved by the community, we will proceed.

The data of performance improvement as follows:

RPS(request per second) PING_INLINE PING_BULK SET GET INCR LPUSH RPUSH LPOP RPOP SADD HSET SPOP LPUSH(needed to benchmark LRANGE) LRANGE_100 LRANGE_300 LRANGE_500 LRANGE_600 MSET (10 keys)
redis_origin 55493.90 55224.21 55540.44 55549.07 55652.95 56640.22 56493.03 56379.64 56280.96 55788.94 56218.62 55697.90 56774.31 33953.20 15290.75 12066.89 9730.44 57729.39
redis_add_uring + close_sqpoll 73336.37 72344.24 72844.88 73514.27 73542.93 72688.68 73133.63 73871.06 72998.56 72183.41 72502.65 73361.65 72535.25 43849.07 18304.73 13540.14 10733.82 61616.95
redis_add_uring + open_sqpoll 86625.09 84141.09 86079.27 84939.39 85744.91 84075.30 85814.08 85478.12 85657.51 85462.05 85095.52 84509.42 84403.15 51821.53 18953.36 14276.23 11673.47 83557.55
improvement of close_sqpoll 32.15% 31.00% 31.16% 32.34% 32.15% 28.33% 29.46% 31.02% 29.70% 29.39% 28.97% 31.71% 27.76% 29.15% 19.71% 12.21% 10.31% 6.73%
improvement of open_sqpoll 56.10% 52.36% 54.98% 52.91% 54.07% 48.44% 51.90% 51.61% 52.20% 53.19% 51.37% 51.73% 48.66% 52.63% 23.95% 18.31% 19.97% 44.74%

The test environment is as follows: System: Anolis 8.4 [A down-stream of Centos 8] Kernel: Linux 4.19 + patch of io_uring Test Tool: redis-benchmark Test Command: redis-benchmark -c 500 -n 10000000(Both redis-server and redis-benchmark are bound fixed CPU cores)

For more details, you can see the poll request of #9440 .

3365261wang commented 3 years ago

Anolis 8.4 [A down-stream of Centos 8]?

Let's try it !

He-Jingkai commented 11 months ago

Hello!

I'm trying to use your redis (io_uring) project (https://github.com/HanGuangyu/redis/tree/feat/io_uring) and reproduced the evaluation results. However, when I evaluated the SET command, I found that when the value size is larger than or equal to 32k, the request execution will often get stuck, causing the test to fail. Mainline redis that does not use io_uring will not have this problem.

In order to make redis support io with larger size, I made the following modifications in src/server.h to expand the io buffer:

- #define PROTO_IOBUF_LEN (1024*16)
+ #define PROTO_IOBUF_LEN (1024*1024)

If you can help me solve this bug or provide some debugging suggestions, thank you very much!

I used the following script

./src/redis-benchmark -t set -d 32768 -c 1 -n 100 -p 6379

Update:

It's found that when the the message is fragmented into multiple TCP packets and sent, Redis using io_uring will only read the first TCP packet and ignore the subsequent ones.