Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate to github.com/rueian/rueidis #262

Merged
merged 53 commits into from
Nov 28, 2022
Merged

Migrate to github.com/rueian/rueidis #262

merged 53 commits into from
Nov 28, 2022

Conversation

FZambia
Copy link
Member

@FZambia FZambia commented Oct 13, 2022

An alternative approach to #235 + Sharded PUB/SUB support (relates #228). Relates #210.

@j178 hello, I was already working on replacing redigo to rueidis for some time before you opened #235, but rueidis did not support RESP2 till the v0.0.80 release (published today). So it seems a viable alternative to go-redis now.

This PR contains an approach to scale PUB/SUB in Redis Cluster using Rediis 7 sharded PUB/SUB feature. Probably it should be a separate pr - but just had it already... In sharded PUB/SUB case we split the key space of broker to configured NumClusterShards parts. Then we start separate PUB/SUB routines to work with each PUB/SUB shard. This means that instead of 16384 slots (usually used by Redis Cluster) we have NumClusterShards slots for all broker ops. This still limits scalability a bit (though I think sth like NumClusterShards == 16/32/64 is OK for many use cases) but otherwise we would require too many connections to deal with PUB/SUB for millions of channels. It's also worth noting that turning on NumClusterShards option to a value greater than zero will result into different keys to keep values in Redis than keys we have when not using sharded PUB/SUB.

I am personally biased towards rueidis at the moment, though still have not put enough effort into testing and comparing both implementations. I'll try to update this pr with comments as I proceed with some checks.

I also removed IdleTimeout and UseTLS options from Redis shard config as they do not match rueidis options (matched to redigo options currently). And added possibility to set ClientName

@tony-pang, hello - are you still interested in sharded PUB/SUB implementation?

@codecov
Copy link

codecov bot commented Oct 13, 2022

Codecov Report

Merging #262 (2b23f1d) into master (5335955) will increase coverage by 0.73%.
The diff coverage is 69.55%.

@@            Coverage Diff             @@
##           master     #262      +/-   ##
==========================================
+ Coverage   83.55%   84.29%   +0.73%     
==========================================
  Files          36       37       +1     
  Lines        8234     7876     -358     
==========================================
- Hits         6880     6639     -241     
+ Misses       1025      914     -111     
+ Partials      329      323       -6     
Impacted Files Coverage Δ
broker_redis.go 71.31% <67.70%> (-2.17%) ⬇️
presence_redis.go 71.55% <70.00%> (-4.04%) ⬇️
redis_shard.go 80.35% <90.69%> (+13.99%) ⬆️
internal/convert/convert_unsafe.go 100.00% <100.00%> (ø)
client.go 83.89% <0.00%> (-0.13%) ⬇️
handler_websocket.go 82.31% <0.00%> (+1.02%) ⬆️
internal/recovery/sync.go 84.74% <0.00%> (+8.47%) ⬆️

📣 We’re building smart automated test selection to slash your CI/CD build times. Learn more

@FZambia
Copy link
Member Author

FZambia commented Oct 14, 2022

Single instance Redis benchmarks (redigo vs rueidis):

❯ benchstat redigo.txt rueidis.txt
name                                old time/op    new time/op    delta
RedisExtractPushData-8                35.2ns ± 0%    35.7ns ± 0%    +1.54%  (p=0.008 n=5+5)
RedisSurvey/1_node_512B-8             1.11µs ± 1%    1.01µs ± 3%    -8.52%  (p=0.008 n=5+5)
RedisSurvey/2_nodes_512B-8            23.3µs ± 1%    27.8µs ± 0%   +19.59%  (p=0.008 n=5+5)
RedisSurvey/3_nodes_512B-8            28.8µs ± 1%    28.8µs ± 0%      ~     (p=1.000 n=5+5)
RedisSurvey/4_nodes_512B-8            36.9µs ± 6%    33.2µs ± 2%   -10.18%  (p=0.008 n=5+5)
RedisSurvey/5_nodes_512B-8            43.3µs ± 5%    39.1µs ±14%      ~     (p=0.056 n=5+5)
RedisSurvey/10_nodes_512B-8           79.3µs ± 4%    78.0µs ± 8%      ~     (p=0.643 n=5+5)
RedisSurvey/100_nodes_512B-8           763µs ± 5%     733µs ± 7%      ~     (p=0.310 n=5+5)
RedisSurvey/1_node_4096B-8            1.19µs ± 0%    1.10µs ± 1%    -7.04%  (p=0.008 n=5+5)
RedisSurvey/2_nodes_4096B-8           28.5µs ± 1%    30.3µs ± 1%    +6.12%  (p=0.008 n=5+5)
RedisSurvey/3_nodes_4096B-8           41.6µs ± 2%    35.5µs ± 3%   -14.56%  (p=0.008 n=5+5)
RedisSurvey/4_nodes_4096B-8           53.8µs ± 5%    42.6µs ± 5%   -20.95%  (p=0.008 n=5+5)
RedisSurvey/5_nodes_4096B-8           64.9µs ± 4%    52.4µs ± 6%   -19.24%  (p=0.008 n=5+5)
RedisSurvey/10_nodes_4096B-8           128µs ± 6%     108µs ± 6%   -15.43%  (p=0.008 n=5+5)
RedisSurvey/100_nodes_4096B-8         1.59ms ± 6%    1.19ms ± 4%   -24.80%  (p=0.008 n=5+5)
RedisConsistentIndex-8                46.7ns ± 1%    47.0ns ± 0%      ~     (p=0.151 n=5+5)
RedisIndex-8                          26.3ns ± 0%    26.5ns ± 1%    +1.04%  (p=0.032 n=5+5)
RedisPublish_1Ch/lists-8              3.02µs ± 3%    0.74µs ± 4%   -75.48%  (p=0.008 n=5+5)
RedisPublish_1Ch/streams-8            2.94µs ± 1%    0.76µs ± 4%   -74.02%  (p=0.008 n=5+5)
RedisPublish_ManyCh/lists-8           2.99µs ± 1%    0.80µs ± 1%   -73.42%  (p=0.016 n=4+5)
RedisPublish_ManyCh/streams-8         3.01µs ± 3%    0.81µs ± 0%   -73.21%  (p=0.008 n=5+5)
RedisPublish_History_1Ch/lists-8      12.4µs ± 1%     8.2µs ± 1%   -33.86%  (p=0.008 n=5+5)
RedisPublish_History_1Ch/streams-8    13.9µs ± 1%    10.2µs ± 4%   -26.72%  (p=0.008 n=5+5)
RedisPub_History_ManyCh/lists-8       12.9µs ± 3%     9.5µs ± 3%   -26.33%  (p=0.008 n=5+5)
RedisPub_History_ManyCh/streams-8     13.3µs ± 3%     9.8µs ± 1%   -26.65%  (p=0.008 n=5+5)
RedisSubscribe/non_cluster-8          2.37µs ± 3%    3.62µs ±27%   +52.65%  (p=0.008 n=5+5)
RedisHistory_1Ch/lists-8              12.1µs ± 5%     9.6µs ± 1%   -20.79%  (p=0.008 n=5+5)
RedisHistory_1Ch/streams-8            39.3µs ±12%    29.8µs ± 1%   -24.11%  (p=0.008 n=5+5)
RedisRecover_1Ch/lists-8               259µs ± 2%     211µs ± 4%   -18.47%  (p=0.008 n=5+5)
RedisRecover_1Ch/streams-8            51.1µs ±11%    37.3µs ± 1%   -27.07%  (p=0.008 n=5+5)
RedisHistoryIteration/lists-8          377ms ± 1%     343ms ± 0%    -9.19%  (p=0.008 n=5+5)
RedisHistoryIteration/streams-8       52.4ms ± 1%    55.6ms ± 1%    +6.06%  (p=0.008 n=5+5)
RedisAddPresence_1Ch/lists-8          4.75µs ± 0%    3.88µs ± 0%   -18.43%  (p=0.008 n=5+5)
RedisAddPresence_1Ch/streams-8        4.78µs ± 2%    3.91µs ± 2%   -18.06%  (p=0.008 n=5+5)
RedisPresence_1Ch/lists-8             5.60µs ± 1%    4.92µs ± 2%   -12.07%  (p=0.008 n=5+5)
RedisPresence_1Ch/streams-8           5.54µs ± 0%    4.99µs ± 1%    -9.89%  (p=0.008 n=5+5)
RedisPresence_ManyCh/lists-8          5.11µs ± 1%    5.38µs ± 1%    +5.21%  (p=0.008 n=5+5)
RedisPresence_ManyCh/streams-8        5.11µs ± 0%    5.46µs ± 1%    +6.81%  (p=0.008 n=5+5)

name                                old alloc/op   new alloc/op   delta
RedisExtractPushData-8                 16.0B ± 0%     16.0B ± 0%      ~     (all equal)
RedisSurvey/1_node_512B-8             1.14kB ± 0%    1.14kB ± 0%      ~     (all equal)
RedisSurvey/2_nodes_512B-8            7.41kB ± 0%    7.58kB ± 0%    +2.24%  (p=0.016 n=5+4)
RedisSurvey/3_nodes_512B-8            12.5kB ± 0%    13.2kB ± 0%    +5.46%  (p=0.008 n=5+5)
RedisSurvey/4_nodes_512B-8            17.6kB ± 0%    18.7kB ± 0%    +6.81%  (p=0.008 n=5+5)
RedisSurvey/5_nodes_512B-8            22.6kB ± 0%    24.3kB ± 0%    +7.56%  (p=0.016 n=5+4)
RedisSurvey/10_nodes_512B-8           48.9kB ± 0%    53.2kB ± 0%    +8.76%  (p=0.008 n=5+5)
RedisSurvey/100_nodes_512B-8           525kB ± 0%     570kB ± 0%    +8.67%  (p=0.008 n=5+5)
RedisSurvey/1_node_4096B-8            1.15kB ± 0%    1.15kB ± 0%      ~     (p=1.000 n=5+5)
RedisSurvey/2_nodes_4096B-8           28.2kB ± 0%    36.9kB ± 0%   +31.00%  (p=0.008 n=5+5)
RedisSurvey/3_nodes_4096B-8           54.0kB ± 0%    71.8kB ± 0%   +32.88%  (p=0.016 n=5+4)
RedisSurvey/4_nodes_4096B-8           79.8kB ± 0%   106.8kB ± 0%   +33.74%  (p=0.008 n=5+5)
RedisSurvey/5_nodes_4096B-8            106kB ± 0%     142kB ± 0%   +34.14%  (p=0.016 n=4+5)
RedisSurvey/10_nodes_4096B-8           237kB ± 1%     318kB ± 1%   +34.40%  (p=0.008 n=5+5)
RedisSurvey/100_nodes_4096B-8         2.58MB ± 0%    3.47MB ± 0%   +34.48%  (p=0.008 n=5+5)
RedisConsistentIndex-8                 8.00B ± 0%     8.00B ± 0%      ~     (all equal)
RedisIndex-8                           8.00B ± 0%     8.00B ± 0%      ~     (all equal)
RedisPublish_1Ch/lists-8                489B ± 1%      193B ± 1%   -60.47%  (p=0.008 n=5+5)
RedisPublish_1Ch/streams-8              490B ± 1%      205B ± 7%   -58.14%  (p=0.008 n=5+5)
RedisPublish_ManyCh/lists-8             496B ± 1%      200B ± 3%   -59.74%  (p=0.008 n=5+5)
RedisPublish_ManyCh/streams-8           514B ±16%      202B ± 3%   -60.75%  (p=0.008 n=5+5)
RedisPublish_History_1Ch/lists-8      1.54kB ±12%    0.59kB ± 2%   -61.66%  (p=0.008 n=5+5)
RedisPublish_History_1Ch/streams-8    1.66kB ±11%    0.61kB ± 2%   -63.42%  (p=0.008 n=5+5)
RedisPub_History_ManyCh/lists-8       1.53kB ±21%    0.65kB ± 3%   -57.73%  (p=0.008 n=5+5)
RedisPub_History_ManyCh/streams-8     1.32kB ± 0%    0.72kB ±19%   -45.31%  (p=0.008 n=5+5)
RedisSubscribe/non_cluster-8          1.26kB ± 0%    1.22kB ± 7%      ~     (p=0.651 n=5+5)
RedisHistory_1Ch/lists-8              1.70kB ± 1%    1.35kB ±14%   -20.46%  (p=0.008 n=5+5)
RedisHistory_1Ch/streams-8            2.56kB ± 2%    4.04kB ± 8%   +58.08%  (p=0.008 n=5+5)
RedisRecover_1Ch/lists-8               166kB ± 3%     198kB ± 0%   +19.76%  (p=0.008 n=5+5)
RedisRecover_1Ch/streams-8            3.76kB ±10%    4.36kB ± 1%   +16.01%  (p=0.008 n=5+5)
RedisHistoryIteration/lists-8          163MB ± 0%     210MB ± 3%   +28.84%  (p=0.008 n=5+5)
RedisHistoryIteration/streams-8       3.21MB ± 2%    8.30MB ± 9%  +158.97%  (p=0.008 n=5+5)
RedisAddPresence_1Ch/lists-8            926B ± 1%      228B ±31%   -75.37%  (p=0.008 n=5+5)
RedisAddPresence_1Ch/streams-8        1.01kB ± 9%    0.17kB ±18%   -82.91%  (p=0.008 n=5+5)
RedisPresence_1Ch/lists-8             1.33kB ± 7%    0.79kB ± 2%   -40.20%  (p=0.008 n=5+5)
RedisPresence_1Ch/streams-8           1.33kB ± 4%    0.82kB ±14%   -38.54%  (p=0.008 n=5+5)
RedisPresence_ManyCh/lists-8            894B ± 1%      493B ±16%   -44.90%  (p=0.016 n=4+5)
RedisPresence_ManyCh/streams-8          894B ± 1%      511B ±13%   -42.89%  (p=0.008 n=5+5)

name                                old allocs/op  new allocs/op  delta
RedisExtractPushData-8                  1.00 ± 0%      1.00 ± 0%      ~     (all equal)
RedisSurvey/1_node_512B-8               15.0 ± 0%      15.0 ± 0%      ~     (all equal)
RedisSurvey/2_nodes_512B-8              91.0 ± 0%      56.0 ± 0%   -38.46%  (p=0.008 n=5+5)
RedisSurvey/3_nodes_512B-8               142 ± 0%        85 ± 0%   -39.97%  (p=0.008 n=5+5)
RedisSurvey/4_nodes_512B-8               192 ± 0%       114 ± 0%   -40.62%  (p=0.008 n=5+5)
RedisSurvey/5_nodes_512B-8               242 ± 0%       143 ± 0%   -40.91%  (p=0.008 n=5+5)
RedisSurvey/10_nodes_512B-8              495 ± 0%       289 ± 0%   -41.62%  (p=0.008 n=5+5)
RedisSurvey/100_nodes_512B-8           5.18k ± 0%     2.91k ± 0%   -43.83%  (p=0.008 n=5+5)
RedisSurvey/1_node_4096B-8              15.0 ± 0%      15.0 ± 0%      ~     (all equal)
RedisSurvey/2_nodes_4096B-8             92.0 ± 0%      56.0 ± 0%   -39.13%  (p=0.008 n=5+5)
RedisSurvey/3_nodes_4096B-8              143 ± 0%        85 ± 0%   -40.56%  (p=0.008 n=5+5)
RedisSurvey/4_nodes_4096B-8              193 ± 0%       114 ± 0%   -40.93%  (p=0.029 n=4+4)
RedisSurvey/5_nodes_4096B-8              245 ± 1%       147 ± 3%   -40.08%  (p=0.016 n=4+5)
RedisSurvey/10_nodes_4096B-8             512 ± 5%       305 ±13%   -40.48%  (p=0.008 n=5+5)
RedisSurvey/100_nodes_4096B-8          5.37k ± 1%     2.94k ± 0%   -45.34%  (p=0.008 n=5+5)
RedisConsistentIndex-8                  1.00 ± 0%      1.00 ± 0%      ~     (all equal)
RedisIndex-8                            1.00 ± 0%      1.00 ± 0%      ~     (all equal)
RedisPublish_1Ch/lists-8                9.00 ± 0%      4.00 ± 0%   -55.56%  (p=0.008 n=5+5)
RedisPublish_1Ch/streams-8              9.00 ± 0%      4.00 ± 0%   -55.56%  (p=0.008 n=5+5)
RedisPublish_ManyCh/lists-8             10.0 ± 0%       4.0 ± 0%   -60.00%  (p=0.000 n=5+4)
RedisPublish_ManyCh/streams-8           10.0 ±10%       4.4 ±14%   -56.00%  (p=0.008 n=5+5)
RedisPublish_History_1Ch/lists-8        31.4 ± 8%      12.0 ± 0%   -61.78%  (p=0.008 n=5+5)
RedisPublish_History_1Ch/streams-8      33.0 ± 6%      13.0 ± 0%   -60.61%  (p=0.008 n=5+5)
RedisPub_History_ManyCh/lists-8         31.4 ±11%      13.0 ± 0%   -58.60%  (p=0.008 n=5+5)
RedisPub_History_ManyCh/streams-8       29.0 ± 0%      15.0 ±13%   -48.28%  (p=0.008 n=5+5)
RedisSubscribe/non_cluster-8            25.0 ± 0%      13.6 ± 4%   -45.60%  (p=0.008 n=5+5)
RedisHistory_1Ch/lists-8                49.0 ± 0%      31.0 ± 6%   -36.73%  (p=0.008 n=5+5)
RedisHistory_1Ch/streams-8              84.0 ± 1%      55.4 ± 8%   -34.05%  (p=0.008 n=5+5)
RedisRecover_1Ch/lists-8               5.10k ± 1%     4.02k ± 0%   -21.08%  (p=0.008 n=5+5)
RedisRecover_1Ch/streams-8               109 ± 4%        59 ± 2%   -46.07%  (p=0.008 n=5+5)
RedisHistoryIteration/lists-8          5.07M ± 0%     4.10M ± 2%   -19.07%  (p=0.008 n=5+5)
RedisHistoryIteration/streams-8         136k ± 1%      103k ± 9%   -24.38%  (p=0.008 n=5+5)
RedisAddPresence_1Ch/lists-8            18.0 ± 0%       3.6 ±17%   -80.00%  (p=0.008 n=5+5)
RedisAddPresence_1Ch/streams-8          19.2 ± 6%       3.0 ± 0%   -84.38%  (p=0.008 n=5+5)
RedisPresence_1Ch/lists-8               26.0 ± 4%      10.0 ± 0%   -61.54%  (p=0.008 n=5+5)
RedisPresence_1Ch/streams-8             26.0 ± 4%      10.0 ± 0%   -61.54%  (p=0.016 n=5+4)
RedisPresence_ManyCh/lists-8            19.0 ± 0%       7.8 ±15%   -58.95%  (p=0.016 n=4+5)
RedisPresence_ManyCh/streams-8          19.0 ± 0%       7.8 ±15%   -58.95%  (p=0.008 n=5+5)

@FZambia
Copy link
Member Author

FZambia commented Oct 14, 2022

The same (single Redis) with some optimizations from latest commit:

❯ benchstat redigo.txt rueidis3.txt
name                                old time/op    new time/op    delta
RedisExtractPushData-8                35.2ns ± 0%    30.4ns ± 0%   -13.48%  (p=0.008 n=5+5)
RedisSurvey/1_node_512B-8             1.11µs ± 1%    1.08µs ± 3%    -2.42%  (p=0.016 n=5+5)
RedisSurvey/2_nodes_512B-8            23.3µs ± 1%    28.2µs ± 0%   +21.22%  (p=0.008 n=5+5)
RedisSurvey/3_nodes_512B-8            28.8µs ± 1%    31.7µs ± 2%    +9.87%  (p=0.008 n=5+5)
RedisSurvey/4_nodes_512B-8            36.9µs ± 6%    39.4µs ± 1%    +6.77%  (p=0.016 n=5+4)
RedisSurvey/5_nodes_512B-8            43.3µs ± 5%    44.0µs ± 5%      ~     (p=0.690 n=5+5)
RedisSurvey/10_nodes_512B-8           79.3µs ± 4%    81.9µs ± 6%      ~     (p=0.135 n=5+5)
RedisSurvey/100_nodes_512B-8           763µs ± 5%     791µs ± 3%      ~     (p=0.151 n=5+5)
RedisSurvey/1_node_4096B-8            1.19µs ± 0%    1.17µs ± 1%      ~     (p=0.063 n=5+5)
RedisSurvey/2_nodes_4096B-8           28.5µs ± 1%    31.5µs ± 3%   +10.42%  (p=0.008 n=5+5)
RedisSurvey/3_nodes_4096B-8           41.6µs ± 2%    36.4µs ± 2%   -12.55%  (p=0.008 n=5+5)
RedisSurvey/4_nodes_4096B-8           53.8µs ± 5%    44.0µs ± 5%   -18.24%  (p=0.008 n=5+5)
RedisSurvey/5_nodes_4096B-8           64.9µs ± 4%    51.6µs ± 4%   -20.58%  (p=0.008 n=5+5)
RedisSurvey/10_nodes_4096B-8           128µs ± 6%     105µs ± 7%   -17.96%  (p=0.008 n=5+5)
RedisSurvey/100_nodes_4096B-8         1.59ms ± 6%    1.20ms ± 9%   -24.47%  (p=0.008 n=5+5)
RedisConsistentIndex-8                46.7ns ± 1%    46.8ns ± 1%      ~     (p=0.889 n=5+5)
RedisIndex-8                          26.3ns ± 0%    26.7ns ± 1%    +1.83%  (p=0.008 n=5+5)
RedisPublish_1Ch/lists-8              3.02µs ± 3%    0.82µs ± 8%   -72.97%  (p=0.008 n=5+5)
RedisPublish_1Ch/streams-8            2.94µs ± 1%    0.82µs ± 8%   -72.15%  (p=0.008 n=5+5)
RedisPublish_ManyCh/lists-8           2.99µs ± 1%    0.84µs ± 4%   -71.94%  (p=0.016 n=4+5)
RedisPublish_ManyCh/streams-8         3.01µs ± 3%    0.83µs ± 0%   -72.25%  (p=0.016 n=5+4)
RedisPublish_History_1Ch/lists-8      12.4µs ± 1%     8.1µs ± 1%   -34.54%  (p=0.008 n=5+5)
RedisPublish_History_1Ch/streams-8    13.9µs ± 1%     9.9µs ± 1%   -28.43%  (p=0.008 n=5+5)
RedisPub_History_ManyCh/lists-8       12.9µs ± 3%     9.4µs ± 2%   -27.41%  (p=0.008 n=5+5)
RedisPub_History_ManyCh/streams-8     13.3µs ± 3%     9.8µs ± 3%   -26.60%  (p=0.008 n=5+5)
RedisSubscribe/non_cluster-8          2.37µs ± 3%    2.66µs ±18%      ~     (p=0.310 n=5+5)
RedisHistory_1Ch/lists-8              12.1µs ± 5%     9.9µs ± 3%   -18.14%  (p=0.008 n=5+5)
RedisHistory_1Ch/streams-8            39.3µs ±12%    31.9µs ± 4%   -19.00%  (p=0.008 n=5+5)
RedisRecover_1Ch/lists-8               259µs ± 2%     203µs ± 3%   -21.52%  (p=0.008 n=5+5)
RedisRecover_1Ch/streams-8            51.1µs ±11%    39.4µs ± 1%   -22.94%  (p=0.008 n=5+5)
RedisHistoryIteration/lists-8          377ms ± 1%     317ms ± 1%   -16.04%  (p=0.008 n=5+5)
RedisHistoryIteration/streams-8       52.4ms ± 1%    54.9ms ± 1%    +4.77%  (p=0.008 n=5+5)
RedisAddPresence_1Ch/lists-8          4.75µs ± 0%    3.99µs ± 3%   -16.10%  (p=0.008 n=5+5)
RedisAddPresence_1Ch/streams-8        4.78µs ± 2%    4.16µs ± 1%   -12.94%  (p=0.008 n=5+5)
RedisPresence_1Ch/lists-8             5.60µs ± 1%    5.53µs ± 1%    -1.30%  (p=0.008 n=5+5)
RedisPresence_1Ch/streams-8           5.54µs ± 0%    5.58µs ± 1%      ~     (p=0.222 n=5+5)
RedisPresence_ManyCh/lists-8          5.11µs ± 1%    5.82µs ± 1%   +13.92%  (p=0.008 n=5+5)
RedisPresence_ManyCh/streams-8        5.11µs ± 0%    5.87µs ± 2%   +14.84%  (p=0.008 n=5+5)

name                                old alloc/op   new alloc/op   delta
RedisExtractPushData-8                 16.0B ± 0%      0.0B       -100.00%  (p=0.008 n=5+5)
RedisSurvey/1_node_512B-8             1.14kB ± 0%    1.14kB ± 0%      ~     (all equal)
RedisSurvey/2_nodes_512B-8            7.41kB ± 0%    6.23kB ± 0%   -15.90%  (p=0.000 n=5+4)
RedisSurvey/3_nodes_512B-8            12.5kB ± 0%    10.6kB ± 0%   -15.05%  (p=0.008 n=5+5)
RedisSurvey/4_nodes_512B-8            17.6kB ± 0%    15.0kB ± 0%   -14.71%  (p=0.016 n=5+4)
RedisSurvey/5_nodes_512B-8            22.6kB ± 0%    19.3kB ± 0%   -14.50%  (p=0.008 n=5+5)
RedisSurvey/10_nodes_512B-8           48.9kB ± 0%    42.1kB ± 0%   -13.88%  (p=0.008 n=5+5)
RedisSurvey/100_nodes_512B-8           525kB ± 0%     450kB ± 0%   -14.30%  (p=0.008 n=5+5)
RedisSurvey/1_node_4096B-8            1.15kB ± 0%    1.15kB ± 0%      ~     (p=1.000 n=5+4)
RedisSurvey/2_nodes_4096B-8           28.2kB ± 0%    27.0kB ± 0%    -4.29%  (p=0.008 n=5+5)
RedisSurvey/3_nodes_4096B-8           54.0kB ± 0%    52.1kB ± 0%    -3.59%  (p=0.008 n=5+5)
RedisSurvey/4_nodes_4096B-8           79.8kB ± 0%    77.2kB ± 0%    -3.25%  (p=0.016 n=5+4)
RedisSurvey/5_nodes_4096B-8            106kB ± 0%     103kB ± 1%    -2.92%  (p=0.016 n=4+5)
RedisSurvey/10_nodes_4096B-8           237kB ± 1%     230kB ± 0%    -2.76%  (p=0.008 n=5+5)
RedisSurvey/100_nodes_4096B-8         2.58MB ± 0%    2.50MB ± 0%    -3.08%  (p=0.016 n=5+4)
RedisConsistentIndex-8                 8.00B ± 0%     8.00B ± 0%      ~     (all equal)
RedisIndex-8                           8.00B ± 0%     8.00B ± 0%      ~     (all equal)
RedisPublish_1Ch/lists-8                489B ± 1%      194B ± 0%   -60.43%  (p=0.008 n=5+5)
RedisPublish_1Ch/streams-8              490B ± 1%      194B ± 1%   -60.42%  (p=0.016 n=5+4)
RedisPublish_ManyCh/lists-8             496B ± 1%      212B ± 8%   -57.32%  (p=0.008 n=5+5)
RedisPublish_ManyCh/streams-8           514B ±16%      214B ± 8%   -58.33%  (p=0.008 n=5+5)
RedisPublish_History_1Ch/lists-8      1.54kB ±12%    0.57kB ± 2%   -63.15%  (p=0.008 n=5+5)
RedisPublish_History_1Ch/streams-8    1.66kB ±11%    0.58kB ± 2%   -65.08%  (p=0.008 n=5+5)
RedisPub_History_ManyCh/lists-8       1.53kB ±21%    0.61kB ± 3%   -60.29%  (p=0.008 n=5+5)
RedisPub_History_ManyCh/streams-8     1.32kB ± 0%    0.62kB ± 3%   -53.11%  (p=0.008 n=5+5)
RedisSubscribe/non_cluster-8          1.26kB ± 0%    1.20kB ± 3%    -5.38%  (p=0.008 n=5+5)
RedisHistory_1Ch/lists-8              1.70kB ± 1%    1.36kB ±10%   -19.90%  (p=0.008 n=5+5)
RedisHistory_1Ch/streams-8            2.56kB ± 2%    4.02kB ±16%   +57.22%  (p=0.008 n=5+5)
RedisRecover_1Ch/lists-8               166kB ± 3%     175kB ± 0%    +5.66%  (p=0.008 n=5+5)
RedisRecover_1Ch/streams-8            3.76kB ±10%    4.47kB ± 2%   +18.84%  (p=0.008 n=5+5)
RedisHistoryIteration/lists-8          163MB ± 0%     188MB ± 3%   +15.29%  (p=0.008 n=5+5)
RedisHistoryIteration/streams-8       3.21MB ± 2%    8.41MB ±10%  +162.40%  (p=0.008 n=5+5)
RedisAddPresence_1Ch/lists-8            926B ± 1%      154B ± 3%   -83.38%  (p=0.008 n=5+5)
RedisAddPresence_1Ch/streams-8        1.01kB ± 9%    0.17kB ± 4%   -83.62%  (p=0.008 n=5+5)
RedisPresence_1Ch/lists-8             1.33kB ± 7%    0.80kB ± 2%   -39.87%  (p=0.008 n=5+5)
RedisPresence_1Ch/streams-8           1.33kB ± 4%    0.87kB ±10%   -34.91%  (p=0.008 n=5+5)
RedisPresence_ManyCh/lists-8            894B ± 1%      496B ±18%   -44.54%  (p=0.016 n=4+5)
RedisPresence_ManyCh/streams-8          894B ± 1%      401B ± 3%   -55.17%  (p=0.000 n=5+4)

name                                old allocs/op  new allocs/op  delta
RedisExtractPushData-8                  1.00 ± 0%      0.00       -100.00%  (p=0.008 n=5+5)
RedisSurvey/1_node_512B-8               15.0 ± 0%      15.0 ± 0%      ~     (all equal)
RedisSurvey/2_nodes_512B-8              91.0 ± 0%      51.0 ± 0%   -43.96%  (p=0.008 n=5+5)
RedisSurvey/3_nodes_512B-8               142 ± 0%        77 ± 0%   -45.62%  (p=0.008 n=5+5)
RedisSurvey/4_nodes_512B-8               192 ± 0%       103 ± 0%   -46.35%  (p=0.008 n=5+5)
RedisSurvey/5_nodes_512B-8               242 ± 0%       129 ± 0%   -46.69%  (p=0.008 n=5+5)
RedisSurvey/10_nodes_512B-8              495 ± 0%       260 ± 0%   -47.47%  (p=0.008 n=5+5)
RedisSurvey/100_nodes_512B-8           5.18k ± 0%     2.61k ± 0%   -49.60%  (p=0.008 n=5+5)
RedisSurvey/1_node_4096B-8              15.0 ± 0%      15.0 ± 0%      ~     (all equal)
RedisSurvey/2_nodes_4096B-8             92.0 ± 0%      51.0 ± 0%   -44.57%  (p=0.008 n=5+5)
RedisSurvey/3_nodes_4096B-8              143 ± 0%        77 ± 0%   -46.15%  (p=0.008 n=5+5)
RedisSurvey/4_nodes_4096B-8              193 ± 0%       103 ± 0%   -46.63%  (p=0.029 n=4+4)
RedisSurvey/5_nodes_4096B-8              245 ± 1%       134 ± 5%   -45.39%  (p=0.016 n=4+5)
RedisSurvey/10_nodes_4096B-8             512 ± 5%       278 ± 1%   -45.64%  (p=0.008 n=5+5)
RedisSurvey/100_nodes_4096B-8          5.37k ± 1%     2.63k ± 0%   -51.06%  (p=0.008 n=5+5)
RedisConsistentIndex-8                  1.00 ± 0%      1.00 ± 0%      ~     (all equal)
RedisIndex-8                            1.00 ± 0%      1.00 ± 0%      ~     (all equal)
RedisPublish_1Ch/lists-8                9.00 ± 0%      4.00 ± 0%   -55.56%  (p=0.008 n=5+5)
RedisPublish_1Ch/streams-8              9.00 ± 0%      4.00 ± 0%   -55.56%  (p=0.008 n=5+5)
RedisPublish_ManyCh/lists-8             10.0 ± 0%       4.6 ±13%   -54.00%  (p=0.008 n=5+5)
RedisPublish_ManyCh/streams-8           10.0 ±10%       5.0 ± 0%   -50.00%  (p=0.016 n=5+4)
RedisPublish_History_1Ch/lists-8        31.4 ± 8%      11.0 ± 0%   -64.97%  (p=0.008 n=5+5)
RedisPublish_History_1Ch/streams-8      33.0 ± 6%      12.0 ± 0%   -63.64%  (p=0.008 n=5+5)
RedisPub_History_ManyCh/lists-8         31.4 ±11%      12.0 ± 0%   -61.78%  (p=0.008 n=5+5)
RedisPub_History_ManyCh/streams-8       29.0 ± 0%      13.0 ± 0%   -55.17%  (p=0.008 n=5+5)
RedisSubscribe/non_cluster-8            25.0 ± 0%      13.0 ± 0%   -48.00%  (p=0.008 n=5+5)
RedisHistory_1Ch/lists-8                49.0 ± 0%      27.8 ± 8%   -43.27%  (p=0.008 n=5+5)
RedisHistory_1Ch/streams-8              84.0 ± 1%      55.0 ±15%   -34.52%  (p=0.008 n=5+5)
RedisRecover_1Ch/lists-8               5.10k ± 1%     3.02k ± 0%   -40.72%  (p=0.008 n=5+5)
RedisRecover_1Ch/streams-8               109 ± 4%        60 ± 2%   -44.79%  (p=0.008 n=5+5)
RedisHistoryIteration/lists-8          5.07M ± 0%     3.12M ± 2%   -38.50%  (p=0.008 n=5+5)
RedisHistoryIteration/streams-8         136k ± 1%      104k ±10%   -23.38%  (p=0.008 n=5+5)
RedisAddPresence_1Ch/lists-8            18.0 ± 0%       3.0 ± 0%   -83.33%  (p=0.008 n=5+5)
RedisAddPresence_1Ch/streams-8          19.2 ± 6%       3.0 ± 0%   -84.38%  (p=0.008 n=5+5)
RedisPresence_1Ch/lists-8               26.0 ± 4%      10.0 ± 0%   -61.54%  (p=0.008 n=5+5)
RedisPresence_1Ch/streams-8             26.0 ± 4%      10.8 ±11%   -58.46%  (p=0.008 n=5+5)
RedisPresence_ManyCh/lists-8            19.0 ± 0%       8.0 ±12%   -57.89%  (p=0.000 n=4+5)
RedisPresence_ManyCh/streams-8          19.0 ± 0%       7.0 ± 0%   -63.16%  (p=0.000 n=5+4)

@FZambia
Copy link
Member Author

FZambia commented Oct 14, 2022

Redis Cluster benchmarks (redigo vs rueidis). (some missing as bench run timed out)

name                                        old time/op    new time/op    delta
RedisSurvey/1_node_512B_cluster-8             1.10µs ± 1%    1.05µs ± 1%    -4.28%  (p=0.008 n=5+5)
RedisSurvey/2_nodes_512B_cluster-8            23.8µs ± 0%    28.4µs ± 2%   +19.16%  (p=0.016 n=4+5)
RedisSurvey/3_nodes_512B_cluster-8            30.2µs ± 3%    29.3µs ± 0%      ~     (p=0.063 n=5+4)
RedisSurvey/4_nodes_512B_cluster-8            38.9µs ± 8%    33.6µs ± 3%   -13.54%  (p=0.016 n=4+5)
RedisSurvey/5_nodes_512B_cluster-8            45.3µs ± 7%    40.4µs ± 3%   -10.76%  (p=0.008 n=5+5)
RedisSurvey/10_nodes_512B_cluster-8           88.2µs ± 5%    76.1µs ± 7%   -13.78%  (p=0.008 n=5+5)
RedisSurvey/100_nodes_512B_cluster-8           837µs ± 2%     775µs ± 6%    -7.47%  (p=0.016 n=4+5)
RedisSurvey/1_node_4096B_cluster-8            1.20µs ± 1%    1.22µs ± 0%    +1.70%  (p=0.016 n=5+5)
RedisSurvey/2_nodes_4096B_cluster-8           29.5µs ± 2%    32.5µs ± 3%   +10.27%  (p=0.008 n=5+5)
RedisSurvey/3_nodes_4096B_cluster-8           44.6µs ± 8%    39.6µs ± 7%   -11.33%  (p=0.008 n=5+5)
RedisSurvey/4_nodes_4096B_cluster-8           56.0µs ± 3%    48.4µs ± 5%   -13.66%  (p=0.008 n=5+5)
RedisSurvey/5_nodes_4096B_cluster-8           67.9µs ± 5%    59.8µs ± 4%   -11.94%  (p=0.008 n=5+5)
RedisSurvey/10_nodes_4096B_cluster-8           132µs ± 4%     111µs ± 9%   -16.20%  (p=0.008 n=5+5)
RedisSurvey/100_nodes_4096B_cluster-8         1.69ms ± 4%    1.16ms ± 4%   -31.34%  (p=0.008 n=5+5)
RedisPublish_1Ch/lists_cluster-8              3.64µs ± 7%    2.74µs ± 3%   -24.70%  (p=0.008 n=5+5)
RedisPublish_1Ch/streams_cluster-8            3.67µs ± 3%    2.82µs ± 6%   -23.04%  (p=0.008 n=5+5)
RedisPublish_ManyCh/lists_cluster-8           3.90µs ± 3%    2.89µs ± 3%   -25.98%  (p=0.008 n=5+5)
RedisPublish_ManyCh/streams_cluster-8         3.91µs ± 3%    2.98µs ± 1%   -23.93%  (p=0.008 n=5+5)
RedisPublish_History_1Ch/lists_cluster-8      13.3µs ± 5%    10.0µs ± 2%   -24.40%  (p=0.008 n=5+5)
RedisPublish_History_1Ch/streams_cluster-8    15.1µs ± 5%    11.5µs ± 1%   -23.37%  (p=0.008 n=5+5)
RedisPub_History_ManyCh/lists_cluster-8       10.7µs ± 8%     7.5µs ± 2%   -29.63%  (p=0.008 n=5+5)
RedisPub_History_ManyCh/streams_cluster-8     11.1µs ± 6%     7.7µs ± 2%   -30.80%  (p=0.008 n=5+5)
RedisSubscribe/with_cluster-8                 2.58µs ± 6%    2.60µs ±17%      ~     (p=0.889 n=5+5)
RedisHistory_1Ch/lists_cluster-8              13.0µs ± 6%    10.2µs ± 2%   -21.45%  (p=0.008 n=5+5)
RedisHistory_1Ch/streams_cluster-8            32.0µs ± 3%    31.7µs ± 2%      ~     (p=0.548 n=5+5)
RedisRecover_1Ch/lists_cluster-8               206µs ± 4%     210µs ± 3%      ~     (p=0.151 n=5+5)
RedisRecover_1Ch/streams_cluster-8            38.5µs ± 1%    38.7µs ± 1%      ~     (p=0.151 n=5+5)
RedisHistoryIteration/lists_cluster-8          372ms ± 2%     320ms ± 1%   -13.90%  (p=0.008 n=5+5)
RedisHistoryIteration/streams_cluster-8       52.3ms ± 1%    59.3ms ± 0%   +13.27%  (p=0.008 n=5+5)
RedisAddPresence_1Ch/lists_cluster-8          8.52µs ± 6%    4.55µs ± 0%   -46.58%  (p=0.008 n=5+5)
RedisAddPresence_1Ch/streams_cluster-8        8.93µs ± 8%    4.57µs ± 0%   -48.81%  (p=0.008 n=5+5)
RedisPresence_1Ch/lists_cluster-8             9.13µs ± 4%    5.66µs ± 2%   -37.98%  (p=0.008 n=5+5)
RedisPresence_1Ch/streams_cluster-8           9.04µs ± 8%    5.89µs ± 3%   -34.89%  (p=0.008 n=5+5)
RedisPresence_ManyCh/lists_cluster-8          7.39µs ± 7%    4.13µs ± 4%   -44.11%  (p=0.008 n=5+5)

name                                        old alloc/op   new alloc/op   delta
RedisSurvey/1_node_512B_cluster-8             1.14kB ± 0%    1.14kB ± 0%      ~     (all equal)
RedisSurvey/2_nodes_512B_cluster-8            7.41kB ± 0%    6.23kB ± 0%   -15.89%  (p=0.008 n=5+5)
RedisSurvey/3_nodes_512B_cluster-8            12.5kB ± 0%    10.6kB ± 0%   -15.06%  (p=0.008 n=5+5)
RedisSurvey/4_nodes_512B_cluster-8            17.6kB ± 0%    15.0kB ± 0%   -14.70%  (p=0.000 n=4+5)
RedisSurvey/5_nodes_512B_cluster-8            22.6kB ± 0%    19.3kB ± 0%   -14.51%  (p=0.008 n=5+5)
RedisSurvey/10_nodes_512B_cluster-8           48.9kB ± 0%    42.1kB ± 0%   -13.90%  (p=0.008 n=5+5)
RedisSurvey/100_nodes_512B_cluster-8           527kB ± 0%     449kB ± 0%   -14.73%  (p=0.008 n=5+5)
RedisSurvey/1_node_4096B_cluster-8            1.15kB ± 0%    1.14kB ± 0%      ~     (p=0.881 n=5+5)
RedisSurvey/2_nodes_4096B_cluster-8           28.2kB ± 0%    27.0kB ± 0%    -4.16%  (p=0.008 n=5+5)
RedisSurvey/3_nodes_4096B_cluster-8           54.0kB ± 0%    52.2kB ± 0%    -3.40%  (p=0.008 n=5+5)
RedisSurvey/4_nodes_4096B_cluster-8           79.9kB ± 0%    77.2kB ± 0%    -3.35%  (p=0.008 n=5+5)
RedisSurvey/5_nodes_4096B_cluster-8            106kB ± 1%     103kB ± 1%    -2.89%  (p=0.008 n=5+5)
RedisSurvey/10_nodes_4096B_cluster-8           237kB ± 1%     230kB ± 1%    -2.86%  (p=0.008 n=5+5)
RedisSurvey/100_nodes_4096B_cluster-8         2.59MB ± 0%    2.50MB ± 0%    -3.15%  (p=0.008 n=5+5)
RedisPublish_1Ch/lists_cluster-8                559B ± 1%      229B ± 8%   -59.04%  (p=0.008 n=5+5)
RedisPublish_1Ch/streams_cluster-8              600B ±11%      221B ±25%   -63.21%  (p=0.008 n=5+5)
RedisPublish_ManyCh/lists_cluster-8             628B ± 5%      186B ± 2%   -70.43%  (p=0.008 n=5+5)
RedisPublish_ManyCh/streams_cluster-8           555B ± 0%      190B ± 3%   -65.84%  (p=0.016 n=4+5)
RedisPublish_History_1Ch/lists_cluster-8      1.53kB ± 1%    0.75kB ±23%   -51.23%  (p=0.008 n=5+5)
RedisPublish_History_1Ch/streams_cluster-8    1.55kB ± 2%    0.74kB ±22%   -51.92%  (p=0.008 n=5+5)
RedisPub_History_ManyCh/lists_cluster-8       1.69kB ±10%    0.58kB ± 1%   -65.43%  (p=0.008 n=5+5)
RedisPub_History_ManyCh/streams_cluster-8     1.52kB ± 0%    0.62kB ±12%   -59.02%  (p=0.016 n=4+5)
RedisSubscribe/with_cluster-8                 1.27kB ± 0%    1.19kB ± 6%    -5.97%  (p=0.040 n=5+5)
RedisHistory_1Ch/lists_cluster-8              2.11kB ±13%    1.23kB ± 2%   -41.74%  (p=0.008 n=5+5)
RedisHistory_1Ch/streams_cluster-8            3.26kB ±13%    3.80kB ± 7%   +16.60%  (p=0.008 n=5+5)
RedisRecover_1Ch/lists_cluster-8               161kB ± 0%     175kB ± 0%    +8.77%  (p=0.008 n=5+5)
RedisRecover_1Ch/streams_cluster-8            3.09kB ± 4%    4.48kB ± 1%   +44.92%  (p=0.008 n=5+5)
RedisHistoryIteration/lists_cluster-8          163MB ± 0%     183MB ± 0%   +12.32%  (p=0.008 n=5+5)
RedisHistoryIteration/streams_cluster-8       3.36MB ± 2%    8.21MB ± 5%  +144.10%  (p=0.008 n=5+5)
RedisAddPresence_1Ch/lists_cluster-8          1.28kB ±11%    0.18kB ± 1%   -85.62%  (p=0.008 n=5+5)
RedisAddPresence_1Ch/streams_cluster-8        1.22kB ±13%    0.19kB ± 4%   -84.39%  (p=0.008 n=5+5)
RedisPresence_1Ch/lists_cluster-8             1.47kB ± 1%    0.81kB ± 1%   -44.64%  (p=0.008 n=5+5)
RedisPresence_1Ch/streams_cluster-8           1.48kB ± 2%    0.85kB ±15%   -42.31%  (p=0.008 n=5+5)
RedisPresence_ManyCh/lists_cluster-8          1.25kB ±10%    0.41kB ± 1%   -67.06%  (p=0.008 n=5+5)

name                                        old allocs/op  new allocs/op  delta
RedisSurvey/1_node_512B_cluster-8               15.0 ± 0%      15.0 ± 0%      ~     (all equal)
RedisSurvey/2_nodes_512B_cluster-8              91.0 ± 0%      51.0 ± 0%   -43.96%  (p=0.008 n=5+5)
RedisSurvey/3_nodes_512B_cluster-8               141 ± 0%        77 ± 0%   -45.39%  (p=0.008 n=5+5)
RedisSurvey/4_nodes_512B_cluster-8               192 ± 0%       103 ± 0%   -46.35%  (p=0.008 n=5+5)
RedisSurvey/5_nodes_512B_cluster-8               242 ± 0%       129 ± 0%   -46.69%  (p=0.008 n=5+5)
RedisSurvey/10_nodes_512B_cluster-8              495 ± 0%       260 ± 0%   -47.47%  (p=0.008 n=5+5)
RedisSurvey/100_nodes_512B_cluster-8           5.24k ± 0%     2.61k ± 0%   -50.15%  (p=0.008 n=5+5)
RedisSurvey/1_node_4096B_cluster-8              15.0 ± 0%      15.0 ± 0%      ~     (all equal)
RedisSurvey/2_nodes_4096B_cluster-8             92.0 ± 0%      51.0 ± 0%   -44.57%  (p=0.008 n=5+5)
RedisSurvey/3_nodes_4096B_cluster-8              142 ± 0%        77 ± 0%   -45.77%  (p=0.029 n=4+4)
RedisSurvey/4_nodes_4096B_cluster-8              194 ± 0%       103 ± 0%      ~     (p=0.079 n=4+5)
RedisSurvey/5_nodes_4096B_cluster-8              247 ± 5%       136 ± 8%   -45.15%  (p=0.008 n=5+5)
RedisSurvey/10_nodes_4096B_cluster-8             513 ± 4%       276 ± 6%   -46.12%  (p=0.008 n=5+5)
RedisSurvey/100_nodes_4096B_cluster-8          5.41k ± 1%     2.63k ± 0%   -51.47%  (p=0.008 n=5+5)
RedisPublish_1Ch/lists_cluster-8                10.0 ± 0%       3.0 ± 0%   -70.00%  (p=0.008 n=5+5)
RedisPublish_1Ch/streams_cluster-8              10.4 ± 6%       3.4 ±18%   -67.31%  (p=0.008 n=5+5)
RedisPublish_ManyCh/lists_cluster-8             11.4 ± 5%       4.0 ± 0%   -64.91%  (p=0.000 n=5+4)
RedisPublish_ManyCh/streams_cluster-8           11.0 ± 0%       4.0 ± 0%   -63.64%  (p=0.008 n=5+5)
RedisPublish_History_1Ch/lists_cluster-8        34.0 ± 0%      13.0 ±15%   -61.76%  (p=0.008 n=5+5)
RedisPublish_History_1Ch/streams_cluster-8      34.4 ± 2%      14.0 ±14%   -59.30%  (p=0.008 n=5+5)
RedisPub_History_ManyCh/lists_cluster-8         36.0 ± 6%      12.0 ± 0%   -66.67%  (p=0.008 n=5+5)
RedisPub_History_ManyCh/streams_cluster-8       34.0 ± 0%      13.0 ± 0%   -61.76%  (p=0.029 n=4+4)
RedisSubscribe/with_cluster-8                   25.0 ± 0%      13.0 ± 0%   -48.00%  (p=0.000 n=5+4)
RedisHistory_1Ch/lists_cluster-8                56.6 ± 6%      25.4 ± 2%   -55.12%  (p=0.008 n=5+5)
RedisHistory_1Ch/streams_cluster-8              95.4 ± 6%      52.2 ± 5%   -45.28%  (p=0.008 n=5+5)
RedisRecover_1Ch/lists_cluster-8               5.04k ± 0%     3.03k ± 0%   -40.02%  (p=0.008 n=5+5)
RedisRecover_1Ch/streams_cluster-8               103 ± 2%        60 ± 1%   -41.47%  (p=0.008 n=5+5)
RedisHistoryIteration/lists_cluster-8          5.07M ± 0%     3.05M ± 0%   -39.71%  (p=0.008 n=5+5)
RedisHistoryIteration/streams_cluster-8         138k ± 1%      101k ± 5%   -26.49%  (p=0.008 n=5+5)
RedisAddPresence_1Ch/lists_cluster-8            24.6 ± 7%       3.0 ± 0%   -87.80%  (p=0.008 n=5+5)
RedisAddPresence_1Ch/streams_cluster-8          24.0 ± 8%       3.0 ± 0%   -87.50%  (p=0.008 n=5+5)
RedisPresence_1Ch/lists_cluster-8               30.0 ± 0%      10.0 ± 0%   -66.67%  (p=0.008 n=5+5)
RedisPresence_1Ch/streams_cluster-8             30.0 ± 0%      10.0 ± 0%   -66.67%  (p=0.029 n=4+4)
RedisPresence_ManyCh/lists_cluster-8            25.6 ± 6%       7.0 ± 0%   -72.66%  (p=0.008 n=5+5)

@FZambia
Copy link
Member Author

FZambia commented Oct 14, 2022

RedisHistoryIteration/streams-8 3.21MB ± 2% 8.41MB ±10% +162.40% (p=0.008 n=5+5)

Adressed this in 98bda70, now cmp is:

name                             old time/op    new time/op    delta
RedisHistoryIteration/streams-8    54.7ms ± 1%    53.3ms ± 1%   -2.51%  (p=0.008 n=5+5)

name                             old alloc/op   new alloc/op   delta
RedisHistoryIteration/streams-8    3.04MB ± 0%    4.09MB ± 0%  +34.39%  (p=0.008 n=5+5)

name                             old allocs/op  new allocs/op  delta
RedisHistoryIteration/streams-8      134k ± 0%       72k ± 0%  -46.37%  (p=0.008 n=5+5)

@tony-pang
Copy link

Hi, This is great, I don't work on the same project anymore, I will let my colleague follow this up. Thank you :)

@FZambia
Copy link
Member Author

FZambia commented Oct 15, 2022

Addressed Redis Survey benchmarks in d03b278, made implementation match to what we have in redigo case - NumCPU workers to process control messages.

name                           old time/op    new time/op    delta
RedisSurvey/1_node_512B-8        1.11µs ± 1%    1.06µs ± 4%   -4.61%  (p=0.008 n=5+5)
RedisSurvey/2_nodes_512B-8       23.8µs ± 1%    12.1µs ± 2%  -49.20%  (p=0.008 n=5+5)
RedisSurvey/3_nodes_512B-8       30.1µs ± 2%    17.1µs ± 5%  -43.08%  (p=0.008 n=5+5)
RedisSurvey/4_nodes_512B-8       36.2µs ± 9%    22.9µs ± 7%  -36.92%  (p=0.008 n=5+5)
RedisSurvey/5_nodes_512B-8       44.9µs ± 3%    28.0µs ± 2%  -37.58%  (p=0.008 n=5+5)
RedisSurvey/10_nodes_512B-8      83.6µs ±14%    52.6µs ± 3%  -37.10%  (p=0.008 n=5+5)
RedisSurvey/100_nodes_512B-8      951µs ±16%     592µs ± 5%  -37.73%  (p=0.008 n=5+5)
RedisSurvey/1_node_4096B-8       1.18µs ± 1%    1.27µs ± 0%   +7.27%  (p=0.008 n=5+5)
RedisSurvey/2_nodes_4096B-8      29.8µs ± 2%    17.9µs ± 4%  -39.76%  (p=0.008 n=5+5)
RedisSurvey/3_nodes_4096B-8      44.9µs ± 4%    26.7µs ± 2%  -40.60%  (p=0.016 n=4+5)
RedisSurvey/4_nodes_4096B-8      65.7µs ±17%    35.4µs ± 4%  -46.22%  (p=0.008 n=5+5)
RedisSurvey/5_nodes_4096B-8      72.7µs ± 6%    42.9µs ± 4%  -40.93%  (p=0.008 n=5+5)
RedisSurvey/10_nodes_4096B-8      135µs ± 4%      83µs ± 2%  -38.10%  (p=0.008 n=5+5)
RedisSurvey/100_nodes_4096B-8    1.76ms ± 5%    1.06ms ± 6%  -39.97%  (p=0.008 n=5+5)

name                           old alloc/op   new alloc/op   delta
RedisSurvey/1_node_512B-8        1.14kB ± 0%    1.14kB ± 0%     ~     (all equal)
RedisSurvey/2_nodes_512B-8       7.41kB ± 0%    6.23kB ± 0%     ~     (p=0.079 n=4+5)
RedisSurvey/3_nodes_512B-8       12.5kB ± 0%    10.6kB ± 0%  -15.09%  (p=0.008 n=5+5)
RedisSurvey/4_nodes_512B-8       17.6kB ± 0%    15.0kB ± 0%  -14.71%  (p=0.008 n=5+5)
RedisSurvey/5_nodes_512B-8       22.6kB ± 0%    19.3kB ± 0%  -14.53%  (p=0.008 n=5+5)
RedisSurvey/10_nodes_512B-8      48.9kB ± 0%    42.1kB ± 0%  -13.90%  (p=0.008 n=5+5)
RedisSurvey/100_nodes_512B-8      527kB ± 0%     450kB ± 0%  -14.74%  (p=0.008 n=5+5)
RedisSurvey/1_node_4096B-8       1.14kB ± 0%    1.14kB ± 0%     ~     (p=1.000 n=5+5)
RedisSurvey/2_nodes_4096B-8      28.2kB ± 0%    27.0kB ± 0%   -4.24%  (p=0.008 n=5+5)
RedisSurvey/3_nodes_4096B-8      54.0kB ± 0%    52.1kB ± 0%   -3.56%  (p=0.016 n=4+5)
RedisSurvey/4_nodes_4096B-8      79.9kB ± 0%    77.3kB ± 0%   -3.28%  (p=0.008 n=5+5)
RedisSurvey/5_nodes_4096B-8       106kB ± 1%     102kB ± 0%   -3.75%  (p=0.008 n=5+5)
RedisSurvey/10_nodes_4096B-8      237kB ± 1%     230kB ± 0%   -3.19%  (p=0.008 n=5+5)
RedisSurvey/100_nodes_4096B-8    2.58MB ± 0%    2.50MB ± 0%   -3.12%  (p=0.008 n=5+5)

name                           old allocs/op  new allocs/op  delta
RedisSurvey/1_node_512B-8          15.0 ± 0%      15.0 ± 0%     ~     (all equal)
RedisSurvey/2_nodes_512B-8         91.0 ± 0%      51.0 ± 0%  -43.96%  (p=0.008 n=5+5)
RedisSurvey/3_nodes_512B-8          141 ± 0%        77 ± 0%     ~     (p=0.079 n=4+5)
RedisSurvey/4_nodes_512B-8          192 ± 0%       103 ± 0%  -46.35%  (p=0.008 n=5+5)
RedisSurvey/5_nodes_512B-8          242 ± 0%       129 ± 0%  -46.69%  (p=0.008 n=5+5)
RedisSurvey/10_nodes_512B-8         495 ± 0%       260 ± 0%  -47.47%  (p=0.008 n=5+5)
RedisSurvey/100_nodes_512B-8      5.26k ± 1%     2.61k ± 0%  -50.32%  (p=0.008 n=5+5)
RedisSurvey/1_node_4096B-8         15.0 ± 0%      15.0 ± 0%     ~     (all equal)
RedisSurvey/2_nodes_4096B-8        92.0 ± 0%      51.0 ± 0%  -44.57%  (p=0.008 n=5+5)
RedisSurvey/3_nodes_4096B-8         143 ± 0%        77 ± 0%     ~     (p=0.079 n=4+5)
RedisSurvey/4_nodes_4096B-8         194 ± 1%       104 ± 0%  -46.28%  (p=0.000 n=5+4)
RedisSurvey/5_nodes_4096B-8         252 ± 5%       130 ± 1%  -48.37%  (p=0.008 n=5+5)
RedisSurvey/10_nodes_4096B-8        517 ± 6%       271 ± 5%  -47.50%  (p=0.008 n=5+5)
RedisSurvey/100_nodes_4096B-8     5.39k ± 0%     2.63k ± 0%  -51.24%  (p=0.008 n=5+5)

@FZambia
Copy link
Member Author

FZambia commented Oct 15, 2022

First comparison between goredis (old) and rueidis (new)

Survey benchmarks:

benchstat goredis.txt rueidis.txt
name                           old time/op    new time/op    delta
RedisSurvey/1_node_512B-8        1.11µs ± 1%    1.06µs ± 4%   -4.66%  (p=0.016 n=5+5)
RedisSurvey/2_nodes_512B-8       16.1µs ± 2%    12.1µs ± 2%  -25.08%  (p=0.008 n=5+5)
RedisSurvey/3_nodes_512B-8       20.5µs ± 4%    17.1µs ± 5%  -16.57%  (p=0.008 n=5+5)
RedisSurvey/4_nodes_512B-8       26.0µs ± 5%    22.9µs ± 7%  -12.18%  (p=0.008 n=5+5)
RedisSurvey/5_nodes_512B-8       32.1µs ± 3%    28.0µs ± 2%  -12.69%  (p=0.008 n=5+5)
RedisSurvey/10_nodes_512B-8      60.9µs ±10%    52.6µs ± 3%  -13.72%  (p=0.008 n=5+5)
RedisSurvey/100_nodes_512B-8      634µs ± 9%     592µs ± 5%     ~     (p=0.095 n=5+5)
RedisSurvey/1_node_4096B-8       1.22µs ± 1%    1.27µs ± 0%   +4.03%  (p=0.008 n=5+5)
RedisSurvey/2_nodes_4096B-8      21.8µs ± 2%    17.9µs ± 4%  -17.55%  (p=0.008 n=5+5)
RedisSurvey/3_nodes_4096B-8      33.2µs ± 6%    26.7µs ± 2%  -19.46%  (p=0.008 n=5+5)
RedisSurvey/4_nodes_4096B-8      44.2µs ± 5%    35.4µs ± 4%  -19.96%  (p=0.008 n=5+5)
RedisSurvey/5_nodes_4096B-8      53.3µs ± 4%    42.9µs ± 4%  -19.50%  (p=0.008 n=5+5)
RedisSurvey/10_nodes_4096B-8      110µs ± 5%      83µs ± 2%  -24.19%  (p=0.008 n=5+5)
RedisSurvey/100_nodes_4096B-8    1.33ms ± 4%    1.06ms ± 6%  -20.53%  (p=0.008 n=5+5)

name                           old alloc/op   new alloc/op   delta
RedisSurvey/1_node_512B-8        1.14kB ± 0%    1.14kB ± 0%     ~     (all equal)
RedisSurvey/2_nodes_512B-8       6.99kB ± 0%    6.23kB ± 0%     ~     (p=0.079 n=4+5)
RedisSurvey/3_nodes_512B-8       11.7kB ± 0%    10.6kB ± 0%   -9.68%  (p=0.008 n=5+5)
RedisSurvey/4_nodes_512B-8       16.5kB ± 0%    15.0kB ± 0%   -9.19%  (p=0.008 n=5+5)
RedisSurvey/5_nodes_512B-8       21.2kB ± 0%    19.3kB ± 0%   -8.93%  (p=0.008 n=5+5)
RedisSurvey/10_nodes_512B-8      45.9kB ± 0%    42.1kB ± 0%   -8.28%  (p=0.008 n=5+5)
RedisSurvey/100_nodes_512B-8      490kB ± 0%     450kB ± 0%   -8.36%  (p=0.008 n=5+5)
RedisSurvey/1_node_4096B-8       1.15kB ± 0%    1.14kB ± 0%     ~     (p=0.968 n=4+5)
RedisSurvey/2_nodes_4096B-8      27.8kB ± 0%    27.0kB ± 0%   -2.74%  (p=0.008 n=5+5)
RedisSurvey/3_nodes_4096B-8      53.2kB ± 0%    52.1kB ± 0%   -2.08%  (p=0.008 n=5+5)
RedisSurvey/4_nodes_4096B-8      78.7kB ± 0%    77.3kB ± 0%   -1.86%  (p=0.008 n=5+5)
RedisSurvey/5_nodes_4096B-8       104kB ± 0%     102kB ± 0%   -1.75%  (p=0.008 n=5+5)
RedisSurvey/10_nodes_4096B-8      234kB ± 1%     230kB ± 0%   -1.87%  (p=0.008 n=5+5)
RedisSurvey/100_nodes_4096B-8    2.55MB ± 1%    2.50MB ± 0%   -1.81%  (p=0.008 n=5+5)

name                           old allocs/op  new allocs/op  delta
RedisSurvey/1_node_512B-8          15.0 ± 0%      15.0 ± 0%     ~     (all equal)
RedisSurvey/2_nodes_512B-8         81.0 ± 0%      51.0 ± 0%  -37.04%  (p=0.008 n=5+5)
RedisSurvey/3_nodes_512B-8          124 ± 0%        77 ± 0%  -37.90%  (p=0.008 n=5+5)
RedisSurvey/4_nodes_512B-8          167 ± 0%       103 ± 0%  -38.32%  (p=0.008 n=5+5)
RedisSurvey/5_nodes_512B-8          210 ± 0%       129 ± 0%     ~     (p=0.079 n=4+5)
RedisSurvey/10_nodes_512B-8         428 ± 0%       260 ± 0%  -39.20%  (p=0.008 n=5+5)
RedisSurvey/100_nodes_512B-8      4.43k ± 0%     2.61k ± 0%  -41.06%  (p=0.008 n=5+5)
RedisSurvey/1_node_4096B-8         15.0 ± 0%      15.0 ± 0%     ~     (all equal)
RedisSurvey/2_nodes_4096B-8        81.0 ± 0%      51.0 ± 0%  -37.04%  (p=0.008 n=5+5)
RedisSurvey/3_nodes_4096B-8         125 ± 0%        77 ± 0%     ~     (p=0.079 n=4+5)
RedisSurvey/4_nodes_4096B-8         169 ± 1%       104 ± 0%  -38.32%  (p=0.000 n=5+4)
RedisSurvey/5_nodes_4096B-8         212 ± 0%       130 ± 1%  -38.58%  (p=0.008 n=5+5)
RedisSurvey/10_nodes_4096B-8        448 ± 4%       271 ± 5%  -39.52%  (p=0.008 n=5+5)
RedisSurvey/100_nodes_4096B-8     4.65k ± 3%     2.63k ± 0%  -43.54%  (p=0.008 n=5+5)

Other single Redis benchmarks

name                                old time/op    new time/op    delta
RedisExtractPushData-8                30.8ns ± 0%    30.4ns ± 0%   -1.27%  (p=0.008 n=5+5)
RedisConsistentIndex-8                45.4ns ± 1%    46.2ns ± 0%   +1.71%  (p=0.008 n=5+5)
RedisIndex-8                          24.1ns ± 0%    26.1ns ± 1%   +8.27%  (p=0.008 n=5+5)
RedisPublish_1Ch/lists-8              3.01µs ± 2%    0.65µs ± 4%  -78.44%  (p=0.008 n=5+5)
RedisPublish_1Ch/streams-8            3.02µs ± 3%    0.65µs ± 3%  -78.58%  (p=0.008 n=5+5)
RedisPublish_ManyCh/lists-8           2.98µs ± 2%    0.66µs ± 2%  -77.72%  (p=0.008 n=5+5)
RedisPublish_ManyCh/streams-8         2.93µs ± 2%    0.67µs ± 4%  -77.04%  (p=0.008 n=5+5)
RedisPublish_History_1Ch/lists-8      9.85µs ± 0%    7.97µs ± 0%  -19.11%  (p=0.008 n=5+5)
RedisPublish_History_1Ch/streams-8    11.3µs ± 0%     9.8µs ± 1%  -13.35%  (p=0.008 n=5+5)
RedisPub_History_ManyCh/lists-8       10.2µs ± 2%     9.1µs ± 2%  -11.43%  (p=0.008 n=5+5)
RedisPub_History_ManyCh/streams-8     10.5µs ± 2%     9.4µs ± 1%  -10.31%  (p=0.008 n=5+5)
RedisSubscribe/non_cluster-8          2.06µs ± 7%    2.93µs ±31%  +42.10%  (p=0.008 n=5+5)
RedisHistory_1Ch/lists-8              16.0µs ± 1%     9.5µs ± 1%  -40.96%  (p=0.016 n=4+5)
RedisHistory_1Ch/streams-8            64.0µs ± 6%    29.7µs ± 1%  -53.65%  (p=0.008 n=5+5)
RedisRecover_1Ch/lists-8               234µs ± 2%     200µs ± 1%  -14.51%  (p=0.008 n=5+5)
RedisRecover_1Ch/streams-8            68.4µs ± 2%    37.1µs ± 1%  -45.85%  (p=0.008 n=5+5)
RedisHistoryIteration/lists-8          332ms ± 1%     314ms ± 1%   -5.29%  (p=0.008 n=5+5)
RedisHistoryIteration/streams-8       52.7ms ± 0%    54.1ms ± 1%   +2.63%  (p=0.008 n=5+5)

name                                old alloc/op   new alloc/op   delta
RedisExtractPushData-8                 0.00B          0.00B          ~     (all equal)
RedisConsistentIndex-8                 7.00B ± 0%     7.00B ± 0%     ~     (all equal)
RedisIndex-8                           7.00B ± 0%     7.00B ± 0%     ~     (all equal)
RedisPublish_1Ch/lists-8                497B ± 0%      168B ± 0%  -66.22%  (p=0.008 n=5+5)
RedisPublish_1Ch/streams-8              497B ± 0%      168B ± 0%  -66.22%  (p=0.008 n=5+5)
RedisPublish_ManyCh/lists-8             500B ± 0%      171B ± 0%     ~     (p=0.079 n=4+5)
RedisPublish_ManyCh/streams-8           500B ± 0%      171B ± 0%  -65.80%  (p=0.008 n=5+5)
RedisPublish_History_1Ch/lists-8      1.08kB ± 0%    0.55kB ± 1%  -49.39%  (p=0.016 n=4+5)
RedisPublish_History_1Ch/streams-8    1.08kB ± 0%    0.55kB ± 1%  -49.23%  (p=0.008 n=5+5)
RedisPub_History_ManyCh/lists-8       1.08kB ± 0%    0.58kB ± 1%  -46.63%  (p=0.008 n=5+5)
RedisPub_History_ManyCh/streams-8     1.08kB ± 0%    0.58kB ± 1%  -46.54%  (p=0.008 n=5+5)
RedisSubscribe/non_cluster-8          1.08kB ± 1%    1.15kB ± 4%   +6.67%  (p=0.008 n=5+5)
RedisHistory_1Ch/lists-8              1.49kB ± 0%    1.17kB ± 0%  -21.78%  (p=0.008 n=5+5)
RedisHistory_1Ch/streams-8            2.10kB ± 0%    2.19kB ± 0%   +4.26%  (p=0.008 n=5+5)
RedisRecover_1Ch/lists-8               130kB ± 0%     175kB ± 0%  +34.57%  (p=0.008 n=5+5)
RedisRecover_1Ch/streams-8            2.36kB ± 0%    2.60kB ± 0%  +10.20%  (p=0.016 n=4+5)
RedisHistoryIteration/lists-8          130MB ± 0%     182MB ± 0%  +39.74%  (p=0.008 n=5+5)
RedisHistoryIteration/streams-8       2.81MB ± 1%    4.16MB ± 0%  +48.15%  (p=0.016 n=5+4)

name                                old allocs/op  new allocs/op  delta
RedisExtractPushData-8                  0.00           0.00          ~     (all equal)
RedisConsistentIndex-8                  0.00           0.00          ~     (all equal)
RedisIndex-8                            0.00           0.00          ~     (all equal)
RedisPublish_1Ch/lists-8                8.00 ± 0%      3.00 ± 0%  -62.50%  (p=0.008 n=5+5)
RedisPublish_1Ch/streams-8              8.00 ± 0%      3.00 ± 0%  -62.50%  (p=0.008 n=5+5)
RedisPublish_ManyCh/lists-8             8.00 ± 0%      3.00 ± 0%  -62.50%  (p=0.008 n=5+5)
RedisPublish_ManyCh/streams-8           8.00 ± 0%      3.00 ± 0%  -62.50%  (p=0.008 n=5+5)
RedisPublish_History_1Ch/lists-8        25.0 ± 0%      11.0 ± 0%  -56.00%  (p=0.008 n=5+5)
RedisPublish_History_1Ch/streams-8      25.0 ± 0%      12.0 ± 0%  -52.00%  (p=0.008 n=5+5)
RedisPub_History_ManyCh/lists-8         25.0 ± 0%      12.0 ± 0%  -52.00%  (p=0.008 n=5+5)
RedisPub_History_ManyCh/streams-8       25.0 ± 0%      13.0 ± 0%  -48.00%  (p=0.008 n=5+5)
RedisSubscribe/non_cluster-8            19.0 ± 0%      13.0 ± 0%  -31.58%  (p=0.008 n=5+5)
RedisHistory_1Ch/lists-8                43.0 ± 0%      25.0 ± 0%  -41.86%  (p=0.008 n=5+5)
RedisHistory_1Ch/streams-8              74.0 ± 0%      41.0 ± 0%  -44.59%  (p=0.008 n=5+5)
RedisRecover_1Ch/lists-8               4.03k ± 0%     3.02k ± 0%  -25.16%  (p=0.000 n=4+5)
RedisRecover_1Ch/streams-8              86.0 ± 0%      48.0 ± 0%  -44.19%  (p=0.008 n=5+5)
RedisHistoryIteration/lists-8          4.05M ± 0%     3.04M ± 0%  -24.95%  (p=0.008 n=5+5)
RedisHistoryIteration/streams-8         124k ± 0%       73k ± 0%  -41.35%  (p=0.016 n=5+4)

@FZambia
Copy link
Member Author

FZambia commented Oct 15, 2022

Was able to tune go-redis (old) a bit for publishing (adding additional publish and data pipeline goroutines and playing with batch limit), but still rueidis (new) produces fantastic results for publish without LUA, and great in allocs:

name                                old time/op    new time/op    delta
RedisPublish_1Ch/lists-8              1.61µs ± 2%    0.64µs ± 1%  -60.24%  (p=0.008 n=5+5)
RedisPublish_1Ch/streams-8            1.58µs ±11%    0.66µs ± 7%  -58.38%  (p=0.008 n=5+5)
RedisPublish_ManyCh/lists-8           1.64µs ± 3%    0.68µs ± 4%  -58.40%  (p=0.008 n=5+5)
RedisPublish_ManyCh/streams-8         1.54µs ±19%    0.71µs ± 5%  -53.85%  (p=0.008 n=5+5)
RedisPublish_History_1Ch/lists-8      8.01µs ± 1%    8.00µs ± 0%     ~     (p=0.690 n=5+5)
RedisPublish_History_1Ch/streams-8    9.71µs ± 1%    9.79µs ± 0%     ~     (p=0.056 n=5+5)

name                                old alloc/op   new alloc/op   delta
RedisPublish_1Ch/lists-8                496B ± 0%      168B ± 0%  -66.13%  (p=0.008 n=5+5)
RedisPublish_1Ch/streams-8              496B ± 0%      168B ± 0%  -66.13%  (p=0.008 n=5+5)
RedisPublish_ManyCh/lists-8             499B ± 0%      171B ± 0%  -65.73%  (p=0.008 n=5+5)
RedisPublish_ManyCh/streams-8           499B ± 0%      171B ± 0%  -65.73%  (p=0.008 n=5+5)
RedisPublish_History_1Ch/lists-8      1.08kB ± 0%    0.55kB ± 0%  -48.98%  (p=0.008 n=5+5)
RedisPublish_History_1Ch/streams-8    1.08kB ± 0%    0.55kB ± 1%  -49.23%  (p=0.000 n=4+5)

name                                old allocs/op  new allocs/op  delta
RedisPublish_1Ch/lists-8                8.00 ± 0%      3.00 ± 0%  -62.50%  (p=0.008 n=5+5)
RedisPublish_1Ch/streams-8              8.00 ± 0%      3.00 ± 0%  -62.50%  (p=0.008 n=5+5)
RedisPublish_ManyCh/lists-8             9.00 ± 0%      3.00 ± 0%  -66.67%  (p=0.008 n=5+5)
RedisPublish_ManyCh/streams-8           9.00 ± 0%      3.00 ± 0%  -66.67%  (p=0.008 n=5+5)
RedisPublish_History_1Ch/lists-8        25.0 ± 0%      11.0 ± 0%  -56.00%  (p=0.008 n=5+5)
RedisPublish_History_1Ch/streams-8      25.0 ± 0%      12.0 ± 0%  -52.00%  (p=0.008 n=5+5)

@j178
Copy link
Contributor

j178 commented Oct 15, 2022

Hi, this is a really exciting improvement!
I ran the benchmarks under master, go-redis and rueidis by myself, and here is the result:
https://perf.golang.org/search?q=upload:20221015.11

rueidis is impressively better than go-redis in almost all cases, I agree it is a better solution.

But there is still one case where rueidis is slower, maybe there is some room for optimization:

RedisSubscribe/non_cluster-16 7.81µs ± 2% 7.59µs ± 1% 14.56µs ± 2%

@FZambia
Copy link
Member Author

FZambia commented Nov 2, 2022

@j178 thanks, I'll try to come with detailed comment with examples about this sharding very soon then

@FZambia
Copy link
Member Author

FZambia commented Nov 2, 2022

So here are options we have in RedisBrokerConfig:

type RedisBrokerConfig struct {
        ...
	// NumPubSubShards defines how many PUB/SUB shards will be used by Centrifuge.
	// Each PUB/SUB shard uses dedicated connection to Redis. Zero value means 1.
	NumPubSubShards int

	// NumPubSubSubscribers defines how many subscriber goroutines will be used by
	// Centrifuge for each PUB/SUB shard. Zero value tells Centrifuge to use 16
	// subscriber goroutines per PUB/SUB shard.
	NumPubSubSubscribers int

	// NumPubSubProcessors allows configuring number of workers which will process messages
	// coming from Redis PUB/SUB. Zero value tells Centrifuge to use the number calculated as
	// runtime.NumCPU / NumPubSubShards / NumClusterShards (if used) (minimum 1).
	NumPubSubProcessors int

	// NumClusterShards when greater than zero allows turning on a mode when broker
	// will use Redis Cluster with sharded PUB/SUB feature. To achieve PUB/SUB
	// efficiency RedisBroker reduces possible Redis Cluster slots to the NumClusterShards
	// value and starts a separate PUB/SUB for each shard. By default, sharded PUB/SUB is
	// not used - i.e. we use globally distributed PUBLISH commands in Redis Cluster.
	// Note, that turning on NumClusterShards will cause Centrifuge to generate different
	// keys and Redis channels than in the base Redis Cluster mode since we need to control
	// slots and be sure our subscriber routines work with the same Redis Cluster slot - thus
	// making it possible to subscribe over a single connection.
	// This feature requires Redis >= 7.
	NumClusterShards int
}

Also RedisBroker has []*shardWrapper (which is mostly []*RedisShard):

type RedisBroker struct {
        ...
	config                 RedisBrokerConfig
	shards                 []*shardWrapper
}

RedisBroker.shards

Let's start from RedisBroker.shards - it's a way to shard requests over different Redis instances from application level. Centrifuge will shard requests using consistent hashing formula based on channel. Why it's useful? This allows to scale using isolated standalone Redis instances. I.e. one can start several Redis instances which do not know nothing about each other, like one per CPU core. And Centrifuge will spread load between those instances. This can be isolated master-replica setups with Sentinel or isolated different Redis Clusters (this was previously useful to scale PUB/SUB with Redis Cluster and Centrifuge - i.e. use isolated Redis Clusters).

This is sth we had here before.

RedisBrokerConfig.NumPubSubSubscribers

RedisBrokerConfig.NumPubSubSubscribers is a number of Subscriber goroutines Centrifuge will start per each RedisShard. Why we need several goroutines? Because we use issue subscribe/unsubscribe requests using single pipeline. We need single pipeline to synchronize order of subscribe and unsubscribe. But if we have a single pipeline then in case of increasing latency between Centrifuge and Redis we will have small subscribe request throughput. Since we need to wait RTT time till pipeline objects are processed. So we shard by channel and use several such pipelines by default - so we multiply throughput of subscription requests. Even we have many NumPubSubSubscribers we still use a single Redis connection inside runPubSub goroutine.

RedisBrokerConfig.NumPubSubProcessors

RedisBrokerConfig.NumPubSubSubscribers is simple I think - it's several goroutines to process messages coming from Redis PUB/SUB (from Redis to Centrifuge) - so we can parallelize processing and have fast loop which handles incoming messages from Redis.

RedisBrokerConfig.NumClusterShards

This is most tricky I suppose. Redis Cluster has sharded PUB/SUB. So where previously we had to use several RedisBroker.shards to scale PUB/SUB in Redis Cluster by providing several Redis Clusters we now can just use single Redis Cluster. And PUB/SUB will scale in that Redis cluster.

Though Redis sharded PUB/SUB feature does not come for free in our case. We can not issue isolated SSUBSCRIBE commands and listen for changes from Redis. Because we may have millions of channels on one Centrifuge node. And we still need to synchronize issuing SSUBSCRIBE with issuing SUNSUBSCRIBE. To use a limited number of connections for PUB/SUB with Redis we divide cluster to NumClusterShards slots. This NumClusterShards should be in general larger than number of nodes in Redis Cluster. For each such slot we start own subscriber goroutine - so we can use Redis sharded PUB/SUB and still process subscriptions in batches with pipelining and receive messages from Redis over limited number of connections. In each such shard we have channels which belong to the same Redis Cluster slot, because we construct a special key to achieve this (using the number of PUB/SUB shard channel belongs to and putting that number into {} - ...{PUB_SUB_SHARD_NUMBER}...).

TBH I don't like this approach a lot in its current state as it involves some thinking from developers how many cluster slots they need. There may be a theoretical situation when the number of Redis nodes in Redis cluster grows above initially selected NumClusterShards – and in this case scalability of the system will be limited to that selected number. But seems it's the only working approach as all SSUBSCRIBE commands which go through dedicated connection should belong to the same Redis Cluster slot. And to achieve this guarantee we are reducing slots to some controlled number.

RedisBrokerConfig.NumPubSubShards

Turned out that PUB/SUB throughput may be maximized if we additionally split message passing over several connections (by default we use a single connection for subscribing/receiving in our subscriber goroutines). To be honest it's hard for me to explain where exactly the benefit comes from - but BenchmarkPubSubThroughput clearly demonstrated the gain from this. I suppose that most users won't need to tune this option. But the increase in BenchmarkPubSubThroughput benchmark I observed is worth to have an option for this I think.

@j178 hope the motivation is a bit more clear now. Please feel free to ask so I could expand sth

@rueian
Copy link

rueian commented Nov 20, 2022

While code is similar - looks like our batching approach for subscribe clashes with rueidis batching algorithm somehow so throughput through the connection is less in the end.

Hi @FZambia,

I just have a look into the RedisSubscribe benchmark case. I think the batching of chIDs in the runPubSub indeed clashes with rueidis. I wonder if it is possible just letting rueidis do the batching?

For example, storing the conn in the runPubSub first:

func (b *RedisBroker) runPubSub(s *shardWrapper, eventHandler BrokerEventHandler, clusterShardIndex, psShardIndex int, useShardedPubSub bool) {
	...
	conn, cancel := s.shard.client.Dedicate()
	defer cancel()
	defer conn.Close()

	wait := conn.SetPubSubHooks(rueidis.PubSubHooks{...})
	s.subChannels[clusterShardIndex][psShardIndex].conn.Store(conn)
	close(s.subChannels[clusterShardIndex][psShardIndex].stored)
	...
}

and use it at sendSubscribe like this:

func (b *RedisBroker) sendSubscribe(s *shardWrapper, r subRequest, clusterShardIndex, psShardIndex, subscriberShardIndex int) error {
	<-s.subChannels[clusterShardIndex][psShardIndex].stored
	conn := s.subChannels[clusterShardIndex][psShardIndex].conn.Load().(rueidis.DedicatedClient)
	return conn.Do(context.Background(), conn.B().Subscribe().Channel(*(*[]string)(unsafe.Pointer(&r.channels))...).Build()).Error()
}

Here is benchmark result comparing to master branch on my macbook:

▶ benchstat old.txt new.txt
name                           old time/op    new time/op    delta
RedisSubscribe/non_cluster-10    4.46µs ± 3%    1.96µs ±10%  -55.94%  (p=0.000 n=9+10)

name                           old alloc/op   new alloc/op   delta
RedisSubscribe/non_cluster-10    1.46kB ± 7%    1.07kB ± 0%  -27.02%  (p=0.000 n=10+7)

name                           old allocs/op  new allocs/op  delta
RedisSubscribe/non_cluster-10      30.2 ± 4%      12.0 ± 0%  -60.33%  (p=0.000 n=8+10)

@FZambia
Copy link
Member Author

FZambia commented Nov 20, 2022

@rueian many thanks, I'll try to evaluate whether it's possible to do this way. Can't understand quickly as there is some logic for resubscribing to channels upon connection lost – and it's hard to quickly realize is it safe to avoid going through runPubSub pipeline.

BTW, in the blog post benchmarks I ran Redigo benchmarks against https://github.com/centrifugal/centrifuge/tree/redigo_optimized branch where I tried to optimize Redigo-based engine we have in master before comparing it to Rueidis. Could you re-run the bench compared to that branch? I believe Rueidis still should perform better as we bypass some code, but Redigo should be closer.

@rueian
Copy link

rueian commented Nov 20, 2022

Could you re-run the bench compared to that branch? I believe Rueidis still should perform better as we bypass some code, but Redigo should be closer.

Sure. I also notice that there are some configuration differences between the two branches:

  1. testBenchmarkNode vs testNode
  2. SetParallelism(64) vs SetParallelism(128)

The following result uses testBenchmarkNode + SetParallelism(128) for both branches:

▶ benchstat oldbenchnode.txt newbenchnode.txt
name                           old time/op    new time/op    delta
RedisSubscribe/non_cluster-10    2.26µs ±31%    1.81µs ± 9%  -19.65%  (p=0.022 n=10+10)

name                           old alloc/op   new alloc/op   delta
RedisSubscribe/non_cluster-10      942B ±17%      714B ± 0%  -24.22%  (p=0.000 n=10+7)

name                           old allocs/op  new allocs/op  delta
RedisSubscribe/non_cluster-10      23.2 ±21%       9.0 ± 0%  -61.21%  (p=0.000 n=10+10)
▶ cat newbenchnode.txt
goos: darwin
goarch: arm64
pkg: github.com/centrifugal/centrifuge
BenchmarkRedisSubscribe/non_cluster-10         	  837580	      1688 ns/op	     655 B/op	       9 allocs/op
BenchmarkRedisSubscribe/non_cluster-10         	 1000000	      1767 ns/op	     714 B/op	       9 allocs/op
BenchmarkRedisSubscribe/non_cluster-10         	 1000000	      1742 ns/op	     714 B/op	       9 allocs/op
BenchmarkRedisSubscribe/non_cluster-10         	 1000000	      1824 ns/op	     714 B/op	       9 allocs/op
BenchmarkRedisSubscribe/non_cluster-10         	 1000000	      1853 ns/op	     714 B/op	       9 allocs/op
BenchmarkRedisSubscribe/non_cluster-10         	 1000000	      1910 ns/op	     714 B/op	       9 allocs/op
BenchmarkRedisSubscribe/non_cluster-10         	 1000000	      1792 ns/op	     714 B/op	       9 allocs/op
BenchmarkRedisSubscribe/non_cluster-10         	  906090	      1767 ns/op	     731 B/op	       9 allocs/op
BenchmarkRedisSubscribe/non_cluster-10         	 1000000	      1797 ns/op	     714 B/op	       9 allocs/op
BenchmarkRedisSubscribe/non_cluster-10         	  977815	      1981 ns/op	     718 B/op	       9 allocs/op
PASS
ok  	github.com/centrifugal/centrifuge	20.290s
▶ cat oldbenchnode.txt
goos: darwin
goarch: arm64
pkg: github.com/centrifugal/centrifuge
BenchmarkRedisSubscribe/non_cluster-10         	  491959	      2964 ns/op	    1101 B/op	      28 allocs/op
BenchmarkRedisSubscribe/non_cluster-10         	  531633	      2676 ns/op	    1035 B/op	      26 allocs/op
BenchmarkRedisSubscribe/non_cluster-10         	  484117	      2278 ns/op	     906 B/op	      22 allocs/op
BenchmarkRedisSubscribe/non_cluster-10         	  586744	      2339 ns/op	     900 B/op	      22 allocs/op
BenchmarkRedisSubscribe/non_cluster-10         	  526400	      2118 ns/op	     904 B/op	      22 allocs/op
BenchmarkRedisSubscribe/non_cluster-10         	  485445	      2525 ns/op	     900 B/op	      22 allocs/op
BenchmarkRedisSubscribe/non_cluster-10         	  655501	      2334 ns/op	     991 B/op	      25 allocs/op
BenchmarkRedisSubscribe/non_cluster-10         	  611888	      1892 ns/op	     885 B/op	      21 allocs/op
BenchmarkRedisSubscribe/non_cluster-10         	  591780	      1722 ns/op	     903 B/op	      22 allocs/op
BenchmarkRedisSubscribe/non_cluster-10         	  700071	      1705 ns/op	     897 B/op	      22 allocs/op
PASS
ok  	github.com/centrifugal/centrifuge	25.110s

@FZambia
Copy link
Member Author

FZambia commented Nov 23, 2022

@rueian I tried approach with saving conn to atomic.Value – but for some reason it provides a latency a bit worse than current approach with batching on Centrifuge level and pub/sub channel. I decided to not dive into reasons for now – given the fact it requires careful refactoring anyway I think it's better to proceed with current approach, especially since you were able to speed up it with redis/rueidis@9cfcaa4

@rueian
Copy link

rueian commented Nov 24, 2022

I tried approach with saving conn to atomic.Value – but for some reason it provides a latency a bit worse than current approach with batching on Centrifuge level and pub/sub channel.

That was quit surprising.

I decided to not dive into reasons for now – given the fact it requires careful refactoring anyway I think it's better to proceed with current approach, especially since you were able to speed up it with redis/rueidis@9cfcaa4

Sure, please let me know if you need other help. I am also planing to release v0.0.86 this weekend.

@FZambia FZambia changed the title Migrate to github.com/rueian/rueidis + sharded PUB/SUB support Migrate to github.com/rueian/rueidis Nov 27, 2022
@FZambia
Copy link
Member Author

FZambia commented Nov 27, 2022

In 9db9225 I made some parts of the work done here non-public for now. This includes:

  • possibility to turn on sharded PUB/SUB part – I'd like to think a bit more about the implementation since enabling it results into using different cluster keys for PUB/SUB and history streams/meta compared to the basic mode with Redis Cluster. I suppose we will make it public eventually, ideally I'd like to have real use case that justifies using Redis sharded PUB/SUB feature
  • made some Broker options (which control broker internal sharding) non-public. Defaults provide a good throughput I believe and this can give us some room to improve internals without breaking changes in the near future.

@FZambia
Copy link
Member Author

FZambia commented Dec 13, 2022

I tried approach with saving conn to atomic.Value – but for some reason it provides a latency a bit worse than current approach with batching on Centrifuge level and pub/sub channel.

That was quit surprising.

@rueian it's a never-ending work... I just discovered the reason why Redigo was better in Subscribe – it does not wait for Subscribe response from Redis synchronously. Only flushes command to the network. It's pretty surprising for me, and actually can lead to the bug in Centrifugo since I relied on the fact whether subscribe op returned error or not - so theoretically client connection could receive subscribe success while actually result is unknown.

Since Rueidis waits synchronously it results in worse subscribe throughput under increased latency between app and Redis. I decided to give the approach you suggested above one more shot, using Rueidis Client directly without intermediate pipelines - it provides better throughput.

@rueian
Copy link

rueian commented Dec 14, 2022

I just discovered the reason why Redigo was better in Subscribe – it does not wait for Subscribe response from Redis synchronously.

Oh, that is not very surprising to me though. Actually, rueidis also didn't wait subscribe results until we fixed the redis/rueidis#55. The pubsub protocol makes the desired behavior hard to be implemented.

it's a never-ending work...

I believe it is not a bad thing... At least we know more about these libraries. I am also working on improving rueidis' flush delay mechanism we added last week by looking into historical statistics: redis/rueidis#159

It now performs better in your benchmark with low parallelism, especially when setting MaxFlushDelay=100µs. I also would like to have your opinions about this new approach before merging it.

@FZambia
Copy link
Member Author

FZambia commented Dec 14, 2022

Oh, that is not very surprising to me though. Actually, rueidis also didn't wait subscribe results until we fixed the redis/rueidis#55. The pubsub protocol makes the desired behavior hard to be implemented.

But it will work the same way as now in the future right?

@rueian
Copy link

rueian commented Dec 14, 2022

Sure, rueidis will keep the current behavior - waiting for subscribe results.

@FZambia FZambia deleted the migrate_to_rueidis branch April 15, 2023 18:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants