RedisTemplate scan instead of using the command keys

Scan method instead of using keys RedisTemplate

   点关注不迷路,欢迎再访!		

Redis is single-threaded, command keys make thread is blocked, and the keys are implemented in a way traversal time complexity is O (n), the more Redis library key, the longer blocked when the seek time, if this when a large number of service request delivery Redis, could lead to the collapse of Redis, so the online environment must disable keys command.

The scan command is achieved by means of incremental iterations, each execution only return a small amount of locations and index key, we have multiple calls
to get all the collection of key scan [subscript position] command. It's like when we eat buffet to take less to take the same ground, each taking a small amount of data, it is less time-consuming (but certainly time consuming than the total of the command keys for a long time), it will not block the thread.

	public static final String SERVER_NAME = "tpaic_";
	
	private RedisTemplate<?, ?> redisTemplate;
	
	public void setRedisTemplate(RedisTemplate<?, ?> redisTemplate) {
		this.redisTemplate = redisTemplate;
	}

	public Set<String> getTotalKeys() {
	    Set<String> allUsers =redisTemplate.execute(new RedisCallback<Set<String>>() {
	      @Override
	      public Set<String> doInRedis(RedisConnection connection) throws DataAccessException {
	        Set<String> partUers = new HashSet<>();
	        // 放在try中自动释放cursor
	        try (Cursor<byte[]> cursor = connection.scan(new ScanOptions.ScanOptionsBuilder()
	                .match(SERVER_NAME + "*").count(1000).build())) {
	          while (cursor.hasNext()) {
	            partUers.add(new String(cursor.next()));
	          }
	        } catch (IOException e) {
	        	logger.error("getTotalUsers cursor close {}", e);
	        }
	        System.out.println(partUers);
	        return partUers;
	      }
	    });
		return allUsers;
	}


   /**
	 * 刷新缓存
    */
	@Override
	protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception {
		try {
			Set<String> keys = sgetTotalKeys();
			logger.info("即将刷新redis缓存:" + keys);
			for (String key : keys) {
				redisTemplate.delete(key);
			}
		} catch (Exception e) {
			logger.error(e);
		}
	}
Published 101 original articles · won praise 33 · views 20000 +

Guess you like

Origin blog.csdn.net/qq_39443053/article/details/103464731