redis的深度理解

news2024/12/22 15:32:13

上篇博客我们说到了redis的基本概念和基本操作,本篇我们就更深入去了解一些redis的操作和概念,我们就从red的主从同步、redis哨兵模式和redis集群三个方面来了解redis数据库

一、主从同步

像MySQL一样,redis是支持主从同步的,而且也支持一主多从以及多级从结构。 主从结构,一是为了纯粹的冗余备份,二是为了提升读性能,比如很消耗性能的SORT就可以由从服务器来承担。 redis的主从同步是异步进行的。

1.主从同步原理

从服务器会向主服务器发出SYNC指令,当主服务器接到此命令后,就会调用BGSAVE指令来创建一个子进程专门进行数据持久化工作,也就是将主服务器的数据写入RDB文件中。在数据持久化期间,主服务器将执行的写指令都缓存在内存中。
在BGSAVE指令执行完成后,主服务器会将持久化好的RDB文件发送给从服务器,从服务器接到此文件后会将其存储到磁盘上,然后再将其读取到内存中。这个动作完成后,主服务器会将这段时间缓存的写指令再以redis协议的格式发送给从服务器。
另外,要说的一点是,即使有多个从服务器同时发来SYNC指令,主服务器也只会执行一次BGSAVE,然后把持久化好的RDB文件发给多个从服务器。

2.部署主从同步(一主两从)

部署环境

192.168.91.5       redis-master
192.168.91.149     redis-slave-1
192.168.91.150     redis-slave-2

关闭防火墙和selinux
systemctl stop firewalld         
systemctl disable firewalld       #关闭防火墙
setenforce 0      #关闭selinux

 修改master配置文件

# vim /usr/local/redis/redis.conf

bind 0.0.0.0
protected-mode no

修改slave配置文件

#vim /usr/local/redis/redis.conf

bind 0.0.0.0
protected-mode no
replicaof 192.168.91.5

 重启redis服务,再netstat -nlpt查看一下端口即可

二、哨兵模式

哨兵模式是用于监控redis主从复制中Master状态的工具,所以我们的哨兵模式都是基于主从复制的基础去做的

1.作用

检测Master状态,如果Master异常,则会进行Master-Slave切换,将其中一个Slave作为Master,将之前的Master作为Slave, Master-Slave切换后,sentinel的监控目标会随之调换 

2.工作模式

1):每个Sentinel以每秒钟一次的频率向它所知的Master,Slave以及其他 Sentinel 实例发送一个 PING 命令 

2):如果一个实例(instance)距离最后一次有效回复 PING 命令的时间超过 down-after-milliseconds 选项所指定的值,则这个实例会被 Sentinel 标记为主观下线。 

3):如果一个Master被标记为主观下线,则正在监视这个Master的所有 Sentinel 要以每秒一次的频率确认Master的确进入了主观下线状态。 

4):当有足够数量的 Sentinel(大于等于配置文件指定的值)在指定的时间范围内确认Master的确进入了主观下线状态, 则Master会被标记为客观下线 

ps:quorum 的值一般设置为哨兵个数的二分之一加1,例如 3 个哨兵就设置 2。

3.主观下线和客观下线

主观下线:Subjectively Down,简称 SDOWN,指的是当前 Sentinel 实例对某个redis服务器做出的下线判断。 
客观下线:Objectively Down, 简称 ODOWN,指的是多个 Sentinel(哨兵) 实例在对Master Server做出 SDOWN  判断,并且通过 SENTINEL is-master-down-by-addr 命令互相交流之后,得出的Master  Server下线判断,然后开启failover(故障转移)

4.配置哨兵模式

vim /usr/local/redis/sentinel.conf

daemonize yes                                #设置哨兵放后台运行
logfile "/var/log/sentinel.log"                    #设置哨兵日志
sentinel monitor mymaster 192.168.91.5 6379 2        #当集群中有2个sentinel认为master死了时,才能真正认为该master已经不可用了。 (slave上面写的是master的ip,master写自己ip)
protected-mode no             #将加密保护关闭
sentinel down-after-milliseconds mymaster 3000          #单位毫秒
sentinel failover-timeout mymaster 10000           #若sentinel在该配置值内未能完成failover(故障转移)操作(即故障时master/slave自动切换),则认为本次failover失败。

[root@redis-master redis]# ./src/redis-sentinel sentinel.conf   #开启哨兵模式

三、redis集群

1.使用redis集群的原因

1.首先Redis单实例主要有单点,容量有限,流量压力上限的问题。
Redis单点故障,可以通过主从复制replication,和自动故障转移sentinel哨兵机制。但Redis单Master实例提供读写服务,仍然有容量和压力问题。

2.并发问题
redis官方声称可以达到 10万/每秒,每秒执行10万条命令
假如业务需要每秒100万的命令执行呢?
解决方案如下
正确的应该是考虑分布式,加机器,把数据分到不同的位置,分摊集中式的压力。那么一堆机器做一件事.还需要一定的机制保证数据分区,并且数据在各个主Master节点间不能混乱。

总结:
redis cluster:主要是针对海量数据+高并发+高可用的场景,海量数据,如果你的数据量很大,那么建议就用redis cluster

2.redis集群特点

1.所有的redis节点彼此互联(PING-PONG机制)。
2.客户端与redis节点直连,不需要中间proxy层.客户端不需要连接集群所有节点,连接集群中任何一个可用节点即可。
3.节点的fail是通过集群中超过半数的节点检测失效时才生效。
4.Redis-Cluster采用无中心结构,每个节点保存数据和整个集群状态,每个节点都和其他所有节点连接。

3.数据分布存储原理

Redis 集群使用数据分片来实现:Redis 集群中内置了 16384 个哈希槽,当需要在 Redis 集群中放置一个 key-value 时,redis 先对 key 使用 crc16 算法算出一个结果,然后把结果对 16384 求余数(集群使用公式 CRC16(key) % 16384),这样每个key 都会对应一个编号在 0-16384 之间的哈希槽,那么redis就会把这个key 分配到对应范围的节点上了。同样,当连接三个节点任何一个节点想获取这个key时,也会这样的算法,然后内部跳转到存放这个key节点上获取数据。

4.集群部署

准备环境 

1.准备三机器,关闭防火墙和selinux
2.制作解析并相互做解析。
注:规划架构两种方案,一种是单机多实例,这里我们采用多机器部署:
三台机器,每台机器上面两个redis实例,一个master一个slave,第一列做主库,第二列做备库
#记得选出控制节点

redis-cluster1 192.168.91.5   7000、7001
redis-cluster2 192.168.91.149   7002、7003
redis-cluster3 192.168.91.150   7004、7005

安装redis(三台机器都需要操作)

yum -y install gcc automake autoconf libtool make    #安装编译工具
wget https://download.redis.io/releases/redis-6.2.0.tar.gz      #下载
tar xzvf redis-6.2.0.tar.gz -C /usr/local        #解压
mv /usr/local/redis-6.2.0 /usr/local/redis        #改名
cd /usr/local/redis
make                      #编译
mkdir /usr/local/redis/data        #创建存放数据的目录

创建节点目录:按照规划在每台redis节点的安装目录中创建对应的目录(以端口号命名)

[root@redis-cluster1 redis]# pwd
/usr/local/redis

[root@redis-cluster1 redis]# mkdir cluster #创建集群目录
[root@redis-cluster1 redis]# cd cluster/
[root@redis-cluster1 cluster]# mkdir 7000 7001 #创建节点目录

[root@redis-cluster2 redis]# mkdir cluster
[root@redis-cluster2 redis]# cd cluster/
[root@redis-cluster2 cluster]# mkdir 7002 7003

[root@redis-cluster3 redis]# mkdir cluster
[root@redis-cluster3 redis]# cd cluster/
[root@redis-cluster3 cluster]# mkdir 7004 7005

拷贝配置文件到节点目录中

[root@redis-cluster1 cluster]# cp /data/redis/redis.conf 7000/
[root@redis-cluster1 cluster]# cp /data/redis/redis.conf 7001/

[root@redis-cluster2 cluster]# cp /data/redis/redis.conf 7002/
[root@redis-cluster2 cluster]# cp /data/redis/redis.conf 7003/

[root@redis-cluster3 cluster]# cp /data/redis/redis.conf 7004/
[root@redis-cluster3 cluster]# cp /data/redis/redis.conf 7005/

修改集群redis配置文件。(主要是端口、ip、pid文件,三台机器相同操作)

[root@redis-cluster1 7000]# vim redis.conf 

bind 192.168.116.172               #每个实例的配置文件修改为对应节点的ip地址
port 7000                    #监听端口,运行多个实例时,需要指定规划的每个实例不同的端口号
daemonize yes #redis后台运行
pidfile /var/run/redis_7000.pid           #pid文件,运行多个实例时,需要指定不同的pid文件
logfile /var/log/redis_7000.log           #日志文件位置,运行多实例时,需要将文件修改的不同。
dir /data/redis/data            #存放数据的目录
appendonly yes           #开启AOF持久化,redis会把所接收到的每一次写操作请求都追加到appendonly.aof文件中,当redis重新启动时,会从该文件恢复出之前的状态。
appendfilename "appendonly.aof"           #AOF文件名称
appendfsync everysec        #表示对写操作进行累积,每秒同步一次

以下为打开注释并修改
cluster-enabled yes #启用集群
cluster-config-file nodes-7000.conf                 #集群配置文件,由redis自动更新,不需要手动配置,运行多实例时请注修改为对应端口
cluster-node-timeout 5000             #单位毫秒。集群节点超时时间,即集群中主从节点断开连接时间阈值,超过该值则认为主节点不可以,从节点将有可能转为master
cluster-replica-validity-factor 10               #在进行故障转移的时候全部slave都会请求申请为master,但是有些slave可能与master断开连接一段时间了导致数据过于陈旧,不应该被提升为master。该参数就是用来判断slave节点与master断线的时间是否过长。
cluster-migration-barrier 1         #一个主机将保持连接的最小数量的从机,以便另一个从机迁移到不再被任何从机覆盖的主机
cluster-require-full-coverage yes     #集群中的所有slot(16384个)全部覆盖,才能提供服务

注:所有节点配置文件全部修改切记需要修改的ip、端口、pid文件...避免冲突。确保所有机器都修改。

启动三台机器上面的每个节点

[root@redis-cluster1 src]# ./redis-server ../cluster/7000/redis.conf 
[root@redis-cluster1 src]# ./redis-server ../cluster/7001/redis.conf

[root@redis-cluster2 7003]# cd /data/redis/src/
[root@redis-cluster2 src]# ./redis-server ../cluster/7002/redis.conf 
[root@redis-cluster2 src]# ./redis-server ../cluster/7003/redis.conf

[root@redis-cluster3 7005]# cd /data/redis/src/
[root@redis-cluster3 src]# ./redis-server ../cluster/7004/redis.conf 
[root@redis-cluster3 src]# ./redis-server ../cluster/7005/redis.conf

查看端口

netsata -lnpt                   #查看端口

查看到这些信息之后,就说明我们的redis集群搭建成功了

四、总结redis在运维方面的经典问题

一、如何解决Redis,mysql双写一致性?
1.最经典的缓存+数据库读写的模式:
读的时候,先读缓存,缓存没有的话,就读数据库,然后取出数据后放入缓存,同时返回响应。
更新的时候,先更新数据库,然后再删除缓存。
2.给缓存设置过期时间,这种方案下,可以对存入缓存的数据设置过期时间,所有的写操作以数据库为准,也就是说如果数据库写成功,缓存更新失败,那么只要到达过期时间,则后面的读请求自然会从数据库中读取新值然后回填缓存。

二、缓存雪崩
数据未加载到缓存中,或者缓存同一时间大面积的失效,从而导致所有请求都去查数据库,导致数据库CPU和内存负载过高,甚至宕机。

产生雪崩的简单过程:
1、redis集群大面积故障
2、缓存失效,但依然大量请求访问缓存服务redis
3、redis大量失效后,大量请求转向到mysql数据库,mysql的调用量暴增,很快就扛不住了,甚至直接宕机
4、由于大量的应用服务依赖mysql和redis的服务,这个时候很快会演变成各服务器集群的雪崩,最后网站彻底崩溃。

解决问题:
1.缓存的高可用性
缓存层设计成高可用,防止缓存大面积故障。即使个别节点、个别机器、甚至是机房宕掉,依然可以提供服务,例如 Redis Sentinel 和 Redis Cluster 都实现了高可用。
2.缓存降级
可以利用ehcache等本地缓存(暂时支持),主要还是对源服务访问进行限流、资源隔离(熔断)、降级等。
当访问量剧增、服务出现问题仍然需要保证服务还是可用的。系统可以根据一些关键数据进行自动降级,也可以配置开关实现人工降级,这里会涉及到运维的配合。
降级的最终目的是保证核心服务可用,即使是有损的。
在进行降级之前要对系统进行梳理,比如:哪些业务是核心(必须保证),哪些业务可以容许暂时不提供服务(利用静态页面替换)等,以及配合服务器核心指标,来后设置整体。
3.Redis备份和快速预热
1)Redis数据备份和恢复
2)快速缓存预热
4.提前演练
最后,建议还是在项目上线前,演练缓存层宕掉后,应用以及后端的负载情况以及可能出现的问题,对高可用提前预演,提前发现问题。

三、缓存穿透
缓存穿透是指查询一个一不存在的数据。例如:从缓存redis没有命中,需要从mysql数据库查询,查不到数据则不写入缓存,这将导致这个不存在的数据每次请求都要到数据库去查询,造成缓存穿透。

解决问题:
如果查询数据库也为空,直接设置一个默认值存放到缓存,这样第二次到缓冲中获取就有值了,而不会继续访问数据库。设置一个过期时间或者当有值的时候将缓存中的值替换掉即可。

四、redis有哪些好处
(1) 速度快,因为数据存在内存中.
(2) 支持丰富数据类型,支持string,list,set,sorted set,hash
(3) 支持事务,操作都是原子性,所谓的原子性就是对数据的更改要么全部执行,要么全部不执行
(4) 丰富的特性:可用于缓存,消息,按key设置过期时间,过期后将会自动删除
redis相比memcached有哪些优势
(1) memcached所有的值均是简单的字符串,redis作为其替代者,支持更为丰富的数据类型
(2) redis可以持久化其数据
redis常见性能问题和解决方案
(1) Master最好不要做任何持久化工作,如RDB内存快照和AOF日志文件
(2) 如果数据比较重要,某个Slave开启AOF备份数据,策略设置为每秒同步一次
(3) 为了主从复制的速度和连接的稳定性,Master和Slave最好在同一个局域网内
(4) 尽量避免在压力很大的主库上增加从库

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1305860.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

12月12日作业

设计一个闹钟 头文件 #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QTimerEvent> #include <QTime> #include <QTime> #include <QTextToSpeech>QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_NAMESPACEclass …

【深度学习】强化学习(六)基于值函数的学习方法

文章目录 一、强化学习问题1、交互的对象2、强化学习的基本要素3、策略&#xff08;Policy&#xff09;4、马尔可夫决策过程5、强化学习的目标函数6、值函数7、深度强化学习 二、基于值函数的学习方法 一、强化学习问题 强化学习的基本任务是通过智能体与环境的交互学习一个策略…

GeMap:Online Vectorized HD Map Construction using Geometry

参考代码&#xff1a;GeMap 动机与出发点 出了原本针对单点的L1损失&#xff0c;车道线具备的几何结构信息作为监督信息也可以再被挖掘挖掘&#xff0c;像车道线实例中点和点之间的距离与夹角、线与线之间的夹角、不同线上点与点之间的关系都可用来作为监督约束&#xff0c;但…

Redis - RDB与AOF持久化技术

Redis 持久化技术 RDB 是默认持久化方式&#xff0c;但 Redis 允许 RDB 与 AOF 两种持久化技术同时 开启&#xff0c;此时系统会使用 AOF 方式做持久化&#xff0c;即 AOF 持久化技术的优先级要更高。同样的道 理&#xff0c;两种技术同时开启状态下&#xff0c;系…

字符设备驱动开发基础

一. 简介 本文简单了解一下&#xff0c;在字符设备驱动开发开始前对其一些基本认识。简单了解一下&#xff0c;应用程序与驱动的交互原理&#xff0c;以及字符设备驱动开发流程。 二. 字符设备驱动开发流程 1. 在 Linux 中一切皆为文件&#xff0c;驱动加载成功以后会在“…

【教程】制作 iOS 推送证书

​ 目录 证书类型 MAC Key Store 消息推送控制台 制作证书 创建苹果 App ID 使用appuploder制作 .p12文件 创建证书 如需向 iOS 设备推送数据&#xff0c;您首先需要在消息推送控制台上配置 iOS 推送证书。iOS 推送证书用于推送通知&#xff0c;本文将介绍消息推送服务支…

K8S(二)—介绍

K8S的整体结构图 k8s对象 在 Kubernetes 系统中&#xff0c;Kubernetes 对象是持久化的实体。 Kubernetes 使用这些实体去表示整个集群的状态。 具体而言&#xff0c;它们描述了如下信息&#xff1a; 哪些容器化应用正在运行&#xff08;以及在哪些节点上运行&#xff09;可…

【Java 进阶篇】Jedis 操作 Hash:Redis中的散列类型

在Redis中&#xff0c;Hash是一种存储键值对的数据结构&#xff0c;它适用于存储对象的多个属性。Jedis作为Java开发者与Redis交互的工具&#xff0c;提供了丰富的API来操作Hash类型。本文将深入介绍Jedis如何操作Redis中的Hash类型数据&#xff0c;通过生动的代码示例和详细的…

Github仓库远程操作——简单版

Github远程操作 github仓库简单的远程操作&#xff0c;更多复杂的功能请参考github官方文档 标题 Github远程操作添加公钥到githubGithub仓库远程操作 远程操作之前&#xff0c;先添加本地的公钥到github 添加公钥到github 创建本地ssh公私钥&#xff1a;使用powershell或者gi…

Kubernetes实战(十三)-使用kube-bench检测Kubernetes集群安全

1 概述 在当今云原生应用的开发中&#xff0c;Kubernetes已经成为标准&#xff0c;然而&#xff0c;随着其使用的普及&#xff0c;也带来了安全问题的挑战。本文将介绍如何使用kube-bench工具来评估和增强Kubernetes集群的安全性。 2 CIS (Center for Internet Security)简介…

DNSLog漏洞探测(三)之XSS漏洞实战

DNSLog漏洞探测(三)之XSS漏洞实战 通过前面的学习&#xff0c;我们已经明白了什么是DNSLog平台&#xff0c;那么DNSLog平台到底能为我们做些什么呢&#xff1f; DNSLog的平台实际使用很长见的一种情况就是针对漏洞无回显的情况&#xff0c;我们通过让受害者的服务器主动发起对…

数据结构之----数组、链表、列表

数据结构之----数组、链表、列表 什么是数组&#xff1f; 数组是一种线性数据结构&#xff0c;它将相同类型的元素存储在连续的内存空间中。 我们将元素在数组中的位置称为该元素的索引。 数组常用操作 1. 初始化数组 我们可以根据需求选用数组的两种初始化方式&#xff…

Docker容器:Centos7搭建Docker镜像私服harbor

目录 1、安装docker 1.1、前置条件 1.2、查看当前操作系统的内核版本 1.3、卸载旧版本(可选) 1.4、安装需要的软件包 1.5、设置yum安装源 1.6、查看docker可用版本 1.7、安装docker 1.8、开启docker服务 1.9、安装阿里云镜像加速器 1.10、设置docker开机自启 2、安…

【Hadoop_05】NN、2NN以及DataNode的工作机制

1、NameNode和SecondaryNameNode1.1 NN和2NN工作机制1.2 Fsimage和Edits解析1.3 CheckPoint时间设置 2、DataNode2.1 DataNode工作机制2.2 数据完整性2.3 掉线时限参数设置 1、NameNode和SecondaryNameNode 1.1 NN和2NN工作机制 思考&#xff1a;NameNode中的元数据是存储在哪…

css选择器介绍

css选择器介绍 01 css概念介绍 用于更改标签的视觉效果 02 css格式 选择器 {属性1&#xff1a;值1&#xff1b;属性2&#xff1a;值2} 03 三种样式 1.内联样式 直接写在标签的style属性中。 优点&#xff1a;简单明显缺点&#xff1a;无法重复使用代码 <img src&quo…

【Amis Low Code 结合FastAPI进行前端框架开发】

官方文档 封装思想 直接复制官网json数据即可开发每个json中的接口由fastapi 转发&#xff08;透传&#xff09;使其开发模式与前端思维一致 基础组件 from amis import Page, Service, App from pydantic import BaseModel, Field from fastapi import FastAPI, Request, …

Node.js 事件循环简单介绍

1.简介 Node.js 事件循环是 Node.js 运行时环境中的一个核心机制&#xff0c;用于管理异步操作和回调函数的执行顺序。它基于事件驱动模型&#xff0c;通过事件循环来处理和派发事件&#xff0c;以及执行相应的回调函数。 Node.js 是单进程单线程应用程序&#xff0c;但是因为…

java版Spring Cloud+Spring Boot+Mybatis之隐私计算 FATE - 多分类神经网络算法测试

一、说明 本文分享基于 Fate 使用 横向联邦 神经网络算法 对 多分类 的数据进行 模型训练&#xff0c;并使用该模型对数据进行 多分类预测。 二分类算法&#xff1a;是指待预测的 label 标签的取值只有两种&#xff1b;直白来讲就是每个实例的可能类别只有两种 (0 或者 1)&…

SpringBoot系列之基于Jedis实现分布式锁

Redis系列之基于Jedis实现分布式锁 1、为什么需要分布式锁 在单机环境&#xff0c;我们使用最多的是juc包里的单机锁&#xff0c;但是随着微服务分布式项目的普及&#xff0c;juc里的锁是不能控制分布锁环境的线程安全的&#xff0c;因为单机锁只能控制同个进程里的线程安全&…

独立完成软件的功能的测试(3)

独立完成软件的功能的测试&#xff08;3&#xff09; &#xff08;12.13&#xff09; 执行测试用例 缺陷相关知识 缺陷的定义&#xff1a;软件再使用过程中出现的错误&#xff0c;Bug 评判标准 少功能&#xff0c;需求规格说明书中明确要求的功能功能错误多功能隐性功能错误…