• Yanqi Lv's avatar
    Optimize performance when many clients [p|s]unsubscribe simultaneously (#12838) · c452e414
    Yanqi Lv authored
    I'm testing the performance of Pub/Sub command recently. I find if many
    clients unsubscribe or are killed simultaneously, Redis needs a long
    time to deal with it.
    
    In my experiment, I set 5000 clients and each client subscribes 100
    channels. Then I call `client kill type pubsub` to simulate the
    situation where clients unsubscribe all channels at the same time and
    calculate the execution time. The result shows that it takes about 23s.
    I use the _perf_ and find that `listSearchKey` in
    `pubsubUnsubscribeChannel` costs more than 90% cpu time. I think we can
    optimize this situation.
    
    In this PR, I replace list with dict to track the clients subscribing
    the channel more efficiently. It changes O(N) to O(1) in the search
    phase. Then I repeat the experiment as above. The results are as
    follows.
    
    |              | Execution Time(s) |used_memory(MB) |
    | :---------------- | :------: | :----: |
    | unstable(1bd0b549)        |   23.734   | 65.41 |
    | optimize-pubsub           |   0.288   | 67.66 |
    
    Thanks for #11595 , I use a no-value dict and the results shows that the
    performance improves significantly but the memory usage only increases
    slightly.
    
    Notice:
    
    - This PR will cause the performance degradation about 20% in
    `[p|s]subscribe` command but won't freeze Redis.
    c452e414
server.h 182 KB