欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 新闻 > 会展 > Redis

Redis

2024/10/23 21:38:55 来源:https://blog.csdn.net/weixin_47467550/article/details/142924720  浏览:    关键词:Redis

1.redis实现分布式锁... 1

1.1如何合理的设置锁的时长... 2

1.2Redisson的这个锁,可以重入吗?. 2

2.在Redis中提供的集群方案总共有三种... 2

3.redis使用场景... 2

3.1缓存适用场景... 2

3.1.1缓存穿透:关键字缓存中不存在的数据... 2

3.1.2缓存击穿:关键字缓存过期了,这一时刻打来大量的请求... 3

3.1.3缓存雪崩... 3

4.介绍缓存和DB的数据一致性?... 4

5.是先删除缓存还是先修改数据库?... 4

5.1强一致性的双写一致性(性能差,强一致)... 4

5.2大概是弱一致性... 4

6.redis的数据持久化?... 5

6.1rdb执行原理?... 5

6.2aof 5

7数据过期策略... 6

8数据淘汰策略... 7

9分布式锁redission. 7

9.1redission分布式锁能否保证主从一致性。... 8

10在Redis中提供的集群方案总共有三种... 9

10.1redis主从复制,主从同步流程... 9

10.2说一下主从同步流程... 9

11哨兵模式... 10

11.1哨兵的三大特点:... 10

11.1.1哨兵的服务状态监控和选主模式... 11

12分片集群,数据读写规则(如果海量数据存储和高并发写怎么解决)... 12

13单线程redis为什么那么快。... 13

1.redis实现分布式锁

直接setnx一般用set lock value nx 10

而且锁的时间和这个设置分布式锁写在一句话,为什么呢。这样能保证原子性。不设置时间可能导致死锁。因为如果服务器宕机了,没释放锁,就会死锁。如果设置锁的时间就不一样了。

1.1如何合理的设置锁的时长

(1)根据业务的执行时间预估

(2)给锁续期。一开始设置锁的时间,再开另外一个线程来监控这个锁的时长。这就是redssion实现分布式锁。

等业务执行完了就通知看门狗不用再监听了

这里redission默认三十秒锁的失效时间。每隔三分之一的时间进行续期。

加锁、设置过期时间等操作都是基于lua脚本完成。能够调用redis命令来保持多条命令的原子性。

1.2Redission的这个锁,可以重入吗?

可以重入,多个锁重入需要判断是否是当前线程,在redis中进行存储的时候使用的hash结构来存储线程信息和重入的次数.

2.在Redis中提供的集群方案总共有三种

主从复制

哨兵模式

分片集群

3.redis使用场景

缓存、

3.1缓存适用场景

3.1.1缓存穿透:关键字缓存中不存在的数据

缓存穿透:查询一个不存在的数据,mysql查询不到数据也不会直接写入缓存,就会导致每次请求都查数据库

解决方案一:缓存空数据,查询返回的数据为空,仍把这个空结果进行缓存

缓存压力会变大。如果缓存null后面又加上了数据,可能会数据不一致

优点:简单

缺点:消耗内存,可能会发生不一致的问题

方案二:布隆过滤器

优点:内存占用较少,没有多余key

缺点:实现复杂,存在误判

布隆过滤器主要是用于检索一个元素是否在一个集合中。我们当时使用的是redisson实现的布隆过滤带

它的底层主要是先去初始化一个比较大数组,里面存放的二进制0或1。在一开始都是0,当一个key来了之后经过3次hash计算,模于数组长度找到数据的下标然后把数组中原来的0改为1,这样的话,三个数组的位置就能标明一个key的存在。查找的过程也是一样的。

当然是有缺点的,布隆过滤器有可能会产生一定的误判,我们一般可以设置这个误判率,大概不会超过5%,其实这个误判是必然存在的,要不就得增加数组的长度,其实已经算是很划分了,5%以内的误判率一般的项目也能接受,不至于高并发下压倒数据库。

3.1.2缓存击穿:关键字缓存过期了,这一时刻打来大量的请求

缓存击穿:给某一个key设置了过期时间,当key过期的时候,恰好这时间点对这个key有大量的并发请求过来,这些并发的请求可能会瞬间把DB压垮

解决方案一:互斥锁

保证数据强一致,多个线程之间需要等待。性能很差。(一般用于银行交易)

解决方案二:逻辑过期。性能优,高可用,不能保证数据强一致

保证高可用。在获取不到缓存后,直接返回一个过期的缓存数据,此时又新执行一个线程来延长锁的时间。继而再获取缓存可返回合理的数据。

3.1.3缓存雪崩

缓存雪崩是指在同一时段大量的缓存key同时失效或者Redis服务宕机,导致大量请求到达数据库,带来巨大压力。

解决方案:

不同的key设置随机事件。避免集体同时失效

为了防止服务器宕机。利用Redis集群提高服务的可用性。集群模式哨兵模式、

给缓存业务添加降级限流策略                         ngxin或spring cloud gateway

给业务添加多级缓存                                       Guava或Caffeine

4.介绍缓存和DB的数据一致性?

介绍之前一定要先介绍业务。是一致性要求高(银行交易),还是允许延迟一致(高可用?性能优先)

双写一致性:当修改了数据库的数据也要同时更新缓存的数据,缓存和数据库的数据要保持一致

5.是先删除缓存还是先修改数据库?

这俩都不要太行

一般情况下数据库是主从模式,是读写分离的。

这里读操作很正常。写操作:延迟双删

使用互斥锁(分布式锁?)实现双写一致性

5.1强一致性的双写一致性(性能差,强一致)

读多写少

共享锁:读锁readLock,加锁之后,其他线程可以共享读操作。

排他锁:独占锁writeLock也叫,加锁之后,阻塞其他线程读写操作

5.2大概是弱一致性

6.redis的数据持久化?

RDB全称Redis Database Backup file(Redis数据备份文件),也被叫做Redis数据快照。简单来说就是把内存中的所有数据都记录到磁盘中。当Redis实例故障重启后,从磁盘读取快照文件恢复数据。

AOF全称为Append Only File(追加文件)。Redis处理的每一个写命令都会记录在AOF文件,可以看做是命令日志文件。

6.1rdb执行原理?

这里因为担心主进程发生写rdb的故障会阻塞,继而影响别的,就可以用子进程来实现rdb

bgsave开始时会fork主进程得到子进程,子进程共享主进程的内存数据。完成fork后读取内存数据并写入 RDB 文件。

因为底层物理内存条中的物理内存操作不了,但页表是记录逻辑地址与物理地址的映射关系,通过fork将主进程的页表复制到子进程,实现子进程也可以操作内存中的数据。

如果内存中数据发生改变,子进程写新rdb替换旧rdb文件

每次主进程写操作都会拷贝一个数据副本B,读的时候也是读最新改的副本,这样就避免了脏写

6.2aof

以下是刷盘策略

AOF默认是关闭的,需要修改redis.conf配置文件来开启AOF配置项

配置项Always、everysec、no

一般用everysec

这里always是所有的,同步刷盘,性能差不丢数据。Everysec是最常用的,秒单位刷盘。

No就是操作系统凭感觉保留缓存数据。

7数据过期策略

Redis的key过期了,会立即删除吗?

惰性删除:去获取key,检查是否过期,过期了就删除,没过期就获取

优点:对CPU友好,只会在使用该key时才会进行过期检查,对于很多用不到的key不用浪费时间进行过期检查。

缺点:对内存不友好,如果一个key已经过期,但是一直没有使用,那么该key就会一直存在内存中,内存永远不会释放。

定期删除:每隔一段时间,我们就对一些key进行检查,删除里面过期的key(从一定数量的数据库中取出一定数量的随

机key进行检查,并删除其中的过期key)。

定期清理有两种模式:

SLOW模式是定时任务,执行频率默认为10hz,每次不超过25ms,以通过修改配置文件redis.conf的hz 选项来调整这个次数

FAST模式执行频率不固定,但两次间隔不低于2ms,每次耗时不超过1ms

优点:可以通过限制删除操作执行的时长和频率来减少删除操作对 CPU 的影响。另外定期删除,也能有效释放过期键占用的内存。

缺点:难以确定删除操作执行的时长和频率。

8数据淘汰策略

缓存太多,内存有限,内存满了怎么办?

13点16分-

这个删除内存中的数据的规则就叫做数据淘汰策略!!!总共有八种!

Noeviction(默认不淘汰,满了就不让写了):不淘汰任何key,但是内存满时不允许写入新数据,默认就是这种策略

volatile-ttl(个人理解,设置优先级,越低的先被干掉):对设置了TTL的key,比较key的剩余TTL值,TTL越小越先被淘汰

allkeys-random(随即干掉):对全体key,随机进行淘汰。

volatile-random:对设置了TTL的key ,随机进行淘汰。

allkeys-lru:对全体key,基于LRU算法进行淘汰

allkeys-lfu :对全体key,基于LFU算法进行淘汰

volatile-lfu

对设置了TTL的key,基于LFU算法进行淘汰

9分布式锁redission

redis分布式锁,是如何实现的?

需要结合项目中的业务进行回答,通常情况下,分布式锁使用的场景集群情况下的定时任务、抢单、幂等性场景

13点49分-

普通的sync一般只能是同一个jvm下的锁对线程有效,多个集群就白瞎了

一个线程设置锁的时间,另一线程监控这个锁的时间来续期。这个方案很好已经实现了叫做redission!!!

这个锁是可重入的,可重入锁的逻辑是怎么判断的呢,同一个线程id则可以重入这个锁,并且标记value+1,释放了呢就value-1

15点25分

锁的等待机制(重视机制):线程二在获取不到锁的时候会循环等待。在一定次数就返回获取锁失败。

TryLock获取锁,参数(10,单位)最大等待时间10s

如果是三个参数,10,30,timeunit.secends

等待时间,失效时间,单位

如果设定失效时间了,就不会有看门狗机制了watch dog

加锁、设置过期时间等操作都是基于lua脚本完成。(保证了命令执行的原子性)

Lua脚本可以调用redission命令,来保证多条命令的原子性。

重点三个:

  1. 看门狗可以给锁续期2.抢不到锁的线程会等待3.所有的redssion命令是lua脚本完成的,保证了命令的原子性。

这里关于锁的可重入性用是利用hash结构记录线程id和重入次数,记录锁,是key,field是线程名,value是重入次数;可重入性可以很好的利用锁的力度。

15点36分-

Redis能保证主从数据一致性的问题吗?

       不能解决,但是可以使用redission提供的红锁来解决,但是这样的话,性能就太低了。如果业务中非要保证数据的强一致性,建议使用zookeeper的实现分布式锁。

9.1redission分布式锁能否保证主从一致性。

一般分为主从两个节点,主节点用于增删改,从节点对外读操作。

主节点发生写操作都会同步给从节点;

Redis的哨兵模式:主节点宕机,会选择一个从节点来替代为主节点。

10在Redis中提供的集群方案总共有三种

主从复制

哨兵模式

分片集群

10.1redis主从复制,主从同步流程

介绍-下redis的主从同步

单节点Redis的并发能力是有上限的,要进一步提高Redis的并发能力,就需要搭建主从集群,实现读写分离。一般都是一主多从,主节点负责写数据,从节点负责读数据

10.2说一下主从同步流程

全量同步:

1.从节点请求主节点同步数据(replication id、 offset )

2.主节点判断是否是第一次请求,是第一次就与从节点同步版本信息(replication id和offset)

3.主节点执行bgsave,生成rdb文件后,发送给从节点去执行

4.在rdb生成执行期间,主节点会以命令的方式记录到缓冲区(一个日志文件)5.把生成之后的命令日志文件发送给从节点进行同步

增量同步:

为了保证redis集群的高可用性,redis提供了哨兵模式,一旦主节点宕机,会使用哨兵模式解决数据丢失的问题。

11哨兵模式

Redis提供了哨兵sentinel机制来实现主从集群的自动故障恢复

11.1哨兵的三大特点:

监控,自动故障恢复,通知。

监控、自动故障恢复。监控主节点和从节点是否按预期工作;如果master故障,setinel会将一个slave提升为master

一旦故障恢复,redis客户端就需要重新找到新的主节点,因为是主从是一对多的关系,主节点主要用来写操作,多个从节点主要用来读操作。

通知:Sentinel充当Redis客户端的服务发现来源,当集群发生故障转移时,会将最新信息推送给Redis的客户端

11.1.1哨兵的服务状态监控和选主模式

服务状态监控

Sentinel基于心跳机制检测服务状态;每隔一秒向集群的每个实例发送ping命令;

主观下线:发送ping之后,如果某sentinel节点发现某示例未在规定时间内响应,则主观下线。

客观下线:超过一定数量的sentinel都认为该实例主观下线,则该实例客观下线,一般数量为示例数量的一半。

选主模式

主从断开时间长短, 时间超过指定值的不会被选为主

判断优先级,slave-priority越小优先级越高。

Salve-prioprity一样的offset值越大,越接近主数据,优先级也就越高(因为数据是最全的)

主节点写并发是8万条。从节点的读并发是十万条。

主从集群解决高并发读问题,哨兵机制解决高可用的问题。

 

12分片集群,数据读写规则(如果海量数据存储和高并发写怎么解决)

       可以使用多个master,每个master保存不同的数据,每个master也可以有多个slave,这样就形成了主从集群。

使用分片集群可以解决上述问题,分片集群特征

集群中有多个master,每个master保存不同数据

每个master都可以有多个slave节点

master之间通过ping监测彼此健康状态

客户端请求可以访问集群任意节点,最终都会被转发到正确节点

 13单线程redis为什么那么快。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com