Solve the pit stepped by Java Redis to delete key in HashMap

  • 2021-08-31 07:53:39
  • OfStack

Phenomenon

When Java uses Redis to delete key in HashMap, after taking out the corresponding HashMap, remove key by remove method of HashMap in Java and then call Hmset method of redis again, the overwrite will be invalid

Sample code


// Pass key Take out the corresponding HashMap
Map<String, String> ruleMap = jedisCluster.hgetAll("HashKey");
// Pass java Remove from HashMap In Key
ruleMap.remove("ruleA");
// Will remove the HashMap Re-deposit redis Adj. hashmap Medium 
jedisCluster.hmset(key, ruleMap);
// Here comes the problem , Through here HashKey From redis Take out in HashMap Discover when ruleA Adj. key The content of still exists 
Map<String, String> newRuleMap = jedisCluster.hgetAll("HashKey");
System.out.println(newRuleMap);

Solutions

Delete the specified Key from the specified HashMap through the hdel command:

Using HDEL key field [field...]:

Delete one or more specified fields in the hash table key, and non-existent fields will be ignored

Sample code


// Pass redis Aiming at hashmap Remove the specified key Function to process 
jedisCluster.hdel("HashKey", "ruleA");

Principle

When the hash table in redis stores values, it will only search the corresponding key value in redis for overwriting and rewriting the key existing in hashmap sent by the client.

As for the remove operation on the HashMap through the Java code, it is not perceived in redis,

Therefore, when operating through the HMSET function, redis will only find the key override, and will not execute the del operation. In fact, the deletion of hashmap and key in redis can only be done through the HDEL function

Sample code

We use the source code of redis. clients. jedis. BinaryClient. hmset method in Jedis package to see the operation when the command is finally sent to redis server for execution


// Is actually being sent to redis Before executing the command , Will HashMap Convert to byte data set in 
public void hmset(byte[] key, Map<byte[], byte[]> hash) {
  List<byte[]> params = new ArrayList();
  params.add(key);
  Iterator i$ = hash.entrySet().iterator();
  while(i$.hasNext()) {
    Entry<byte[], byte[]> entry = (Entry)i$.next();
    params.add(entry.getKey());
    params.add(entry.getValue());
  }
  this.sendCommand(Command.HMSET, (byte[][])params.toArray(new byte[params.size()][]));
}

The actual corresponding redis command is:


redis 127.0.0.1:6379> HSET HashKey "ruleA" "valA" "ruleB" "valB"

Supplement: redis whole delete, whole hash delete, batch delete, single delete, regular delete

Deletion of hash data structure for redis:


pool = redis.ConnectionPool(host='127.0.0.1',port=6381,db=0,decode_responses=True)
r = redis.Redis(connection_pool=pool)
pool = redis.ConnectionPool(host='127.0.0.1',port=6381,decode_responses=True)
r = redis.Redis(connection_pool=pool)
r = redis.Redis(host='127.0.0.1',port=6381,db=0,decode_responses=True)

The above three ways of connecting to the database have been tested to be effective, mainly because the following decode_responses parameters can omit binary writing.

Deletion of the entire database:


r.fushall()

Batch delete the whole large dictionary of hash:


r.delete(*r.keys('^test'))   # Indicates the deletion of the test Beginning hash Big dictionary. 
r.delete(key1,key2)# Indicates deletion key1 Dictionary and key2 Dictionary 

The entire hash dictionary is deleted:


r.delete(dict_name)

Batch deletion of multiple keys in a specific hash dictionary:


r.hdel(dict_name,key1)

Related articles: