超强Redis基础学习 优化 使用 常见问题

问题大纲

为什么Redis可以这么快?

它是纯内存操作,内存本身就很快

其次,它是单线程的,Redis服务器核心是基于非阻塞的IO多路复用机制,单线程避免了多线程的频繁上下文切换问题

Redis的持久化机制

Redis提供了持久化机制给我们用,分别是RDB和AOF

RDB指的就是:根据我们自己配置的时间或者手动去执行BGSAVE或SAVE命令,Redis就会去生成RDB文件,实际上就是一个经过压缩的二进制文件,Redis可以通过这个文件在启动的时候来还原我们的数据

AOF则是把Redis服务器接收到的所有写命令都记录到日志   Redis重跑一遍这个记录下的日志文件,就相当于还原了数据

RDB会执行SAVE或BESAVE命令,redis单个线程处理会导致低效率吗?

BGSAVE命令实际上会fork出一个子进程来进行完成持久化(生成RDB文件)

在fork的过程中,父进程(主线程)肯定是阻塞的。fork完之后,是fork出来的子进程去完成持久化,因此即使是单线程,效率也不会很低

其实Redis在较新的版本中,有些地方都使用了多线程来进行处理, 只不过,核心的处理命令请求和响应还是单线程

主从架构

为了Redis「高可用」,现在基本都会给Redis做「备份」:多启一台Redis服务器,形成「主从架构」

「从服务器」的数据由「主服务器」复制过去,主从服务器的数据是一致的

如果主服务器挂了,那可以「手动」把「从服务器」升级为「主服务器」,缩短不可用时间

「主服务器」是如何把自身的数据「复制」给「从服务器」的呢

「复制」也叫「同步」,在Redis使用的是「PSYNC」命令进行同步,该命令有两种模型:完全重同步和部分重同步

如果是第一次「同步」或者切换目标同步,数据差距过大,那就会采用「完全重同步」模式进行复制;如果只是由于网络中断,只是「短时间」断连,那就会采用「部分重同步」模式进行复制

(假如主从服务器的数据差距实在是过大了,还是会采用「完全重同步」模式进行复制)

缓存穿透

原因:入侵者大量查询不存在的数据  使得Redis不断去访问数据库  然而Redis也无法缓存,就导致每次都会查询数据库...数据库的并发度不高   就会宕机

解决办法

布隆过滤器:作用:拦截不存在的数据

布隆过滤器 原理:把数据的id通过多次哈希计算标记数组,新来个数据就计算哈希,看是否能验证标记,但是会有以下的误判情况

缓存击穿

某一个key设置了过期时间,当key过期的时候,恰好对这个key有大量的并发请求,导致所有的请求都落到数据库上  这些请求可能会瞬间把DB压垮

解决方案

互斥锁
逻辑过期:数据不一定完全准确,但性能方面很优

缓存雪崩 

统一时段内大量的缓存key同时失效或者Redis服务

双写一致性

有两种考察情况:

一种是要求实时性很高的

一种是允许延时一致(即延时以后再数据一致,不严格要求)

延迟双删---延时一致方案

有缺陷,但是面试爱问,如果只删除一次缓存,那么无论什么顺序都有可能脏读

而且,其实三步清除缓存也仍然有概率脏读

MQ很适用于延时一致的业务,具体用以下方式实现

互斥锁方案---要求强一致性的方案

共享锁(读锁):加锁以后只能共享读操作

排他锁(写锁):加锁以后阻塞其他读写操作,仅当前线程进行写操作

Redis集群

使用集群的原因

redis服务器升级至一定程度后  持久化的成本过高

当 Redis 需要持久化数据时,它需要将数据从内存中写入磁盘,这个过程会产生一定的性能开销。

Redis 的 RDB(Redis DataBase)持久化机制是通过 fork 子进程来实现的。当 Redis 需要持久化数据时,它会 fork 一个子进程,然后让子进程将数据写入一个临时文件。当持久化过程完成后,Redis 会使用这个临时文件来替换旧的 RDB 文件。

然而,如果 Redis 使用的内存过大,fork 子进程的过程可能会导致主线程阻塞时间过长。这是因为 fork 子进程需要复制父进程的内存空间,如果内存空间过大,这个过程就会变得非常耗时。因此,如果 Redis 使用的内存过大,就可能会导致主线程在 fork 子进程时阻塞过长时间,从而降低了 Redis 的性能。

集群解决方案

Redis Cluster是一个用于实现Redis集群的解决方案,它能够避免哨兵机制复杂的Master监控与选举操作,并方便地实现数据的分片处理,以提供更加高效的Redis解决方案。

Redis Cluster把所有的数据划分为16384个不同的槽位,并可以根据机器的性能把不同的槽位分配给不同的Redis实例。每个节点都与其他节点有关联,只需获得一个节点的信息,其他节点的信息也就可以获取到。

这些槽位被称作哈希槽,通过hash算法分配槽位,放入要缓存的数据

每个实例都会向其他实例/传播/自己负责的哈希槽,这样每台redis实例都记录有所有的关系信息了! 有了这样的映射关系,客户端也就知道去哪个实例上操作了

集群新增或者删除实例

当发生了删除或者新增时, 那么redis实例负责的哈希槽关系会发生变化

但是客户端是无感知的,因为客户端会发送请求到原来的redis实例

原来的实例会给出moved命令,告诉客户端重定向

客户端收到以后就会去新的实例请求, 并且更新本地缓存

总的来说就是

如果集群Redis实例存在变动,由于Redis实例之间会「通讯」

所以等到客户端请求时,Redis实例总会知道客户端所要请求的数据在哪个Redis实例上

如果已经迁移完毕了,那就返回「move」命令告诉客户端应该去找哪个Redis实例要数据,并且客户端应该更新自己的缓存(映射关系)

如果正在迁移中,那就返回「ack」命令告诉客户端应该去找哪个Redis实例要数据

为什么是16384个哈希槽?

「服务端 路由」的大致原理

服务端路由一般指的一种代理层,  专门对接客户端的请求,然后转发到Redis集群进行处理

现在比较流行的是Codis

它与Redis Cluster最大的区别是,Redis Cluster是直连Redis实例,而Codis则客户端直连Proxy,再由Proxy进行分发到不同的Redis实例进行处理

在Codis对Key路由的方案跟Redis Cluster很类似,Codis初始化出1024个哈希槽,然后分配到不同的Redis服务器中   哈希槽与Redis实例的映射关系由Zookeeper进行存储和管理

扩容Codis Redis实例的流程是怎么样的?

1.「原实例」某一个Solt的部分数据发送给「目标实例」。2.「目标实例」收到数据后,给「原实例」返回ack。3.「原实例」收到ack之后,在本地删除掉刚刚给「目标实例」的数据。4.不断循环1、2、3步骤,直至整个solt迁移完毕

Codis也是支持「异步迁移」的,针对上面的步骤2,「原实例」发送数据后,不等待「目标实例」返回ack,就继续接收客户端的请求。

未迁移完的数据标记为「只读」,不会影响到数据的一致性。如果对迁移中的数据存在「写操作」,那会让客户端进行「重试」,最后会写到「目标实例」上

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

计算机毕业设计选题推荐-跑腿平台微信小程序/安卓APP-项目实战

✨作者主页:IT研究室✨ 个人简介:曾从事计算机专业培训教学,擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Python…

Ansible自动化运维工具介绍与部属

Ansible自动化运维工具介绍与部属 一、ansible简介1.1、什么是Ansible1.2、Ansible的特点1.3、Ansible的架构 二、Ansible任务执行解析2.1、ansible任务执行模式2.2、ansible执行流程2.3、ansible命令执行过程 三、部署ansible管理集群3.1、实验环境3.2、安装ansible3.3、查看基…

警惕听力下降的七大因素,一定要当心

随着现代社会的高速发展,工作生活节奏的加快,各种压力增大,再加上熬夜,长期佩戴耳机、饮食油腻辛辣等不良生活习惯的影响,听力损伤人群越来越多,已经不仅仅影响老年人群,近年来,听力…

OpenGL ES相关库加载3D 车辆模型

需求类似奇瑞的这个效果,就是能全方位旋转拖拽看车,以及点击开关车门车窗后备箱等 瑞虎9全景看车 (chery.cn) 最开始收到这个需求的时候还有点无所适从,因为以前没有做过类似的效果,后面一经搜索后发现实现的方式五花八门&#xf…

SpringBoot -- 请求数据多态映射(jackson)

有些情况下,服务端提供了一个抽象类及其多个实现类,当前端传递 json 数据到后端时,我们希望映射得到的对象数据是根据某个特征区分开的具体的实现类对象。 文章目录 实现方式示例抽象类对象若干实现类测试接口及前端传递请求体接参结果 JsonT…

API Testing v0.0.14 新增 gRPC, tRPC 协议的支持

api-testing 本次版本发布中的内容中,包含了两位高校同学的 contribution,其中屈晗煜在GitLink编程夏令营(GLCC)活动期间非常给力地增加了gRPC 协议的支持。 atest 版本发布 v0.0.14 atest 是一款用 Golang 编写的、开源的接口测试…

设备树(以STM32MP1为例)

1.设备树(Device Tree) 是一种用于描述硬件信息和配置的数据结构,以提供一个统一的方式来描述各种硬件设备的特性和连接方式。 设备树并不是从开始就存在,而是后来加入到Linux中,设备树主要用来描述系统的硬件结构 它是…

【智能座舱系列】- 深度解密小米Hyper OS,华为HarmonyOS区别

上一篇文章《小米的澎湃OS到底牛不牛?与鸿蒙系统之间差距有多大》,从多个方面比较了小米Hyper OS 与 华为HarmonyOS的区别,本篇文章继续从架构层面深度解读两者本质的区别。 小米澎湃OS是“以人为中心,打造人车家全生态操作系统”,该系统基于深度进化的Android以及自研的V…

【JAVA】类与对象的重点解析

个人主页:【😊个人主页】 系列专栏:【❤️初识JAVA】 文章目录 前言类与对象的关系JAVA源文件有关类的重要事项static关键字 前言 Java是一种面向对象编程语言,OOP是Java最重要的概念之一。学习OOP时,学生必须理解面向…

笔记软件Notability mac中文版软件功能

Notability mac是一款帮助用户备注文件的得力工具,Notability Mac版可用于注释文稿、草拟想法、录制演讲、记录备注等。它将键入、手写、录音和照片结合在一起,便于您根据需要创建相应的备注。 Mac Notability mac中文版软件功能 将手写,照片…

【git】git拉取代码报错,fatal: refusing to merge unrelated histories问题解决

大家好,我是好学的小师弟。今天准备将之前写的代码,拉到新的工程文件夹(仓库)下面,用了pull命令,结果报错了,报错截图如下 $ git pull https://gitee.com/* #仓库地址 fatal: refusing to merge unrelated histor…

前端有关的算法

1、最近距离排序 let me {name: 王强, home: 20}, let students [{name: 小明, home: 18},{name: 张三, home: 24},{name: 李四, home: 30},{name: 王五, home: 16} ] let resstudents.sort((a,b)>Math.abs(a.home-me.home)-Math.abs(b.home-me.home)) [{"name"…