这段JavaScript代码的主要功能是从Redis数据库中扫描并检索所有符合特定模式的键(key)。它使用了redis
和async
两个Node.js模块。这里使用了async.series
来定义一个异步任务的序列。首先连接Redis,然后扫描Redis键。所有任务完成后,执行最终的回调函数。在第一个任务中,代码创建了一个Redis客户端,并设置了错误处理函数。如果连接成功,就调用回调函数。在第二个任务中,调用了my_redis_scan_keys
函数来扫描Redis键。该函数使用Redis的SCAN
命令来迭代地检索键。SCAN
命令返回一个游标和一个键的数组。如果游标不是'0',表示还有更多的键需要检索,函数会递归地调用自己,使用新的游标继续检索。如果游标是'0',表示已经检索完所有的键。在每次递归调用中,函数都会将新检索到的键添加到strKeyList
数组中。当检索完成时,会调用回调函数。
// 用scan方式,遍历redis中的所有key
var async = require("async");
var redis = require('redis');
var g_strRedisHost = '127.0.0.1';
var g_iRedisPort = 6379;
var g_iRedisDb = 0;
var g_iScanRoundNo = 0;
var g_iScanSleepMilliSec = 1;
var g_strScanPattern = "22*";
var g_iScanCount = 100000;
var g_tRedisClient = null;
async.series([
function(callback) {
console.log('S-1: connecting to redis...');
g_tRedisClient = redis.createClient({host: g_strRedisHost, port: g_iRedisPort, db: g_iRedisDb});
g_tRedisClient.on('error', function(err) {
console.log('Error: ' + err);
});
callback(null, 'one');
},
function(callback) {
console.log('S-2: redis scanning...');
my_redis_scan_keys('0', g_strScanPattern, [], callback);
}
],
// optional callback
function(err, results) {
// results is now equal to ['one', 'two']
console.log('results:', results);
console.log('S-END:', 'EXIT PROCESS');
process.exit(0);
}
);
function my_redis_scan_keys(strCursor, strPattern, strKeyList, callback) {
g_iScanRoundNo ++;
console.log('RoundNo.', g_iScanRoundNo, 'starting...');
if (!strKeyList) {
strKeyList = [];
}
g_tRedisClient.scan(strCursor, 'MATCH', strPattern, 'COUNT', g_iScanCount, function(err, result) {
if (err) {
throw err;
}
var strThisKeys = result[1];
var strNextCursor = result[0];
strKeyList = strKeyList.concat(strThisKeys);
if (strNextCursor !== '0') {
// 继续遍历
console.log('RoundNo.', g_iScanRoundNo, 'get', strThisKeys.length, 'keys');
setTimeout(function() {
my_redis_scan_keys(strNextCursor, strPattern, strKeyList, callback);
}, g_iScanSleepMilliSec);
} else {
// 遍历完成
console.log('RoundNo.', g_iScanRoundNo, 'get', strThisKeys.length, 'keys', '--', 'completed!');
console.log(strKeyList.slice(0,5));
console.log(strKeyList.slice(-5));
console.log('strKeyList.length:', strKeyList.length);
callback(null, 'two');
}
});
}
这个函数是执行Redis键扫描的核心部分。它接收当前游标、扫描模式、已检索到的键的列表和回调函数作为参数。
在函数内部,它使用Redis客户端的scan
方法执行扫描操作,并处理返回的结果。如果游标不是'0',它会设置一个定时器来递归调用自己,使用新的游标继续扫描。如果游标是'0',表示扫描完成,它会打印出已检索到的键的部分列表和总数,并调用回调函数。
注意,这个代码示例中使用了全局变量来存储扫描的状态(如游标和键的列表)。这在实际应用中可能不是最佳实践,因为它可能导致代码更难理解和维护。更好的做法可能是将这些状态封装在一个对象中,并将该对象作为参数传递给函数。
此外,这个代码示例没有处理Redis客户端连接失败或SCAN
命令执行失败的情况。在实际应用中,你可能需要添加更多的错误处理逻辑来确保代码的健壮性。