Redis详解(二)

news2025/1/10 17:22:10

文章目录

        • Redis的单线程模型
        • Redis数据过期
          • 删除策略
          • 内存淘汰机制
          • 手写LRU
        • 持久化
          • 快照持久化(RDB)
          • RDB优缺点
          • AOF持久化
          • AOF优缺点
          • RDB和AOF的选择
        • 注意事项
          • Redis修改配置后未生效(windows)

Redis的单线程模型

Redis基于Reactor模式来设计开发了自己的一套高效的时间处理模型。

Redis内部使用文件事件处理器file event handler,这个文件事件处理器是单线程的,所以Redis才叫做单线程的模型。它采用IO多路复用机制同时监听多个socket,将产生事件的socket压入内存队列中,事件分派器根据socket上的事件类型来选择对应的事件处理器进行处理。

文件事件处理器的结构包含4个部分

  • 多个socket
  • IO多路复用程序
  • 文件事件分派器
  • 事件处理器(连接应答处理器、命令请求处理器、命令回复处理器)

多个socket可能会并发产生不同的操作,每个操作对应不同的文件事件,但是IO多路复用程序会监听多个socket,会将产生事件的socket放入队列中排队,事件分派器每次从队列中取出一个socket,根据socket的事件类型交给对应的事件处理器进行处理。主要是以空间换时间
在这里插入图片描述
因此,Redis快的原因主要是基于非阻塞的IO多路复用机制。单线程避免了多线程的频繁上下文切换,预防了多线程可能产生竞争问题。Redis单机并发 10w+。

Redis数据过期

Redis通过一个叫做过期字典(可以看做是hash表)来保存数据过期的时间。键是指向Redis数据库的某个key,值是一个long long类型的整数,这个整数保存了key所指向的数据库键的过期时间

typedef struct redisDb {
    ···
    dict *dict; // 数据库键空间,保存着数据库中所有键值对
    dict *expires; // 过期字典,保存着键的过期时间
    ···
} redisDb;
删除策略

常用的过期数据删除策略有两个:

  1. 定期删除:每隔一段时间随机抽取一批key执行删除过期的key操作。对内存友好。
    假设Redis里放了10w个key,都设置了过期时间,你每隔几百毫秒,就检查10w个key,那Redis基本就死了,CPU负载很高的,消耗在你的检查过期key上了。注意,这里可不是每隔100ms就遍历所有的设置过期时间的key,那样就是一场性能上的灾难。实际上Redis是每隔100ms随机抽取一些key来检查和删除的。但是问题是,定期删除可能会导致很多过期key到了时间并没有被删除掉。这时候就是惰性删除了。

  2. 惰性删除:只会在取出key的时候才对数据进行过期检查。对象CPU友好,但可能造成太多的key没有被删除。
    在你获取某个key的时候,Redis会检查一下,这个key如果设置了过期时间那么是否过期了?如果过期了此时就会删除,不会返回任何东西。

Redis采用的是定期删除+惰性删除,但还是存在漏掉了很多过期key的情况。会导致Out of memory了。为了解决这个问题,Redis引进了Redis内存淘汰机制

内存淘汰机制

Q:MySQL里有2000W数据,Redis中只存20W的数据,如何保证Redis中的数据都是热点数据?

Redis提供6种数据淘汰策略:

  1. volatile-lru(least recently used):从已设置过期时间的键空间中挑选最近最少使用的数据淘汰。
  2. volatile-ttl:从已设置过期时间的数据集(server.db[i].expires)中挑选将要过期的数据淘汰。
  3. volatile-random:从已设置过期时间的数据集(server.db[i].expires)中任意选择数据淘汰。
  4. allkeys-lru(least recently used):当内存不足以容纳新写入数据时,在键空间中,移除最近最少使用的key。
  5. allkeys-random:内存不足以容纳新写入数据时,在键空间中随机移除某个key。
  6. no-eviction:禁止驱逐数据,也就是当内存不足以容纳新写入数据时,新写入操作会报错。(不会使用)

4.0版本后增加以下两种:

  1. volatile-lfu(least frequently used):从已设置过期时间的数据集(server.db[i].expires)中挑选最不经常使用的数据淘汰。
  2. allkeys-lfu(least frequently used):当内存不足以容纳新写入数据时,在键空间中,移除最不经常使用的key。

一般就用 volatile-lru:就行了,淘汰最近最少使用的key

手写LRU

继承LinkedHashMap可以简易实现LRU

public class LRUCacheLinkedHashMap<K, V> extends LinkedHashMap<K, V> {

    private final int capacity;

    LRUCacheLinkedHashMap(int capacity) {
        super(capacity, 0.75f, true);
        this.capacity = capacity;
    }

    @Override
    protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
        return size() > capacity;
    }

    public static void main(String[] args) {
        LRUCacheLinkedHashMap<String, String> cache = new LRUCacheLinkedHashMap<>(5);

        cache.put("1", "a");
        cache.put("2", "b");
        cache.put("3", "c");
        cache.put("4", "d");
        cache.put("5", "e");

        printCache(cache);

        System.out.println("插入第6个元素后的顺序:");
        cache.put("6", "f");
        printCache(cache);

        System.out.println("访问第3个元素后的顺序:");
        cache.get("3");
        printCache(cache);
    }


    private static void printCache(LRUCacheLinkedHashMap<String, String> map) {
        map.forEach((key, value) -> {
            System.out.print(String.format("%s ", key));
        });
        System.out.println();
    }
}

持久化

Redis相对比于Memcached支持持久化,而且支持两种不同的持久化操作,快照(Redis DataBase,RDB)和只追加文件(Append-Only File,AOF)

快照持久化(RDB)

RDB持久化是指在指定的时间间隔内将内存中的数据集快照写入磁盘。默认的持久化方式。这种方式就是将内存中数据以快照的方式写入到二进制文件中,默认的文件的名字dump.rdb

快照文件默认存放在安装的根目录下,dir ./
在这里插入图片描述
可以修改配置文件redis.config dir D:/redis/rdb

触发方式有三种:

  1. save命令触发
    该命令会阻塞当前Redis服务器,执行save命令期间,Redis不能处理其他命令,直到RDB过程完成为止,执行完成时候如果存在老的RDB文件,就把新的RDB文件替换掉旧的RDB文件。

  2. bgsave触发方式
    执行该命令时,Redis会在后台异步进行快照操作,快照同时还可以响应客户端请求。具体操作是Redis进程执行fork操作创建子进程,RDB持久化过程由子进程负责,完成后自动结束。阻塞只发生在fork阶段,一般时间很短。基本上Redis内存所有的RDB操作都是采用bgsave命令。

  3. 自动触发
    在配置文件redis.conf中配置

    save 900 1    #在900秒(15分钟)之后,如果至少有1个key发生变化,Redis就会自动触发BGSAVE命令创建快照。
    
    save 300 10   #在300秒(5分钟)之后,如果至少有10个key发生变化,Redis就会自动触发BGSAVE命令创建快照。
    
    save 60 10000 #在60秒(1分钟)之后,如果至少有10000个key发生变化,Redis就会自动触发BGSAVE命令创建快照。
    

    RDB的一些配置参数:

    • save:这里是用来配置触发Redis的RDB持久化条件,不需要持久化,那么你可以注释掉所有的save行来停用保存功能。

    • stop-writes-on-bgsave-error:默认值为yes。当RDB后台保存数据失败,Redis会拒绝新的写入。

    • rdbcompression:默认值是yes。对于存储到磁盘中的快照,可以设置是否进行压缩存储

    • dbfilename:设置快照的文件名,默认是dump.db

    • rdbchecksum:默认值是yes。在存储快照后,我们还可以让Redis使用CRC64算法来进行数据校验,但是这样会增加大约10%的性能消耗,如果希望获取到最大的性能提升,可以关闭此功能。

    • dir:设置快照文件的存放路径,这个配置项一定是个目录,而不能是文件名。

RDB优缺点

优点:

  1. RDB文件紧凑,全量备份,适合用于备份和灾难恢复
  2. 生成RDB文件的时候,Redis主进程会fork()一个子进程来处理所有保存工作,主进程不需要进行任何磁盘IO操作
  3. RDB在恢复大数据集时的速度比AOF的恢复速度快

缺点:

RDB进行快照持久化时,会开启一个子进程专门负责快照持久化,子进程会拥有父进程的内存数据,父进程修改内存子进程不会反应出来,所以在快照持久化期间修改的数据不会被保存,可能丢失数据

AOF持久化

全量备份总是耗时的,Redis提供了一种更加高效的方式-AOF。原理是Redis会将每一个收到的写命令都通过write函数追加到文件中。相当于对写命令进行日志记录。
在这里插入图片描述
触发方式
默认情况下Redis没有开启AOF,可以修改为yes进行开启。

appendonly no

开启AOF持久化后每执行一条会更改Redis中的数据的命令,Redis就会该命令写入硬盘中的AOF文件。AOF文件的保存位置和RDB文件的位置相同,都是通过dir参数设置的,默认的文件名是appendonly.aof

AOF可以配置三种持久化方式

# appendfsync always # 每次有数据修改发生时都会写入AOF文件,这样会严重降低Redis的速度
appendfsync everysec # 默认,每秒钟同步一次,显示地将多个写命令同步到硬盘
# appendfsync no   # 让操作系统决定何时进行同步
AOF优缺点

优点

  1. AOF可以更好的保护数据不丢失,一般AOF会每隔1秒,通过后台线程执行一个fsync操作,最多丢失1秒的数据
  2. AOF日志文件没有任何磁盘寻址的开销,写入性能非常高,文件不容器破损。
  3. AOF日志文件即使过大的时候,出现后台重写操作,也不会影响客户端的读写。

缺点

AOF日志文件通常比RDB快照数据文件更大

RDB和AOF的选择

Redis 支持同时开启开启两种持久化方式,我们可以综合使用 AOF 和 RDB 两种持久化机制,用 AOF 来保证数据不丢失,作为数据恢复的第一选择;用 RDB 来做不同程度的冷备,在 AOF 文件都丢失或损坏不可用的时候,还可以使用 RDB 来进行快速的数据恢复。

注意事项

Redis修改配置后未生效(windows)

运行redis-sever.exe需要指定配置文件
在这里插入图片描述

待整理知识点
- 缓存雪崩/缓存击穿/缓存穿透
- 缓存和数据库一致性问题
- Redis集群-主从架构/哨兵模式

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

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

相关文章

leetcode-每日一题-1669-合并两个链表(中等,链表操作)

这道题就是考察对链表的理解&#xff0c;但是题目给的链表和我们数据结构学的还是有点不一样的&#xff0c;这里面的头节点是带节点信息的&#xff0c;我们按照课本来说的话头节点&#xff0c;或者叫首元节点如果我记得不错的话就是叫这个&#xff0c;是不提供节点信息的&#…

[数字媒体] PR视频剪辑之自定义音频、视频加速转场和特显停顿

这篇博客是作者数字媒体系列的笔记&#xff0c;仅作为在线笔记供大家学习。在剪辑视频中&#xff0c;我们会遇到自定义音频、视频加速转场、特显停顿、画面调整等技巧&#xff0c;这篇文章将详细介绍。希望对您有所帮助&#xff0c;后续有时间会深入分享视频制作、动画制作等内…

结合淘宝与Twitter详解分布式系统与其架构设计,分布式其实并不难,阿里架构师用实战给讲明白了!

什么是分布式架构 分布式系统&#xff08;distributed system&#xff09; 是建立在网络之上的软件系统。 内聚性&#xff1a;是指每一个数据库分布节点高度自治&#xff0c;有本地的数据库管理系统。 透明性&#xff1a;是指每一个数据库分布节点对用户的应用来说都是透明的…

手把手教你如何从0到1开发自动化测试框架,你确定不看?

目录 一、序言 二、自动化测试框架技术选型 三、自动化测试框架的设计思路 四、自动化框架介绍 五、框架技术要点解析 六、后续TODO 一、序言 随着项目版本的快速迭代、APP测试有以下几个特点&#xff1a; 首先&#xff0c;功能点多且细&#xff0c;测试工作量大&#x…

Redis基本通用命令

通用命令 查看使用文档&#xff0c;例如要查看select怎么使用 help select切换数据库 select 1查看符合模板的所有key keys * keys *a keys a*判断key是否存在 exists k1给key设置有效期&#xff0c;给k1设置20秒有效期 expire k1 20查看key剩余有效期&#xff0c;查看k1…

2014年408算法题

文章目录0 结果1 题目2 思路0 结果 1 题目 2 思路 二叉树的带权路径长度&#xff08;WPL&#xff09;的计算方法有两种&#xff1a; 1&#xff0c;定义&#xff1a;WPL所有叶结点的权值Wi∗该结点深度Di求和WPL所有叶结点的权值W_i*该结点深度D_i求和WPL所有叶结点的权值Wi​…

linux环境minio安装启动,管理员登录,nginx代理

一.下载minio 官网下载: MinIO | Code and downloads to create high performance object storage 直接点击下载或者用wget https://dl.min.io/server/minio/release/linux-amd64/minio 最后都是得到一个文件minio(大概100M) 二.启动minio 1.创建文件夹,比如 mkdir /data…

mysql的redolog、undolog、binlog介绍,及mysql两阶段提交

https://blog.csdn.net/weixin_45676738/article/details/124770085 https://blog.csdn.net/TABE_/article/details/124935324 三种log REDO LOG 称为 重做日志 &#xff0c;提供再写入操作&#xff0c;恢复提交事务修改的页操作&#xff0c;用来保证事务的持久性。 UNDO LOG 称…

电源管理系统的功能和发展前景分析

电源对于电子设备的重要性不言而喻&#xff0c;电源管理系统是将电源有效分配给系统中的不同组成&#xff0c;在电子设备中起到了电能变换、控制、检测等作用&#xff0c;保证系统的稳定运行&#xff0c;对设备的性能有着直接影响&#xff0c;广泛用在工业、新能源、机器设备、…

一、初识 Spring 框架

文章目录一、Spring 简介二、Spring 框架的优点三、Spring 框架的组成四、Spring 框架 学习路线一、Spring 简介 Spring 框架简介 2004年3月24日发布了Spring 1.0正式版&#xff0c;Spring 框架的诞生给整个软件行业带来了春天。这个框架极大程度上简化了开发&#xff0c;其本…

基于无人机和背负式激光雷达点云的黄河三角洲刺槐林地上生物量估算

论文标题&#xff1a;Estimation of aboveground biomass of Robinia pseudoacacia forest in the Yellow River Delta based on UAV and Backpack LiDAR point clouds ABSTRACT 人工林是陆地碳汇的重要来源。黄河三角洲刺槐林是我国最大的人工生态防护林。然而&#xff0c;自…

“深度学习”学习日记。与学习有关的技巧--超参数的验证

2023.1.31 超参数是指神经网络中&#xff0c;神经元的数量、batch的大小、参数更新时的学习率或权值衰减等&#xff0c;虽然超参数的取值非常重要&#xff0c;但是决定超参数的值时会伴随很多人工的试错&#xff0c;所以我们需要高效地寻找超参数的值的方法 一&#xff0c;验…

【4】【Spring】,【Ioc/DI】,【IoC容器】,【Bean】

1、Ioc/DI,IoC容器&#xff0c;Bean 为了解决不同实现方式耦合度高 Ioc&#xff1a;&#xff08;Inversion of Control&#xff09;控制反转 主要思想&#xff1a;使用对象时&#xff0c;由主动new产生对象转换为由外部提供对象&#xff0c;此过程中对象创建控制权由程序转移…

vite打包静态文件打开显示空白

vite 打包生成静态文件打开显示空白 需求场景 本地调试访问打包的文件看是否有啥问题&#xff0c;方便定位线上问题安卓手机需要去直接访问静态文件&#xff0c;而不是访问域名的情况 vite 打包生成的文件如果直接放在服务器中是可以正常访问的&#xff0c;但是本地直接访问…

三个方面使CRM在360度客户视图中受益

360度客户视图这个词相信您不会陌生&#xff0c;很多关于CRM客户管理系统的文章中都有所提及。所谓的360度客户视图&#xff0c;是帮助企业和业务人员建立客户认知&#xff0c;消除客户生命周期中的信息脱节&#xff0c;让业务人员为客户提供一致性的体验。接下来我们们说&…

Windows10神州网信版的安装

在大约20天里面我完成了Windows10神州网信版72台的安装&#xff0c;有些2009&#xff5e;2014年的计算机完成安装后做一般的办公应用也能流畅运行。买一台新的计算机至少要好几千&#xff0c;通过更换固态硬盘和内存条可以达到旧物新用的目的。 一、安装过程   1、检查硬件  …

Coggle 30 Days of ML(23年1月)打卡

前言 任务链接 这个任务内容比较感兴趣而且和工作内容相关&#xff0c;学习一下打个卡。 编码完成任务1&#xff0c;2&#xff0c;3&#xff0c;5&#xff0c;6&#xff0c;目前手上只有2080&#xff0c;之后在3090上跑。 最近杂事多&#xff0c;笔记、任务4和7之后再补充。 …

vue前端框架课程笔记(五)

目录非文件组件使用步骤定义组件示例&#xff08;第一部分&#xff09;&#xff1a;使用Vue.extend函数创建三个组件注册组件示例&#xff08;第二部分&#xff09;&#xff1a;组件的全局和局部注册组件使用示例&#xff08;第三部分&#xff09;&#xff1a;编写组件标签最终…

软件工程(三)——需求工程、需求开发、需求定义

目录 一、需求定义 二、需求验证 三、需求管理 1.定义需求基线 2.需求跟踪 3.变更控制 四、软件系统建模 一、需求定义 把已经分析好的需求&#xff0c;落成文档&#xff0c;把东西记录下来&#xff0c;成为《需求规格说明书》。需求定义的方法有严格定义法 以及 原型法…

Java三路快速排序

概念 三路快速排序&#xff1a; 是双路快速排序的进一步改进版本&#xff0c;三路排序算法把排序的数据分为三部分&#xff0c;分别为小于 v&#xff0c;等于 v&#xff0c;大于 v&#xff0c;v 为标定值&#xff0c;这样三部分的数据中&#xff0c;等于 v 的数据在下次递归中…