怎么使用Redis缓存淘汰策略和事务实现乐观锁


    缓存淘汰策略

    标题LRU原理

    lru(least recently used,最近最少使用)算法根据数据的历史访问记录来进行淘汰数据,其核心思想是“如果数据最近被访问过,那么将来被访问的几率也更高”。

    最常见的实现是使用一个链表保存缓存数据,详细算法实现如下:

    怎么使用Redis缓存淘汰策略和事务实现乐观锁

    • 新数据插入到链表头部;

    • 每当缓存命中(即缓存数据被访问),则将数据移到链表头部;

    • 当链表满的时候,将链表尾部的数据丢弃。

    在J*a中可以使用LinkHashMap去实现LRU利用哈希链表实现:

    怎么使用Redis缓存淘汰策略和事务实现乐观锁

    标题Redis缓存淘汰策略

    设置最大缓存

    在 redis 中,允许用户设置最大使用内存大小maxmemory,默认为0,没有指定最大缓存,如果有新的数据添加,超过最大内存,则会使redis崩溃,所以一定要设置。

    redis 内存数据集大小上升到一定大小的时候,就会实行数据淘汰策略。

    淘汰策略

    redis淘汰策略配置:maxmemory-policy voltile-lru,支持热配置

    redis 提供 6种数据淘汰策略:

    • volatile-lru:从已设置过期时间的数据集(server.db[i].expires)中挑选最近最少使用的数据淘汰

    • volatile-ttl:从已设置过期时间的数据集(server.db[i].expires)中挑选将要过期的数据淘汰

    • volatile-random:从已设置过期时间的数据集(server.db[i].expires)中任意选择数据淘汰

    • allkeys-lru:从数据集(server.db[i].dict)中挑选最近最少使用的数据淘汰

    • allkeys-random:从数据集(server.db[i].dict)中任意选择数据淘汰

    • no-enviction(驱逐):禁止驱逐数据

    Redis事务

    Redis事务介绍

    • Redis 的事务是通过 MULTI 、 EXEC 、 DISCARD 和 WATCH 、UNWATCH这五个命令来完成的。

    • Redis 的单个命令都是原子性的,所以这里需要确保事务性的对象是命令集合。

    • Redis 将命令集合序列化并确保处于同一事务的命令集合连续且不被打断的执行

    • Redis 不支持回滚操作。 事务命令

    MULTI

    用于标记事务块的开始。Redis会逐个将后续的命令放入队列中,然后使用原子化的EXEC命令执行这个命令序列。

    语法:

    Mootion Mootion

    Mootion是一个革命性的3D动画创作平台,利用AI技术来简化和加速3D动画的制作过程。

    Mootion 232 查看详情 Mootion
    multi

    EXEC

    在一个事务中执行所有先前放入队列的命令,然后恢复正常的连接状态

    语法:

    exec

    DISCARD

    清除所有先前在一个事务中放入队列的命令,然后恢复正常的连接状态。

    语法:

    discard

    WATCH

    当某个[事务需要按条件执行]时,就要使用这个命令将给定的[键设置为受监控]的状态。

    语法:

    watch key [key…]

    注意事项:使用该命令可以实现 Redis 的乐观锁。

    UNWATCH

    清除所有先前为一个事务监控的键

    语法:

    unwatch

    命令图解:

    怎么使用Redis缓存淘汰策略和事务实现乐观锁

    事务演示:

    127.0.0.1:6379> multi
    OK
    127.0.0.1:6379> set s1 111
    QUEUED
    127.0.0.1:6379> hset set1 name zhangsan
    QUEUED
    127.0.0.1:6379> exec
    1) OK
    2) (integer) 1
    127.0.0.1:6379> multi
    OK
    127.0.0.1:6379> set s2 222
    QUEUED
    127.0.0.1:6379> hset set2 age 20
    QUEUED
    127.0.0.1:6379> discard
    OK
    127.0.0.1:6379> exec (error) ERR EXEC without MULTI 
    127.0.0.1:6379> watch s1
    OK
    127.0.0.1:6379> multi
    OK
    127.0.0.1:6379> set s1 555
    QUEUED 127.0.0.1:6379> exec # 此时在没有exec之前,通过另一个命令窗口对监控的s1字段进行修改 
    (nil)
    127.0.0.1:6379> get s1
    111

    Redis 不支持事务回滚(为什么呢)

    大多数事务失败是因为语法错误或者类型错误,这两种错误,在开发阶段都是可以预见的Redis 为了性能方面就忽略了事务回滚。

    Redis乐观锁

    乐观锁基于CAS(Compare And Swap)思想(比较并替换),是不具有互斥性,不会产生锁等待而消耗资源,但是需要反复的重试,但也是因为重试的机制,能比较快的响应。因此我们可以利用redis来

    实现乐观锁。具体思路如下:

    • 利用redis的watch功能,监控这个redisKey的状态值

    • 获取redisKey的值

    • 创建redis事务

    • 给这个key的值+1

    • 然后去执行这个事务,如果key的值被修改过则回滚,key不加1

    public void watch() {
    	try {
    		String watchKeys = "watchKeys";
    		//初始值 value=1
    		jedis.set(watchKeys, 1);
    		//监听key为watchKeys的值
    		jedis.watch(watchkeys);
    		//开启事务
    		Transaction tx = jedis.multi();
    		//watchKeys自增加一
    		tx.incr(watchKeys);
    		//执行事务,如果其他线程对watchKeys中的value进行修改,则该事务将不会执行
    		//通过redis事务以及watch命令实现乐观锁
    		List<Object> exec = tx.exec();
    		if (exec == null) {
    			System.out.println("事务未执行");
    		} else {
    			System.out.println("事务成功执行,watchKeys的value成功修改");
    		}
    	} catch (Exception e) {
    		e.printStackTrace();
    	} finally {
    		jedis.close();
    	}
    }

    Redis乐观锁实现秒杀

    public class RedisLock {
        public static void main(String[] arg) {
            //库存key 
            String redisKey = "stock";
            ExecutorService executorService = Executors.newFixedThreadPool(20);
            try {
                Jedis jedis = new RedisProperties.Jedis("127.0.0.1", 6378);
                // 可以被秒杀的库存的初始值,库存总共20个
                jedis.set(redisKey, "0");
                jedis.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
            for (int i = 0; i < 1000; i++) {
                executorService.execute(() -> {
                    Jedis jedis1 = new Jedis("127.0.0.1", 6378);
                    try {
                        jedis1.watch(redisKey);
                        String redisValue = jedis1.get(redisKey);
                        int valInteger = Integer.valueOf(redisValue);
                        String userInfo = UUID.randomUUID().toString();
                        // 没有秒完
                        if (valInteger < 20) {
                            Transaction tx = jedis1.multi();
                            tx.incr(redisKey);
                            List list = tx.exec();
                            // 秒成功 失败返回空list而不是空
                            if (list != null && list.size() > 0) {
                                System.out.println("用户:" + userInfo + ",秒杀成 功!当前成功人数:" + (valInteger + 1));
                            }
                            // 版本变化,被别人抢了。
                            else {
                                System.out.println("用户:" + userInfo + ",秒杀失 败");
                            }
                        }
                        // 秒完了
                        else {
                            System.out.println("已经有20人秒杀成功,秒杀结束");
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    } finally {
                        jedis1.close();
                    }
                });
            }
            executorService.shutdown();
        }
    }

    以上就是怎么使用Redis缓存淘汰策略和事务实现乐观锁的详细内容,更多请关注其它相关文章!


    # 如何实现  # 丰泽区机械网站推广电话  # 阜阳seo推广策划方案  # 推广软件赚钱网站  # 厦门自助网站推广企业  # 文章推广的网站设计案例  # 网站怎么优化最小kb  # 惠州正规网站建设  # 阜宁网站推广服务商  # 网站建设资源文档有哪些  # 抖音seo标签修改方法  # redis  # 网络带宽  # 恢复正常  # 不支持  # 已设置  # 先前  # 是因为  # 都是  # 秒杀  # 链表 


    相关栏目: 【 Google疑问12 】 【 Facebook疑问10 】 【 优化推广96088 】 【 技术知识133117 】 【 IDC资讯59369 】 【 网络运营7196 】 【 IT资讯61894


    相关推荐: Fedora怎么安装 Fedora Workstation安装步骤  为什么XML解析器对大小写敏感? 理解XML规范中的大小写规则与最佳实践  163邮箱网页版入口 163邮箱在线使用  荣耀Magic7拍照夜景噪点处理_荣耀Magic7相机优化  《下一站江湖2》大雪山加入方法  Final Cut Pro视频加EQ教程  《气泡星球》兑换码礼包大全  快递查询,一键速查  《漫蛙manwa2》防走失网页版链接2025  12306不能订票的时间段是固定的吗? | 节假日购票时间有无变化  快递优选如何查优选物流_快递优选专属物流渠道查询与配送时效  Mac如何开启画中画模式_Mac Safari浏览器视频画中画功能  mysql通配符能用于日志查询吗_mysql通配符在系统日志查询中的实际使用方法  Excel如何快速找到并断开外部数据源链接_Excel外部数据源断开方法  《浙里办》电子发票开具方法  银信通自动开通原因揭秘  j*a中赋值运算符是什么?  《兴业银行》注册登录方法  lol小红书怎么|直播|?lol小红书|直播|是什么意思?  C++ switch case字符串_C++如何实现字符串switch匹配  PointNet++语义分割模型中类别变更引发的断言错误及标签处理策略  大众点评了却看不到是怎么回事  批改网官网首页登录 批改网学生用户登录入口  C++如何实现单例模式_C++线程安全的单例模式写法  百度竞价WAP显示PC链接问题  C++ static关键字作用_C++静态成员变量与静态函数  企查查官网和爱企查 企查查企业查询官网入口  研招网官方网站招生平台入口_中国研究生招生信息网官网登录  三角洲行动2025年9月10日摩斯密码分享  鲨鱼剧场app金币获取方法  TikTok视频播放不流畅怎么办 TikTok视频播放优化方法  支付宝网页版在线入口 支付宝官网电脑登录入口  iPhone 14 Pro如何更改区域设置_iPhone 14 Pro地区语言修改教程  Scipy Sparse CSR 矩阵非零元素行级遍历的最佳实践  画质怪兽120帧安卓和平精英免费版  Go语言反射机制:如何访问被嵌入结构体遮蔽的方法  知音漫客官网首页入口_知音漫客热门漫画推荐  猫眼电影app如何筛选支持退改签的影院_猫眼电影退改签影院筛选方法  顺丰快递收费标准查询_如何查看顺丰最新收费价格  163邮箱在线登录 163邮箱网页版在线入口  C++ cast类型转换总结_C++ reinterpret_cast与const_cast的使用  MongoDB聚合管道:高效统计列表中各项的文档数量  行者app怎样导出日志  @Team是什么?揭秘团队含义  微信网页版在线登录 微信网页版在线使用入口  猫眼app抢票快还是小程序快  荣耀Magic6 Pro拍照成像偏暗_荣耀Magic6 Pro夜景优化  顺丰快递怎么查物流_顺丰快递物流信息实时查询操作指南  中通快递官网指定查询 中通快递单号查询平台入口  如何解决Casbin日志与应用日志不统一的问题,使用casbin/psr3-bridge实现无缝集成 

     2023-06-03

    了解您产品搜索量及市场趋势,制定营销计划

    同行竞争及网站分析保障您的广告效果

    点击免费数据支持

    提交您的需求,1小时内享受我们的专业解答。

    运城市盐湖区信雨科技有限公司


    运城市盐湖区信雨科技有限公司

    运城市盐湖区信雨科技有限公司是一家深耕海外推广领域十年的专业服务商,作为谷歌推广与Facebook广告全球合作伙伴,聚焦外贸企业出海痛点,以数字化营销为核心,提供一站式海外营销解决方案。公司凭借十年行业沉淀与平台官方资源加持,打破传统外贸获客壁垒,助力企业高效开拓全球市场,成为中小企业出海的可靠合作伙伴。

     8156699

     13765294890

     8156699@qq.com

    Notice

    We and selected third parties use cookies or similar technologies for technical purposes and, with your consent, for other purposes as specified in the cookie policy.
    You can consent to the use of such technologies by closing this notice, by interacting with any link or button outside of this notice or by continuing to browse otherwise.