Welcome to umMON + Technical Dry Goods 3: Redis cluster environment how to batch delete cache by prefix. Hope it can be helpful to developers in practical application.

The background,

Add cache support to the data source list. Multiple values can be transmitted in the types field, such as APP, mini, web, etc. The following cache keys will be constructed.

  • application_list:123456:app
  • application_list:123456:mini
  • application_list:123456:web
  • application_list:123456:app,mini
  • application_list:123456:app,web
  • application_list:123456:mini,web
  • application_list:123456:app,mini,web
  • .

When creating, updating, or deleting an application, you need to delete the cache of the old version in batches.

Second, the train of thought

1. Query all related keys according to the prefix ‘application_list:123456’

2. Iterate over keys and delete keys

** @param prefix prefix */ public static void deleteByPrefix(String prefix) {long start = System.currentTimeMillis(); Set<String> keys; try { keys = jedisCluster.keys(CacheKeyUtils.buildCacheKey(prefix, "*")); LOGGER.info("cache keys {} with prefix {}", keys, prefix); if (keys ! = null && ! keys.isEmpty()) { jedisCluster.del(keys.toArray(new String[keys.size()])); } } catch (Exception e) { LOGGER.error("cache deleteByPrefix error, prefix = {}", prefix, e); throw new BusinessException(CoreErrorEnum.CACHE_DELETE_ERROR, prefix); } long end = System.currentTimeMillis(); LOGGER.info("cache deleteByPrefix success, prefix = {}, cost {} ms", prefix, (end - start)); }Copy the code

Three, problem,

Execute an error, “JedisCluster only supports KEYS commands with patterns containing hash-tags ( curly-brackets enclosed strings )”

Redis Cluster uses virtual slot partitions, and all keys are mapped to integer slots 0 to 16383 based on the hash function. Slot = CRC16(key) % 16384. Each node is responsible for maintaining a part of slots and the key value data mapped to the slots, as shown in the figure:

Four,

Generate cache keys using hashtags

if (StringUtils.isNotEmpty(platform)) { cacheKey = CacheKeyUtils.buildCacheKey( CacheKeyUtils.buildHashTag(CacheConstant.APPLICATION_LIST, String.valueOf(userId)), "platform", platform); } else if (types ! = null && ! types.isEmpty()) { cacheKey = CacheKeyUtils.buildCacheKey( CacheKeyUtils.buildHashTag(CacheConstant.APPLICATION_LIST, String.valueOf(userId)), "types", types.stream().sorted().collect(Collectors.joining(","))); } else { cacheKey = CacheKeyUtils.buildCacheKey( CacheKeyUtils.buildHashTag(CacheConstant.APPLICATION_LIST, String.valueOf(userId))); }Copy the code
  • {application_list:123456}:app
  • {application_list:123456}:mini
  • {application_list:123456}:web
  • {application_list:123456}:app,mini
  • {application_list:123456}:app,web
  • {application_list:123456}:mini,web
  • {application_list:123456}:app,mini,web
  • .

Caches full data sources for users

Query all data sources under the current user from the cache or database each time and filter by parameter.

The original link

This article is the original content of Aliyun and shall not be reproduced without permission.