docker搭建redis集群踩坑记录Could not get a resource from the pool
skyeye办公管理系统
skyeye项目采用了redis集群的方式进行缓存存储,需要搭建相应的运行环境。
#redis集群
redis:
clusterNodes: ${redis.ip1}:${redis.host1},${redis.ip2}:${redis.host2},${redis.ip3}:${redis.host3},${redis.ip4}:${redis.host4},${redis.ip5}:${redis.host5},${redis.ip6}:${redis.host6}
#连接超时时间(毫秒)
timeout: 10000
#redis操作的超时时间
commandTimeout: 10000
pool:
#连接池最大连接数(使用负值表示没有限制)
max-active: 10
#连接池中的最大空闲连接
max-idle: 8
#连接池中的最小空闲连接
min-idle: 2
#连接池最大阻塞等待时间(使用负值表示没有限制)
max-wait: 100
一开始采用的是慕课网资料中的方式进行集群搭建 采用的redis镜像是:(yyyyttttwwww/redis–慕课网老师提供的应该是把配置文件以及Ruby工具都包含的镜像)
具体步骤可参考:redis集群搭建
1.第一步需要创建内部网段
docker network create --subnet=172.19.0.0/16 net2
2.创建6节点Redis容器
docker run -it -d --name r1 -p 5001:6379 --net=net2 --ip 172.19.0.2 redis bash
docker run -it -d --name r2 -p 5002:6379 --net=net2 --ip 172.19.0.3 redis bash
docker run -it -d --name r3 -p 5003:6379 --net=net2 --ip 172.19.0.4 redis bash
docker run -it -d --name r4 -p 5004:6379 --net=net2 --ip 172.19.0.5 redis bash
docker run -it -d --name r5 -p 5005:6379 --net=net2 --ip 172.19.0.6 redis bash
3.启动6节点Redis服务器
#进入r1节点
docker exec -it r1 bash
cp /home/redis/redis.conf /usr/redis/redis.conf
cd /usr/redis/src
./redis-server ../redis.conf
#进入r2节点
docker exec -it r2 bash
cp /home/redis/redis.conf /usr/redis/redis.conf
cd /usr/redis/src
./redis-server ../redis.conf
#进入r3节点
docker exec -it r3 bash
cp /home/redis/redis.conf /usr/redis/redis.conf
cd /usr/redis/src
./redis-server ../redis.conf
#进入r4节点
docker exec -it r4 bash
cp /home/redis/redis.conf /usr/redis/redis.conf
cd /usr/redis/src
./redis-server ../redis.conf
#进入r5节点
docker exec -it r5 bash
cp /home/redis/redis.conf /usr/redis/redis.conf
cd /usr/redis/src
./redis-server ../redis.conf
#进入r6节点
docker exec -it r6 bash
cp /home/redis/redis.conf /usr/redis/redis.conf
cd /usr/redis/src
./redis-server ../redis.conf
4.创建Cluster集群
#在r1节点上执行下面的指令
cd /usr/redis/src
mkdir -p ../cluster
cp redis-trib.rb ../cluster/
cd ../cluster
#创建Cluster集群
./redis-trib.rb create --replicas 1 172.19.0.2:6379 172.19.0.3:6379 172.19.0.4:6379 172.19.0.5:6379 172.19.0.6:6379 172.19.0.7:6379
集群创建成功,外部通过可视化工具也都可以正常访问。但是启动项目时,进行登陆操作报错:Could not get a resource from the pool
redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool at redis.clients.util.Pool.getResource(Pool.java:53)
at redis.clients.jedis.JedisPool.getResource(JedisPool.java:226)
at redis.clients.jedis.JedisSlotBasedConnectionHandler.getConnectionFromSlot(JedisSlotBasedConnectionHandler.java:66)
at redis.clients.jedis.JedisClusterCommand.runWithRetries(JedisClusterCommand.java:116)
at redis.clients.jedis.JedisClusterCommand.runWithRetries(JedisClusterCommand.java:141)
at redis.clients.jedis.JedisClusterCommand.runWithRetries(JedisClusterCommand.java:141)
at redis.clients.jedis.JedisClusterCommand.runWithRetries(JedisClusterCommand.java:141)
at redis.clients.jedis.JedisClusterCommand.runWithRetries(JedisClusterCommand.java:141)
at redis.clients.jedis.JedisClusterCommand.run(JedisClusterCommand.java:31)
at redis.clients.jedis.JedisCluster.set(JedisCluster.java:103) at com.skyeye.jedis.impl.JedisClientServiceImpl.set(JedisClientServiceImpl.java:57)
at com.skyeye.eve.service.impl.SysEveUserServiceImpl.queryUserToLogin(SysEveUserServiceImpl.java:232)
最开始以为时连接池连接数太小,加大发现并无卵用
debug之后发现可能和集群ip设置有关系
似乎连接池获取连接资源时使用的是集群中配置的节点,参考了一些文章。
参考1
参考2
于是决定对原有的节点配置文件进行删除重配
错误提示是:
slot插槽被占用了(这是 搭建集群前时,以前redis的旧数据和配置信息没有清理干净。)
解决方案是: 用redis-cli 登录到每个节点执行 flushall 和 cluster reset 就可以了。更改所有redis配置中的ip为虚拟机ip。
外部单点都可以访问,但是无法建立集群,卡在Waiting for the cluster to join。
。。。。。就很烦。。
于是干脆换一种方式重新搭建集群。
先stop所有容器,再rm进行删除。
1.这次pull官方镜像
docker pull redis
2.创建一个集群相关的文件夹,之后进行映射由于配置文件等挂载
mkdir -p /home/redis-cluster
3.创建配置模板信息
vim redis-cluster.tmpl
内容如下:
port ${PORT}
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
cluster-announce-ip 192.168.168.131
cluster-announce-port ${PORT}
cluster-announce-bus-port 1${PORT}
appendonly yes
4.执行如下脚本,进行文件的循环创建
for port in `seq 7000 7005`; do \
mkdir -p ./${port}/conf \
&& PORT=${port} envsubst < ./redis-cluster.tmpl > ./${port}/conf/redis.conf \
&& mkdir -p ./${port}/data; \
done
6.执行脚本循环创建容器
for port in `seq 7000 7005`; do \
docker run -d -ti -p ${port}:${port} -p 1${port}:1${port} \
-v /home/redis-cluster/${port}/conf/redis.conf:/usr/local/etc/redis/redis.conf \
-v /home/redis-cluster/${port}/data:/data \
--restart always --name redis-${port} --net host \
--sysctl net.core.somaxconn=1024 redis redis-server /usr/local/etc/redis/redis.conf; \
done
这里遇到一个问题,容器一直提示重启
查看日志发现生成的conf文件有部分问题,可能是之前脚本循环创建时有小错误,手动改正一下。看日志还是很重要滴!!
docker logs XXXX
容器启动成功
接下来进入某个容器搭建集群(这次节点IP配置的是虚拟机IP而不是内部网段对应IP!!)
docker exec -it redis-7000 bash
redis-cli --cluster create 192.168.239.254:7000 192.168.239.254:7001 192.168.239.254:7002 192.168.239.254:7003 192.168.239.254:7004 192.168.239.254:7005
看到绿色就很开心啦,生活过得去~~
接下来启动项目测试下下。
成功~