Redis进阶篇

Redis线程模型

redis是基于内存运行的高性能k-v数据库,6.x之前是单线程, 对外提供的键值存储服务的主要流程 是单线程,也就是网络 IO 和数据读写是由单个线程来完成,6.x之后引入多线程而键值对读写命 令仍然是单线程处理的,所以 Redis 依然是并发安全的

Redis为什么快

  1. 完全基于内存操作,避免了传统的磁盘io读取内存这部分的消耗

  2. 数据结构简单,基于哈希表结构,可以在 O(1)的时间内计算出 hash 值并且找到对应的 entry位置,entry 里面是一个一个 key 指针和 value 指针这也是 redis 之所以性能高的原因之一

  3. 采用单线程,避免线程切换的事件,不存在竞争条件,也不会出现死锁而造成性能消耗

Redis多线程

1、Redis6.0 之前为什么一直不使用多线程?

Redis使用单线程的可维护性高。多线程模型虽然在某些方面表现优异,但是它却引入了程序执行顺序的不确定性,带来了并发读写的一系列问题,增加了系统复杂度、同时可能存在线程切换、甚至加锁解锁、死锁造成的性能损耗。

2、Redis6.0 为什么要引入多线程呢?

因为Redis的瓶颈不在内存,而是在网络I/O模块带来CPU的耗时,所以Redis6.0的多线程是用来处理网络I/O这部分,充分利用CPU资源,减少网络I/O阻塞带来的性能损耗。

3、Redis6.0 如何开启多线程?

默认情况下Redis是关闭多线程的,可以在conf文件进行配置开启 4、多线程模式下,是否存在线程并发安全问题?

如图,一次redis请求,要建立连接,然后获取操作的命令,然后执行命令,最后将响应的结果写到socket上。

在redis的多线程模式下,获取、解析命令,以及输出结果着两个过程,可以配置成多线程执行的,因为它毕竟是我们定位到的主要耗时点,但是命令的执行,也就是内存操作,依然是单线程运行的。所以,Redis 的多线程部分只是用来处理网络数据的读写和协议解析,执行命令仍然是单线程顺序执行,也就不存在并发安全问题。

Redis持久化

Redis 是一个内存数据库,数据保存在内存中,但是我们都知道内存的数据变化是很快的,也容易发生丢失。Redis 还为我们提供了持久化的机制,分别是RDB(Redis DataBase)和 AOF(Append Only File)

  1. RDB方式

RDB 持久化是指在指定的时间间隔内将内存中的数据集快照写入磁盘。也是默认的持久化方式,这种方式是就是将内存中数据以快照的方式写入到二进制文件中,默认的文件名为 dump.rdb。 在我们安装了 redis 之后,所有的配置都是在 redis.conf 文件中,里面保存了 RDB 和 AOF 两种持久化机制的各种配置。当符合一定条件时 Redis 会自动将内存中的数据进行快照并持久化到硬盘。

触发时机

(1)save命令触发:

该命令会阻塞当前Redis服务器,执行save命令期间,Redis不能处理其他命令,直到RDB完成为止,如果数据量大的话会造成长时间的阻塞,所以线上环境一般禁止使用。

(2)bgsave命令触发:

执行该命令时,Redis会在后台异步进行快照操作,快照同时还可以响应客户端请求。具体流程如下:

执行bgsave命令时,Redis主进程会fork一个子进程来完成RDB的过程,会先将数据写入到一个临时二进制文件中,待持久化过程都结束了,再用这个临时文件替换上次持久化好的文件(可以理解为Copy On Write机制)。Redis主进程阻塞时间只有fork阶段的那一下。相对于save,阻塞时间很短。基本上 Redis 内部所有的RDB操作都是采用 bgsave 命令。

fork的作用是复制一个与当前进程一样的进程。新进程的所有数据(变量、环境变量、程序计数器等)数值都和原进程一致,但是是一个全新的进程,并作为原进程的子进程。

(3)自动触发:

自动触发是可以在redis.conf配置文件中修改,默认达到以下三种条件,就会自动触发持久化,触发后,底层调用的其实还有bgsave命令

  1. AOF方式

以日志的形式来记录每个写操作,将 Redis 执行过的所有指令记录下来(读操作不记录),只许追文件但不可以改写文件,redis 启动之初会读取该文件重新构建数据,换言之,redis 重启的话就根据日志文件的内容将写指令从前到后执行一次以完成数据的恢复工作

Redis双写一致性

延时双删

  • (1)先淘汰缓存

  • (2)再写数据库

  • (3)休眠1秒,再次淘汰缓存

异步队列

增加消息队列,将redis更新操作交给kafka,由消息队列保证可靠性,再搭建一个消费服务,来异步更新redis

订阅binlog

通过订阅binlog来更新redis,把搭建的消费服务作为mysql的一个slave,订阅binlog,解析出更新内容,再更新到redis

Redis事务

Redis 事务本质是一组命令的集合,一个事务中的所有命令都会被序列化,在事务执行过程的中,会按照顺序执行. 所有的命令在事务中,并没有直接被执行. 只有发起执行 exec 命令的时候才会执行. 事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。但是事务不保证同一事物中多条命令执行的原子性,即使命令有错误也会添加到队列中,执行报错也不影响其他命令执行

、MULTI:

用于标记事务块的开启。MULTI执行之后,Redis会将后续的命令逐个放到一个缓存队列中,当EXEC命令被调用时,所有队列中的命令才会被原子化执行。

2、EXEC:

在一个事务中执行所有先前放入队列的命令,然后恢复正常的连接状态。当使用WATCH命令时,只有当受监控的键没有被修改时,EXEC命令才会执行事务中的命令。

3、DISCARD:

放弃事务,清除事务队列中的命令,然后恢复正常的连接状态。如果使用了UNWATCH命令,那么DISCARD命令就会取消当前连接监控的所有键。

主从复制

主从复制,是指将一台 Redis 服务器的数据,复制到其他的 Redis 服务器。前者称为主节点(master),后者称为从节点(slave),数据的复制是单向的,只能由主节点到从节点

1、Redis为什么需要主从复制? 使用Redis主从复制的原因主要是单台Redis节点存在以下的局限性:

(1)Redis虽然读写的速度都很快,单节点的Redis能够支撑QPS大概在5w左右,如果上千万的用户访问,Redis就承载不了,成为了高并发的瓶颈。

(2)单节点的Redis不能保证高可用,当Redis因为某些原因意外宕机时,会导致缓存不可用

(3)CPU的利用率上,单台Redis实例只能利用单个核心,这单个核心在面临海量数据的存取和管理工作时压力会非常大。

2主从复制的好处: (1)数据冗余:主从复制实现了数据的热备份,是持久化之外的一种数据冗余方式。

(2)故障恢复:如果master宕掉了,使用哨兵模式,可以提升一个 slave 作为新的 master,进而实现故障转移,实现高可用

(3)负载均衡:可以轻易地实现横向扩展,实现读写分离,一个 master 用于写,多个 slave 用于分摊读的压力,从而实现高并发;

3、主从复制的缺点: 由于所有的写操作都是先在Master上操作,然后同步更新到Slave上,所以从Master同步到Slave服务器有一定的延迟,当系统很繁忙的时候,延迟问题会更加严重,Slave机器数量的增加也会使这个问题更加严重

哨兵机制

哨兵模式是一种特殊的模式,首先 Redis 提供了哨兵的命令,哨兵是一个独立的进程,作为进程,它会独立运行。其原理是哨兵通过发送命令,等待 Redis 服务器响应,从而监控运行的多个 Redis 实例。

key过期策略

  1. 惰性删除:惰性删除是指,某个键值过期后,此键值不会马上被删除,而是等 到下次被使用的时候,才会被检查到过期,此时才能得到删除。所以惰性删除的 缺点很明显:浪费内存,还需要维护一个字典记录 key 是否过期。

  2. 定期删除:每隔一定的时间,会扫描一定数量的数据库字典中一定数量的 key, 并清除其中已过期的 key。通过调整定时扫描的时间间隔和每次扫描的限定耗 时,可以在不同情况下使得 CPU 和内存资源达到最优的平衡效果。

Redis 中同时使用了惰性过期和定期过期两种过期策略

缓存穿透

key对应的数据不存在,例如id=-1 DB和Redis都没有数据

解决:

  1. 参数校验

  2. 对空值进行缓存,返回value=null

  3. 布隆过滤器,使用bitmap先将可以访问到的资源通过映射关系放入过滤器,当请求到达时,先走过滤器

缓存击穿

某个key再数据库存在,但在redis中key过期

解决:

  1. 提前对key做过期时间设置

  2. 监控数据

  3. 使用锁,只有一个请求获得互斥锁,然后db中将数据查询并返回到redis中,之后所有请求从redis中查询

缓存雪崩

redis中大量key集体过期

解决:

  1. 将失效时间分散,生成随机数key

  2. 多级架构,nginx缓存+redis缓存

  3. 记录缓存标记,如果过期会通知另一个线程更新

  4. 查不到加排他锁

缓存预热

1、什么是缓存预热:

缓存预热是指系统上线后,提前将相关的缓存数据加载到缓存系统。避免在用户请求的时候,先查询数据库,然后再将数据缓存的问题,用户直接查询事先被预热的缓存数据。

如果不进行预热,那么Redis初始状态数据为空,系统上线初期,对于高并发的流量,都会访问到数据库中, 对数据库造成流量的压力。

2、缓存预热解决方案:

(1)数据量不大的时候,工程启动的时候进行加载缓存动作;

(2)数据量大的时候,设置一个定时任务脚本,进行缓存的刷新;

(3)数据量太大的时候,优先保证热点数据进行提前加载到缓存

缓存降级

缓存降级是指缓存失效或缓存服务器挂掉的情况下,不去访问数据库,直接返回默认数据或访问服务的内存数据。降级一般是有损的操作,所以尽量减少降级对于业务的影响程度。

在项目实战中通常会将部分热点数据缓存到服务的内存中,这样一旦缓存出现异常,可以直接使用服务的内存数据,从而避免数据库遭受巨大压力。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

[SpringDataMongodb开发游戏服务器实战]

背景: xdb其实足够完美了,现在回想一下,觉得有点复杂,我们不应该绑定语言,最好有自己的架构思路。 七号堡垒作为成功的商业项目,告诉我:其实数据是多读少写的,有修改的时候直接改库也…

离散数学 第八单元 布尔代数

目录 1. 布尔函数 2. duality 二元性 3. 表示布尔函数的布尔表达式 sum-of-products expansions 4. Functional Completeness 5. Logic Gates 逻辑门​​​​​​​ 4. 最小化 K-map卡诺图 Quine-McCluskey法 1. 布尔函数 嗯也就是我要知道布尔代数是啥形式&#xff…

[面试] 什么是死锁? 如何解决死锁?

什么是死锁 死锁,简单来说就是两个或者多个的线程在执行的过程中,争夺同一个共享资源造成的相互等待的现象。如果没有外部干预线程会一直阻塞下去. 导致死锁的原因 互斥条件,共享资源 X 和 Y 只能被一个线程占用; 请求和保持条件&#xf…

VMware虚拟机从一台电脑复制到另一台电脑

1 概述 在一台电脑上利用虚拟机安装了OS系统,特别是如果虚拟机中的系统进行了各种繁琐的配置,因为换电脑或者需要在其他电脑上配置,这个时候就可以将虚拟机中的系统复制拷贝一份到新电脑上,省时省力。 2 操作步骤 2.1 vmx文件 …

数字化转型导师坚鹏:政府数字化运营三步曲之认知、行动、结果

政府数字化运营三步曲之认知、行动、结果 课程背景: 很多政府都在开展数字化运营工作,目前存在以下问题急需解决: 不清楚政府数字化运营包括哪些关键工作? 不清楚政府数字化运营工作的核心方法论? 不清楚政府数…

单词倒排——c语言解法

以下是题目: 这个题中有三个点, 一个是将非字母的字符转换为空格, 第二是如果有两个连续的空格, 那么就可以将这两个连续的空格变成一个空格。 第三个点就是让单词倒排。 那么我们就可以将这三个点分别封装成三个函数。 还有就是…

电脑闹钟软件哪个好用?

电脑闹钟软件哪个好用?一款带有闹钟定时提醒的备忘录软件是比较实用的,很多上班族每天都要处理堆积如山的工作,总是会忙于一件事的时候忘记另外一件事,导致效率极低。如当一项重要会议需要提前准备资料时,我们却忙于其…

复旦大学MBA聚劲联合会:洞见智慧,拓宽思维格局及国际化视野

12月2日,“焕拥时代 俱创未来”聚劲联合会俱创会年度盛典暨俱乐部募新仪式圆满收官。16家复旦MBA俱乐部、200余名同学、校友、各界同仁齐聚复旦管院,一起在精彩纷呈的圆桌论坛里激荡思想,在活力四射的俱乐部风采展示中凝聚力量。      以…

《Docker 简易速速上手小册》第1章 Docker 基础入门(2024 最新版)

文章目录 1.1 Docker 简介与历史1.1.1 Docker 基础知识1.1.2 重点案例:Python Web 应用的 Docker 化1.1.3 拓展案例 1:使用 Docker 进行 Python 数据分析1.1.4 拓展案例 2:Docker 中的 Python 机器学习环境 1.2 安装与配置 Docker1.2.1 重点基…

《隐私计算简易速速上手小册》第9章:实现隐私计算的步骤(2024 最新版)

文章目录 9.1 规划与设计:描绘你的隐私保护蓝图9.1.1 基础知识9.1.2 主要案例:设计一个隐私保护的数据分享平台9.1.3 拓展案例 1:创建一个隐私保护的健康数据分析系统9.1.4 拓展案例 2:开发一个加密的即时通讯应用9.2 实施与部署:从蓝图到现实9.2.1 基础知识9.2.2 主要案例…

BentoML:如何使用 JuiceFS 加速大模型加载?

BentoML 是一个开源的大语言模型(LLM) AI 应用的开发框架和部署工具,致力于为开发者提供最简单的构建大语言模型 AI 应用的能力,其开源产品已经支持全球数千家企业和组织的核心 AI 应用。 当 BentoML 在 Serverless 环境中部署模型…

牛客网 HJ10 字符个数统计

思路: 我们创建两个数组,一个数组接受输入的字符,另一个数组用来统计字符种数 同时将该字符作为下标传给另一个数组,如果另一个数组的这个下标对应的值为0,说明该字符没有被统计过,计数器加1,…

在当前源文件的目录或生成系统路径中未找到文件

vsqt中增加,减少文件,都必须要动一下cmakelist.txt,点一下换行或者保存 因为vsqt反应不过来 1。都必须要动一下cmakelist.txt,点一下换行或者保存 2.然后全部重新生成,或者重新扫描解决方案(多扫几次)

现货黄金中短线投资该怎么做?

要明确什么是现货黄金的中短线投资,中短线投资是指在短期内(一般为几天至几周)对现货黄金进行买卖操作,以期获得收益的投资方式。相较于长线投资,中短线投资的风险相对较大,但同时收益也更为可观。那么&…

只需三步即可更改centos7系统语言,centos7系统语言更换,centos7系统中文互换

只需三步即可更改centos7系统语言,centos7系统语言更换,centos7系统中文互换 操作系统:centOS7.8 64位 ssh登录工具:FinalShell FinalShell可以点此下载 先查看系统的默认语言 locale #zh_CN 中文如何验证是中文,可以使用umtui来验证 umtui是一款…

【MATLAB源码-第146期】基于matlab的信源编码仿真GUI,对比霍夫曼编码,算术编码和LZ编码。

操作环境: MATLAB 2022a 1、算法描述 霍夫曼编码、算术编码和LZ编码是三种广泛应用于数据压缩领域的编码技术。它们各自拥有独特的设计哲学、实现方式和适用场景,因此在压缩效率、编解码速度和内存使用等方面表现出不同的特点。接下来详细描述这三种编…

Spring基础之AOP和代理模式

文章目录 理解AOPAOP的实现原理 AOP代理模式静态代理动态代理1-JDK动态代理2-CGLIB动态代理 总结 理解AOP OOP - - Object Oriented Programming 面向对象编程 AOP - - Aspect Oriented Programming 面向切面编程 AOP是Spring提供的关键特性之一。AOP即面向切面编程&#xff0…

Java+SpringBoot,打造极致申报体验

✍✍计算机编程指导师 ⭐⭐个人介绍:自己非常喜欢研究技术问题!专业做Java、Python、微信小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。 ⛽⛽实战项目:有源码或者技术上的问题欢迎在评论区一起讨论交流! ⚡⚡ Java实战 |…

Vivado MIG ip核使用教程

Step 1 在ip catalog中搜索mig ip核并打开,检查硬件配置 Step 2 Step 3 选择对其他芯片类型的兼容性,若无此方面需求,可直接点击next Step 4 选择存储器类型 Step 5 配置DDR3芯片工作频率、用户时钟、mig ip核输入时钟、DDR3芯片类型…

中兴通讯携吉林移动迈向5G-A新阶段,完成3CC技术应用

日前,中兴通讯携手中国移动吉林移动分公司,在5G-A领域取得新突破。具体来说,双方基于MTK芯片M80终端,完成了5G-A三载波聚合试点,实测下行速率达到理论峰值4.25Gbps,相比2.6G单载波速率提升2.5倍。如此成绩&…
最新文章