-ERR invalid cursor(master node idx out of range)\\r\\n. It indicates that the status of the historical shard bound to the cursor has become invalid. If the error is forcibly ignored and the iteration continues, the valid data cannot be obtained, and a dead loop may occur due to the asynchronization between the cursor and shard logic, severely consuming system resources.package com.example.service.impl;import com.example.config.RedisConnectionFactory;import com.example.service.RedisService;import redis.clients.jedis.Jedis;import redis.clients.jedis.params.ScanParams;import redis.clients.jedis.resps.ScanResult;import java.util.*;/*** TencentDB for Redis® service implementation class.*/public class RedisServiceImpl implements RedisService {//scan Maximum number of retries.private static final int MAX_RETRIES = 3;private final RedisConnectionFactory connectionFactory;/*** Construction function.*/public RedisServiceImpl() {this.connectionFactory = RedisConnectionFactory.getInstance();}/*** scan Best practices.* @param pattern Matching mode.* @param count Number of returned keys for each iteration.*/@Overridepublic void scanKeys(String pattern, int count) {try (Jedis jedis = connectionFactory.getConnection()) {int retryCount = 0;boolean scanCompleted = false;int totalKeysProcessed = 0;int totalBatches = 0;long startTime = System.currentTimeMillis();// Capture the reported errors during the scan process and restart the scan from 0 upon encountering an error.while (!scanCompleted && retryCount <= MAX_RETRIES) {String cursor = ScanParams.SCAN_POINTER_START;ScanParams scanParams = new ScanParams();scanParams.count(count);scanParams.match(pattern);try {while (true) {ScanResult<String> scanResult = jedis.scan(cursor, scanParams);List<String> keys = scanResult.getResult();totalBatches++;if (!keys.isEmpty()) {totalKeysProcessed += keys.size();// Process the obtained keys - business logic.processKeysWithBusinessLogic(keys);}cursor = scanResult.getCursor();// Scan is completed when the cursor is "0".if (cursor.equals(ScanParams.SCAN_POINTER_START)) {long endTime = System.currentTimeMillis();double timeElapsed = (endTime - startTime) / 1000.0;System.out.println("\\n🎉 Scan completed.");System.out.println("Total number of batches: " + totalBatches);System.out.println("Total number of keys: " + totalKeysProcessed);System.out.println("Scan duration: " + timeElapsed + " Second");System.out.println("Average speed: " + (totalKeysProcessed / timeElapsed) + " Key/Second");scanCompleted = true;break;}}} catch (Exception e) {retryCount++;System.err.println("⚠️ An error occurs during scanning, and attempting to rescan from 0. (" + retryCount + "/" + MAX_RETRIES + ")");e.printStackTrace();// The maximum number of retries is exceeded, and the retry is terminated.if (retryCount > MAX_RETRIES) {throw new RuntimeException("Maximum number of retries is reached. (" + MAX_RETRIES + "),Scan failed.", e);}}}} catch (Exception e) {System.err.println("Scanning keys failed.: " + e.getMessage());e.printStackTrace();}}/*** Business logic of processing keys.*/private void processKeysWithBusinessLogic(List<String> keys) {// Business processing logic....System.out.println(keys.size());}}
Feedback