Redis集群主要有五种方案:
官方cluster方案、twemproxy代理方案、哨兵模式、Codis、客户端分片。
其中以豌豆荚的Codis使用最多,本文主要介绍Codis。
1. 安装最新版 3.2
1) java 环境
yum -y install java-1.8.0
2)go环境
tar zxvf /root/go1.8.3.linux-amd64.tar.gz -C /usr/local/
/usr/local/go/bin/go version
mkdir -p /data/go
echo 'export PATH=$PATH:/usr/local/go/bin:/usr/local/codis/bin' >>/etc/profile
echo 'export GOPATH=/data/go' >>/etc/profile
source /etc/profile
go env GOPATH
3) 安装codis
4)安装zookeeper
zookeeper 至少部署 3台
1. 角色划分
192.168.180.120 codis120 codis-server zookeeper
192.168.180.121 codis121 codis-server zookeeper
192.168.180.122 codis122 codis-server zookeeper
192.168.180.123 codis123 codis-server codis-proxy nginx-tcp lvs
192.168.180.124 codis124 codis-server codis-proxy nginx-tcp lvs
192.168.180.125 codis125 codis-server codis-dashboard codis-fe
2. 启动codis-dashobard(codis125上操作)
修改dashboard.toml配置文件:
coordinator_name = "zookeeper"
coordinator_addr = "192.168.180.120:2181,192.168.180.121:2181,192.168.180.122:2181"
product_name = "codis-product1"
product_auth = ""
admin_addr = "0.0.0.0:18080"
启动命令:
./admin/codis-dashboard-admin.sh start
3. 启动codis-proxy(codis123与codis124上操作)
修改codis-proxy启动脚本:
cat admin/codis-proxy-admin.sh | grep DASH
CODIS_DASHBOARD_ADDR="192.168.180.125:18080"
修改proxy.toml配置:
cat config/proxy.toml|grep -Ev "^#|^$"
product_name = "codis-product1"
product_auth = ""
session_auth = ""
admin_addr = "0.0.0.0:11080"
proto_type = "tcp4"
proxy_addr = "0.0.0.0:19000"
启动codis-proxy脚本:
./admin/codis-proxy-admin.sh start
检查日志和端口:
cat log/codis-proxy.log
netstat -tulpn | grep codis-proxy
4. 启动codis-server(需要在所有上操作)
1)修改启动脚本
vim /usr/local/codis/admin/codis-server-admin-6379.sh start
vim /usr/local/codis/admin/codis-server-admin-6380.sh start
主要注意以下几点
[root@codis125 codis]# cat /usr/local/codis/admin/codis-server-admin-6379.sh |grep -Ev "^#|^$"|grep 6379
CODIS_SERVER_PID_FILE=/data/codis/6379/redis_6379.pid
CODIS_SERVER_LOG_FILE=/data/codis/6379/redis_6379.log
CODIS_SERVER_CONF_FILE=$CODIS_CONF_DIR/redis-6379.conf
2)修改服务配置
[root@codis120 codis]# mkdir -p /data/redis/6379
[root@codis120 codis]# mkdir -p /data/redis/6380
[root@codis120 codis]# vim /usr/local/codis/config/redis-6379.conf
[root@codis120 codis]# vim /usr/local/codis/config/redis-6380.conf
主要是注意以下几点
[root@codis120 codis]# cat /usr/local/codis/config/redis-6379.conf |grep -Ev "^#|^$"|grep 6379
port 6379
pidfile /data/redis/6379/redis_6379.pid
logfile "/data/redis/6379/redis_6379.log"
dir /data/redis/6379
3)启动codis-server服务
[root@codis120 codis]# ./admin/codis-server-admin-6379.sh start
/usr/local/codis/admin/../config/redis-6379.conf
starting codis-server ...
[root@codis120 codis]# ./admin/codis-server-admin-6380.sh start
/usr/local/codis/admin/../config/redis-6380.conf
starting codis-server ...
5. 启动codis-fe(codis125上操作)
1)修改codis-fe启动脚本
[root@codis125 codis]# cat admin/codis-fe-admin.sh
主要修改这几行
#!/usr/bin/env bash
#COORDINATOR_NAME="filesystem"
#COORDINATOR_ADDR="/tmp/codis"
COORDINATOR_NAME="zookeeper"
COORDINATOR_ADDR="192.168.180.120:2181,192.168.180.121:2181,192.168.180.122:2181"
2)启动codis-fe脚本
[root@codis125 codis]# ./admin/codis-fe-admin.sh start
3)访问面板
http://192.168.188.125:9090/#codis-product1
6. codis-fe面板操作
1)通过codis-fe添加group
通过web浏览器访问集群管理页面(fe地址:http://192.168.188.125:9090/#codis-product1) 选择我们刚搭建的集群 codis-product1,在 Proxy 栏可看到我们已经启动的 Proxy, 但是
Group 栏为空,因为我们启动的 codis-server 并未加入到集群 添加 NEW GROUP,NEW GROUP 行输入 1,再点击 NEW GROUP 即可 添加 Codis Server,Add Server 行输入我们刚刚启动的
codis-server 地址,添加到我们刚新建的 Group,然后再点击 Add Server 按钮即可。
如上依次添加6个group,12个codis-server,默认每组里面第一个添加的为主,第二个添加的设置为从,同一个节点2个实例不能设置为同一group。
2)通过codis-fe初始化solt
新增的集群 slot 状态是 offline,因此我们需要对它进行初始化(将 1024 个 slot 分配到各个 group),而初始化最快的方法可通过 fe 提供的 rebalance all slots 按钮来做,如下图
所示,点击此按钮,我们即快速完成了一个集群的搭建。
自动分配1024个solt到6个group,reblance all solts会自动分配完所以solt到6个group。
7. 代理HA
1)在codis123与codis124上安装lvs与nginx-tcp
2)配置好VIP+19000端口为第一个codis-dashboard业务线使用,其他类推
做好平滑的数据同步迁移,不影响业务正常使用。
redis-port 工具做数据迁移
参考:https://www.cnblogs.com/yotone/p/6556480.html
使用redis-port:
[www@m180p10 redis-port]$ nohup ./bin/redis-port sync --ncpu=1 --from=192.168.180.10:6001 --password=whyredis --target=192.168.180.12:19002 --auth=codiswyt >> /opt/codis/redis-port/log/redis-to-codis.log 2>&1 &
1. 如何做到不停机,数据迁移?
数据迁移过程中,如果不停机,新集群 和 旧集群 数据只能是趋近于相等,但不可能绝对相等。
我们需要考虑的是,切流量那一会新打入旧集群的缓存信息,在新集群不存在,是否会影响业务?是否可以接受?
2. 如果有影响,那么就需要考虑影响范围最小化,如何最小化?
因为缓存一旦没有信息,势必会穿透到DB, 这样DB压力会上升。
我们可以通过流量控制,开始只切5% 的流量(甚至更小 1%) 到 Codis, 观察情况,没问题逐步切流量到新集群。
3. 梳理旧集群 redis key, 分析哪些key 是必不可少的。检查迁移是否有遗漏。
4. 故障回滚方式:灰度 和线上 两份,连接新旧集群,进行切换。
使用jodis做codis的连接,在项目中封装多代理ip 轮询负载均衡,实现高可用。
pom.xml配置:
properties 文件:
codis.zkAddr=127.0.0.1:2181,127.0.0.1:2181,127.0.0.1:2181
codis.zk.proxy.dir=/jodis/codis
codis.password=
1. 代码实现
@Bean
public JedisResourcePool getPool() {
JedisPoolConfig poolConfig = new JedisPoolConfig();
poolConfig.setMaxIdle(max_idle);
poolConfig.setMaxTotal(max_active);
poolConfig.setTestOnBorrow(true); //在borrow一个jedis实例的时候,是否要进行验证操作,如果赋值true。则得到的jedis实例肯定是可以用的。
poolConfig.setTestOnReturn(true); //在return一个jedis实例的时候,是否要进行验证操作,如果赋值true。则放回jedispool的jedis实例肯定是可以用的。
poolConfig.setMaxWaitMillis(max_wait);
poolConfig.setBlockWhenExhausted(false); //连接耗尽的时候,是否阻塞,false 会抛出异常,true 阻塞直到超时。默认为true。
JedisResourcePool pool = RoundRobinJedisPool.create().poolConfig(poolConfig)
.curatorClient(zkAddr, timeout)
.password(password).zkProxyDir(zkProxyDir).build();
return pool;
}
注意:如果没有设置密码,以上代码去掉password。
封装以上jedisPool为启动时加载,注入bean,其他服务使用时,注入即可。
线上环境使用时,将127.0.0.1 换成自己的真实ip即可,这里只是范例。
2. Spring 配置方式接入
报错: JedisException- Proxy list empty
解决:
1. 检查proxy是否已经成功的添加到集群中,在zk中就可以查看。/jodis/productName路径下,看是否有对应的proxy。
2. 修改codis3的proxy.toml文件
# Set jodis address & session timeout.
jodis_addr = "127.0.0.1:2181,127.0.0.1:2181,127.0.0.1:2181"
jodis_addr必须设置
报错: Could not get a resource from the pool
查询异常详情,发现 cause by ERR Client sent AUTH, but no password is set
这里意思是服务端没有设置password,客户端链接是确使用了password ,就会报这个错误。去掉password 即可。