Redis学习笔记3

2021-08-23  本文已影响0人  这货不是王马勺

P1 sentinel
13.redis-sentinel(哨兵)
1、监控
2、自动选主,切换(6381 slaveof no one)
3、2号从库(6382)指向新主库(6381)
4、应用透明
5、自动处理故障节点
sentinel和MHA一样可一次性管理多套集群
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 

配置文件内容一共就五行,前两行是端口号和工作目录,
第三行到第五行中mymaster是我们取的集群名,未来如果再有其他集群,那么类似第三行到第五行的内容还需要再写一组
第三行写主库的ip地址和端口号,最后的数字1代表了有1台哨兵认为主库宕了就切换
标配是三个哨兵,2台认为主库宕了就切换
第四行代表了判定主库为宕的时间是5000ms,即5s
第五行是集群节点密码,和主从密码一致(主从密码设置相同也是为了sentinel此时能切换)

启动:

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

可以查看/tmp/sentinel.log日志信息


正常的启动信息

==============================
如果有问题:
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),看状态

redis-server /data/6380/redis.conf

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 意见的情况下, 强制开始一次自动故障迁移,理解为手动failover。

P2 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),每个槽位可以存n多个键值对
3、每组分片分得1/3 slot个数(0-5500 5501-11000 11001-16383)
4、基于CRC16运算(key) % 16384(和16384取模) ====》值 (槽位号)。

P3 Redis Cluster搭建
14.2 规划、搭建过程
6个redis实例,一般会放到3台硬件服务器
注:在企业规划中,一个分片的两个分到不同的物理机,防止硬件主机宕机造成的整个分片数据丢失。
端口号:7000-7005

安装集群插件
EPEL源安装ruby支持,因为redis集群插件是用ruby开发的(早期是纯手工敲命令部署)
redis集群功能是在3版本之后才有

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

gem就是安装ruby专用的程序
安装的插件可以理解为一个让ruby能操作redis的驱动

集群节点准备

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 
[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]  

将节点加入集群管理:

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

记得敲yes,别直接回车就退出了

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

redis-cli -p 7000 cluster nodes | grep master
主节点

最左边一长串是nodeid,是节点通信用的,然后就是ip地址和端口
再后边是角色,7000节点的myself可以理解为是管理节点
connected后边的数字就是槽位分布,不管多少个节点,总数都是16384

集群从节点状态

redis-cli -p 7000 cluster nodes | grep slave

注:同一组的主和从是不能放在同一硬件上的,我们此处示例用了多实例是为了方便

P4 Redis Cluster添加节点
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

此时会有提示问你移动多少个slot?我们计算一下16384/4=4096,此处输入4096
提示谁接受这些slot,则输入新加节点的node id
源节点输入all
这个操作需要在业务窗口期操作,比较影响性能

添加一个从节点:

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

这个master id要用你选的主节点的id,比如此处就找7006的id

P5删除节点
14.4 删除节点
首先将需要删除节点slot移动走(reshard)
像我们的7006,就要原路返回,哪来的回哪去,而不是都挪到一个上面
所以要分三次挪,输入slot数量、接收的node id,源node id(7006的id),再done

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

因为7007没有slot所以可以直接删除:


删除7007节点

设置redis最大内存

config set maxmemory 102400000

P6 Redis API支持for python
15. redis的多API支持
python为例

yum install -y python36 
python3 -V
yum install -y python36-pip
pip3 install redis  --单击和sentinel
pip3 install redis-py-cluster  --集群的

++++++++++++源码方式+++++++++++++++
https://redis.io/clients
下载redis-py-master.zip
安装驱动:

unzip redis-py-master.zip
cd redis-py-master
python3 setup.py install

redis cluster的连接并操作(python2.7.2以上版本才支持redis cluster,我们选择的是3.6)
https://github.com/Grokzen/redis-py-cluster
安装redis-cluser的客户端程序

cd redis-py-cluster-unstable
python3 setup.py install

+++++++++++++++++++++++++++++++++

对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')

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')  
```

python连接rediscluster集群测试
在应用端将六个节点都加到连接池,应用通过正确的驱动连redis集群,
就有转向错误提醒功能
使用

python3
```
>>> from rediscluster import StrictRedisCluster  
>>> 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 = StrictRedisCluster(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。



上一篇下一篇

猜你喜欢

热点阅读