Redis

Redis作为一个高效的内存数据库,常用于数据缓存。它支持多种数据类型,包括String、Hash、List、Set和Zset,并采用单线程模式确保命令执行的原子性。本文详细介绍了Redis的持久化机制,如RDB和AOF,以及主从复制、哨兵机制等高可用策略。同时,讨论了缓存穿透、缓存击穿和缓存雪崩的问题及其解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

主要做数据缓存,redis运行在内存中,数据也保存在内存中。

缓存:让数据离程序更近

一般把redis成为中间件

缓存---让数据离程序更近

NoSQL

NoSQL(Not Only SQL): 泛指非关系型的数据库

关系型数据库: 使用标准得出sql语言进行操作

非关系型数据库:没有固定的关系,以键值对的形式存储。

不是相互替代,是相辅相成的。

Redis

redis:是键值对 存储在内存中也可以存储在硬盘上。

存储结构简单,性能高,易扩展,支持多语言,保证操作原子性,支持多种数据类型。

关系型数据库

关系型数据库: 不能代替,基本数据还是存储在关系型数据库中。

不足: I/O瓶颈

非关系型数据库

非关系型数据库: 结构简单,易扩展,高性能

只适合放简单的数据,不适合放时间太久以及太多的数据

Redis数据类型

redis是键值对 键都是String

5种数据类型指的是值的类型

String(字符串)

Hash(哈希)

List(列表)

Set(集合)

Zset(有序)

6种底层结构

全局哈希表: 存储数据,底层结构是Hash结构,可以通过Key计算出位置,将Key-Value都存储在此位置。

Hash冲突问题: 提供两块内存空间(相当于扩容),将原来的映射渐进式的复制到扩容后的哈希表中,然后释放之前的空间。

String

Key Value

单值缓存: 只存储一个值 手机号/邮箱: 验证码

对象缓存: 建议值不在改变

计数器

incr Key 值自增1 要求值为数字

decr Key 值自减1

Web集群 Session共享

Hash结构

适合存储对象数据(适合存储需要改变对象属性值的场景)

user:acc1 123 ph1 153

acc2 321 ph2 153

hmset Key 属性1 值1 属性2 值2 (存储多个键值对)

hmget Key 属性1 属性2 (批量获取哈希表 key 中多个 键值)

hdel Key 属性 (删除哈希表 key 中的 键值)

hlen Key (返回Key下面有多少组属性值)

hgetall Key (返回Hash表Key中的所有属性值)

List

Redis 列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列 表的头部(左边)或者尾部(右边)。

lpush Key Value... 将一个或多个值插入到 key 列表的表头(最左边)
rpush Key Value... 将一个或多个值插入到 key 列表的表尾(最右边)
lpop key 移除并返回 key 列表的头元素 
rpop key 移除并返回 key 列表的尾元素

实现队列,栈结构

Set

Redis 的 Set 是无序集合。

sadd key member[member...] 往集合 key 中存入元素,元素存在则忽略, 若 key 不存在则新建
srem key member[member...] 从集合 key 中删除元素
smembers key 获取集合 key 中所有元素 
scard key 获取集合 key 的元素个数

Zset

redis zset 也是不允许重复的成员,但是是有序的。

zset 的成员是唯一的,但分数(score)却可以重复。

zadd key score member[[score member]..] 往有序集合 key 中加入带分值元素
zrem key member[member...] 从有序集合 key 中删除元素
zscore key member 返回有序集合 key 中元素 member 的分值
zincrby key increment member 为有序集合 key 中元素 member 的分值 加上 increment
zcard key 返回有序集合 key 中元素个数
zrange key start stop[withscores] 正序获取有序集合 keyastart 下标到 stop 下标的元素

设置失效时间

EX 表示以秒为单位

PX 表示以毫秒为单位

EX,PX 不区分大小写

set name jim EX 30 设置失效时间为 30 秒
ttl 键 查看剩余时间(秒)
pttl 键 查看剩余时间(毫秒)

expire 键 时间(秒)

pexpire 键 时间(毫秒)

Redis进阶

Redis线程模式

redis是单线程还是多线程?

不同的版本是有区别的 6.X之前是正真意义上的单线程;处理客户端连接和执行操作的命令,都是由一个线程来完成的。

6.X之后引用了多线程,处理客户端请求是由专门的线程处理的,执行命令还是单线程。

为什么是单线程模式 速度还非常快?

数据存储在内存中,读取速度快,CPU不是性能瓶颈。

结构简单,Key--Vaule 底层哈希结构,查找操作速度是O(1)

采用IO多路复用,非阻塞IO模式,提高了连接访问效率

单线程执行命令,不存在线程切换。节省开销而且是线程安全

Redis持久化

对象信息持久保存在硬盘上

(mySQL jdbc) mybatis是一个java的数据持久层框架。

redis数据存储在内存中,内存数据时临时保存。

redis支持将数据持久化到硬盘上。

redis如何进行数据持久化 RDB方式(Redis DataBase)(默认) AOF方式(Append Only File)

这两种方式都在redis.conf文件中可以配置

redis默认使用RDB方式 : 直接将内存的数据快照(k-v)存储起来

配置触发持久化的机制:

1.save m n save 多少秒内 多少键 触发

2.flushall 命令

3.退出redis 产生clump.rab

AOF方式

以日志的形式来记录每个写操作 存储在文件中 还原时相当于将命令逐个执行 还原数据。

默认是不开启的,在配置文件中开启。 appendonly no

同步机制

appendfsync always 每次set记录一次

appendfsync everysec 每秒记录一次

Redis事务

不保证原子性(一次操作或者多次操作中,要么所有的操作全部都得到了执行并且不会受到任何因素的干扰而中断,要么所有的操作都不执行,多个操作是一个不可以分割的整体。)

保证隔离性

redis在执行单条命令是,是原子性的(单线程一次只能有一个线程来执行命令)

有时候,一次操作需要执行多条命令,如何保证多条命令整体执行。可以通过Redis中的事务实现:

开启事务: multil

添加命令...... 命令添加进来不会立即执行,添加到一个多列

执行exec命令时,才会将对列中的多条命令依次执行,执行一个事务中多条命令时,其他客户端会被隔离,不会交替执行.

但是事务不保证多条命令执行的原子性( 假如执行3条命令,其中有一条语法出错了,那么会将其他2两条正确继续执行 )

主从复制

主从-------主机 和 从机-------集群架构

为什么用集群? 如果只有一台redis服务,万一服务宕机,所有的请求都会到达MySQL,导致MySQL宕机。

可以搭建多台redis服务器 如果其中一台出现故障,其他的服务也能正常使用。

主机负责 写数据 将数据同步到从机

读数据从 从机中查询。

实现了读写分离 写命令由主机执行 读命令由从机执行

哨兵机制

有一个单位的线程,对集群中多台服务进行监听,给每一个服务发请求,如果没有响应,表明出现了故障。

比如主机宕机,会在从机中选举一台当做主机。

当原来的主机恢复后,又可以当做主机来继续使用。

Key过期策略

为Key设置过到期时间,时间到了后redis如何处理过期的Key。

1.立即删除,到期后立即执行回调函数。立即释放内存,对redis性能有影响。

2.惰性删除,到期后,不会立即删除,到下次使用该键的时候,根据状态(设置时是会记录的)来决定是删除还是继续使用。 占用内存。

3.定期删除,每隔一段时间,对所有到期的键进行删除(类似于java中的垃圾回收机制)。

redis使用的过期键值策略是:惰性删除加定期删除,两者配合使用。

缓存穿透

查询数据流程

缓存中有,直接返回。

发送查询请求------缓存------没有------数据库查询

但是使用缓存在一些极端情况下也会出现一些问题

缓存穿透

所有查询的数据在数据库中没有 缓存中没有 每次还是会去访问数据库

解决方法

1.查询出来的定值放在缓存中。

2.对查询的参数进行一个验证。

缓存击穿

数据库中有数据,只是某个热点,Key在某个时间点上过期了,此时有大量的查询请求到达(查询不加锁)查询缓存没有一起都向数据库发送请求,导致数据库击穿。

解决方法

1。设置热点Key不过期或时间长(计算合理的过期时间)

2.查询缓存没有后,访问数据库时可以加锁。

缓存雪崩

大量的热点Key过期或者redis服务故障,导致大量请求到达数据库。

解决方法

1.随机设置Key失效时间,避免大量Key集体失效。

2.集群部署,把热点Key放在不同的redis服务上。

3.设置不过期。

4.跑定时任务(java中)在缓存失效前刷新。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值