redis主从与集群

redis主从与集群

 

redis(Master-Replicaset) *****
11.1 原理 (背)
  1. 副本库通过slaveof 10.0.0.51 6379命令,连接主库,并发送SYNC给主库
  2. 主库收到SYNC,会立即触发BGSAVE,后台保存RDB,发送给副本库
  3. 副本库接收后会应用RDB快照
  4. 主库会陆续将中间产生的新的操作,保存并发送给副本库
  5. 到此,我们主复制集就正常工作了
  6. 再此以后,主库只要发生新的操作,都会以命令传播的形式自动发送给副本库.
  7. 所有复制相关信息,从info信息中都可以查到.即使重启任何节点,他的主从关系依然都在.
  8. 如果发生主从关系断开时,从库数据没有任何损坏,在下次重连之后,从库发送PSYNC给主库
  9. 主库只会将从库缺失部分的数据同步给从库应用,达到快速恢复主从的目的

11.2主从数据一致性保证

min-slaves-to-write 1
min-slaves-max-lag 3

11.3 主库是否要开启持久化?
  如果不开有可能,主库重启操作,造成所有主从数据丢失!

12. 主从复制实现
  1、环境:
  准备两个或两个以上redis实例

mkdir /data/638{0..2}

配置文件示例:

cat >> /data/6380/redis.conf <<EOF
port 6380
daemonize yes
pidfile /data/6380/redis.pid
loglevel notice
logfile "/data/6380/redis.log"
dbfilename dump.rdb
dir /data/6380
requirepass 123
masterauth 123
EOF
cat >> /data/6381/redis.conf <<EOF
port 6381
daemonize yes
pidfile /data/6381/redis.pid
loglevel notice
logfile "/data/6381/redis.log"
dbfilename dump.rdb
dir /data/6381
requirepass 123
masterauth 123
EOF
cat >> /data/6382/redis.conf <<EOF
port 6382
daemonize yes
pidfile /data/6382/redis.pid
loglevel notice
logfile "/data/6382/redis.log"
dbfilename dump.rdb
dir /data/6382
requirepass 123
masterauth 123
EOF


启动:

redis-server /data/6380/redis.conf
redis-server /data/6381/redis.conf
redis-server /data/6382/redis.conf

 



主节点:6380
从节点:6381、6382

  2、开启主从:
  6381/6382命令行:

redis-cli -p 6381 -a 123 SLAVEOF 127.0.0.1 6380
redis-cli -p 6382 -a 123 SLAVEOF 127.0.0.1 6380

 

  解除:

redis-cli -p 6381 -a 123 SLAVEOF no one

  3、查询主从状态

redis-cli -p 6380 -a 123 info replication
redis-cli -p 6381 -a 123 info replication
redis-cli -p 6382 -a 123 info replication


哨兵(sentinel搭建过程)

mkdir /data/26380
cd /data/26380
vim sentinel.conf
port 26380
dir "/data/26380"
sentinel monitor mymaster 127.0.0.1 6380 1
sentinel down-after-milliseconds mymaster 5000
sentinel auth-pass mymaster 123

启动:

redis-sentinel /data/26380/sentinel.conf &>/tmp/sentinel.log &

==============================
如果有问题:
  1、重新准备1主2从环境
  2、kill掉sentinel进程
  3、删除sentinel目录下的所有文件
  4、重新搭建sentinel
================================
停主库测试:

redis-cli -p 6380 shutdown
redis-cli -p 6381
info replication

启动源主库(6380),看状态。

Sentinel管理命令:

redis-cli -p 26380

  PING :返回 PONG
  SENTINEL masters :列出所有被监视的主服务器
  SENTINEL slaves <master name>
  SENTINEL get-master-addr-by-name <master name> : 返回给定名字的主服务器的 IP 地址和端口号。
  SENTINEL reset <pattern> : 重置所有名字和给定模式 pattern 相匹配的主服务器。
  SENTINEL failover <master name> : 当主服务器失效时, 在不询问其他 Sentinel 意见的情况下, 强制开始一次自动故障迁移。

14. redis cluster(集群)
14.1 介绍
高性能
  1、在多分片节点中,将16384个槽位,均匀分布到多个分片节点中
  2、存数据时,将key做crc16(key),然后和16384进行取模,得出槽位值(0-16383之间)
  3、根据计算得出的槽位值,找到相对应的分片节点的主节点,存储到相应槽位上
  4、如果客户端当时连接的节点不是将来要存储的分片节点,分片集群会将客户端连接切换至真正  存储节点进行数据存储

高可用:
  在搭建集群时,会为每一个分片的主节点,对应一个从节点,实现slaveof的功能,同时当主节点  down,实现类似于sentinel的自动failover的功能。

  1、redis会有多组分片构成(3组)
  2、redis cluster 使用固定个数的slot存储数据(一共16384slot)
  3、每组分片分得1/3 slot个数(0-5500 5501-11000 11001-16383)
  4、基于CRC16(key) % 16384 ====》值 (槽位号)。
14.2 规划、搭建过程:
  6个redis实例,一般会放到3台硬件服务器
注:在企业规划中,一个分片的两个分到不同的物理机,防止硬件主机宕机造成的整个分片数据丢失
  端口号:7000-7005
  安装集群插件:
  EPEL源安装ruby支持

yum install ruby rubygems -y

  使用国内源
  gem sources -l
  gem sources -a http://mirrors.aliyun.com/rubygems/
  gem sources --remove https://rubygems.org/
  gem sources -l
  gem install redis -v 3.3.3

集群节点准备

mkdir /data/700{0..5}
cat > /data/7000/redis.conf <<EOF
port 7000
daemonize yes
pidfile /data/7000/redis.pid
loglevel notice
logfile "/data/7000/redis.log"
dbfilename dump.rdb
dir /data/7000
protected-mode no
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes
EOF
cat >> /data/7001/redis.conf <<EOF
port 7001
daemonize yes
pidfile /data/7001/redis.pid
loglevel notice
logfile "/data/7001/redis.log"
dbfilename dump.rdb
dir /data/7001
protected-mode no
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes
EOF
cat >> /data/7002/redis.conf <<EOF
port 7002
daemonize yes
pidfile /data/7002/redis.pid
loglevel notice
logfile "/data/7002/redis.log"
dbfilename dump.rdb
dir /data/7002
protected-mode no
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes
EOF
cat >> /data/7003/redis.conf <<EOF
port 7003
daemonize yes
pidfile /data/7003/redis.pid
loglevel notice
logfile "/data/7003/redis.log"
dbfilename dump.rdb
dir /data/7003
protected-mode no
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes
EOF
cat >> /data/7004/redis.conf <<EOF
port 7004
daemonize yes
pidfile /data/7004/redis.pid
loglevel notice
logfile "/data/7004/redis.log"
dbfilename dump.rdb
dir /data/7004
protected-mode no
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes
EOF
cat >> /data/7005/redis.conf <<EOF
port 7005
daemonize yes
pidfile /data/7005/redis.pid
loglevel notice
logfile "/data/7005/redis.log"
dbfilename dump.rdb
dir /data/7005
protected-mode no
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes
EOF

启动节点:

redis-server /data/7000/redis.conf
redis-server /data/7001/redis.conf
redis-server /data/7002/redis.conf
redis-server /data/7003/redis.conf
redis-server /data/7004/redis.conf
redis-server /data/7005/redis.conf
 ps -ef |grep redis

  root 8854 1 0 03:56 ? 00:00:00 redis-server *:7000 [cluster]
  root 8858 1 0 03:56 ? 00:00:00 redis-server *:7001 [cluster]
  root 8860 1 0 03:56 ? 00:00:00 redis-server *:7002 [cluster]
  root 8864 1 0 03:56 ? 00:00:00 redis-server *:7003 [cluster]
  root 8866 1 0 03:56 ? 00:00:00 redis-server *:7004 [cluster]
  root 8874 1 0 03:56 ? 00:00:00 redis-server *:7005 [cluster]
将节点加入集群管理

redis-trib.rb create --replicas 1 127.0.0.1:7000 127.0.0.1:7001 \
127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005

 

集群状态查看
  集群主节点状态
  

redis-cli -p 7000 cluster nodes | grep master

  集群从节点状态
  

redis-cli -p 7000 cluster nodes | grep slave

14.3 集群节点管理
  

  增加新的节点

mkdir /data/7006
mkdir /data/7007
cat > /data/7006/redis.conf <<EOF
port 7006
daemonize yes
pidfile /data/7006/redis.pid
loglevel notice
logfile "/data/7006/redis.log"
dbfilename dump.rdb
dir /data/7006
protected-mode no
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes
EOF

cat > /data/7007/redis.conf <<EOF
port 7007
daemonize yes
pidfile /data/7007/redis.pid
loglevel notice
logfile "/data/7007/redis.log"
dbfilename dump.rdb
dir /data/7007
protected-mode no
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes
EOF
redis-server /data/7006/redis.conf
redis-server /data/7007/redis.conf

  添加主节点:

redis-trib.rb add-node 127.0.0.1:7006 127.0.0.1:7000

  转移slot(重新分片)

redis-trib.rb reshard 127.0.0.1:7000

进入分片界面:

计算:
  16384/节点数 计算每个节点上应有的槽点数
  在交互界面填入该值。
  下一步:选择all 意思为新节点的槽点来自其他所有节点。
  下一步交互界面:yes
  即可。
添加一个从节点

redis-trib.rb add-node --slave --master-id 8ff9ef5b78e6da62bd7b362e1fe190cba19ef5ae 127.0.0.1:7007 127.0.0.1:7000

 

14.4 删除节点
  将需要删除节点slot移动走
  redis-trib.rb reshard 127.0.0.1:7000
  49257f251824dd815bc7f31e1118b670365e861a
  127.0.0.1:7006
  0-1364 5461-6826 10923-12287
  1365 1366 1365
删除一个节点
  删除master节点之前首先要使用reshard移除master的全部slot,然后再删除当前节点

redis-trib.rb del-node 127.0.0.1:7006 8ff9ef5b78e6da62bd7b362e1fe190cba19ef5ae

 


++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
redis集群搭建,5.0以上版本,5.0以下需要安装ruby。(未开启哨兵模式)
1。准备redis节点,并安装redis:(因为redis集群为去中心化设计,至少得6个节点,3主3从,保证投票可用主。此处虚拟机单节点伪集群)
  创建集群配置以及数据目录:

mkdir /data/redis_cluster
mkdir /data/redis_cluster/700{0..5}

在集群总目录下生成各个节点的配置(注:此处为伪集群所以一个目录生成多个节点的配置,多节点需在各个节点上配置)
mkdir 7000 7001 7002 7003 7004 7005(此处为生成伪集群六个节点的配置目录)
将源码包内生成的redis.conf文件拷贝到以上各个目录中:

cp redis.conf ../redis_cluster/7000/
cp redis.conf ../redis_cluster/7001/
cp redis.conf ../redis_cluster/7002/
cp redis.conf ../redis_cluster/7003/
cp redis.conf ../redis_cluster/7004/
cp redis.conf ../redis_cluster/7005/

(以上可以更改一个文件其余使用该文件修改端口即可)
根据目录修改相应的配置:
举例模板为:
port 7000 //端口7000,7002,7003
bind 本机ip //默认ip为127.0.0.1 需要改为其他节点机器可访问的ip 否则创建集群时无法访问对应的端口,无法创建集群
daemonize yes //redis后台运行
pidfile /var/run/redis_7000.pid //pidfile文件对应7000,7001,7002
cluster-enabled yes //开启集群 把注释#去掉
cluster-config-file nodes_7000.conf //集群的配置 配置文件首次启动自动生成 7000,7001,7002 把注释#去掉
cluster-node-timeout 15000 //请求超时 默认15秒,可自行设置 把注释#去掉
appendonly yes //aof日志开启 有需要就开启,它会每次写操作都记录一条日志 

修改端口:

sed -i 's/7000/7001/g' ../7001/redis.conf
sed -i 's/7000/7002/g' ../7002/redis.conf
sed -i 's/7000/7003/g' ../7003/redis.conf
sed -i 's/7000/7004/g' ../7004/redis.conf
sed -i 's/7000/7005/g' ../7005/redis.conf

 


启动相关服务:

/usr/local/redis/bin/redis-server /data/redis_cluster/7000/redis.conf
/usr/local/redis/bin/redis-server /data/redis_cluster/7001/redis.conf
/usr/local/redis/bin/redis-server /data/redis_cluster/7002/redis.conf
/usr/local/redis/bin/redis-server /data/redis_cluster/7003/redis.conf
/usr/local/redis/bin/redis-server /data/redis_cluster/7004/redis.conf
/usr/local/redis/bin/redis-server /data/redis_cluster/7005/redis.conf

 


检查服务:

ps -ef | grep redis
netstat -anptl | grep redis

 


创建集群
原命令 redis-trib.rb 这个工具目前已经废弃,使用redis-cli (5.0之前版本使用redis-trib.rb)

/usr/local/redis/bin/redis-cli --cluster create --cluster-replicas 1 192.168.75.33:7000 192.168.75.33:7001 192.168.75.33:7002 192.168.75.33:7003 192.168.75.33:7004 192.168.75.33:7005

 


然后输入:yes确定等集群创建
出现如下字样表示集群创建成功:
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered
验证集群:

/usr/local/redis/bin/redis-cli -c -h 192.168.75.15 -p 7000(注意-c选项启用集群链接。)
cluster info
cluster nodes

显示集群信息,正常输出则集群成功。

缓存穿透
访问一个不存在的key,缓存不起作用,请求会穿透到DB,流量大时DB会挂掉。
解决方案
采用布隆过滤器,使用一个足够大的bitmap,用于存储可能访问的key,不存在的key直接被过滤;
访问key未在DB查询到值,也将空值写进缓存,但可以设置较短过期时间。

缓存雪崩
  大量的key设置了相同的过期时间,导致在缓存在同一时刻全部失效,造成瞬时DB请求量大、压力骤增,引起雪崩。

解决方案
可以给缓存设置过期时间时加上一个随机值时间,使得每个key的过期时间分布开来,不会集中在同一时刻失效。

缓存击穿
一个存在的key,在缓存过期的一刻,同时有大量的请求,这些请求都会击穿到DB,造成瞬时DB请求量大、压力骤增。
解决方案
在访问key之前,采用SETNX(set if not exists)来设置另一个短期key来锁住当前key的访问,访问结束再删除该短期key。
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

 

 

 

posted on 2021-09-15 15:04  华华中  阅读(109)  评论(0编辑  收藏  举报

导航