redis主从复制,哨兵模式,集群,分布式Session管理,

redis主从复制

主从复制

在这里插入图片描述

主从复制架构仅仅用来解决数据的冗余备份,从节点仅仅用来同步数据
主机数据更新后根据配置和策略, 自动同步到备机的master/slaver机制,Master以写为主,Slave以读为主

无法解决: 1.master节点出现故障的自动故障转移

搭建主从复制

只配置从库,不用配置主库
查看当前redsi信息

info replication

在这里插入图片描述

修改端口、pid名字、log文件名字、dump.rdb

# 1.准备3台机器并修改配置
- master
	port 6379
	bind 0.0.0.0
	
- slave1
	port 7000
	bind 0.0.0.0
	pidfile /var/run/redis_7000.pid
	logfile "/usr/local/bin/redis_7000.log"
	dbfilename dump_7000.rdb
	slaveof masterip masterport

- slave2
	port 7001
	bind 0.0.0.0
	pidfile /var/run/redis_7001.pid
	logfile "/usr/local/bin/redis_7001.log"
	dbfilename dump_7001.rdb
	slaveof masterip masterport

修改端口

在这里插入图片描述

修改pid名字

在这里插入图片描述

修改log文件名字

在这里插入图片描述

修改dump.rdb

在这里插入图片描述

启动并查看redis

在这里插入图片描述
这里我以6379位主服务器,7000和7001为从服务器

从服务器执行命令

# slaveof host port
127.0.0.1:7000> slaveof 123.57.252.81 6379

主服务器查看

info replication

在这里插入图片描述
到此主从复制已完成,注意这里是命令配置的,redis重启后会主从复制会消失。真实的主从配置应该在配置文件配置,这样的话就是永久的

永久配置

设置配置文件
在这里插入图片描述

# replicaof <masterip> <masterport>

 replicaof 123.57.252.81 6379

除了拷贝完整的配置文件外也可以建立空的文件使用include引入

include /myredis/redis.conf
pidfile /var/run/redis_6379.pid
port 6379
dbfilename dump6379.rdb

主从特点

1,主机可以写,从机不能写只能读,主机中所有信息和数据都会自动保存到从机汇总。
向主机中存入数据,主机能存也能取
在这里插入图片描述
在这里插入图片描述
2.主机断开连接,从机依旧连接到主机,但是没有写操作,这个时候主机如果重启了,从机依旧可以获取到主机写的信息

注意如果是用命令方式来配置从机,如果重启了此时该从机就会变成主机

薪火相传

上一个Slave可以是下一个slave的Master,Slave同样可以接收其他 slaves的连接和同步请求,那么该slave作为了链条中下一个的master, 可以有效减轻master的写压力,去中心化降低风险。
用 slaveof
中途变更转向:会清除之前的数据,重新建立拷贝最新的
风险是一旦某个slave宕机,后面的slave都没法备份
主机挂了,从机还是从机,无法写数据了

反客为主

当一个master宕机后,后面的slave可以立刻升为master,其后面的slave不用做任何修改。
用 slaveof no one 将从机变为主机

slaveof  no one

这个是手动变得后面的哨兵模式可以实现自动

复制原理

slave启动成功连接到master后会发送一个sync同步命令。
master接到命令,启动后台的存盘进程,同时收集所有接收到的用于修改数据集的命令,在后台程序执行完毕之后,matser将传送整个数据文件到slave,并完成一次完全同步。

全量复制: 而slave服务在接收到数据库文件数据后,将其存盘,并加载到内存汇总
增量复制:master继续将新的 所有收集到的修改命令依次传给slave,完成同步
但是只要是重新连接master,一次完全同步(全量复制)将会被自动执行,我们的数据移一定可以在从机中看到

哨兵模式

反客为主的自动版,能够后台监控主机是否故障,如果故障了根据投票数自动将从库转换为主库
Sentinel(哨兵)是Redis 的高可用性解决方案:由一个或多个Sentinel 实例 组成的Sentinel 系统可以监视任意多个主服务器,以及这些主服务器属下的所有从服务器,并在被监视的主服务器进入下线状态时,自动将下线主服务器属下的某个从服务器升级为新的主服务器。简单的说哨兵就是带有自动故障转移功能的主从架构

无法解决: 1.单节点并发压力问题 2.单节点内存和磁盘物理上限
在这里插入图片描述

新建sentinel.conf文件,名字绝不能错

touch sentinel.conf

配置哨兵,填写内容

#sentinel monitor 被监控数据库名字(自己起名字) ip port 1

sentinel monitor mymaster 127.0.0.1 6379 1

其中mymaster为监控对象起的服务器名称, 1 为至少有多少个哨兵同意迁移的数量。

启动哨兵

redis-sentinel myredisconfig/sentinel.conf

在这里插入图片描述

当主机挂掉,从机选举中产生新的主机

在这里插入图片描述

注意

Next failover delay: I will not start a failover before Sat Aug 7 11:28:18 2021
如果出现这个,请注意开放云服务器的端口
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

复制延时

由于所有的写操作都是先在Master上操作,然后同步更新到Slave上,所以从Master同步到Slave机器有一定的延迟,当系统很繁忙的时候,延迟问题会更加严重,Slave机器数量的增加也会使这个问题更加严重。
在这里插入图片描述
优先级在redis.conf中默认:slave-priority 100,值越小优先级越高
偏移量是指获得原主机数据最全的
每个redis实例启动后都会随机生成一个40位的runid

新版的是
在这里插入图片描述

springboot操作哨兵

# redis sentinel 配置
# master书写是使用哨兵监听的那个名称
spring.redis.sentinel.master=mymaster
# 连接的不再是一个具体redis主机,书写的是多个哨兵节点
spring.redis.sentinel.nodes=192.168.202.206:26379
  • 注意:如果连接过程中出现如下错误:RedisConnectionException: DENIED Redis is running in protected mode because protected mode is enabled, no bind address was specified, no authentication password is requested to clients. In this mode connections are only accepted from the loopback interface. If you want to connect from external computers to Redis you may adopt one of the following solutions: 1) Just disable protected mode sending the command ‘CONFIG SET protected-mode no’ from the loopback interface by connecting to Redis from the same host the server is running, however MAKE SURE Redis is not publicly accessible from internet if you do so. Use CONFIG REWRITE to make this change permanent. 2)
  • 解决方案:在哨兵的配置文件中加入bind 0.0.0.0 开启远程连接权限

Redis集群

Redis在3.0后开始支持Cluster(模式)模式,目前redis的集群支持节点的自动发现,支持slave-master选举和容错,支持在线分片(sharding shard )等特性。reshard

集群细节

  • 所有的redis节点彼此互联(PING-PONG机制),内部使用二进制协议优化传输速度和带宽.
  • 节点的fail是通过集群中超过半数的节点检测失效时才生效.
  • 客户端与redis节点直连,不需要中间proxy层.客户端不需要连接集群所有节点,连接集群中任何一个可用节点即可
  • redis-cluster把所有的物理节点映射到[0-16383]slot上,cluster 负责维护node<->slot<->value

什么是slots

一个 Redis 集群包含 16384 个插槽(hash slot), 数据库中的每个键都属于这 16384 个插槽的其中一个,
集群使用公式 CRC16(key) % 16384 来计算键 key 属于哪个槽, 其中 CRC16(key) 语句用于计算键 key 的 CRC16 校验和 。
集群中的每个节点负责处理一部分插槽。 举个例子, 如果一个集群可以有主节点, 其中:
节点 A 负责处理 0 号至 5460 号插槽。
节点 B 负责处理 5461 号至 10922 号插槽。
节点 C 负责处理 10923 号至 16383 号插槽

在集群中录入值

在redis-cli每次录入、查询键值,redis都会计算出该key应该送往的插槽,如果不是该客户端对应服务器的插槽,redis会报错,并告知应前往的redis实例地址和端口。
redis-cli客户端提供了 –c 参数实现自动重定向。
如 redis-cli -c –p 6379 登入后,再录入、查询键值对可以自动重定向。

不在一个slot下的键值,是不能使用mget,mset等多键操作

在这里插入图片描述

可以通过{}来定义组的概念,从而使key中{}内相同内容的键值对放到一个slot中去。

在这里插入图片描述

在这里插入图片描述

集群搭建

判断一个是集群中的节点是否可用,是集群中的所用主节点选举过程,如果半数以上的节点认为当前节点挂掉,那么当前节点就是挂掉了,所以搭建redis集群时建议节点数最好为奇数,搭建集群至少需要三个主节点,三个从节点,至少需要6个节点

新版

旧版redis

环境

# 1.准备环境安装ruby以及redis集群依赖
- yum install -y ruby rubygems
- gem install redis-xxx.gem

在一台机器创建7个目录

每个目录复制一份配置文件

修改不同目录配置文件


- port 	6379 .....                		 //修改端口
- bind  0.0.0.0                   		 //开启远程连接
- cluster-enabled  yes 	        			 //开启集群模式
- cluster-config-file  nodes-port.conf //集群节点配置文件
- cluster-node-timeout  5000      	   //集群节点超时时间
- appendonly  yes   		               //开启AOF持久化

模板

include /usr/local/bin/myredisconfig/redis.conf
port 7000
pidfile "/var/run/redis_7000.pid"
dbfilename "dump7000.rdb"
dir "/usr/local/bin/redisjiqun"
logfile "/usr/local/bin/redisjiqun/redis_err_7000.log"
cluster-enabled yes
cluster-config-file nodes-7000.conf
cluster-node-timeout 10000

使用查找替换修改另外文件

:%s/6379/7000

指定不同目录配置文件启动不同节点

在这里插入图片描述

查看进程

 ps -ef|grep redis

在这里插入图片描述

查看nodes-xxxx.conf文件都生成正常

在这里插入图片描述

创建集群

低版本需要自己安装ruby环境,高版本直接进入安装redis目录里面的src下面

 cd /opt/redis-6.0.6/src
redis-cli --cluster create --cluster-replicas 1 123.57.252.81:7000 123.57.252.81:7001 123.57.252.81:7002 123.57.252.81:7003 123.57.252.81:7004 123.57.252.81:7005 123.57.252.81:7006

此处不要用127.0.0.1, 请用真实IP地址
是否接受当前分配

在这里插入图片描述

集群创建成功出现如下提示

注意如果是云服务器要开发全部端口,不然就会显示一直等待
在这里插入图片描述

看集群状态 check [原始集群中任意节点]

./redis-cli --cluster check 192.168.220.132:7000

集群节点状态说明


- 主节点 
	主节点存在hash slots(哈希槽),且主节点的hash slots(哈希槽) 没有交叉
	主节点不能删除
	一个主节点可以有多个从节点
	主节点宕机时多个副本之间自动选举主节点

- 从节点
	从节点没有hash slots(哈希槽)
	从节点可以删除
	从节点不负责数据的写,只负责数据的同步

-c 采用集群策略连接,设置数据会自动切换到相应的写主机

./redis-cli -p 7000 -c(加-c才是集群连接,不加是单机连接)

通过 cluster nodes 命令查看集群信息

在这里插入图片描述
在这里插入图片描述

redis cluster 如何分配

一个集群至少要有三个主节点。
选项 --cluster-replicas 1 表示我们希望为集群中的每个主节点创建一个从节点。
分配原则尽量保证每个主数据库运行在不同的IP地址,每个从库和主库不在一个IP地址上。

故障恢复

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
再开一个终端连接上7001
在这里插入图片描述

在这里插入图片描述

如果所有某一段插槽的主从节点都宕掉,redis服务是否还能继续?

如果某一段插槽的主从都挂掉,而cluster-require-full-coverage 为yes ,那么 ,整个集群都挂掉
如果某一段插槽的主从都挂掉,而cluster-require-full-coverage 为no ,那么,该插槽数据全都不能使用,也无法存储。
redis.conf中的参数 cluster-require-full-coverage

添加主节点

添加主节点 add-node [新加入节点] [原始集群中任意节点]

./redis-cli --cluster add-node 192.168.220.132:7006 192.168.220.132:7005
  • 注意:
    1.该节点必须以集群模式启动
    2.默认情况下该节点就是以master节点形式添加

添加从节点

./redis-cli --cluster add-node 192.168.220.132:7006 192.168.220.132:7000 --cluster-slave
- 注意:
	当添加副本节点时没有指定主节点,redis会随机给副本节点较少的主节点添加当前副本节点

删除副本节点

./redis-cli --cluster del-node 192.168.220.132:7002 4db5ad74e49137e15bf6842903745c67fc83b814

- 注意:
 1.被删除的节点必须是从节点或没有被分配hash slots的节点

集群在线分片

在线分片 reshard [集群中任意节点]
redis-cli --cluster reshard 192.168.220.132:7000

Redis 集群好处

实现扩容
分摊压力
无中心配置相对简单

Redis实现分布式Session管理

redis的session管理是利用spring提供的session管理解决方案,将一个应用session交给Redis存储,整个应用中所有session的请求都会去redis中获取对应的session数据。
在这里插入图片描述

开发Session管理

创建一个springboot项目

引入依赖

		<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.session</groupId>
            <artifactId>spring-session-data-redis</artifactId>
        </dependency>

配置文件

server:
  port: 8080
spring:
  redis:
    cluster:
      nodes:
        - 123.57.252.81:7000
        - 123.57.252.81:7001
        - 123.57.252.81:7002
        - 123.57.252.81:7003
        - 123.57.252.81:7004
        - 123.57.252.81:7005
        - 123.57.252.81:7006

Session管理配置类

package com.blb.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;

@Configuration
@EnableRedisHttpSession //将整个应用中使用session的数据全部交给redis处理
public class RedisSessionManager {
    
    
}

测试


@Controller
//使用redis的session管理 注意:当session中数据发送变化时必须将session中变化的数据同步到redis中
public class TestController {
    
    
    @RequestMapping("/test")
    public void test(HttpServletRequest request, HttpServletResponse response) throws IOException {
    
    
        List<String> list=(List<String>) request.getSession().getAttribute("list");
        if(list==null){
    
    
            list=new ArrayList<>();

        }
        list.add("dyk");
        request.getSession().setAttribute("list",list);//每次session变化都要同步session
        response.getWriter().println("size:"+list.size());
        response.getWriter().println("sessionid: "+request.getSession().getId());
    }
}


在这里插入图片描述
在这里插入图片描述

おすすめ

転載: blog.csdn.net/qq_44866153/article/details/119462613