网站访问量统计怎么做,南宁网站定制团队,怎么把几个网站做互通,概念产品设计网站一、Redis主从
1.1、搭建主从架构
单节点的Redis的并发能力是有上限的#xff0c;要进一步的提高Redis的并发能力#xff0c;据需要大家主从集群#xff0c;实现读写分离。 共包含三个实例#xff0c;由于资源有限#xff0c;所以在一台虚拟机上#xff0c;开启多个red…一、Redis主从
1.1、搭建主从架构
单节点的Redis的并发能力是有上限的要进一步的提高Redis的并发能力据需要大家主从集群实现读写分离。 共包含三个实例由于资源有限所以在一台虚拟机上开启多个redis的实例端口不同下面是具体的配置
IPPORT角色192.168.152.1337001master192.168.152.1337002slave/replica192.168.152.1337003slave/replica
第一步准备实例和配置
要在同一台虚拟机上开启三个redis实例就必须要准备三分不同的redis.conf的配置文件为了方便管理这里创建三个文件夹存放不同的配置文件
创建目录
创建出三个分别以端口号命名的文件夹700170027003
# 进入redis的按照目录
cd /usr/local/bin
# 创建目录
mkdir -p 7001 7002 7003
ll如图 修改配置文件
修改redis.conf的配置文件将其中的持久化模式改为开启rdb关闭aof并指定ip端口。 其中如果想要用redis的可视化连接工具链接还需要关闭保护模式protected-mode no # 关闭aof
appendonly no思考为什么要开启rdb模式关闭aof呢❓
拷贝配置文件到700170027003
#方式一逐个拷贝
cp /opt/redis-5/redis.conf ./7001/
cp /opt/redis-5/redis.conf ./7002/
cp /opt/redis-5/redis.conf ./7003/
#方式二管道操作
echo 7001 7002 7003 | xargs -t -n 1 cp redis-5/redis.conf修改端口数据保存目录
sed -i -e s/6379/7001/g -e s/dir .\//dir \/usr\/local\/bin\/7001\//g ./7001/redis.conf
sed -i -e s/6379/7002/g -e s/dir .\//dir \/usr\/local\/bin\/7002\//g ./7002/redis.conf
sed -i -e s/6379/7003/g -e s/dir .\//dir \/usr\/local\/bin\/7003\//g ./7003/redis.confdaemonize no表示不后台启动实际生产需要修改为yes这里为了方便观察日志暂时关闭 修改每个实例的声明IP
虚拟机本身存在多个ip为了避免混淆我们需要在配置文件的第一行声明每个实例的IP
sed -i 1a replica-announce-ip 192.168.152.133 ./7001/redis.conf
sed -i 1a replica-announce-ip 192.168.152.133 ./7002/redis.conf
sed -i 1a replica-announce-ip 192.168.152.133 ./7003/redis.conf第二步启动redis实例
执行如下命令
redis-server ./7001/redis.conf
redis-server ./7002/redis.conf
redis-server ./7003/redis.conf第三步构建主从关系
完成上面的操作之后其实还没有完成主从的搭建因为这样只是启动三个单独的redis实例这三个redis实例之间没有任何的联系。需要在从节点下执行如下命令
# 方式一永久修改
在redis.conf文件里添加slaveof masterIp masterPort
只要添加了这行命令的redis实例就会成为被添加的masterIp的从节点# 方式二临时修改重启后将失效
# 进入redis-cli客户端执行slaveof
slaveof 主节点IP 主节点端口观察日志变化 1.2、主从同步原理
全量同步
数据同步图解
数据同步原理
Redis主从的第一次数据同步是全量同步 如何判断是否是第一次
那么由上图我们可以知道master必须要对发来的slave节点进行判断看是不是第一次如果是第一次需要做全量同步数据那么问题来了master怎么知道是不是第一次呢
这里就涉及到了两个概念 Replication Id: 简称replid是数据集的标记id一致则说明是同一个数据集每一个master都有唯一的replidslave则会继承master的replid。 **offset**随着repl_back_log中地数据量的增大而增加slave完成同步时也会记录当前地offset所以slave地offset偏移量一定是小于等于master地offset。 答案是Replid因为slave在成成为master地从节点之前自己也是master也有自己的replid故replid是唯一的。 日志分析
接下来我们看下日志进行进一步的分析
【步骤一】 【步骤二】 【步骤三】
由于是第一次所以没有offset故没有日志但是redis后台会监控
增量同步
增量同步图解 增量同步地关键就是repl_baklog上面讲过一个概念offset他记录的是主从节点同步的节点信息也就是说假如slave宕机了但是这个时候master还持续地往里面写数据这个时候slave地offset一直没有增加而master地offset一直在增加。当我们地slave重新恢复的时候slave地offset与master地offset的差值就是slave需要做增量同步的数据。 那么repl_baklog是怎么实现记录的操作呢 原理就如上图左下角所示 repl_baklog数据结构实际上就是一个环形数组绿色的部分代表slave的offset而红色的部分代表需要同步的数据也就是master的offset与slave的offset的差值我们实际要关注的也就是这部分。 什么时候无法增量同步 由于是一个环形的数据结构所以一旦master的offset覆盖掉slave宕机前的offset位置那么此时就无法实现增量同步。
如何优化主从集群 二、Redis哨兵 思考 slave节点宕机恢复后可以找master节点数据同步那master节点宕机了呢怎么办 2.1、哨兵的作用与原理
哨兵的作用
Redis提供了哨兵模式Sentinel其主要的作用就是监控主从集群用于自动的故障检测与恢复以及通知。 服务状态监控 选举新的Master 故障转移原理 ⚓️注意 当原master宕机后sentinel会选举出新的master同时会强制修改master节点的redis.conf配置文件添加一行slaveof 新的masterip 新的master端口 故如果重新使用原理的redis.conf启动主从就无法实现主从的搭建。 2.2、搭建哨兵集群
节点PORT角色sentinel127001mastersentinel227002slave/replicasentinel327003slave/replica
第一步准备实例和配置
必须要准备三分不同的sentinel.conf的配置文件为了方便管理这里创建三个文件夹存放不同的配置文件sentinel27001 sentinel27002 sentinel27003
创建目录
创建出三个分别以端口号命名的文件夹700170027003
# 进入redis的按照目录
cd /usr/local/bin
# 创建目录
mkdir -p sentinel27001 sentinel27002 sentinel27003
ll如图 修改配置文件
sentinel.conf的配置文件
vim ./sentinel27001/sentinel.confport 27001
sentinel announce-ip 192.168.152.133
# 客观下线数目 2台sentinel都认为下线则认为主管下线
# mymaster 为sentinel的名字随意但是前后须保持一致
# 192.168.152.133 7001 为master主节点的ip端口
sentinel monitor mymaster 192.168.152.133 7001 2
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 60000
dir /usr/local/bin/sentinel27001拷贝配置文件到sentinel27002sentinel27003
#方式二管道操作
echo sentinel27002 sentinel27003 | xargs -t -n 1 cp ./sentinel27001/sentinel.conf修改端口数据保存目录
sed -i -e s/27001/27002/g -e s/sentinel27001/sentinel27002/g ./sentinel27002/sentinel.conf
sed -i -e s/27001/27003/g -e s/sentinel27001/sentinel27003/g ./sentinel27003/sentinel.confdaemonize no表示不后台启动实际生产需要修改为yes这里为了方便观察日志暂时关闭 修改每个实例的声明IP
虚拟机本身存在多个ip为了避免混淆我们需要在配置文件的第一行声明每个实例的IP
sed -i 1a replica-announce-ip 192.168.152.133 ./7001/redis.conf
sed -i 1a replica-announce-ip 192.168.152.133 ./7002/redis.conf
sed -i 1a replica-announce-ip 192.168.152.133 ./7003/redis.conf第二步启动sentinel实例
执行如下命令
redis-sentinel ./sentinel27001/sentinel.conf
redis-sentinel ./sentinel27002/sentinel.conf
redis-sentinel ./sentinel27003/sentinel.conf第三步模拟master宕机 哨兵服务监控7001状态并完成新的sentinel-leader的选举并最终由选举出来的sentinel-leader完成故障恢复 由选举出来的27001哨兵选举出7003节点成为新的master并向7003发送了一个slaveof-noone的命令【起来不愿做奴隶的人】使得7003成为新的master 向7001发起reconf命令
恢复7001节点后地位变成了slave并实现了一次全量同步数据7003 2.3、RedisTemplate的哨兵模式
SpringBoot为访问Redis提供了一个RedisTemplate的包集成了Lettuce和Jedis两种Java访问Redis的客户端接下来让我们来使用一下
【引入依赖】 !-- redis核心依赖 --dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-data-redis/artifactId/dependency!-- 对象池框架redis依赖 --dependencygroupIdorg.apache.commons/groupIdartifactIdcommons-pool2/artifactId/dependency!-- 序列化 --dependencygroupIdcom.alibaba/groupIdartifactIdfastjson/artifactIdversion1.2.73/version/dependencyapplication.yml
server:port: 9088
# 开启redis的日志
logging:level:[io.lettuce.core]: debugpattern:dateformat: MM-dd HH:mm:ss:SSS
# redis配置信息
spring:redis:sentinel:master: mymasternodes:- 192.168.152.133:27001- 192.168.152.133:27002- 192.168.152.133:27003【redisConfig配置类】
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.data.redis.LettuceClientConfigurationBuilderCustomizer;
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;import io.lettuce.core.ReadFrom;/**
* ClassName: RedisConfig
* Description: Redis配置类
* author weiyongpeng
* date 2023年10月5日 下午12:37:19*/
Configuration
AutoConfigureBefore(RedisAutoConfiguration.class)
public class RedisConfig {/*** 方法描述 初始化redis连接* param factory redis连接工厂* return {link RedisTemplate}*/Beanpublic RedisTemplate redisTemplate(RedisConnectionFactory factory) {// 新建redisTemplate对象RedisTemplateString, Object template new RedisTemplate();// 设置工厂template.setConnectionFactory(factory);//序列化配置Jackson2JsonRedisSerializer jackson2JsonRedisSerializer new Jackson2JsonRedisSerializer(Object.class);StringRedisSerializer stringRedisSerializer new StringRedisSerializer();//1用StringRedisSerializer进行序列化的值在Java和Redis中保存的内容是一样的//2用Jackson2JsonRedisSerializer进行序列化的值在Redis中保存的内容比Java中多了一对双引号。//3用JdkSerializationRedisSerializer进行序列化的值对于Key-Value的Value来说是在Redis中是不可读的。对于Hash的Value来说比Java的内容多了一些字符。//如果Key的Serializer也用和Value相同的Serializer的话在Redis中保存的内容和上面Value的差异是一样的所以我们保存时只用StringRedisSerializer进行序列化// key采用String的序列化方式template.setKeySerializer(stringRedisSerializer);// value序列化方式采用jacksontemplate.setValueSerializer(stringRedisSerializer);// hash的key也采用String的序列化方式template.setHashKeySerializer(stringRedisSerializer);// hash的value序列化方式采用jacksontemplate.setHashValueSerializer(stringRedisSerializer);// 返回redisTemplate对象return template;}/*** 描述配置读写分离* Title: configurationBuilderCustomizer* return* author weiyongpeng* date 2023年10月5日 上午10:20:57*/Beanpublic LettuceClientConfigurationBuilderCustomizer configurationBuilderCustomizer() {// REPLICA_PERFERED表示优先从从节点读取数据当从节点都挂掉才去读masterreturn configurate - configurate.readFrom(ReadFrom.REPLICA_PREFERRED);}
}三、Redis分片集群
3.1、搭建分片集群
首先在搭建Redis分片集群之前先了解下分片集群可以解决哨兵和主从无法解决的那些问题以及分片式集群的特征 **注意**在使用RedisTemplate访问分片集群的时候就不需要指定主从关系可以访问任意一台节点redis会实现自动的路由转发机制 共包含六个实例由于资源有限所以在一台虚拟机上开启多个redis的实例端口不同下面是具体的配置
IPPORT角色192.168.152.1337001master192.168.152.1337002master192.168.152.1337003master192.168.152.1338001slave192.168.152.1338002slave192.168.152.1338003slave
第一步准备实例和配置
为了完成3主3从的redis分片集群的搭建必须要准备六份不同的redis.conf的配置文件为了方便管理这里创建六个文件夹存放不同的配置文件cluster7001 cluster7002 cluster7003 cluster8001 cluster8002 cluster8003
创建目录
创建出三个分别以端口号命名的文件夹cluster7001 cluster7002 cluster7003 cluster8001 cluster8002 cluster8003
# 进入redis的按照目录
cd /usr/local/bin
# 创建目录
mkdir -p cluster7001 cluster7002 cluster7003 cluster8001 cluster8002 cluster8003
ll如图
修改配置文件
重新生成redis.conf的配置文件
vim ./cluster7001/redis.confport 7001
# 开启集群功能
cluster-enabled yes
# 集群的配置文件名称不需要我们创建需要redis自己维护
cluster-config-file /usr/local/bin/cluster7001/nodes.conf
# 节点心跳超时链接时间
cluster-node-timeout 5000
# 持久化数据文件存放路径
dir /usr/local/bin/cluster7001
# 绑定地址
bind 192.168.152.133
# 开启后台运行
daemonize yes
# 声明IP
replica-announce-ip 192.168.152.133
# 保护模式关闭
protected-mode no
# 日志文件路径
logfile /usr/local/bin/cluster7001/cluster.log拷贝配置文件到cluster7002 cluster7003 cluster8001cluster8002 cluster8003
#方式二管道操作
echo cluster7002 cluster7003 cluster8001 cluster8002 cluster8003 | xargs -t -n 1 cp ./cluster7001/redis.conf修改端口数据保存目录
printf %s\n cluster7002 cluster7003 cluster8001 cluster8002 cluster8003 | xargs -I{} -t sed -i s/cluster7001/{}/g {}/redis.confdaemonize no表示不后台启动实际生产需要修改为yes这里为了方便观察日志暂时关闭 第二步启动
执行如下命令
cd /usr/local/binprintf %s\n cluster7001 cluster7002 cluster7003 cluster8001 cluster8002 cluster8003 | xargs -I{} -t redis-server ./{}/redis.conf注意此时还没有完成集群的配置因为这个时候6台redis实例话没有形成任何的关联关系。 第三步创建集群
针对redis5.x之后的把版本执行下述命令
redis-cli --cluster create --cluster-replicas 1 192.168.152.133:7001 192.168.152.133:7002 192.168.152.133:7003 192.168.152.133:8001 192.168.152.133:8002 192.168.152.133:8003命令说明
redis-cli --cluster或者./redis-trib.rb 代表集群操作命令create代表创建集群--replicas 1或者--cluster-replicas 1代表集群中每个master的副本个数为1masterslave的比例就是2那么总节点数➗(mastersalve的比例) 就是当前master个数那么其余的就是salve 自此集群创建完毕那么我们如何查看集群的状态呢 redis-cli -p 7001 -h 192.168.152.133 cluster nodes 3.2、散列插槽原理
Redis会把每一个Master节点映射到0-16383之间共16384个插槽(hash solt)上查看集群信息时就能看到 这些的solts总和正好是16384。
为什么要使用插槽呢原因很简单
**因为redis的节点时有可能宕机的所以redis的key并不是与节点所绑定的而是与插槽绑定。**redis会根据key的有效部分计算插槽分两种情况
key中包含{}且{}中至少有一个字符{}中的部分就是有效部分key中不包含{}整个key作为有效部分 **注意在集群模式下必须使用-c**参数链接redis-cli 所以这就是为什么我们说访问集群的任意一个节点都可以因为他们是通过槽的值自动切换。
总结
如何将同一类的数据固定保存在同一个Redis实例中
这一类数据使用同样的key有效部分例如key都以{typeid}作为前缀
3.3、集群伸缩
添加一个节点到集群 [rootlocalhost bin]# mkdir -p cluster7004
[rootlocalhost bin]# cp ./cluster7001/redis.conf ./cluster7004/
[rootlocalhost bin]# sed -i s/7001/7004/g ./cluster7004/redis.conf
[rootlocalhost bin]# redis-server ./cluster7004/redis.conf
[rootlocalhost bin]# ps -ef | grep redis
root 10717 1 0 16:05 ? 00:00:04 redis-server 192.168.152.133:7001 [cluster]
root 10722 1 0 16:05 ? 00:00:04 redis-server 192.168.152.133:7002 [cluster]
root 10724 1 0 16:05 ? 00:00:04 redis-server 192.168.152.133:7003 [cluster]
root 10732 1 0 16:05 ? 00:00:04 redis-server 192.168.152.133:8001 [cluster]
root 10734 1 0 16:05 ? 00:00:04 redis-server 192.168.152.133:8002 [cluster]
root 10739 1 0 16:05 ? 00:00:04 redis-server 192.168.152.133:8003 [cluster]
root 11285 1 0 16:48 ? 00:00:00 redis-server 192.168.152.133:7004 [cluster]
root 11290 9739 0 16:48 pts/0 00:00:00 grep --colorauto redis
[rootlocalhost bin]#启动完后查看此时的7004的集群信息 接下来我们就要使用add-node添加到集群中
redis-cli --cluster add-node 192.168.152.133:7004 192.168.152.133:7001但是我们这个时候查看一下redis7004的集群信息发现新增的7004没有插槽分配 使用reshard实现插槽的重新分配
redis-cli --cluster reshard 192.168.152.133:7001 # 表示重新分配7001的插槽分配完后查看7004的集群状态发现已经实现类分配 3.4、故障转移
自动故障转移 手动故障转移 3.5、RedisTemplate访问分片集群
spring:redis:cluster:# 集群节点nodes: - 192.168.152.133:7001- 192.168.152.133:7002 - 192.168.152.133:7003 - 192.168.152.133:8001 - 192.168.152.133:8002 - 192.168.152.133:8003# 最大重定向次数max-redirects: 5其余配置和哨兵一致只需要修改application.yml文件即可