Redis相关概念

news2024/7/6 17:37:57

0e56340b9eca46e8834101bb36b5838e.jpg1. 什么是Redis?它主要用来什么的?

 

Redis,英文全称是Remote Dictionary Server(远程字典服务),是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。

 

与MySQL数据库不同的是,Redis的数据是存在内存中的。它的读写速度非常快,每秒可以处理超过10万次读写操作。因此redis被广泛应用于缓存,另外,Redis也经常用来做分布式锁。除此之外,Redis支持事务、持久化、LUA 脚本、LRU 驱动事件、多种集群方案

 

 

 

说说Redis的基本数据结构类型

大多数小伙伴都知道,Redis有以下这五种基本类型:

 

String(字符串)

Hash(哈希)

List(列表)

Set(集合)

zset(有序集合)

它还有三种特殊的数据结构类型

 

Geospatial

Hyperloglog

Bitmap

2.1 Redis 的五种基本数据类型

 

 

 

 

String(字符串)

 

简介:String是Redis最基础的数据结构类型,它是二进制安全的,可以存储图片或者序列化的对象,值最大存储为512M

简单使用举例: set key value、get key等

应用场景:共享session、分布式锁,计数器、限流。

内部编码有3种,int(8字节长整型)/embstr(小于等于39字节字符串)/raw(大于39个字节字符串)

C语言的字符串是char[]实现的,而Redis使用SDS(simple dynamic string) 封装,sds源码如下:

 

struct sdshdr{ unsigned int len; // 标记buf的长度 unsigned int free; //标记buf中未使用的元素个数 char buf[]; // 存放元素的坑 }

 

 

Hash(哈希)

 

简介:在Redis中,哈希类型是指v(值)本身又是一个键值对(k-v)结构

简单使用举例:hset key field value 、hget key field

内部编码:ziplist(压缩列表) 、hashtable(哈希表)

应用场景:缓存用户信息等。

注意点:如果开发使用hgetall,哈希元素比较多的话,可能导致Redis阻塞,可以使用hscan。而如果只是获取部分field,建议使用hmget。

 

 

 

 

 

 

 

 

List(列表)

 

简介:列表(list)类型是用来存储多个有序的字符串,一个列表最多可以存储2^32-1个元素。

简单实用举例:lpush key value [value ...] 、lrange key start end

内部编码:ziplist(压缩列表)、linkedlist(链表)

应用场景:消息队列,文章列表,

一图看懂list类型的插入与弹出:

 

 

 

 

 

 

 

 

list应用场景参考以下:

 

lpush+lpop=Stack(栈)

lpush+rpop=Queue(队列)

lpsh+ltrim=Capped Collection(有限集合)

lpush+brpop=Message Queue(消息队列)

 Set(集合)

 

 

 

 

简介:集合(set)类型也是用来保存多个的字符串元素,但是不允许重复元素

简单使用举例:sadd key element [element ...]、smembers key

内部编码:intset(整数集合)、hashtable(哈希表)

注意点:smembers和lrange、hgetall都属于比较重的命令,如果元素过多存在阻塞Redis的可能性,可以使用sscan来完成。

应用场景:用户标签,生成随机数抽奖、社交需求。

有序集合(zset)

 

简介:已排序的字符串集合,同时元素不能重复

简单格式举例:zadd key score member [score member ...],zrank key member

底层内部编码:ziplist(压缩列表)、skiplist(跳跃表)

应用场景:排行榜,社交需求(如用户点赞)。

 

2.2 Redis 的三种特殊数据类型

Geo:Redis3.2推出的,地理位置定位,用于存储地理位置信息,并对存储的信息进行操作。

HyperLogLog:用来做基数统计算法的数据结构,如统计网站的UV。

Bitmaps :用一个比特位来映射某个元素的状态,在Redis中,它的底层是基于字符串类型实现的,可以把bitmaps成作一个以比特位为单位的数组

 

 

3.Redis为什么这么快

3.1 基于内存存储实现

我们都知道内存读写是比在磁盘快很多的,Redis基于内存存储实现的数据库,相对于数据存在磁盘的MySQL数据库,省去磁盘I/O的消耗。

 

3.2 高效的数据结构

我们知道,Mysql索引为了提高效率,选择了B+树的数据结构。其实合理的数据结构,就是可以让你的应用/程序更快。先看下Redis的数据结构&内部编码图:

 

 

 

 

 

 

 

 

 

 

 

 

 

 

字符串长度处理:Redis获取字符串长度,时间复杂度为O(1),而C语言中,需要从头开始遍历,复杂度为O(n);

空间预分配:字符串修改越频繁的话,内存分配越频繁,就会消耗性能,而SDS修改和空间扩充,会额外分配未使用的空间,减少性能损耗。

惰性空间释放:SDS 缩短时,不是回收多余的内存空间,而是free记录下多余的空间,后续有变更,直接使用free中记录的空间,减少分配。

二进制安全:Redis可以存储一些二进制数据,在C语言中字符串遇到'\0'会结束,而 SDS中标志字符串结束的是len属性。

 

字典

Redis 作为 K-V 型内存数据库,所有的键值就是用字典来存储。字典就是哈希表,比如HashMap,通过key就可以直接获取到对应的value。而哈希表的特性,在O(1)时间复杂度就可以获得对应的值。

 

跳跃表

 

 

 

 

 

 

 

 

 

跳跃表是Redis特有的数据结构,就是在链表的基础上,增加多级索引提升查找效率。

跳跃表支持平均 O(logN),最坏 O(N)复杂度的节点查找,还可以通过顺序性操作批量处理节点。

3.3 合理的数据编码

Redis 支持多种数据数据类型,每种基本类型,可能对多种数据结构。什么时候,使用什么样数据结构,使用什么样编码,是redis设计者总结优化的结果。

 

String:如果存储数字的话,是用int类型的编码;如果存储非数字,小于等于39字节的字符串,是embstr;大于39个字节,则是raw编码。

List:如果列表的元素个数小于512个,列表每个元素的值都小于64字节(默认),使用ziplist编码,否则使用linkedlist编码

Hash:哈希类型元素个数小于512个,所有值小于64字节的话,使用ziplist编码,否则使用hashtable编码。

Set:如果集合中的元素都是整数且元素个数小于512个,使用intset编码,否则使用hashtable编码。

Zset:当有序集合的元素个数小于128个,每个元素的值小于64字节时,使用ziplist编码,否则使用skiplist(跳跃表)编码

 

 

3.4 合理的线程模型

I/O 多路复用

 

 

 

 

 

 

I/O 多路复用

 

多路I/O复用技术可以让单个线程高效的处理多个连接请求,而Redis使用用epoll作为I/O多路复用技术的实现。并且,Redis自身的事件处理模型将epoll中的连接、读写、关闭都转换为事件,不在网络I/O上浪费过多的时间。

 

 

 

什么是I/O多路复用?

 

1

2

3

4

I/O :网络 I/O

多路 :多个网络连接

复用:复用同一个线程。

IO多路复用其实就是一种同步IO模型,它实现了一个线程可以监视多个文件句柄;一旦某个文件句柄就绪,就能够通知应用程序进行相应的读写操作;而没有文件句柄就绪时,就会阻塞应用程序,交出cpu。

单线程模型

 

Redis是单线程模型的,而单线程避免了CPU不必要的上下文切换和竞争锁的消耗。也正因为是单线程,如果某个命令执行过长(如hgetall命令),会造成阻塞。Redis是面向快速执行场景的数据库。,所以要慎用如smembers和lrange、hgetall等命令。

Redis 6.0 引入了多线程提速,它的执行命令操作内存的仍然是个单线程。

 

3.5 虚拟内存机制

Redis直接自己构建了VM机制 ,不会像一般的系统会调用系统函数处理,会浪费一定的时间去移动和请求。

 

Redis的虚拟内存机制是啥呢?

 

虚拟内存机制就是暂时把不经常访问的数据(冷数据)从内存交换到磁盘中,从而腾出宝贵的内存空间用于其它需要访问的数据(热数据)。通过VM功能可以实现冷热数据分离,使热数据仍在内存中、冷数据保存到磁盘。这样就可以避免因为内存不足而造成访问速度下降的问题。

 

4. 什么是缓存击穿、缓存穿透、缓存雪崩?

4.1 缓存穿透问题

先来看一个常见的缓存使用方式:读请求来了,先查下缓存,缓存有值命中,就直接返回;缓存没命中,就去查数据库,然后把数据库的值更新到缓存,再返回。

 

 

 

 

 

 

 

 

读取缓存

 

缓存穿透:指查询一个一定不存在的数据,由于缓存是不命中时需要从数据库查询,查不到数据则不写入缓存,这将导致这个不存在的数据每次请求都要到数据库去查询,进而给数据库带来压力。

 

1

通俗点说,读请求访问时,缓存和数据库都没有某个值,这样就会导致每次对这个值的查询请求都会穿透到数据库,这就是缓存穿透。

缓存穿透一般都是这几种情况产生的: 

 

业务不合理的设计,比如大多数用户都没开守护,但是你的每个请求都去缓存,查询某个userid查询有没有守护。

业务/运维/开发失误的操作,比如缓存和数据库的数据都被误删除了。

黑客非法请求攻击,比如黑客故意捏造大量非法请求,以读取不存在的业务数据

如何避免缓存穿透呢? 一般有三种方法。

 

1.如果是非法请求,我们在API入口,对参数进行校验,过滤非法值。

2.如果查询数据库为空,我们可以给缓存设置个空值,或者默认值。但是如有有写请求进来的话,需要更新缓存哈,以保证缓存一致性,同时,最后给缓存设置适当的过期时间。(业务上比较常用,简单有效)

3.使用布隆过滤器快速判断数据是否存在。即一个查询请求过来时,先通过布隆过滤器判断值是否存在,存在才继续往下查。

 

1

布隆过滤器原理:它由初始值为0的位图数组和N个哈希函数组成。一个对一个key进行N个hash算法获取N个值,在比特数组中将这N个值散列后设定为1,然后查的时候如果特定的这几个位置都为1,那么布隆过滤器判断该key存在。

4.2 缓存雪奔问题

缓存雪奔: 指缓存中数据大批量到过期时间,而查询数据量巨大,请求都直接访问数据库,引起数据库压力过大甚至down机。

 

缓存雪奔一般是由于大量数据同时过期造成的,对于这个原因,可通过均匀设置过期时间解决,即让过期时间相对离散一点。如采用一个较大固定值+一个较小的随机值,5小时+0到1800秒酱紫。

Redis 故障宕机也可能引起缓存雪奔。这就需要构造Redis高可用集群啦。

 

4.3 缓存击穿问题

缓存击穿: 指热点key在某个时间点过期的时候,而恰好在这个时间点对这个Key有大量的并发请求过来,从而大量的请求打到db。

 

缓存击穿看着有点像,其实它两区别是,缓存雪奔是指数据库压力过大甚至down机,缓存击穿只是大量并发请求到了DB数据库层面。可以认为击穿是缓存雪奔的一个子集吧。有些文章认为它俩区别,是区别在于击穿针对某一热点key缓存,雪奔则是很多key。

 

解决方案就有两种:

 

1.使用互斥锁方案。缓存失效时,不是立即去加载db数据,而是先使用某些带成功返回的原子操作命令,如(Redis的setnx)去操作,成功的时候,再去加载db数据库数据和设置缓存。否则就去重试获取缓存。

2. “永不过期”,是指没有设置过期时间,但是热点数据快要过期时,异步线程去更新和设置过期时间。

 

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

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

相关文章

基于Java的毕业设计选题管理系统设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言具体实现截图论文参考详细视频演示为什么选择我自己的网站自己的小程序(小蔡coding)有保障的售后福利 代码参考源码获取 前言 💗博主介绍:✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师、全栈领域优质创作…

44 二叉搜索树中第K个小的元素

二叉搜索树中第K个小的元素 题解1 中序遍历题解2 AVL(手撕平衡二叉树:谢谢力扣官方) 给定一个二叉搜索树的根节点 root ,和一个整数 k ,请你设计一个算法查找其中第 k 个最小元素(从 1 开始计数&#xf…

免杀对抗-成品EXE免杀-反特征码-通用跳转

一、exe程序生成 1.使用如下shellcode加载器&#xff0c;生成c/c语言的exe程序 加载器&#xff1a;1.c #include <Windows.h> #include <stdio.h>#pragma comment(linker,"/section:.data,RWE")unsigned char shellcode[] 生成的shellcode;int main() { …

【一、灵犀考试系统项目设计、框架搭建】

一、创建数据库 1、打开power designer&#xff0c;新建数据库模型 2、新建数据表&#xff0c;以及关系 【注意】 图片的类型有两种&#xff1a;varbinary 和 image varbinary : 二进制字节流&#xff0c;可以自动控制长度 image : 最大可放2G图片 3、创建数据库&#…

基于郊狼优化的BP神经网络(分类应用) - 附代码

基于郊狼优化的BP神经网络&#xff08;分类应用&#xff09; - 附代码 文章目录 基于郊狼优化的BP神经网络&#xff08;分类应用&#xff09; - 附代码1.鸢尾花iris数据介绍2.数据集整理3.郊狼优化BP神经网络3.1 BP神经网络参数设置3.2 郊狼算法应用 4.测试结果&#xff1a;5.M…

国庆假期作业day2

作业&#xff1a;创建一个双向链表&#xff0c;将26个英文字母通过头插的方式插入到链表中&#xff0c;通过尾删的方式将数据读取出来并删除 #ifndef _TEXT_H #define _TEXT_H #include<myhead.h> typedef int datatype; typedef struct dblist {union {datatype data;/…

逆强化学习

1.逆强化学习的理论框架 1.teacher的行为被定义成best 2.学习的网络有两个&#xff0c;actor和reward 3.每次迭代中通过比较actor与teacher的行为来更新reward function&#xff0c;基于新的reward function来更新actor使得actor获得的reward最大。 loss的设计相当于一个排序问…

Java基于SSM的校园一卡通系统设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用JSP技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

解决stm32驱动LCD1602A时不显示第二行的问题

根据这个教程&#xff0c;用仿真测试可以成功&#xff0c;但实际上上真机只显示第一行。 考虑到可能是电压的问题&#xff0c;我外接的是和stm32一样的3.3v&#xff0c;但实际上lcd的额定电压是5v&#xff0c;于是换为5V&#xff0c;结果变这样了&#xff1a; 只能恢复电压3.…

Linux信号解析

文章目录 Linux信号概念信号种类Linux信号产生异步 LInux信号阻塞递达、未决、阻塞、忽略信号集操作函数阻塞信号集操作函数未决信号集操作函数 Linux信号捕捉signal函数sigaction函数 总结 Linux信号概念 信号在我们的生活中无处不在&#xff0c;常见的如电话铃声&#xff0c…

openstack-ansible部署zed版本all-in-one

目录 部署架构部署节点准备安装Rocky linux 9配置rocky 目标节点配置网络配置rocky linux网卡的创建永久网桥的方法&#xff1a; 部署前配置 部署架构 可用的操作系统&#xff1a; Debian11&#xff08;bullseye&#xff09; Ubuntu 22.04或20.04 CentOS Stream 9 或 Rocky Lin…

【Golang】网络编程

网络编程 网络模型介绍 OSI七层网络模型 在软件开发中我们使用最多的是上图中将互联网划分为五个分层的模型&#xff1a; 物理层数据链路层网络层传输层应用层 物理层 我们的电脑要与外界互联网通信&#xff0c;需要先把电脑连接网络&#xff0c;我们可以用双绞线、光纤、…

CocosCreator3.8研究笔记(二十五)CocosCreator 动画系统-2d骨骼动画spine

大家都知道&#xff0c;在游戏中 一般用帧动画或者骨骼动画&#xff0c;实现 人物的行走、奔跑、攻击等动作。 帧动画&#xff0c;在上一篇已经做了介绍&#xff0c;感兴趣的朋友可以前往阅读&#xff1a; CocosCreator3.8研究笔记&#xff08;二十四&#xff09;CocosCreator …

10.5作业

磕磕绊绊还是差不多完成了,tcp多客户端在线词典 代码&#xff1a; 数据库导入&#xff1a;有点粗糙&#xff0c;不知道怎么搞成两列&#xff0c;一个单词中间还是空格卧槽难搞 #include <stdio.h> #include <string.h> #include <stdlib.h> #include <s…

NPDP产品经理知识(产品创新流程)

1.复习组合管理: 组合管理的目标 ===> 价值最大化,项目平衡,战略一致,管道平衡(资源需求和供给),盈利充分 (实现财务目标) 产品创新流程就是管理风险的过程。 模糊前端: 产品创新章程:PIC 包含 =====> 背景,聚焦舞台,目标和目的,特别准则,可持续性 新产…

mysql面试题13:MySQL中什么是异步复制?底层实现?

该文章专注于面试,面试只要回答关键点即可,不需要对框架有非常深入的回答,如果你想应付面试,是足够了,抓住关键点 面试官:讲一讲mysql中什么是异步复制?底层实现? MySQL中的异步复制(Asynchronous Replication)是一种复制模式,主服务器将数据写入二进制日志后,无…

计组——I/O方式

一、程序查询方式 CPU不断轮询检查I/O控制器中“状态寄存器”&#xff0c;检测到状态为“已完成”之后&#xff0c;再从数据寄存器取出输入数据。 过程&#xff1a; 1.CPU执行初始化程序&#xff0c;并预置传送参数&#xff1b;设置计数器、设置数据首地址。 2. 向I/O接口发…

星际争霸之小霸王之小蜜蜂(十六)--狂奔的花猫

系列文章目录 星际争霸之小霸王之小蜜蜂&#xff08;十五&#xff09;--剧将终场 星际争霸之小霸王之小蜜蜂&#xff08;十四&#xff09;--资本家的眼泪 星际争霸之小霸王之小蜜蜂&#xff08;十三&#xff09;--接着奏乐接着舞 星际争霸之小霸王之小蜜蜂&#xff08;十二…

视频讲解|含可再生能源的热电联供型微网经济运行优化(含确定性和源荷随机两部分代码)

1 主要内容 该视频为《含可再生能源的热电联供型微网经济运行优化》代码讲解内容&#xff0c;对应的资源下载链接为考虑源荷不确定性的热电联供微网优化-王锐matlab&#xff08;含视频讲解&#xff09;&#xff0c;对该程序进行了详尽的讲解&#xff0c;基本做到句句分析和讲解…

路径问题【动态规划】

一、不同路径 class Solution { public:int uniquePaths(int m, int n) {vector<vector<int>> dp(m1,vector<int>(n1));dp[0][1] 1;for(int i 1;i < m;i){for(int j 1;j < n;j){dp[i][j] dp[i-1][j]dp[i][j-1];}}return dp[m][n];} }; 二、不同路…