当前位置:首页 > 杂谈 > 正文内容

Redis问题-redis常见问题解决

2023-07-14 15:26:51TONY杂谈156

一、项目中为什么要用Redis

传统关系型数据库已经不适用于所有的场景,例如秒杀活动,很容易把数据库打崩,所以引入了缓存中间件,目前市面上比较常用的缓存中渐渐有Redis和Memcached。

二、Redis和Memcached的区别

Redis:

速度快,因为数据在内存中,类似于HashMap。

支持丰富的数据类型

支持事务,操作都是原子操作

丰富的特性:可用于缓存、消息、设置过期时间、过期后自动删除等

Redis支持Cluster模式

Redis使用单核,所以平均到每个核上,Redis存储小数据会比Mem性能高;但100K以上的数据,Mem的性能高于Redis

三、Redis的线程模型

Redis内部使用文件事件处理器,它是单线程的,所以Redis才叫单线程模型。它采用IO多路复用机制同时监听多个Socket,根据Socket上的事件来选择对应的EventHandler来处理。

多个Socket可能会发生并发操作,每个操作对应不同的文件事件,IO多路复用会监听多个Socket,会将Socket产生的事件放入队列中排队,事件分派器每次从队列中取出一个事件,把该事件交给对应的事件处理器进行处理。

到达过期的时间点时,Redis可能出现卡顿,严重时会出现雪崩。因为大量缓存同时失效,会造成大量请求到达数据库,造成数据库压力增加,崩溃。这时可以在过期时间后面加上一个随机值,使过期的分散一些。

五、分布式锁

通过setnx抢锁,然后通过expire给锁加一个过期时间。

实现方法:

jedis.set(String key, String value, String nxxx, String expx, int time);

第一个是key,我们使用 key来当锁,因为 key 是唯一的。

第二个是value,入参是 requestId,很多人不明白,有 key 作为锁不就够了吗,为何还要用到value?

因为我们上面讲到的可靠性里,分布式锁要满足第4个条件:解铃还须系铃人,通过给 value 赋值为 requestId,我们就知道这把锁是哪个请求加的,在解锁的时候可以有依据。

requestId 可以使用UUID.random().toString() 方法生成。

第三个是nxxx,这个参数 我们填的是NX,意思 set if not exist,即当 key 不存在时,我们进行 set 操作;若 key 已经存在,则不做任何操作;

第四个是expx,这个参数我们传的是PX,意思是我们要给这个 key 加一个过期的设置,具体时间由第五个参数决定;

第五个是time,于第四个参数相呼应,代表 key 的过期时间。

解锁的正确姿势:

public class RedisTool 

{

    private static final Long RELEASE_SUCCESS = 1

L;

    

/**

     * 释放分布式锁

     * @param

 jedis Redis客户端

     * @param

 lockKey 锁

     * @param

 requestId 请求标识

     * @return

 是否释放成功

     */
    public static

 boolean releaseDistributedLock(Jedis jedis, String lockKey, String requestId) {

        String script = "if redis.call(get, KEYS[1]) == ARGV[1] then return redis.call(del, KEYS[1]) else return 0 end"

;

        Object result = jedis.eval

(script, Collections.singletonList(lockKey), Collections.singletonList(requestId));

        if

 (RELEASE_SUCCESS.equals(result)) {

            return true

;

        }

        return false

;

    }

}

script是一个lua脚本,通过jedis.eval方法,传入解锁的key,和对应的requestId。

这几行代码的作用是:先获取锁对应的value值,然后检查是否与reqeustId相等,相等则解锁。

为什么使用Lua脚本呢?因为要确保操作是原子性的,如果通过jedis.del(lockKey)解锁的话,因为没有判断拥有者就直接解锁,所以不安全;如果先判断requestId再决定要不要解锁时,因为是两个操作,不是原子操作,所以会有并发问题。使用eval方法传递给Redis服务端,它会当成一个命令执行,只有执行结束后,才会继续执行其他命令。

六、每秒上千订单场景下,如何对分布式锁的并发进行优化

下单时为了防止库存超卖,每秒上千订单的高并发场景,如何对分布式锁进行高并发优化来应对这个场景?

首先想到库存超卖问题有很多解决方案,悲观锁、分布式锁、乐观锁、队列串行化,Redis原子操作。

针对分布式锁的解决方案,首先看库存超卖是怎么产生的:

使用分布式锁解决库存超卖问题:

区别在于两个订单系统,第一个订单系统进行交易时,会把库存锁住,第二个订单系统想要获取库存必须先等待第一个订单系统释放分布式锁,等第一个释放了之后,订单系统二获取到的库存是不足的,所以就无法下单了。

但是有一定的问题,加了分布式锁之后,其他服务的下单请求都必须等待,这样就成了串行处理。那么如何对分布式锁进行高并发优化?

分段加锁

可以把数据分成很多段,每个段是一个单独的锁,多个线程过来并发修改数据时,可以并发修改不同段的数据。

需要注意:如果下单过程中,加了锁,发现这个分段库存不足,应该立刻释放锁,然后换下一个分段库存,再加锁尝试处理。

七、使用Redis做异步队列

使用List结构做队列,rpush生产消息,lpop消费消息。当lpop没有消息时,适当sleep等待生产者放入消息。或者通过blpop指令,如果没有消息就阻塞。当想要生产一次,消费多次时,可以通过pub/sub主题订阅方式,实现1:N的消息队列。

Redis如何实现延时队列:使用zset有序队列,使用时间戳作为socre,消息内容作为key,调用zadd生产消息,消费者用zrangebyscore指令获取N秒钱的数据进行处理。

八、Redis持久化

Redis有两种持久化方式:RDB和AOF

RDB会保存当前数据库快照,全量持久化

AOF倾向于日志保存,做增量持久化。

停机重启时,通过RDB持久化文件重新构建内存,使用AOF重放近期的操作指令来完全恢复到停机前的状态。

如果机器突然停电,AOF日志的sync属性,如果不要求性能,每条写指令都会同步至磁盘;高性能条件下一般1s1同步,这样最多丢失1s的数据。

九、Redis同步机制

Redis可以主从同步,从从同步。

第一次同步时,主节点做一个bgsave,同时将后续修改操作记录到内存buffer,完成后将RDB文件全量同步到负直接点,复制节点接收完成后将RDB

加载到内存。加载完成后,再通过主节点将期间修改的操作记录同步到复制节点进行重放就完成了同步过程。后续的增量数据通过AOF日志同步。

十、多个系统同时操作Redis带来的数据问题

例如ABC三个系统,分别取Redis的同一个key,本来顺序1,2,3是正常的,但是因为A系统网络卡了一下,BC在他前面操作了Redis这样数据就有问题了。

可以通过上文提到的redis分布式锁,或者通过zookeeper实现分布式锁。

每个系统通过zookeeper获取分布式锁,确保同一时间,只能有一个系统在操作某个key,别人不允许读和写。

数据库和缓存的双写问题,一致性问题

一般都会允许缓存和数据库存在偶尔不一致的问题,如果必须要求一致性,则读请求和写请求串行化,串到一个内存队列中去。但是这样会造成吞吐量大幅度降低。

KV+DB读写模式:

读的时候先查缓存,缓存查不到再去查数据库,读取数据库的值放入缓存,返回响应。

更新的时候,先更新数据库,再删除缓存。

“Redis问题-redis常见问题解决” 的相关文章

免费资源丨支持最新版pubmed网站,含多项实用功能包括全文下载的浏览器插件限时分享

免费资源丨支持最新版pubmed网站,含多项实用功能包括全文下载的浏览器插件限时分享

立即加星标 每天好资源 之前给大家分享过一款叫Scholarscope的浏览器插件,但是现在pubmed网站改版成新版,v3.0.16以及之前的版本已经无法使用了。今天小编给大家带来最新的v3.0.18和v3.1.1两个版本,因此请大家卸载之前的插件,安装新插件吧。...

1月70城房价公布:15城同比上涨,北京涨5.2%领跑一线城市

1月70城房价公布:15城同比上涨,北京涨5.2%领跑一线城市

乐居买房讯 编辑:孙晓萌 2月16日,国家统计局发布了2023年1月份70个大中城市商品住宅销售价格变动情况。1月份,70个大中城市中,新建商品住宅销售价格同比上涨城市有15个,比上月减少1个。...

2月份70城房价:一线城市同比上涨,二手房销售价格由上月下降0.4%转为持平。

2月份70城房价:一线城市同比上涨,二手房销售价格由上月下降0.4%转为持平。

原标题:2月份70城房价:一线城市同比上涨,二手房销售价格由上月下降0.4%转为持平。 2月份70城房价:一线城市同比上涨 随着政策效应逐步显现,住房需求进一步释放,70个大中城市中商品房销售价格上涨的城市数量继续增加。二、三线城市同比降幅收窄。 一线、二线、三线...

谨防上当受骗!临沂多地公安、镇政府发布紧急提醒

谨防上当受骗!临沂多地公安、镇政府发布紧急提醒

临近年底,各类骗局又开始轮番上演,且花样不断翻新。近日,临沂多地发布重要提醒,临报融媒记者为您进行了梳理,在此提醒广大市民,要擦亮眼睛做好防范,谨防上当受骗。 兰山:冒充领导干部诈骗 10月28日,兰山区义堂镇人民政府发布《关于不法分子利用网络、微信冒充义堂镇领导干部名义进...

人民艺术家秦怡去世,为逃婚离家出走,一生曲折离奇,享年100岁

人民艺术家秦怡去世,为逃婚离家出走,一生曲折离奇,享年100岁

她是《铁道游击队》中宁死不屈的芳林嫂、《马兰花开》中性格坚毅的马兰、《篮球5号》中饱受苦难的篮球运动员林洁……这一个个在荧幕中坚毅美丽的女性角色都是由同一个人演绎,她就是人民艺术家秦怡。5月9日凌晨,秦怡在上海病逝,享年100岁。大多数年轻人对这位满头银发的老艺术家可能有些陌生,但对于父辈甚至更老的...

Win11怎么完成文件备份?三种方法可以选择

Win11怎么完成文件备份?三种方法可以选择

Win11怎么完成文件备份?作为当前最新的操作系统,使用Win11的用户可谓越来越多!许多创新功能,增加了新版开始菜单和输入逻辑等,支持与时代相符的混合工作环境,侧重于在灵活多变的体验中提高最终用户的工作效率等。那么,在使用Win11的时候,怎么完成文件备份的操作呢?请不要担心,下面小编就...