Search code examples
javaredisspring-data-redis

Can we use Spring data redis - partialUpdate in Production env?


I have been using partialUpdate, redisKVTemplate.update(entity) and it works well at our development environment, but when run this code in Production environment then Redis server CPU usage is high (~100%) with only several hundreds of transactions. I have investigated bases on https://redis.io/docs/reference/optimization/latency/ and see:

  • When using partialUpdate, it call many KEYS redis commands. Checked by run: redis-cli slowlog get 200 when partialUpdate is called.
  • In the upper link, there is an importance note: a VERY common source of latency generated by the execution of slow commands is the use of the KEYS command in production environments. KEYS, as documented in the Redis documentation, should only be used for debugging purposes.

So does it mean partialUpdate should not use in PD env? if yes, which way should be use for partial update in PD env?


Solution

  • If you look at https://github.com/spring-projects/spring-data-redis/blob/0e847a3da865481d40c353ddc8507fbe9aec2e0a/src/main/java/org/springframework/data/redis/core/RedisKeyValueAdapter.java#L399 you can see the amount of work that the update(PartialUpdate<?> update) is doing.

    I don't know exactly where the KEYS commands are issued in your case but it could be related to secondary index maintenance. You could test updating the specific field in your Hashes using the RedisHashCommands directly. See https://docs.spring.io/spring-data/redis/docs/current/api/org/springframework/data/redis/connection/RedisHashCommands.html

    Mainly hSet, hSetNX and hMSet. In which case you will have to calculate the Redis key for your entries (using you entities IDs and the classname if you didn't use a prefix with @RedisHash)).

    Note: If you are going to do multiple operations, note how the method linked above uses RedisOperations to ensure that everything happens over a single connection:

    redisOps.execute((RedisCallback<Void>) connection -> { ... }