Redis 淘汰策略、持久化、高可用

news2024/9/22 19:42:57

淘汰策略

  • 只有 redis 内存空间已满并且往里面写新数据,才会触发淘汰策略
  • 通过 expire / / /pexpire 让 key-value 过期,从而让 redis 清除这个 key-value。
  • value 的数据结构
    typedef struct redisObject {
    	unsigned tpye:4;
    	unsigned encoding:4;
    	
    	// 判断哪些 key 要被删除
    	unsigned lru:LRU_BITS; // 占用 24位,8位用来记录访问的次数(0-255次),16位用来记录上一次访问的时间
    	
    	int refcount; // 引用计数
    	void *ptr; // 指向 value 的存储空间
    } robj;
    
    object idletime key # 展示 value 的 lru 字段
    
  • 配置淘汰策略
    • 如果 redis 内存空间已满,并且没有设置淘汰策略,再 set key value 会直接返回错误,提示内存空间已满;如果设置了淘汰策略,redis 会按照淘汰策略选择数据进行删除,再 set key value 就会成功。
      # redis.conf
      maxmemory <bytes>  # redis 最多可以使用多少空间
      maxmemory-policy   # 淘汰策略,默认为 noeviction, 不进行淘汰
      maxmemory-samples  # 默认为 5,选择多少个 key 进行淘汰
      
    • 过期 key 中
      • volatile-lru:最长时间没有使用。
      • volatile-lfu:最少次数使用,随机采样。
      • volatile-ttl:最近要过期。
      • volatile-random:随机。
    • 所有 key
      • allkeys-lru。
      • allkeys-lfu 。
      • allkeys-random 。
    • 禁止淘汰:no-eviction。

持久化

  • redis 为什么需要持久化 ?
    • 因为 redis 是内存数据库,一旦关闭,内存中的数据就丢失了,所以需要把内存中的数据写到磁盘中,这样 redis 重启后就可以从磁盘中加载原来的数据到内存中。
    • 只有写操作(增删改操作,会引起数据库变更的操作)才会进行持久化。
  • redis 持久化方式
    • aof
      • 持久化的是写操作协议内容(通过重放恢复内存中的数据),会有很多冗余数据;在 redis 进程中完成,every_sec 会另启线程做持久化。
        *3
        $3
        set
        $4
        mark
        $1
        2
        
      • 策略
        • no:关闭 aof。
        • always:先将数据持久化到磁盘,再响应客户端。(效率很低,一般不采用)
        • every_sec:只要内存修改成功,立刻响应客户端。
          • 先将数据写到 aof buffer 中,一秒后将 aof buffer 中的数据持久化到磁盘,这个过程是异步的,使用 bio_fsync_aof。
        • always 和 every_sec 会调用 fsync(fd) 将 page cache 中的数据立刻持久化到磁盘。 在这里插入图片描述
      • aof-rewrite
        • 因为 aof 文件过大,数据恢复速度太慢,所以要减少 aof 文件大小。
        • 工作原理
          • fork 进程,根据内存数据生成 aof 文件,避免同一个 key 的历史冗余数据。
          • 在重写 aof 期间,对 redis 的写操作会被记录到重写缓冲区,在重写 aof 结束后,再将这些写操作附加到 aof 文件末尾(可能有冗余数据)。
    • rdb
      • 持久化的是二进制数据(根据磁盘中的二进制数据恢复内存中的数据);另启进程做持久化。
      • 工作原理:通过 fork 子进程进行持久化,基于内存中对象编码直接持久化。
        • fork 相当于给父进程的内存做了一个快照。
        • fork 写时复制
          在这里插入图片描述
          • 页表存储了虚拟内存和物理内存之间的映射关系。
          • linux 为了加快 fork 的流程,fork 仅仅会复制页表,然后将两个页表中的所有保护位修改为只读,此时父进程和子进程共用一块物理内存;父进程依然对外提供服务。
          • 当父进程处理写操作时,首先会找到虚拟内存的内存页,然后通过页表写物理内存页的时候,发现保护位是只读的,此时会触发写保护中断:在物理内存中完成一次物理页复制(把原来的物理页复制一份),然后把数据写入到复制后物理页中,最后在写保护中断的处理函数中将页表中的保护位修改为可读可写,并且重新构建页表中的映射关系(页表中该虚拟内存的指向变为新的物理页)。
      • rdb-aof 混用
        • 通过 fork 子进程,根据内存数据生成 rdb 文件。
        • 在 rdb 持久化期间,对 redis 的写操作会被记录到重写缓冲区,在 rdb 持久化结束后,采用 aof 的方式附加到文件末尾。
  • redis 持久化方式优缺点
    • aof
      • 优点:数据可靠,丢失较少;持久化过程代价较低(是顺序磁盘 IO,持久化速度快)。
      • 缺点:aof 文件过大,数据恢复慢(通过重放恢复内存中的数据)。
    • rdb
      • 优点:rdb 文件小,数据恢复快。
      • 缺点:数据丢失较多;持久化过程代价较高。
  • 大 key 问题:kv 中,value 如果占用大量空间就是大 key,比如 value 是 hash、zset,里面存储大量元素。
    • fsync 压力大。
    • 因为页表大,所以 fork 时间长,写时复制造成持久化时间长。

高可用

  • 为什么实际业务中有高可用的需求 ?
    • 比如服务器依赖 redis,如果 redis 宕机了,那么服务器就不能给客户端响应了,此时整个服务器处于不可用状态。
    • redis 高可用:如果 redis 中的一个节点宕机了,会有备用节点顶替它,服务器不会因为 redis 中的一个节点宕机了,造成服务不可用。
  • 什么是高可用 ?
    • 在合理的时间内给出合理的回复。
      • 合理的时间:秒级的。
      • 合理的回复:给一个请求,如果发生错误,需要回复是到底是什么错误,不能模棱两可。
  • 如何实现高可用 ?
    • 数据备份。
    • 节点切换策略。

主从复制

  • 主从复制不能保证高可用,只起到了数据备份的作用。
  • 含义
    • 主从复制是异步复制,服务器写数据到主数据库(master),主数据库立刻返回;从数据库(replica)不断地从主数据库中拉取数据并保存,以达到从数据库和主数据库数据一致。
    • replica 主动向 master 建立连接(否则无法线上新增 replica)
    • replica 主动向 master 拉取数据(若网络出现问题,replica 持有同步位置:复制偏移量)
    • 缺点:可能带来数据不一致:某一时刻如果从 replica 中获取数据,数据可能不是最新的。
  • 实现
    在这里插入图片描述
    在这里插入图片描述
    • master 记录了一个环形缓冲区和一个复制偏移量,replica 记录了一个复制偏移量
    • RUN ID:
      • 无论 master 还是 replica 都有自己的 RUN ID,RUN ID 在其启动时自动产生,由 40 个随机的十六进制字符组成。
      • 当 replica 对 master 初次复制时,master 将自身的 RUN ID 发送给 replica,replica 会将 RUN ID 保存;当 replica 断线重连 master 时,replica 将向 master 发送之前保存的 RUN ID。
      • 如果 replica RUN ID 和 master RUN ID 一致,说明 replica 断线前复制的就是当前的 master,master 尝试执行增量更新。若不一致,说明 replica 断线前复制的 master 并不是当前的 master,则 master 将对 replica 执行全量更新
    • 复制偏移量 offset(64 位的整数且一直累加):
      • master 和 offset 都会维护一个复制偏移量;master 向 replica 发送 N 个字节的数据时,将自己的复制偏移量加上 N,replica 接收到 master 发送的 N 个字节的数据时,将自己的复制偏移量加上 N。
      • 如果 replica 记录的复制偏移量在环形缓冲区中,就将 master 中的数据偏移和 replica 的数据偏移之间的数据发给 replica(增量更新)。
      • 如果 replica 记录的复制偏移量不在环形缓冲区中,就把 master 中的 rdb 数据发给 replica(全量更新)。
      • 通过比较主从偏移量得知主从之间数据是否一致;偏移量相同则数据一致,偏移量不同则数据不一致。
      • 复制偏移量越大,数据越新

哨兵模式

在这里插入图片描述

  • 哨兵模式是 redis 高可用的解决方案:
    • 由一个或多个 sentinel 实例构成 sentinel 集群,该集群可以监视任意多个主库以及这些主库所属的从库;当主库处于下线状态,会自动将该主库所属的某个数据最新的从库升级为新的主库。
    • 客户端连接集群时,首先会连接 sentinel(任意一个 sentinel),通过 sentinel 来查询主库的地址(ip 地址 + 端口),并且通过 subscribe 监听主库切换,然后再连接主库进行数据交互。
    • 当主库发生故障时,sentinel 会主动推送新的主库地址。这样客户端无须重启即可自动完成节点切换。
  • 检测异常
    • 主观下线:sentinel 会以每秒一次的频率向所有节点(其他 sentinel、主节点、从节点)发送 ping 消息,然后通过接收返回判断该节点是否下线;如果配置指定了 down-after-milliseconds,则在该时间内没有返回就被判断为主观下线。
    • 客观下线:当一个 sentinel 节点将一个主节点判断为主观下线之后,为了确
      认这个主节点是否真的下线,它会向其他 sentinel 节点进行询问,如果收到一定数量(半数以上)的已下线回复,sentinel 会将主节点判定为客观下线,并通过领头 sentinel 节点对主节点执行故障转移。
    • 故障转移:
      • 从节点中选举一个节点作为新的主节点(选复制偏移量最大的从节点)。
      • 通知其他从节点复制连接新的主节点。
      • 若故障主节点重新连接,将作为新的主节点的从节点。
  • 缺点:
    • 延迟较大:redis 采用异步复制的方式,意味着当主节点挂掉时,从节点可能没有收到全部的同步消息,这部分未同步的消息将会丢失。如果主从延迟特别大,那么丢失可能会特别多。
    • 不能进行数据扩容
    • 部署麻烦。
  • 配置
    # sentinel.cnf
    # sentinel 只需指定检测主节点就行了,通过主节点自动发现从节点
    sentinel monitor mymaster 127.0.0.1 6379 2
    # 判断主观下线时长
    sentinel down-after-milliseconds mymaster 30000
    # 指定可以有多少个 redis 服务同步新的主机,一般而言,这个数字越小同步时间越长; 越大,则对网络资源要求越高
    sentinel parallel-syncs mymaster 1
    # 指定故障切换允许的毫秒数,超过这个时间,就认为故障切换失败,默认为 3分钟
    sentinel failover-timeout mymaster 180000
    

cluster 集群

在这里插入图片描述

  • 实现高可用
    • 数据备份:每个主节点都会有多个从节点。
    • 主节点转移:集群节点间会互相发送消息,交换节点的状态信息;若某主节点下线,将会被其它节点标记下线,接着在该下线主节点的从节点中选择一个数据最新的从节点作为主节点;从节点继承下线主节点的槽位信息,并广播改消息给集群中的其它节点。
  • 特征:
    • 去中心化:没有中心节点。
    • 主节点对等。
    • 能够进行数据扩容。
    • 读写数据只会通过主节点进入集群。
  • 流程:
    1. 连接集群中任意一个节点。
    2. 若数据不在该节点,将收到连接切换的命令,继而连接到目标节点。
  • 缺点:因为主从采用异步复制,在主节点转移时仍存在数据丢失的情况。
  • 配置集群 在这里插入图片描述
# 创建 6 个文件夹
mkdir -p 7001 7002 7003 7004 7005 7006
cd 7001
vi 7001.conf

# 7001.conf 中的内容如下
pidfile "/home/zcoder/redis-cluster/7001/7001.pid"
logfile "/home/zcoder/redis-cluster/7001/7001.log"
dir /home/zcoder/redis-cluster/7001/
port 7001
daemonize yes
cluster-enabled yes
cluster-config-file nodes-7001.conf
cluster-node-timeout 15000

# 复制配置
cp 7001/7001.conf 7002/7002.conf
cp 7001/7001.conf 7003/7003.conf
cp 7001/7001.conf 7004/7004.conf
cp 7001/7001.conf 7005/7005.conf
cp 7001/7001.conf 7006/7006.conf

# 查看目录结构
tree .

# 修改配置
sed -i 's/7001/7002/g' 7002/7002.conf
sed -i 's/7001/7003/g' 7003/7003.conf
sed -i 's/7001/7004/g' 7004/7004.conf
sed -i 's/7001/7005/g' 7005/7005.conf
sed -i 's/7001/7006/g' 7006/7006.conf
#!/bin/bash
# 创建启动配置 start.sh
redis-server 7001/7001.conf
redis-server 7002/7002.conf
redis-server 7003/7003.conf
redis-server 7004/7004.conf
redis-server 7005/7005.conf
redis-server 7006/7006.conf
# 增加可执行权限
chmod +x start.sh 

# 启动全部 redis 节点 
./start.sh
# 查看 redis 节点是否全部启动
ps aux | grep redis-server

# 智能创建 redis 集群
# --cluster-replicas: 一个主节点对应几个从节点
redis-cli --cluster create 127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005 127.0.0.1:7006 --cluster-replicas 1

在这里插入图片描述

# 读写数据只会通过主节点进入集群
# 进入指定的 redis 节点
redis-cli -c -p 7006 # 127.0.0.1:7006
set zcoder 1         # 会重定向到存储该数据的主节点
# 主节点宕机
redis-cli -p 7001 shutdown
# 主节点重启
redis-server 7001/7001.conf
  • 使用 crc16(zcoder) % 16384,通过增大样本数,让各个主节点存储的数据量较为均衡。
    在这里插入图片描述
  • 扩容:先增加节点,再分配槽位。
    cp -R 7001 7007
    cd 7007
    mv 7001.conf 7007.conf
    rm 7001.log dump.rdb nodes-7001.conf
    sed -i "s/7001/7007/g" 7007.conf
    cp -R 7007 7008
    cd 7008
    mv 7007.conf 7008.conf
    sed -i "s/7007/7008/g" 7008.conf
    cd ..
    redis-server 7007/7007.conf
    redis-server 7008/7008.conf
    # 7007 是主节点,7008 是从节点
    redis-cli --cluster add-node 127.0.0.1:7007 127.0.0.1:7001 
    redis-cli --cluster add-node 127.0.0.1:7008 127.0.0.1:7001 --cluster-slave --cluster-master-id 主节点的id
    
    # 将槽位重新分配到整个集群的所有节点中
    redis-cli --cluster reshard 127.0.0.1:7001
    How many slots do you want to move (from 1 to 16384)? #1000
    What is the receiving node ID? # 主节点的id
    Please enter all the source node IDs.
    Type 'all' to use all the nodes as source nodes for the hash slots.
    Type 'done' once you entered all the source nodes IDs.
    Source node # all
    
    # 将节点 A 的槽位迁移到节点 B
    redis-cli --cluster reshard 127.0.0.1:7001 --cluster-from 节点A的id --cluster-to 节点B的id --cluster-slots 1000
    
  • 缩容:先移动槽位,再删除节点
    redis-cli --cluster reshard 127.0.0.1:7001 --cluster-from 节点B的id --cluster-to 节点A的id --cluster-slots 1000
    # 删除节点 7007
    redis-cli --cluster del-node 127.0.0.1:7001 节点7007的id
    # 此时 7008 成为其他节点的从节点
    redis-cli --cluster del-node 127.0.0.1:7001 节点7008的id
    

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

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

相关文章

C语言初阶—数组

数组是一组相同类型元素的集合。 在C99标准之前&#xff0c;数组的大小必须是常量或常量表达式。 在C99标准之后&#xff0c;数组的大小可以是变量&#xff0c;可以支持变长数组&#xff0c;但变长数组不能初始化。 不完全初始化&#xff0c;剩余的元素默认初始化为0 。 数组访…

【Unity】Node.js安装与配置环境

引言 我们在使用unity开发的时候&#xff0c;有时候会使用一些辅助工具。 Node.js就是开发中&#xff0c;经常会遇到的一款软件。 1.下载Node.js 下载地址&#xff1a;https://nodejs.org/en 2.安装Node.js ①点击直接点击Next下一步 ②把协议勾上&#xff0c;继续点击…

帝恩思SSL证书助力工业领域数据安全保护能力,助力企业高质量发展

为加快提升工业领域数据安全保护能力&#xff0c;助力工业高质量发展&#xff0c;夯实新型工业化发展的安全基石&#xff0c;2024年2月26日&#xff0c;工业和信息化部发布了《工业领域数据安全能力提升实施方案&#xff08;2024-2026年&#xff09;》。 在方案中提出以落实企…

Nodejs 第四十四章(redis基本使用)

字符串的操作 SET key value [NX|XX] [EX seconds] [PX milliseconds] [GET]key&#xff1a;要设置的键名。value&#xff1a;要设置的值。NX&#xff1a;可选参数&#xff0c;表示只在键不存在时才设置值。XX&#xff1a;可选参数&#xff0c;表示只在键已经存在时才设置值。…

七款顶级API测试工具

在现代软件开发中&#xff0c;API接口已成为不可或缺的核心组件。鉴于API缺乏直观的图形用户界面&#xff08;GUI&#xff09;&#xff0c;使得直接对接口进行测试变得困难&#xff0c;对于前后端开发者而言&#xff0c;选择一套高效且实用的工具来测试API接口&#xff0c;从而…

g2o -- curve_fit代码解析

概述 本文介绍通过g2o框架&#xff0c;优化点和曲线的匹配&#xff08;曲线拟合&#xff09;。曲线的公式如下所示&#xff1a; 它有三个参数&#xff1a;a, b, lamba。 代码解析 自定义顶点 /*** \brief the params, a, b, and lambda for a * exp(-lambda * t) b*/ clas…

【AWS Credit】AWS服务抵扣金额兑换操作步骤演示说明

AWS 服务抵扣金额可应用于账单&#xff0c;帮助支付与符合条件的服务相关联的成本。服务抵扣金额在用尽或过期之前均可应用。 文章目录 AWS Credit 使用说明1.登录到AWS控制台2.导航至“账单和成本管理”3.点击“积分”&#xff0c;选择“兑换积分”4.输入优惠代码及安全代码5.…

【MySQL系列】在 MacOS 上安装 MySQL

在 MacOS 上有两种方式安装 MySQL 服务器&#xff1a;通过 brew 安装和通过安装包安装。 文章目录 1、通过 brew 安装 MySQL1.1、安装 MySQL1.2、启动 MySQL 服务器1.3、配置 MySQL 服务器1.4、MySQL 服务器管理命令 2、通过安装包安装 MySQL2.1、下载安装包2.2、安装 MySQL2.3…

demo型xss初级靶场

一、环境 XSS Game - Ma Spaghet! | PwnFunction 二、开始闯关 第一关 看看代码 试一下直接写 明显进来了为什么不执行看看官方文档吧 你不执行那我就更改单标签去使用呗 ?somebody<img%20src1%20onerror"alert(1)"> 防御&#xff1a; innerText 第二关…

Vue中如何创建自定义指令?

在Vue中&#xff0c;除了内置的指令外&#xff0c;我们还可以自定义指令来扩展Vue的功能。自定义指令是Vue的一个重要特性&#xff0c;它使得我们可以在DOM元素上添加特定的行为。下面我们就来看看如何在Vue中创建自定义指令。 首先&#xff0c;让我们先了解一下自定义指令的基…

2024.03.02蓝桥云课笔记

1.scanf与printf取消分隔符的限制方法 示例代码&#xff1a; int main() { char s[10];scanf("%d[^\n]",s);printf("%s",s);return 0; } 运行&#xff1a; 输入&#xff1a;Hello World 输出&#xff1a;Hello World 注&#xff1a;其中[]中是一个正则…

C语言:指针(二)

目录 1.数组名的理解2.使用指针访问数组3.一维数组传参的本质4.二级指针5.指针数组6.字符指针变量7.数组指针变量8.二维数组传参的本质9.函数指针变量10.函数指针数组11.回调函数12.qsort函数13.使用回调函数模拟实现qsort函数 1.数组名的理解 int main() {int arr[] { 1,2,3…

英伟达:通用人工智能最快在五年内通过人类测试能力 | 百能云芯

英伟达&#xff08;NVIDIA&#xff09;的CEO黄仁勋在斯坦福经济政策研究所峰会上发表讲话&#xff0c;表示他预计通用人工智能&#xff08;AGI&#xff09;最快将在五年内问世。通用人工智能是指能够像人类一样学习、推理、解决复杂问题并独立做出决策的人工智能。这一表态引起…

从“茅五泸”到“非茅即五”,泸州老窖是怎么把自己跌出前三的?

文&#xff5c;琥珀食酒社 作者 | 宏一 春节的高端局酒桌上&#xff0c;“非茅即五”是很多人都会做的选择。前者是酱香型白酒的天花板&#xff0c;但后者却是浓香型白酒的“后来者”。 浓香型白酒的“鼻祖”&#xff0c;实际是坐拥国宝级窖池的泸州老窖&#xff0c;其上市时…

开源项目:智能化图像分类技术在新能源发电监控中的应用与实践

一、引言 在当今世界&#xff0c;能源的转型和升级是推动社会可持续发展的关键因素。随着技术的进步&#xff0c;新能源发电逐渐成为能源结构调整的重要力量。在众多发电方式中&#xff0c;新能源发电技术如风力、太阳能等因其清洁、可再生的特性而备受青睐。然而&#xff0c;…

vue入门相关内容

0.vue项目创建 01.vscode创建vue项目以及常见问题汇总 02.项目结构解读 03.启动项目直接访问自定义功能页面非APP.vue 1.事件修饰符 1.1事件修饰符stop 1.2事件修饰符capture 1.3事件修饰符self 1.4事件修…

Vue3中使用ffmpeg.wasm进行转码

一、安装方法 1.1 使用yarn进行安装 yarn add ffmpeg/ffmpeg ffmpeg/core1.2 安装版本 注意安装版本需在0.12.0以上版本才可以使用下面代码&#xff08;目前更新到0.12.10&#xff09;&#xff0c;之前的版本代码使用方法有所不同&#xff08;0.12.10之后的版本也可能会有变动…

【AIGC】如何提高Prompt准确度

前言 随着人工智能的迅猛进展&#xff0c;AIGC&#xff08;通用人工智能聊天工具&#xff09;已成为多个行业中不可或缺的自然语言处理技术。Prompt作为AIGC系统的一项关键功能&#xff0c;在工具的有效运作中发挥了举足轻重的作用。本篇文章将深入探讨Prompt与AIGC之间的紧密…

2024智能遥控器行业市场规模及技术水平分析

智能遥控器&#xff0c;主要是由集成电路板和用来生产不同讯息的按钮所组成&#xff0c;内装有一个中央处理器芯片&#xff0c;芯片在制造时就将设备各种菜单码值信息输入其中&#xff0c;遥控发射器只要发出与之对应的密码就可以实现对设备的控制。无线遥控技术原理就是发射机…

内存飙高问题如何排查?

目录 1、查看日志 2、查看GC情况 3、分析堆内存对象占用情况 4、分析堆内存快照文件 内存飙高如果发生在java进程上&#xff0c;一般情况是因为创建了大量对象导致&#xff0c;持续飙高说明垃圾回收跟不上对象创建的速度&#xff0c;或者内存泄漏导致对象无法被回收&#x…