Redis进阶学习总结(Docker搭建环境)
Posted 玩家_名狱
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Redis进阶学习总结(Docker搭建环境)相关的知识,希望对你有一定的参考价值。
一、主从复制
一个主服务器master,多个从服务器slave。主要作用:数据冗余、故障恢复、负载均衡、高可用集群。
主机可以写,但从节点不能写只能读,主机中的信息都会被从节点保存,主节点宕机了从节点数据还保留着,且从节点的身份不变,等主节点恢复后从节点还能继续连接
查看主从复制的基本信息
127.0.0.1:6379> info replication
# Replication
role:master # 当前角色master
connected_slaves:0 # 从机0个
master_failover_state:no-failover
master_replid:f298b23a9266dd0860de5be3d776ada013e40e86
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:0
second_repl_offset:-1
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
环境搭建(一带N结构)
1、首先启动三个Redis容器
root@iZbp18qtvejt7jqx8ghcanZ:~# docker run -p 6379:6379 -d --name="redis00" bc8d70f9ef6c
2e76a9ca22c00e027d55d971b0d5bc265d16ad33f7891733b87fcbfcda592eef
root@iZbp18qtvejt7jqx8ghcanZ:~# docker run -p 6389:6389 -d --name="redis01" bc8d70f9ef6c
51610b97d4cbdf745d1514800f3a00f5ffc7ea1d4feb23a4e53781bfb50777d0
root@iZbp18qtvejt7jqx8ghcanZ:~# docker run -p 6399:6399 -d --name="redis02" bc8d70f9ef6c
1fcda7dd77cba51aa036591fe1a17dfb672f168e7b4d06ca15bbee17414329af
root@iZbp18qtvejt7jqx8ghcanZ:~# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1fcda7dd77cb bc8d70f9ef6c "docker-entrypoint.s…" 3 minutes ago Up 3 minutes 6379/tcp, 0.0.0.0:6399->6399/tcp redis02
51610b97d4cb bc8d70f9ef6c "docker-entrypoint.s…" 4 minutes ago Up 3 minutes 6379/tcp, 0.0.0.0:6389->6389/tcp redis01
2e76a9ca22c0 bc8d70f9ef6c "docker-entrypoint.s…" 7 seconds ago Up 5 seconds 0.0.0.0:6379->6379/tcp redis00
2、将官方的redis.conf文件从主机拷贝到三个容器内
root@zxh:~# docker cp ./redis.conf 2e76a9ca22c0:/usr/local/bin/
root@zxh:~# docker cp ./redis.conf 51610b97d4cb:/usr/local/bin/
root@zxh:~# docker cp ./redis.conf 1fcda7dd77cb:/usr/local/bin/
3、进入容器修改配置文件,以redis00机器为例:
root@zxh:~# docker exec -it 2e76a9ca22c0 /bin/bash
root@2e76a9ca22c0:/data/# cd /usr/local/bin
root@2e76a9ca22c0:/usr/local/bin# ls
docker-entrypoint.sh redis-check-aof redis-sentinel
gosu redis-check-rdb redis-server
redis-benchmark redis-cli redis.conf
# 为了好辨识各个机器,配置文件名为:redis+机器编号+端口号.conf
# 所以三个机器各名为:redis0079.conf、redis0189.conf、redis0299.conf
root@2e76a9ca22c0:/usr/local/bin# mv redis.conf redis0079.conf
为了能在容器内编辑文件、查看ip信息和ping测试网络,还需要安装工具,三个机器都执行这个命令
root@2e76a9ca22c0:/usr/local/bin# apt update && apt install -y vim && apt install -y iproute2 && apt install -y iputils-ping
机器redis00的配置文件redis0079.conf修改内容如下
port 6379 ==改为==> port 6379
daemonize no ==改为==> daemonize yes
pidfile /var/run/redis_6379.pid ==改为==> pidfile /var/run/redis_6379.pid
logfile "" ==改为==> logfile "6379.log"
dbfilename dump.rdb ==改为==> dbfilename dump6379.rdb
机器redis01的配置文件redis0189.conf修改内容如下
port 6389 ==改为==> port 6389
daemonize no ==改为==> daemonize yes
pidfile /var/run/redis_6389.pid ==改为==> pidfile /var/run/redis_6389.pid
logfile "" ==改为==> logfile "6389.log"
dbfilename dump.rdb ==改为==> dbfilename dump6389.rdb
机器redis02的配置文件redis0299.conf修改内容如下
port 6399 ==改为==> port 6399
daemonize no ==改为==> daemonize yes
pidfile /var/run/redis_6399.pid ==改为==> pidfile /var/run/redis_6399.pid
logfile "" ==改为==> logfile "6399.log"
dbfilename dump.rdb ==改为==> dbfilename dump6399.rdb
4、启动redis
redis00
root@2e76a9ca22c0:/usr/local/bin# redis-server /usr/local/bin/redis0079.conf
redis01
root@51610b97d4cb:/usr/local/bin# redis-server /usr/local/bin/redis0189.conf
redis02
root@1fcda7dd77cb:/usr/local/bin# redis-server /usr/local/bin/redis0299.conf
在主机上查看进程信息
此时每个redis服务都是主节点
5、配置从节点
主节点不用配置,从节点配置主节点地址
先获取主节点的 ip 地址
然后使用**slaveof
host port**命令设置主节点的地址
上面使用命令的方式配置,只是暂时的,修改配置文件才是永久的
在redis01的redis0189.conf文件和redis02的redis0299.conf文件中
# replicaof <masterip> <masterport>改为replicaof 172.18.0.4 6379
之后重启redis01和redis02的redis服务,即可
如果想取消slave身份,配置文件模式只需注释掉即可,命令模式可以使用命令slaveof no one
二、哨兵模式
在主从复制中,一旦主节点宕机了,其他节点不会发生改变,因此整个集群对外不能提供服务。哨兵模式就是增加N个哨兵,一直监听整个集群的主机,并选举出一个主节点,一旦主节点宕机了,就新选举出另一台主节点。
redis安装目录下的redis-sentinel工具就是充当哨兵作用,一般有多个哨兵,因为如果一个哨兵挂了,集群也就挂了
环境搭建(一个哨兵)
依旧使用主从复制的环境,一个主节点,两个从节点,然后继续下面的配置
1、修改redis0079.conf、redis0189.conf、redis0299.conf文件,修改内容相同
protected-mode yes# 改为,关闭安全模式,允许无密码访问protected-mode no
bind 127.0.0.1 -::1# 改为,监听所有地址bind * -::*
2、在任意节点增加一个配置文件。sentinel.conf
,然后配置
# 哨兵 监视 监视名 地址 端口 票数sentinel monitor sentinel01 172.18.0.4 6379 1
3、运行哨兵工具
root@51610b97d4cb:/usr/local/bin# redis-sentinel sentinel.conf
4、测试
把master关闭,几秒钟后,就会在从节点中选举出一台作为主节点
即使刚刚宕机的主机恢复了,也只能当做从节点
三、缓存穿透、缓存击穿、缓存雪崩
1、缓存穿透
概念
我们一般是因为数据库查询较慢且消耗资源较大,因此使用缓存,也就是把数据存在内存中,但因为数据太多或其他原因,并不是数据库的所有数据都放进内存中,因此我们会设置一个策略,如果获取缓存中的数据时找不到了,就到数据库中寻找。现在有一个黑客,伪造了大量的请求,而且请求的数据不在缓存中,因此后台程序就会都到数据库中查找,缓存失去了意义,而且数据库将要承受大量的压力。
请求穿过缓存,到达数据库,这就是缓存击穿。
解决方案
有很多种,最常使用两种:
- 因为伪造的请求或者由于代码bug问题,请求一般会多次出现相同的key,而值为null,而相同的key每次都要到数据库查询,但偏偏查的没有意义,因为都是返回null。因此我们可以将请求的key设为null存储到缓存中
- 使用布隆过滤器(常用)
布隆过滤器原理:
首先有一个bitmap,我们可以将它想象成一个数组,他有长度,有下标,存储的值只能为0或1
然后将我们的数据的key使用不同的hash函数运算,可以是3个hash函数
然后将得到的hash值对bitmap的长度求余,求余得到的结果就是bitmap的下标
然后将三个结果求余后对应bitmap下标的值设为1,代表该key存在
然后随着key增多,有些在bitmap中的位置可能发生重合,但没关系
最后请求过来时,计算请求的key的哈希值,找到对应的bit下标,判断该key是否存在,存在则访问缓存
如果一个请求的key计算的结果对应的bitmap下标值为1,那么该key可能存在,也可能不存在,因为有概率发生不同的key而hash值相同,并且还是计算3个hash值
如果一个请求的key计算的结果对应的bitmap下标值为0,那么该key一定不存在
因此布隆过滤器存在一定概率的误判,但是我们可以接受。
2、缓存击穿
概念
我们存储数据时会考虑到,可能有些key访问量不大,一直保存的话就会浪费空间,而对所有的key都设置了过期时间,就算过期了还能在再次处理请求之后,再保存到缓存中。如果某个key突然成为热点数据,几千万个请求对准了这个key,而该key刚好到达失效时间,那么几千万个请求由于得不到缓存中的结果,就会同时访问到数据库。数据库崩了之后,缓存中的key随着时间逐渐失效,然而数据库不能取到值,那么一个一个键逐渐失效,最后服务结束。
由于一个key的过期瞬间,大量的请求打到数据库,造成数据库宕机,随后一个一个key也是如此,这就是雪崩。
解决方案
没有很好的解决方案:
- 对程序中对key这个资源加锁,使得每次只有一个线程或进程访问。当然也可以使用队列。
3、缓存雪崩
概念
和缓存击穿基本类似,但是缓存击穿是针对一个key的失效瞬间,而缓存雪崩是针对多个key同时失效的瞬间
解决方案
- 熔断机制
以上是关于Redis进阶学习总结(Docker搭建环境)的主要内容,如果未能解决你的问题,请参考以下文章
一文教您如何通过 Docker 快速搭建各种测试环境(Mysql, Redis, Elasticsearch, MongoDB) | 建议收藏