前言
搞技术就是动手,动手再动手,实践出真知,毕竟最终是要解决问题的呢,废话不多讲,开搞,主要是为了记录一下,毕竟过程还是有点艰辛呢
需求(target)
- Windows 电脑 装一个虚拟机
- 用虚拟机构造Linux 系统
- 下载Docker 搭建Redis 集群
- 代码交互集群
过关斩将
- 检查电脑是否开启虚拟话化
- VMware 或者 VirtualBox 等虚拟机软件
以VirtualBox 为例 (根据个人喜好)
1. 进入官网:
https://www.virtualbox.org/
2. 下载对应版本的压缩包文件:
![virtualbox](https://img-blog.csdnimg.cn/c489543054784b50bdaa6807a4a2d462.png)
3.安装 (选择合适的物理盘)
4. 验证
快速搭建Linux(使用镜像)
1.使用vagrant
2.官网:
https://www.vagrantup.com/downloads
https://app.vagrantup.com/boxes/search
3. 安装 (电脑会自动重启)
4. 验证
win + R cmd 黑窗口 vagrant -v
有版本号 ,ok
5.构建Linux
1. vagrant box list (看看可使用的box 列表)
2. vagrant init boxName
例 vagrant init centos-7
会在安装的对应目录下生成一个
3. vagrant up (启动并创建Linux)
有时挺快,大部分时间会失败,因为是国外服务器,如果20分钟还没好就不等了
国内镜像:
https://mirrors.ustc.edu.cn/centos-cloud/centos/7/vagrant/x86_64/images/CentOS-7.box
4.vagrant box add E:\myLinux\CentOS-7.box --name centos-7 (加入box)
4. vargrant ssh (连接)
5. 可以 使用黑窗口 也可以使用xshell
下载docker image
1.卸载之前版本
sudo yum remove -y docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-selinux \
docker-engine-selinux \
docker-engine
2. 安装需要的依赖包:
sudo yum install -y yum-utils
3. 配置阿里镜像
sudo yum-config-manager \
--add-repo \
https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
4. 更新安装docker 容器
sudo yum install docker-ce docker-ce-cli containerd.io
5. docker -v
6.sudo systemctl start docker
如果报错:
Job for docker.service failed because the control process exited with error code. See "systemctl status docker.service" and "journalctl -xe" for details.
更改文件类型:
mv daemon.json daemon.conf
6.查看docker 镜像: sudo docker images
7. 设置开机自启:sudo systemctl enable docker
8. 由于权限问题 命令前加 sudo 或者直接使用 root 账户 :su root
redis 集群搭建(3主3从)
1.docker search redis
2.docker pull redis (默认拉去最新的)
3. 创建虚拟网卡
创建虚拟网卡,主要是用于redis-cluster能于外界进行网络通信,一般常用桥接模式。
docker network create myrediscluster
4. 查看Docker 网卡信息
docker network ls
5. 查看dockerr网络详细信息
docker network inspect myrediscluster
6、补充(删除网卡信息、帮助命令)
docker network rm myrediscluster #删除网卡命令 多个中间 空格隔开
docker network --help #显示可带参数等
7. 编写配置文件
此处用到了一点 shlle 编程中 的一些命令,让我们操作更加便利
for port in $(seq 6390 6395);
do
mkdir -p /mydata/rediscluster/node-${port}/conf
touch /mydata/rediscluster/node-${port}/conf/redis.conf
cat << EOF > /mydata/rediscluster/node-${port}/conf/redis.conf
port ${port}
requirepass 1234
bind 0.0.0.0
protected-mode no
daemonize no
appendonly yes
cluster-enabled yes
cluster-config-file nodes.conf
cluster-announce-ip 192.168.56.10
cluster-node-timeout 18000
cluster-announce-port ${port}
cluster-announce-bus-port 1${port}
EOF
done
8. 启动:
for port in $(seq 6390 6395); \
do \docker run -it -d -p ${port}:${port} -p 1${port}:1${port} \--privileged=true -v /mydata/rediscluster/node-${port}/conf/redis.conf:/usr/local/etc/redis/redis.conf \--privileged=true -v /mydata/rediscluster/node-${port}/data:/data \--restart always --name redis-${port} --net myrediscluster \--sysctl net.core.somaxconn=1024 redis redis-server /usr/local/etc/redis/redis.conf
done
9. 进入容器:
docker exec -it redis-6392 /bin/bash
10. 创建集群:
redis-cli -a 1234 --cluster create 192.168.56.10:6390 192.168.56.10:6391 192.168.56.10:6392 192.168.56.10:6393 192.168.56.10:6394 192.168.56.10:6395 --cluster-replicas 1
11. 先停止运行,再删除(重新来)
for port in $(seq 6390 6395);
do
docker stop redis-${port}
done
for port in $(seq 6390 6395);
do
docker rm redis-${port}
done
12. 命令解释:
port:节点端口;
requirepass:设置密码,访问时需要验证
protected-mode:保护模式,默认值 yes,即开启。开启保护模式以后,需配置 bind ip 或者设置访问密码;关闭保护模式,外部网络可以直接访问;
daemonize:是否以守护线程的方式启动(后台启动),默认 no;
appendonly:是否开启 AOF 持久化模式,默认 no;
cluster-enabled:是否开启集群模式,默认 no;
cluster-config-file:集群节点信息文件;
cluster-node-timeout:集群节点连接超时时间;
cluster-announce-ip:集群节点 IP (对外通讯的地址 或者配置 docker 宿主机地址)
cluster-announce-port:集群节点映射端口;
cluster-announce-bus-port:集群节点总线端口。
启动:
-it:交互
-d:后台运行,容器启动完成后打印容器
–privileged:是否让docker 应用容器 获取宿主机root权限(特殊权限-)
-p :端口映射
-v:文件挂载
–sysctl参数来设置系统参数,通过这些参数来调整系统性能
–restart always:在容器退出时总是重启容器
–name:给容器取名
–net myrediscluster:使用我们创建的虚拟网卡(想详细了解,可以去看看Docker 网络方面知识)
问题&图片展示
上面搭建成功就可以操作了
问题
p1 : Waiting for the cluster to join
p2: 拒绝连接p3: MOVED (-c 使用集群模式访问)
p4:
[ERR] Node 172.18.0.2:6392 is not empty. Either the node already knows other nodes (check with CLUSTER NODES) or contains some key in database 0
上面问题根源都是IP 地址的问题
ifconfig
ip addr
docker inspect redis-6395 | grep IP (docker image ip info)
ping
代码连接
1. 依赖
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>3.7.0</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
<version>2.11.1</version>
</dependency>
2. 单节点demo
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.Jedis;
/**
* @className RedisSingletonDemo
* @description:
* @date 2023/9/1 16:36
* @created by windBird
*/
public class RedisSingletonDemo {
public static void main(String[] args) {
Jedis jedis = new Jedis(new HostAndPort("192.168.56.10",6379));
jedis.set("redisSingleton","我通了");
System.out.println(jedis.get("redisSingleton"));
}
}
3. 集群:
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.JedisCluster;
import redis.clients.jedis.JedisPoolConfig;
import java.util.LinkedHashSet;
import java.util.Set;
/**
* @className RedisDemo
* @description:
* @date 2023/8/14 22:50
* @created by windBird
*/
public class RedisDemo {
public static void main(String[] args) {
JedisCluster cluster =null;
try {
Set<HostAndPort> nodes = new LinkedHashSet<HostAndPort>();
//一般选用slaveof从IP+端口进行增删改查,不用master
nodes.add(new HostAndPort("192.168.56.10", 6390));
nodes.add(new HostAndPort("192.168.56.10", 6391));
nodes.add(new HostAndPort("192.168.56.10", 6392));
nodes.add(new HostAndPort("192.168.56.10", 6393));
nodes.add(new HostAndPort("192.168.56.10", 6394));
nodes.add(new HostAndPort("192.168.56.10", 6395));
// Jedis连接池配置
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
// 最大空闲连接数, 默认8个
jedisPoolConfig.setMaxIdle(100);
// 最大连接数, 默认8个
jedisPoolConfig.setMaxTotal(500);
//最小空闲连接数, 默认0
jedisPoolConfig.setMinIdle(0);
// 获取连接时的最大等待毫秒数(如果设置为阻塞时BlockWhenExhausted),如果超时就抛异常, 小于零:阻塞不确定的时间, 默认-1
jedisPoolConfig.setMaxWaitMillis(-1); // 设置2秒
//对拿到的connection进行validateObject校验
jedisPoolConfig.setTestOnBorrow(true);
//未设置auth Password
// JedisCluster jedis = new JedisCluster(nodes, jedisPoolConfig);
//设置auth Password
JedisCluster jedis = new JedisCluster(nodes,20000,3000,10,"1234", new JedisPoolConfig());
System.out.println(jedis.get("weather"));
jedis.set("name","sugar");
jedis.set("address","china");
System.out.println(jedis.exists("name"));
System.out.println(jedis.get("name"));
System.out.println(jedis.get("address"));
}catch(Exception e) {
e.printStackTrace();
}finally {
if(null !=cluster)
cluster.close();
}
}
}
docker ps -a
docker restart redis (CONTAINER ID 或者 names)
集群超时
批量重启cluster nodes
for port in
(
s
e
q
63906395
)
;
d
o
d
o
c
k
e
r
r
e
s
t
a
r
t
r
e
d
i
s
−
(seq 6390 6395); do docker restart redis-
(seq63906395);dodockerrestartredis−{port}
done
重新设值:
docker exec -it redis-6392 /bin/bash
redis-cli -c -a 1234 -h 192.168.56.10 -p 6392