1. 20 Jun, 2023 2 commits
  2. 19 Jun, 2023 1 commit
    • Binbin's avatar
      Optimize PSUBSCRIBE and PUNSUBSCRIBE from O(N*M) to O(N) (#12298) · b5106249
      Binbin authored
      In the original implementation, the time complexity of the commands
      is actually O(N*M), where N is the number of patterns the client is
      already subscribed and M is the number of patterns to subscribe to.
      The docs are all wrong about this.
      
      Specifically, because the original client->pubsub_patterns is a list,
      so we need to do listSearchKey which is O(N). In this PR, we change it
      to a dict, so the search becomes O(1).
      
      At the same time, both pubsub_channels and pubsubshard_channels are dicts.
      Changing pubsub_patterns to a dictionary improves the readability and
      maintainability of the code.
      b5106249
  3. 18 Jun, 2023 1 commit
    • Wen Hui's avatar
      Cluster human readable nodename feature (#9564) · 070453ee
      Wen Hui authored
      
      
      This PR adds a human readable name to a node in clusters that are visible as part of error logs. This is useful so that admins and operators of Redis cluster have better visibility into failures without having to cross-reference the generated ID with some logical identifier (such as pod-ID or EC2 instance ID). This is mentioned in #8948. Specific nodenames can be set by using the variable cluster-announce-human-nodename. The nodename is gossiped using the clusterbus extension in #9530.
      Co-authored-by: default avatarMadelyn Olson <madelyneolson@gmail.com>
      070453ee
  4. 16 Jun, 2023 3 commits
    • sundb's avatar
      Use Reservoir Sampling for random sampling of dict, and fix hang during fork (#12276) · b00a2351
      sundb authored
      
      
      ## Issue:
      When a dict has a long chain or the length of the chain is longer than
      the number of samples, we will never be able to sample the elements
      at the end of the chain using dictGetSomeKeys().
      This could mean that SRANDMEMBER can be hang in and endless loop.
      The most severe case, is the pathological case of when someone uses SCAN+DEL
      or SSCAN+SREM creating an unevenly distributed dict.
      This was amplified by the recent change in #11692 which prevented a
      down-sizing rehashing while there is a fork.
      
      ## Solution
      1. Before, we will stop sampling when we reach the maximum number
        of samples, even if there is more data after the current chain.
        Now when we reach the maximum we use the Reservoir Sampling
        algorithm to fairly sample the end of the chain that cannot be sampled
      2. Fix the rehashing code, so that the same as it allows rehashing for up-sizing
        during fork when the ratio is extreme, it will allow it for down-sizing as well.
      
      Issue was introduced (or became more severe) by #11692
      Co-authored-by: default avatarOran Agra <oran@redislabs.com>
      b00a2351
    • Binbin's avatar
      Fix SPOP/RESTORE propagation when doing lazy free (#12320) · 439b0315
      Binbin authored
      In SPOP, when COUNT is greater than or equal to set's size,
      we will remove the set. In dbDelete, we will do DEL or UNLINK
      according to the lazy flag. This is also required for propagate.
      
      In RESTORE, we won't store expired keys into the db, see #7472.
      When used together with REPLACE, it should emit a DEL or UNLINK
      according to the lazy flag.
      
      This PR also adds tests to cover the propagation. The RESTORE
      test will also cover #7472.
      439b0315
    • Binbin's avatar
      Add command being unblocked cause another command to get unblocked execution order test (#12324) · 9dc6f93e
      Binbin authored
      * Add command being unblocked cause another command to get unblocked execution order test
      
      In #12301, we observed that if the
      `while(listLength(server.ready_keys) != 0)`
      in handleClientsBlockedOnKeys is changed to
      `if(listLength(server.ready_keys) != 0)`,
      the order of command execution will change.
      
      It is wrong to change that. It means that if a command
      being unblocked causes another command to get unblocked
      (like a BLMOVE would do), then the new unblocked command
      will wait for later to get processed rather than right away.
      
      It'll not have any real implication if we change that since
      we do call handleClientsBlockedOnKeys in beforeSleep again,
      and redis will still behave correctly, but we don't change that.
      
      An example:
      1. $rd1 blmove src{t} dst{t} left right 0
      2. $rd2 blmove dst{t} src{t} right left 0
      3. $rd3 set key1{t}, $rd3 lpush src{t}, $rd3 set key2{t} in a pipeline
      
      The correct order would be:
      1. set key1{t}
      2. lpush src{t}
      3. lmove src{t} dst{t} left right
      4. lmove dst{t} src{t} right left
      5. set key2{t}
      
      The wrong order would be:
      1. set key1{t}
      2. lpush src{t}
      3. lmove src{t} dst{t} left right
      4. set key2{t}
      5. lmove dst{t} src{t} right left
      
      This PR adds corresponding test to cover it.
      
      * Add comment near while(listLength(server.ready_keys) != 0)
      9dc6f93e
  5. 15 Jun, 2023 2 commits
    • Meir Shpilraien (Spielrein)'s avatar
      Prevent PEJ on loading and on readonly replica. (#12304) · cefe4566
      Meir Shpilraien (Spielrein) authored
      While Redis loading data from disk (AOF or RDB), modules will get
      key space notifications. In such stage the module should not register
      any PEJ, the main reason this is forbidden is that PEJ purpose is to
      perform a write operation as a reaction to the key space notification.
      Write operations should not be performed while loading data and so
      there is no reason to register a PEJ. 
      
      Same argument also apply to readonly replica. module should not
      perform any writes as a reaction to key space notifications and so it
      should not register a PEJ.
      
      If a module need to perform some other task which is not involve
      writing, he can do it on the key space notification callback itself.
      cefe4566
    • Binbin's avatar
      Optimize SET PXAT to reduce calls of rewriteClientCommandVector (#12316) · 25447553
      Binbin authored
      In PXAT case, there is no need to do the rewriteClientCommandVector,
      a simply benchmark show we gain a improvement of 10%.
      25447553
  6. 14 Jun, 2023 1 commit
    • judeng's avatar
      improve performance for keys with expiration time (#12177) · 789c33bb
      judeng authored
      This change only affects keys with expiry time.
      For SETEX, the average improvement is 5%, and for GET with
      expiation key, we gain a improvement of 13%.
      
      When keys have expiration time, Redis has an assertion to look
      up the main dict every time when it touches the expires.
      This comes with a performance const, especially during rehash.
      the damage will be double.
      
      It looks like that assert was added some ten years old, maybe out
      of paranoia, and there's probably no reason to keep it at that cost.
      789c33bb
  7. 13 Jun, 2023 2 commits
    • Harkrishn Patro's avatar
      Allow cluster slots/shards api to respond during loading (#12269) · a9e32767
      Harkrishn Patro authored
      It would be helpful for clients to get cluster slots/shards information during a node failover and is loading data.
      a9e32767
    • Binbin's avatar
      Fix XREADGROUP BLOCK stuck in endless loop (#12301) · e7129e43
      Binbin authored
      
      
      For the XREADGROUP BLOCK > scenario, there is an endless loop.
      Due to #11012, it keep going, reprocess command -> blockForKeys -> reprocess command
      
      The right fix is to avoid an endless loop in handleClientsBlockedOnKey and handleClientsBlockedOnKeys,
      looks like there was some attempt in handleClientsBlockedOnKeys but maybe not sufficiently good,
      and it looks like using a similar trick in handleClientsBlockedOnKey is complicated.
      i.e. stashing the list on the stack and iterating on it after creating a fresh one for future use,
      is problematic since the code keeps accessing the global list.
      Co-authored-by: default avatarOran Agra <oran@redislabs.com>
      e7129e43
  8. 12 Jun, 2023 1 commit
  9. 11 Jun, 2023 2 commits
    • YaacovHazan's avatar
      Reset command duration for rejected command. (#12247) · 0bfb6d55
      YaacovHazan authored
      In 7.2, After 971b177f
      
       we make sure (assert) that
      the duration has been recorded when resetting the client.
      
      This is not true for rejected commands.
      The use case I found is a blocking command that an ACL rule changed before
      it was unblocked, and while reprocessing it, the command rejected and triggered the assert.
      
      The PR reset the command duration inside rejectCommand / rejectCommandSds.
      Co-authored-by: default avatarOran Agra <oran@redislabs.com>
      0bfb6d55
    • Binbin's avatar
      Fix ACLAppendUserForLoading memory leak when merge error (#12296) · 5fd9756d
      Binbin authored
      This leak will only happen in loadServerConfigFromString,
      that is, when we are loading a redis.conf, and the user is wrong.
      
      Because it happens in loadServerConfigFromString, redis will
      exit if there is an error, so this is actually just a cleanup.
      5fd9756d
  10. 08 Jun, 2023 1 commit
  11. 05 Jun, 2023 1 commit
  12. 30 May, 2023 1 commit
  13. 29 May, 2023 2 commits
  14. 28 May, 2023 5 commits
  15. 26 May, 2023 1 commit
    • Binbin's avatar
      Add new loglevel nothing to sentinel-config.json (#12235) · e775b34e
      Binbin authored
      It was missing in #12223, and the reply-schemas daily
      was failing:
      ```
      jsonschema.exceptions.ValidationError: 'nothing' is not valid under any of the given schemas
      
      Failed validating 'oneOf' in schema[0]['properties']['loglevel']:
          {'oneOf': [{'const': 'debug'},
                     {'const': 'verbose'},
                     {'const': 'notice'},
                     {'const': 'warning'},
                     {'const': 'unknown'}]}
      
      On instance['loglevel']:
          'nothing'
      ```
      e775b34e
  16. 24 May, 2023 5 commits
    • mojh7's avatar
      Fix typo functoin -> function (#12218) · 627c610f
      mojh7 authored
      functoin -> function
      627c610f
    • Oran Agra's avatar
      Make a light weight version (default) of DEBUG HTSTATS (#12212) · 3ca451c4
      Oran Agra authored
      The light version only shows the table sizes, while the pre-existing
      version that shows chain length stats is reachable with the `full` argument.
      
      This should allow looking into rehashing state, even on huge dicts, on
      which we're afraid to run the command for fear of causing a server freeze.
      
      Also, fix a possible overflow in dictGetStats.
      3ca451c4
    • Oran Agra's avatar
      CI to validate commands.def is up to date (#12227) · c871db24
      Oran Agra authored
      and update recent SENTINEL CONFIG changes.
      c871db24
    • judeng's avatar
      postpone the initialization of oject's lru&lfu until it is added to the db as... · d71478a8
      judeng authored
      postpone the initialization of oject's lru&lfu until it is added to the db as a value object (#11626)
      
      This pr can get two performance benefits:
      1. Stop redundant initialization when most robj objects are created
      2. LRU_CLOCK will no longer be called in io threads, so we can avoid the `atomicGet`
      
      Another code optimization:
      deleted the redundant judgment in dbSetValue, no matter in LFU or LRU, the lru field inold
      robj is always the freshest (it is always updated in lookupkey), so we don't need to judge if in LFU
      d71478a8
    • Binbin's avatar
      Sync the new loglevel nothing to sentinel (#12223) · d0994c5b
      Binbin authored
      We add a new loglevel 'nothing' to disable logging in #12133.
      This PR syncs that config change to sentinel. Because in #11214
      we support modifying loglevel in runtime.
      
      Although I think sentinel doesn't need this nothing config,
      it's better to be consistent.
      d0994c5b
  17. 23 May, 2023 3 commits
    • Ping Xie's avatar
      Exclude aux fields from "cluster nodes" and "cluster replicas" output (#12166) · 4c74dd98
      Ping Xie authored
      This commit excludes aux fields from the output of the `cluster nodes` and `cluster replicas` command.
      We may decide to re-introduce them in some form or another in the future, but not in v7.2.
      4c74dd98
    • zhaozhao.zz's avatar
      add a new loglevel 'nothing' to disable logging (#12133) · 07ea2204
      zhaozhao.zz authored
      Users can record logs of different levels by setting the `loglevel`.
      However, sometimes there are many logs even at the warning level,
      which can affect the performance of Redis.
      
      For example, when a user accesses the tls-port using a non-encrypted link,
      Redis will log lots of "# Error accepting a client connection: ...".
      
      We can provide the ability to disable logging so that users can temporarily turn
      off logging and turn it back on after the problem is resolved.
      07ea2204
    • Shaya Potter's avatar
      Fix memory leak when RM_Call's RUN_AS_USER fails (#12158) · 71e6abe4
      Shaya Potter authored
      previously the argv wasn't freed so would leak.  not a common case, but should be handled.
      
      Solution: move RUN_AS_USER setup and error exit to the right place.
      this way, when we do `goto cleanup` (instead of return) it'll automatically do the right thing (including autoMemoryAdd)
      Removed the user argument from moduleAllocTempClient (reverted to the state before 6e993a5d
      
      )
      Co-authored-by: default avatarOran Agra <oran@redislabs.com>
      71e6abe4
  18. 22 May, 2023 2 commits
    • Binbin's avatar
      Optimize HRANDFIELD and ZRANDMEMBER case 3 when listpack encoded (#12205) · 006ab26c
      Binbin authored
      Optimized HRANDFIELD and ZRANDMEMBER commands as in #8444,
      CASE 3 under listpack encoding. Boost optimization to CASE 2.5. 
      
      CASE 2.5 listpack only. Sampling unique elements, in non-random order.
      Listpack encoded hashes / zsets are meant to be relatively small, so
      HRANDFIELD_SUB_STRATEGY_MUL / ZRANDMEMBER_SUB_STRATEGY_MUL
      isn't necessary and we rather not make copies of the entries. Instead, we
      emit them directly to the output buffer.
      
      Simple benchmarks shows it provides some 400% improvement in HRANDFIELD
      and ZRANGESTORE both in CASE 3.
      
      Unrelated changes: remove useless setTypeRandomElements and fix a typo.
      006ab26c
    • binfeng-xin's avatar
      optimize spopwithcount propagation (#12082) · 38e284f1
      binfeng-xin authored
      
      
      A single SPOP with command with count argument resulted in many SPOP
      commands being propagated to the replica.
      This is inefficient because the key name is repeated many times, and is also
      being looked-up many times.
      also it results in high QPS metrics on the replica.
      To solve that, we flush batches of 1024 fields per SPOP command.
      Co-authored-by: default avatarzhaozhao.zz <zhaozhao.zz@alibaba-inc.com>
      38e284f1
  19. 18 May, 2023 3 commits
    • Binbin's avatar
      Performance improvement to ZADD and ZRANGESTORE, convert to skiplist and... · 48757934
      Binbin authored
      Performance improvement to ZADD and ZRANGESTORE, convert to skiplist and expand dict in advance (#12185)
      
      For zsets that will eventually be stored as the skiplist encoding (has a dict),
      we can convert it to skiplist ahead of time. This change checks the number
      of arguments in the ZADD command, and converts the data-structure
      if the number of new entries exceeds the listpack-max-entries configuration.
      This can cause us to over-allocate memory if there are duplicate entries in the
      input, which is unexpected.
      
      For ZRANGESTORE, we know the size of the zset, so we can expand
      the dict in advance, to avoid the temporary dict from being rehashed
      while it grows.
      
      Simple benchmarks shows it provides some 4% improvement in ZADD and 20% in ZRANGESTORE
      48757934
    • Brennan's avatar
      Prevent repetitive backlog trimming (#12155) · 40e6131b
      Brennan authored
      When `replicationFeedSlaves()` serializes a command, it repeatedly calls
      `feedReplicationBuffer()` to feed it to the replication backlog piece by piece.
      It is unnecessary to call `incrementalTrimReplicationBacklog()` for every small
      amount of data added with `feedReplicationBuffer()` as the chance of the conditions
      being met for trimming are very low and these frequent calls add up to a notable
      performance cost. Instead, we will only attempt trimming when a new block is added
      to the replication backlog.
      
      Using redis-benchmark to saturate a local redis server indicated a performance
      improvement of around 3-3.5% for 100 byte SET commands with this change.
      40e6131b
    • YaacovHazan's avatar
      fix CMD_CALL_FROM_MODULE value (#12195) · 49845c24
      YaacovHazan authored
      CMD_CALL_FROM_MODULE overlapped CMD_CALL_REPROCESSING,
      changing its value to (1<<3)
      49845c24
  20. 17 May, 2023 1 commit