Redis进阶学习总结(Docker搭建环境)

Posted 玩家_名狱

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Redis进阶学习总结(Docker搭建环境)相关的知识,希望对你有一定的参考价值。

一、主从复制

一个主服务器master,多个从服务器slave。主要作用:数据冗余、故障恢复、负载均衡、高可用集群。

主机可以写,但从节点不能写只能读,主机中的信息都会被从节点保存,主节点宕机了从节点数据还保留着,且从节点的身份不变,等主节点恢复后从节点还能继续连接

xxxx

xxx

查看主从复制的基本信息

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

在主机上查看进程信息

xxx

此时每个redis服务都是主节点

5、配置从节点

主节点不用配置,从节点配置主节点地址

先获取主节点的 ip 地址

xxx

然后使用**slaveof host port**命令设置主节点的地址

xxx

上面使用命令的方式配置,只是暂时的,修改配置文件才是永久的

在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关闭,几秒钟后,就会在从节点中选举出一台作为主节点

xxx

即使刚刚宕机的主机恢复了,也只能当做从节点

三、缓存穿透、缓存击穿、缓存雪崩

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搭建环境)的主要内容,如果未能解决你的问题,请参考以下文章

Redis学习总结(Docker搭建环境)

Redis学习总结(Docker搭建环境)

Redis进阶学习07--分布式缓存--下

Docker 学习笔记总结

Docker 学习笔记总结

一文教您如何通过 Docker 快速搭建各种测试环境(Mysql, Redis, Elasticsearch, MongoDB) | 建议收藏