北京网站建设在哪里天/百度今日数据
目录
Redis究竟是什么
Redis为什么能够做到这么快
Redis持久化机制
Redis如何实现过期的key的删除
Redis数据类型及应用场景
Redis的缓存穿透如何解决
什么是缓存穿透?
解决方案:
布隆过滤器
Redis如何解决缓存雪崩
什么是缓存雪崩
措施
Redis分布式锁的实现原理
Redis集群方案
具体场景
Redis集群主从同步原理
Redis缓存一致性解决方案
Redis内存淘汰策略
Redis究竟是什么
Redis是一个开源的高性能键值存储系统,也被称为数据结构服务器。它不仅仅是一个传统意义上的数据库,而是一个功能强大且多用途的存储系统。
虽然Redis可以像数据库那样存储和检索数据,但它与传统关系型数据库(如MySQL)有很多区别:
-
数据模型:Redis主要使用键值对来存储数据,其中键是唯一标识符,值可以是字符串、哈希、列表、集合、有序集合等不同的数据结构。这使得Redis更加灵活,可以以不同的方式组织和访问数据。
-
内存数据库:Redis将数据存储在内存中,这使得它能够提供非常快速的读写性能。与之相比,许多关系型数据库使用磁盘进行持久化存储。尽管Redis支持将数据持久化到磁盘上,但其主要优势在于内存存储。
-
单线程架构:Redis采用单线程的事件驱动模型,这使得它能够处理高并发请求。它通过异步I/O和非阻塞操作来实现高性能。
-
数据库功能的扩展:除了基本的存储和检索操作,Redis还提供了许多附加功能,如发布/订阅、事务、Lua脚本、过期键管理等。这些功能使得Redis不仅可以用于缓存和临时数据存储,还可以用作消息队列、计数器、实时排行榜等应用场景。
我们可以将Redis看作是一个多用途的、高效的数据结构服务器,广泛应用于缓存、会话存储、实时分析、消息传递等领域。
Redis为什么能够做到这么快
(1)完全基于内存操作
(2)数据结构简单,对数据操作也相对简单
(3)Redis执行命令是单线程的,避免了上下文切换所带来的性能开销,也不用考虑锁的问题
(4)采用了非阻塞的IO多路复用技术,使用单线程来处理并发的连接;内部采用的epoll+自己实现的事件分离器
其实Redis并不是完全多线程的,在核心的网络模型中采用多线程用于处理并发连接,但是数据的操作都是单线程的。
Redis坚持单线程是因为Redis的性能瓶颈是网络延迟而不是CPU,因此多线程不会带来明显的性能提升。
Redis持久化机制
(1)快照持久化RDB
Redis默认的持久化机制,通过父进程fork一个子进程,子进程将Redis的数据快照写入一个临时文件,等待持久化完毕之后替换上一次的rdb文件。整个过程主进程不进行任何的IO操作。持久化策略可以通过save配置单位时间内执行多少次操作触发持久化。所以RDB的优点是保证Redis性能最大化,恢复数据速度较快,缺点是可能丢失两次快照之间的数据
(2)追加持久化AOF
以日志的形式记录每一次的写入和删除操作,策略有每秒同步、每次操作同步、不同步,优点是数据完整性高,缺点是运行效率低、恢复时间长
Redis如何实现过期的key的删除
采用了定期过期+惰性过期
定期删除:Redis每隔一段时间从那些设置了过期时间的key的集合里面,随机抽取一些key,查看是否过期,如果过期就将其删除。
惰性删除:Redis在key被访问的时候检查key是否过期(先返回此次的结果,然后立即删除),如果过期则删除
Redis数据类型及应用场景
String:可以用来缓存JSON信息,可以用incr命令实现自增或自减的计数器。
Hash:与String一样可以保存json信息
List:可以用来做消息队列,list的pop是原子性操作能一定程度上保证线程安全
Set:可以实现去重,比如一个用户只能参加一次活动
ZSet:有序的,可以实现排行榜
Redis的缓存穿透如何解决
使用Redis这样的缓存系统时,经常遇到的问题就是——缓存穿透
首先来理解一下缓存的作用。缓存是一种将数据存储到内存的技术,它可以大大提高读取数据的速度。当我们需要获取某个数据的时候,会首先尝试从缓存中读取,如果缓存中存在这个数据,那么我们可以迅速的获取到结果。如果缓存中没有这个数据,则从数据库中读取,然后将结果存入缓存当中,以便下次使用。
什么是缓存穿透?
当一个请求查询一个不存在缓存和数据库的数据时(就是根本就是一条假数据),这个请求每次都会穿过缓存,去数据库中查找全部,然后返回没有查询到的结果。如果并发请求数量很大,数据库的负载会非常高,响应速度也会变得很慢。
举个通俗的例子来说明,假设你是一个超市的收银员,有个顾客每次来买东西都问你要一个不存在的商品编码,你翻遍货架和数据库都找不到这个商品,最后只能告诉顾客没有这个商品。如果每次都有不同的顾客来问同样的问题,肯定就会觉得很无奈和烦躁。
解决方案:
- 在接口上做基础的校验,比如id<=0就拦截
- 缓存空对象:找不到的数据也缓存起来,并设置过期时间,可能会造成短期不一致
- 布隆过滤器:在客户端和缓存直接加一层过滤器,拦截掉不存在的数据请求(用于快速判断请求的数据是否存在。如果布隆过滤器认定数据不存在,就可以避免对数据库进行不必要的查询)
布隆过滤器
布隆过滤器使用哈希函数和位数组来进行判定。它的基本原理是将元素通过多个哈希函数映射为位数组中的位置,并将这些位置标记为已存在。当查询一个元素时,布隆过滤器会将元素经过相同的哈希函数映射到位数组中的位置,并检查这些位置是否都已被标记。如果有任何一个位置未被标记,那么该元素就被判定为不存在于布隆过滤器中;否则,该元素被判定为可能存在于布隆过滤器中。
然而,布隆过滤器存在一定的误判率,即偶尔会将不存在的元素误判为存在。这是因为多个元素可能经过哈希函数映射到位数组时产生冲突,导致相同的位置被标记。误判率主要受到布隆过滤器的容量(位数组大小)和哈希函数数量的影响,以及元素插入数量和哈希函数的选择有关。较低的误判率需要更大的位数组和更多的哈希函数,但也会增加存储空间和查询时间的开销。
当有数据插入时,布隆过滤器会通过多个哈希函数计算出对应的位数组位置,并将这些位置的值设置为1,表示该位置已被标记。这样做的目的是在插入数据时,确保每一条数据都会在位数组上进行初始化标记。
Redis如何解决缓存雪崩
什么是缓存雪崩
要理解缓存雪崩的原因,需要明白缓存的失效机制。通常,在设置缓存的时候会给每个缓存设置一个过期时间过了这个过期时间缓存就会自动失效。当失效时间接近的时候,如果再对该条数据访问系统回去从数据库中重新加载数据,并更新缓存。然而,如果有大量缓存数据在同一时间失效,而且系统无法即使处理这些失效请求,就会导致所有请求全部打到访问数据库上面,造成数据库压力的瞬间激增,最终导致系统崩溃。
举例:假设有一个电商网站,商品信息被存在了Redis当中,每个商品的缓存时间是1小时。然后在某一时刻,由于某种原因,大量商品缓存同时失效。此时,在下一个小时内的所有请求都会直接访问数据库来获取商品信息,导致数据库瞬间承受巨大的压力。
措施
1、针对缓存数据设置不同的过期时间,是缓存失效的时间点分散,避免集中失效
2、设置热点数据永不过期,保证热门数据的一直可用
3、使用集群部署或主从复制等机制,增加缓存层的容错和高可用性。
4、在缓存失效的时候,通过加锁操作只允许一个线程去访问数据库,其他线程等待获取缓存。
5、使用限流和降级策略,当数据库压力过大的时候,暂时拒绝一部分请求或返回默认值。
Redis分布式锁的实现原理
下面是Redis分布式锁的主要实现原理:
-
获取锁:当一个客户端想获取锁时,它会通过执行SET命令将一个特定的键(作为锁的标识)设置到Redis中,并指定一个过期时间。例如,可以使用SETNX(SET if Not eXists)命令来设置锁,如果该键不存在才会成功设置。
-
锁的所有权:只能由设置锁的客户端持有,在设置锁时会返回一个唯一标识符(例如UUID)作为锁的所有者标记。
-
防止死锁:为了防止某个客户端获取锁后发生故障而导致无法释放锁,可以为锁设置一个合适的过期时间,确保即使持有锁的客户端异常退出或崩溃,锁最终也会过期自动释放。
-
释放锁:客户端在完成了对共享资源的操作后,可以通过执行DEL命令来删除对应的锁键,将锁释放。此时其他客户端就可以尝试获取该锁。
需要注意的是,为了确保获取锁和释放锁的原子性操作,可以使用Redis的Lua脚本执行命令,以保证在执行期间不会被其他命令插入。
使用Redis分布式锁时需要注意以下几点:
- 确保锁的标识符在每个客户端是唯一且具有足够的随机性,可以使用UUID等方式生成。
- 设置适当的过期时间,以避免长时间持有锁而导致其他客户端无法获取到锁。
- 处理获取锁失败的情况,可以使用重试机制来尝试重新获取锁,或者设置超时时间避免无限等待。
Redis集群方案
主从模式:一个master节点,多个slave节点,master节点宕机后slave自动变成主节点
哨兵模式:在主从集群基础上添加添加哨兵节点或哨兵集群,用于监控master节点健康状态,通过投票机制选择slave为成为主节点
分片集群:主从模式和哨兵模式解决了并发读的问题,但没有解决并发写的问题,因此有了分片集群。分片集群有多个master节点并且不同master保存着不同的数据,master直接通过ping互相监测其他master的健康状态。
在分片集群中,客户端可以向任意一个节点发送请求,该节点将根据请求的数据进行哈希计算,并将请求转发到正确的主节点。为了实现这一目的,集群将数据划分为多个插槽,每个插槽范围是0-16384。每个主节点负责管理一部分插槽,并维护与之相关的数据。
当客户端发送写入操作时,集群会确定该操作属于哪个插槽范围,然后将请求转发到负责该插槽的主节点,由主节点负责处理写入操作并更新对应的数据。
具体场景
假设我们有一个在线电商平台,每天有成千上万的用户在该平台上进行商品搜索、浏览和购买操作。为了支持这样的高并发访问,我们决定采用分片集群来处理数据存储和查询的需求。
首先,我们将数据根据某个字段(比如用户ID、商品ID等)的哈希值进行分片,生成对应的插槽范围。假设我们选择将用户信息按用户ID进行分片,并设置了4个主节点(master)。
接下来,我们将每个主节点分配一定范围的插槽来管理。例如主节点1负责插槽范围0-4095,主节点2负责插槽范围4096-8191,以此类推。每个主节点都会维护自己所负责的插槽和对应的数据。
当用户发送一个查询请求时,客户端会将该请求发送到任意一个主节点。假设这次请求涉及到用户ID为12345的用户信息。此时,集群会通过哈希算法计算出用户ID的哈希值,并确定该查询属于哪个插槽范围。
假设哈希值为7890,根据插槽范围的规则,这个查询属于主节点2负责的插槽范围。因此,当前的主节点将会把这个查询请求转发给主节点2。主节点2接收到请求后,从自己负责的插槽中找到对应的数据,并将查询结果返回给客户端。
Redis集群主从同步原理
主从同步第一次是全量同步:slave第一次请求master节点会根据replid判断是否是第一次同步,是的话master会生成RDB发送给slave
后续为增量服务:在发送RDB期间,会产生一个缓存区间记录发送RDB期间产生的新的命令,slave节点在加载完之后,会持续缓存区间内的数据
第一次全量同步,也称为初始同步。当从节点第一次连接到主节点时,它会请求主节点进行全量数据复制。主节点会生成一个RDB(Redis Database)文件,包含当前所有的数据,并将该文件发送给从节点。从节点接收到RDB文件后,将其加载到内存中,并与主节点保持同步。
后续的同步则是增量同步。在全量同步过程中,如果主节点有新的写入操作,这些操作将被记录在缓存区间中,而不会立即发送给从节点。当全量同步完成后,主节点会将缓存区间中的变更命令发送给从节点。此时,从节点会持续地读取并执行这些变更命令,从而将自身的数据与主节点保持同步。
通过全量同步和增量同步的方式,主从同步能够确保从节点始终与主节点保持最新的数据一致性。全量同步用于确保从节点能够获取到完整的数据,增量同步则用于实时更新从节点的数据,以保持与主节点的一致性。
这种主从同步机制可以提高系统的可用性和性能。当主节点出现故障时,从节点可以顶替主节点的角色,继续提供服务。同时,从节点还可以分担主节点的读取负载,提高系统的并发处理能力。
Redis缓存一致性解决方案
Redis缓存一致性解决方案主要思考的是删除缓存和更新数据库的先后顺序。
-
先删除缓存后更新数据库(Cache-Aside策略):
- 当需要读取数据时,首先从缓存中查找,如果缓存中存在,则直接返回缓存中的数据。
- 如果缓存中不存在,则从数据库中读取数据,并将读取到的数据写入缓存,同时再返回给调用方使用。
- 当进行数据更新操作时,先更新数据库中的数据,然后再删除缓存中对应的数据。
- 下次读取该数据时,会发现缓存已经不存在,再次按照上述步骤重新加载数据到缓存中。
-
先更新数据库后删除缓存(Write-Through Cache策略):
- 当进行数据更新操作时,先更新数据库中的数据,确保数据库中的数据是最新的。
- 然后,直接更新缓存中对应的键值对,使得缓存中的数据与数据库中的数据保持一致。
- 下次读取该数据时,由于缓存中已经包含了最新的数据,可以直接从缓存中获取,避免了再次访问数据库的开销。
Redis内存淘汰策略
当 Redis 的内存使用达到配置的最大内存限制时,就需要启用内存淘汰策略。
Redis 内存淘汰的目的是为了在内存不足时,从已有的数据集中选择一些键值对进行删除,以释放一定的内存空间。内存淘汰可以通过一定的策略来选择要删除的键值对,以满足特定的需求和优化目标。
Redis 提供了多种内存淘汰策略:
-
noeviction
(默认值):当 Redis 内存使用达到最大限制时,对新的写入操作进行阻塞,并返回错误信息,告知内存不足。 -
allkeys-lru
:使用 LRU(Least Recently Used,最近最少使用)算法,在所有键中选择最近最少使用的键进行淘汰。 -
allkeys-random
:随机选择要淘汰的键。 -
volatile-lru
:使用 LRU 算法,在设置了过期时间的键中选择最近最少使用的键进行淘汰。 -
volatile-random
:在设置了过期时间的键中随机选择要淘汰的键。
通俗来说就是三条:
(1)淘汰最久没有使用过的
(2)淘汰一段时间内最少使用的
(3)淘汰快要过期的
相关文章:

Redis巩固加强(帮助迅速梳理知识,同时适用初学者理解)
目录 Redis究竟是什么 Redis为什么能够做到这么快 Redis持久化机制 Redis如何实现过期的key的删除 Redis数据类型及应用场景 Redis的缓存穿透如何解决 什么是缓存穿透? 解决方案: 布隆过滤器 Redis如何解决缓存雪崩 什么是缓存雪崩 措施 Redis…...

Sui生态项目|集隐私通信、移动钱包、链上朋友圈和红包功能一体的社交应用ComingChat
ComingChat是在Sui网络上构建的去中心化社交平台,功能众多,其中加密聊天功能为用户提供了安全的沟通方式。该功能利用了Signal加密协议,这是一种在Signal、WhatsApp和Skype等应用中广受欢迎的开源软件协议。 ComingChat在Sui上提供了全面的…...

I2S/PCM board-level 约束及同步(latencyskewbitsync)
I2S/PCM是典型的低速串口,在两个方向上分别有两组信号,我们已soc为视角分为soc-adif和外设audio-codec。 那么adif输入: sclk_i, ws_i, sdi 当然并不是三个输入信号同时有效,只有adif RX slave时,三个输入都会有效…...

vue 富文本编辑器
安装 1、npm install wangeditor/editor --save 2、npm install wangeditor/editor-for-vue --save使用 .vue文件//展示<div style"border: 1px solid #ccc;width: 95%;"><!-- 工具栏 --><Toolbar style"border-bottom: 1px solid #ccc" …...

为什么说ChatGPT还不是搜索引擎的对手
一 前言 1950年,英国科学家图灵在一篇论文中预言,人类有可能创造出具有真正智能的机器。 著名的「图灵测试」就此诞生:如果一台机器能够与人类展开对话,而不被辨别出其机器身份,那么称这台机器具有智能。 也是从那时…...

2308C++协程流程
参考 #include <常用> #include <协程> #include "简异中.cpp" //用来中文定义的.元<类 T>构 同步{共针<T>值;同步(共针<T>p):值(p){输出<<"构建同步"<<行尾;//.8}同步(常 同步&s):值(s.值){输出<<&…...

C#实现稳定的ftp下载文件方法
当使用C#实现稳定的FTP下载文件的方法时,我们可以使用FtpWebRequest类来执行FTP操作,并根据需要添加错误处理和重试机制。下面是一个示例代码: using System; using System.IO; using System.Net;public class FTPDownloader {private const…...

八股文之计算机网络
TCP/IP 网络模型有哪几层 该模型用来解决不同设备间的进程通信,就需要网络通信,该模型就应运而生。首先是应用层,我们所接触的App都是在这一层实现的,当不同的设备需要通信时,就需要把数据发给传输层,传输…...

kotlin 比较 let apply
let 和 apply 是 Kotlin 标准库中的两个非常有用的函数,它们用于在代码中实现更简洁和可读的操作。它们通常在函数式编程和链式调用中使用,以简化代码并提高可维护性。下面是关于这两个函数的详细解释: let let 函数是一个作用域函数&#…...

springboot跨域踩坑笔记
事情是这样的,我在进行前后端联调的时候,发送了跨域拦截 马上在spring项目中创建一个CorsConfig类 package com.example.demo.config;import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.an…...

基于STM32+FreeRTOS的四轴机械臂
目录 代码: 注释写的较少,但本文出现的代码都有注释,所以请直接在本文里看注释 项目概述: 一 准备阶段(都是些废话) 二 裸机测试功能 1.摇杆控制 接线: CubeMX配置: 代码 2…...

【C语言】三子棋游戏——超细教学
🚩纸上得来终觉浅, 绝知此事要躬行。 🌟主页:June-Frost 🚀专栏:C语言 🔥该篇将结合之前的知识来实现 三子棋游戏。 目录: 🌟思路框架:测试游戏 🌟…...

redux的介绍、安装、三大核心与执行流程
redux的介绍、安装、三大核心与执行流程 一、redux的基本介绍二、redux的安装三、redux核心概念3.1 action3.2 reducer3.3 store 四、Redux代码执行流程五、加减案例练习 一、redux的基本介绍 redux中文官网Redux 是 React 中最常用的状态管理工具(状态容器&#x…...

Redis 5环境搭建
一、环境搭建 如果是Centos8,yum 仓库中默认的 Redis版本就是5,直接yum install即可。如果是Centos7,yum 仓库中默认的 Redis版本是3系列,比较老~ 为了我们能在 Centos7中下载到 Redis5 首先要安装额外的软件源 sudo yum insta…...

stm32红绿灯源代码示例(附带Proteus电路图)
本代码不能直接用于红路灯,只是提供一个思路 #include "main.h" #include "gpio.h" void SystemClock_Config(void); void MX_GPIO_Init(void) {GPIO_InitTypeDef GPIO_InitStruct {0};/* GPIO Ports Clock Enable */__HAL_RCC_GPIOB_CLK_ENAB…...

Qt与电脑管家4
折线图: #ifndef LINE_CHART_H #define LINE_CHART_H#include <QWidget> #include <QPainter> #include "circle.h" class line_chart : public QWidget {Q_OBJECT public:explicit line_chart(QWidget *parent nullptr); protected:void pa…...

使用css美化gradio界面
基本方法 在默认的前端页面中使用检查工具确定要修改的部分的选择器名称,然后在block_css中对其修改,并在启动网页时传入参数:with gr.Blocks(cssblock_css, thememy_theme) as demo: 禁止修改下拉框文字 input.border-none.svelte-c0u3f0…...

Flink流批一体计算(13):PyFlink Tabel API之SQL DDL
1. TableEnvironment 创建 TableEnvironment from pyflink.table import Environmentsettings, TableEnvironment# create a streaming TableEnvironmentenv_settings Environmentsettings.in_streaming_mode()table_env TableEnvironment.create(env_settings)# or create…...

java笔试手写算法面试题大全含答案
1.统计一篇英文文章单词个数。 public class WordCounting { public static void main(String[] args) { try(FileReader fr new FileReader("a.txt")) { int counter 0; boolean state false; int currentChar; while((currentChar fr.read()) ! -1) { i…...

点云平面拟合和球面拟合
一、介绍 In this tutorial we learn how to use a RandomSampleConsensus with a plane model to obtain the cloud fitting to this model. 二、代码 #include <iostream> #include <thread> #include <pcl/point_types.h> #include <pcl/common/io.…...

部署问题集合(十九)linux设置Tomcat、Docker,以及使用脚本开机自启(亲测)
前言 因为不想每次启动虚拟机都要手动启动一遍这些东西,所以想要设置成开机自启的状态 设置Tomcat开机自启 创建service文件 vi /etc/systemd/system/tomcat.service添加如下内容,注意修改启动脚本和关闭脚本的地址 [Unit] DescriptionTomcat9068 A…...

视觉SLAM:一直在入门,如何能精通,CV领域的绝境长城,
目录 前言 福利:文末有chat-gpt纯分享,无魔法,无限制 1 什么是SLAM? 2 为什么用SLAM? 3 视觉SLAM怎么实现? 4 前端视觉里程计 5 后端优化 6 回环检测 7 地图构建 8 结语 前言 上周的组会上&…...

【报错】yarn --version Unrecognized option: --version Error...
文章目录 问题分析解决问题 在使用 npm install -g yarn 全局安装 yarn 后,查看yarn 的版本号,报错如下 PS D:\global-data-display> yarn --version Unrecognized option: --version Error: Could...

二叉搜索树的(查找、插入、删除)
一、二叉搜索树的概念 二叉搜索树又称二叉排序树,它或者是一棵空树,或者是具有以下性质的二叉树: 1、若它的左子树不为空,则左子树上所有节点的值都小于根节点的值; 2、若它的右子树不为空,则右子树上所有节点的值都…...

电力虚拟仿真 | 高压电气试验VR教学系统
在科技进步的推动下,我们的教育方式也在发生着翻天覆地的变化。其中,虚拟现实(VR)技术的出现,为我们提供了一种全新的、富有沉浸感的学习和培训方式。特别是在电力行业领域,例如,电力系统的维护…...

innovus如何设置size only
我正在「拾陆楼」和朋友们讨论有趣的话题,你⼀起来吧? 拾陆楼知识星球入口 给instance设置size only属性命令如下: dbset [dbGet top.inst.name aa/bb -p] .dontTouch sizeOk 给一个module设置size only需要foreach循环一下: foreach inst [dbGet top.…...

Java之继承详解二
3.7 方法重写 3.7.1 概念 方法重写 :子类中出现与父类一模一样的方法时(返回值类型,方法名和参数列表都相同),会出现覆盖效果,也称为重写或者复写。声明不变,重新实现。 3.7.2 使用场景与案例…...

国内常见的几款可视化Web组态软件
组态软件是一种用于控制和监控各种设备的软件,也是指在自动控制系统监控层一级的软件平台和开发环境。这类软件实际上也是一种通过灵活的组态方式,为用户提供快速构建工业自动控制系统监控功能的、通用层次的软件工具。通常用于工业控制,自动…...

通过 git上传到 gitee 仓库
介绍 Git是目前世界上最先进的分布式版本控制系统,有这么几个特点: 分布式 :是用来保存工程源代码历史状态的命令行工具。保存点 :保存点可以追溯源码中的文件,并能得到某个时间点上的整个工程项目额状态;…...

设置Windows主机的浏览器为wls2的默认浏览器
1. 准备工作 wsl是可以使用Windows主机上安装的exe程序,出于安全考虑,默认情况下改功能是无法使用。要使用的话,终端需要以管理员权限启动。 我这里以Windows Terminal为例,介绍如何默认使用管理员权限打开终端,具体…...