redis-cli连接并管理redis集群
某些场景下,redis集群以内网ip发现节点并提供服务,所以只能在服务器环境下以内网ip访问,此时redis-cli无疑是最可靠的工具。而各种gui工具都傻眼了(当然web ui类工具除外)。
redis-cli nodejs版
redis-cli nodejs版可以脱离redis-server独立安装。
安装
yum install epel-release -y
yum install nodejs npm -y
npm install -g redis-cli
ln -s rdcli /usr/local/bin/redis-cli
连接集群
redis-cli -c -a password -h 192.168.0.182 -p 8001
查看节点
192.168.0.182:8001> cluster nodes
输出如下:
25c0ec80c979ce3a1d5a86b8ee1fb41931a58630 192.168.0.184:8002@18002 slave 13028997bdcfd78e4bbe751875300856b6712f28 0 1686104553205 5 connected
2b824a73ed63d974a44a157153a97caf84d1a386 192.168.0.182:8002@18002 master - 0 1686104555213 7 connected 5461-10922
44c2e3456cef26dc8e06f286989c9a294bf44b5a 192.168.0.184:8001@18001 master - 0 1686104551198 1 connected 0-5460
13028997bdcfd78e4bbe751875300856b6712f28 192.168.0.182:8001@18001 myself,master - 0 1686104553000 5 connected 10923-16383
61bca4eb20f3b3a1dd283e21f9554300892fb36c 192.168.0.59:8001@18001 slave 2b824a73ed63d974a44a157153a97caf84d1a386 0 1686104554209 7 connected
f9e76dd99eb7ee48481b2f4ac0ae76862ec27fea 192.168.0.59:8002@18002 slave 44c2e3456cef26dc8e06f286989c9a294bf44b5a 0 1686104551000 1 connected
redis完整安装包含的redis-cli
例如redis docker container名称为redis-server:
连接集群
docker exec -it redis-server redis-cli -c -a password -h 192.168.0.182 -p 8001
使用方式与nodejs版相同。
使用redis集群公网ip访问
redis集群内部使用内网ip重定向,这导致使用外部网络访问时,有概率被重定向到其他节点的内网ip,导致查询失败。为此,我写了一段Java代码,并发请求所有redis节点,并丢弃被重定向的请求,从而可以快速完成redis命令的执行。
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
public class RedisCli {
private static final String[] ADDRESS = {
"redis_host1:6379",
"redis_host2:6379",
"redis_host3:6379"
};
private static final String PASSWORD = "your_password";
private static final ExecutorService executorService =
Executors.newFixedThreadPool(ADDRESS.length);
public static void main(String[] args) {
String params = String.join(" ", args);
System.out.printf("params:\n%s\n", params);
if (params.isBlank()) {
return;
}
String template = "redis-cli.cmd -c -u redis://default:%s@%s " + params;
List<Future<?>> futures = new ArrayList<>(ADDRESS.length);
for (String address : ADDRESS) {
String command = String.format(template, PASSWORD, address);
Future<?> future = executorService.submit(
() -> {
InputStream inputStream = null;
try {
Process process = Runtime.getRuntime().exec(command);
inputStream = process.getInputStream();
byte[] buffer = new byte[2048];
int length;
StringBuilder builder = new StringBuilder();
while ((length = inputStream.read(buffer)) != -1) {
builder.append(new String(buffer, StandardCharsets.UTF_8));
}
if (!builder.toString().startsWith("-> Redirected")) {
System.out.println("result:");
System.out.print(builder);
System.exit(0);
}
} catch (IOException e) {
System.err.printf("处理错误: %s", e.getMessage());
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
}
}
}
});
futures.add(future);
}
for (Future<?> future : futures) {
try {
future.get(2, TimeUnit.SECONDS);
} catch (Exception e) {
System.out.println("执行超时...");
}
}
executorService.shutdown();
}
}
使用示例
# 编译
javac RedisCli.java
java RedisCli set redis:key test
java RedisCli get redis:key
java RedisCli del redis:key