码迷,mamicode.com
首页 > 其他好文 > 详细

Redis

时间:2020-01-09 22:37:01      阅读:92      评论:0      收藏:0      [点我收藏+]

标签:读写分离   后台   bar   过程   host   rubygems   另一个   lov   doc   

11、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 主库是否要开启持久化?
如果不开有可能,主库重启操作,造成所有主从数据丢失!

  1. 主从复制实现
    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

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

  1. redis-sentinel(哨兵)
    1、监控
    2、自动选主,切换(6381 slaveof no one)
    3、2号从库(6382)指向新主库(6381)
    4、应用透明
    5、自动处理故障节点

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

启动:
[root@db01 26380]# redis-sentinel /data/26380/sentinel.conf &>/tmp/sentinel.log &

项目: Docker(K8s)容器管理Redis Sentinel集群

==============================
如果有问题:
1、重新准备1主2从环境
2、kill掉sentinel进程
3、删除sentinel目录下的所有文件
4、重新搭建sentinel
======================================
停主库测试:
[root@db01 ~]# redis-cli -p 6380 -a 123 shutdown
[root@db01 ~]# redis-cli -p 6381 -a 123 info replication

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

  1. redis cluster分布式分片集群

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

key : value
crc16(key) ----> 22222 -----> 22222%16384 ====> 5838 ------> slot(0-16383)

高可用:
在搭建集群时,会为每一个分片的主节点,对应一个从节点,实现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

(1) 安装集群插件
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

(2)集群节点准备
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

(3) 启动节点:
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

[root@db01 ~]# 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]

(4) 将节点加入集群管理
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

(5)集群状态查看
集群主节点状态
redis-cli -p 7000 cluster nodes | grep master
集群从节点状态
redis-cli -p 7000 cluster nodes | grep slave

14.3 集群节点管理

(1) 增加新的节点
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

(2) 添加主节点:
redis-trib.rb add-node 127.0.0.1:7006 127.0.0.1:7000

(3) 转移slot(重新分片)
redis-trib.rb reshard 127.0.0.1:7000

(4) 添加一个从节点
redis-trib.rb add-node --slave --master-id 3ba9af262145817741a5c614254ec4a707018515 127.0.0.1:7007 127.0.0.1:7000
redis-trib.rb add-node --slave --master-id xxxxxxxxx 127.0.0.1:7007 127.0.0.1:7000

14.4 删除节点

(1)将需要删除节点slot移动走
3ba9af262145817741a5c614254ec4a707018515 127.0.0.1:7006
0-1364 1365
5461-6826 1366
10923-12287 1365

redis-trib.rb reshard 127.0.0.1:7000

(2)删除一个节点
删除master节点之前首先要使用reshard移除master的全部slot,然后再删除当前节点
redis-trib.rb del-node 127.0.0.1:7006 xxxxxxx

  1. redis的多API支持

15.1 环境准备
python为例
yum install -y python36
python3 -V
yum install -y python36-pip

pip3 install redis
pip3 install redis-py-cluster

15.2 对redis的单实例进行连接操作
[root@db01 ~]# redis-server /data/6379/redis.conf

python3

import redis
r = redis.StrictRedis(host=‘10.0.0.51‘, port=6379, db=0,password=‘123456‘)
r.set(‘oldboy‘, ‘oldguo‘)
r.get(‘oldboy‘)

15.3 sentinel集群连接并操作
[root@db01 ~]# redis-server /data/6380/redis.conf
[root@db01 ~]# redis-server /data/6381/redis.conf
[root@db01 ~]# redis-server /data/6382/redis.conf
[root@db01 ~]# redis-sentinel /data/26380/sentinel.conf &
--------------------------------

导入redis sentinel包

from redis.sentinel import Sentinel

指定sentinel的地址和端口号

sentinel = Sentinel([(‘localhost‘, 26380)], socket_timeout=0.1)

测试,获取以下主库和从库的信息

sentinel.discover_master(‘mymaster‘)
sentinel.discover_slaves(‘mymaster‘)

配置读写分离

写节点

master = sentinel.master_for(‘mymaster‘, socket_timeout=0.1,password="123")

读节点

slave = sentinel.slave_for(‘mymaster‘, socket_timeout=0.1,password="123")

读写分离测试 key

master.set(‘oldboy‘, ‘123‘)
slave.get(‘oldboy‘)

15.4 python连接rediscluster集群测试使用
python3

from rediscluster import RedisCluster
startup_nodes = [{"host":"127.0.0.1", "port": "7000"},{"host":"127.0.0.1", "port": "7001"},{"host":"127.0.0.1", "port": "7002"}]

Note: decode_responses must be set to True when used with python3

rc = RedisCluster(startup_nodes=startup_nodes, decode_responses=True)
rc.set("foo", "bar")
True
print(rc.get("foo"))
‘bar‘

16.一些概念
缓存穿透
概念
访问一个不存在的key,缓存不起作用,请求会穿透到DB,流量大时DB会挂掉。

解决方案
采用布隆过滤器,使用一个足够大的bitmap,用于存储可能访问的key,不存在的key直接被过滤;
访问key未在DB查询到值,也将空值写进缓存,但可以设置较短过期时间。
缓存雪崩
概念
大量的key设置了相同的过期时间,导致在缓存在同一时刻全部失效,造成瞬时DB请求量大、压力骤增,引起雪崩。

解决方案
可以给缓存设置过期时间时加上一个随机值时间,使得每个key的过期时间分布开来,不会集中在同一时刻失效。
缓存击穿
概念
一个存在的key,在缓存过期的一刻,同时有大量的请求,这些请求都会击穿到DB,造成瞬时DB请求量大、压力骤增。
解决方案
在访问key之前,采用SETNX(set if not exists)来设置另一个短期key来锁住当前key的访问,访问结束再删除该短期key。
========================Redis END=======================

作者:wwwoldguocom
链接:https://www.jianshu.com/p/8af6177f4c23
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

Redis

标签:读写分离   后台   bar   过程   host   rubygems   另一个   lov   doc   

原文地址:https://www.cnblogs.com/yangxiaoni/p/12173696.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!