当前位置: 首页 > wzjs >正文

广州编程课程培训机构排名seo网站建设步骤

广州编程课程培训机构排名,seo网站建设步骤,wordpress 导入ppt,杭州租房网站建设一、场景介绍 在我们平时开发过程中,把某些数据放到redis中缓存起来用于快速读取已不是什么稀奇的事情。通常的流程是这样的: 1、项目启动时,将数据从数据库中加载出来保存到redis中 2、项目启动成功后,系统在运行过程中&#xff…

一、场景介绍

        在我们平时开发过程中,把某些数据放到redis中缓存起来用于快速读取已不是什么稀奇的事情。通常的流程是这样的:

        1、项目启动时,将数据从数据库中加载出来保存到redis中

        2、项目启动成功后,系统在运行过程中,如果需要这些数据,优先从redis中获取,如果redis中不存在,那么再去查询一次数据库,把查询到的数据先保存到redis中,然后再将数据返回给页面。

        我们通常会把改动不频繁的数据加载到redis中,改动不频繁可不是不改动,当数据发生修改的时候,redis如果不及时更新,那么redis中保存的数据将不可靠,接下来我们分析一下这个问题并且给出一些解决方案。

二、问题复现

       2.1、预先将测试数据加载到redis
    /*** 功能描述:预先将数据加载到redis* @Author:huhy* @Date: 2025/3/21 22:24*/@Testpublic void init(){searchCodeRuleAndSetRedis(2L);}/*** 功能描述: 查询并设置到缓存* @Author:huhy* @Date: 2025/3/21 20:56*/private String searchCodeRuleAndSetRedis(Long id){//通过id查询编码规则TSCodeRule tsCodeRule = codeRuleService.selectTSCodeRuleById(id);String roleJson = JSON.toJSONString(tsCodeRule);//将测试数据保存到redis中redisTemplate.opsForValue().set("dataConsistent:"+tsCodeRule.getId(),roleJson);return roleJson;}

       

        2.2、复现数据库与redis数据不一致
    /*** 功能描述: 数据一致性测试方法* @Author:huhy* @Date: 2025/3/20 23:27*/@Testpublic void dataConsistentTest(){//另起线程去查询new Thread(()->{String data = findData(2L);System.out.println(Thread.currentThread().getName()+"读取到的数据为:"+ data);},"测试线程").start();updateData(2L);}/*** 功能描述: 修改数据* @Author:huhy* @Date: 2025/3/21 21:54*/private void updateData(Long id){//通过id查询数据TSCodeRule tsCodeRule = codeRuleService.selectTSCodeRuleById(id);if(Objects.isNull(tsCodeRule)){return;}//修改CodePrefix字段tsCodeRule.setCodePrefix("test-data-"+UUID.randomUUID().toString().replace("-",""));int result = codeRuleService.updateTSCodeRule(tsCodeRule);if(result!=0){System.out.println(Thread.currentThread().getName()+" 修改成功,修改后的信息为:"+JSON.toJSONString(tsCodeRule));}}/*** 功能描述: 通过id查询* @Author:huhy* @Date: 2025/3/21 21:49*/private String findData(Long id){Object dataObj = redisTemplate.opsForValue().get("dataConsistent:" + id);//如果缓存中不存在,则从数据库中查询if(Objects.isNull(dataObj)){return searchCodeRuleAndSetRedis(id);}else {//如果缓存中存在,直接返回return dataObj.toString();}}

 

三、逐步修复一致性问题

       3.1、坊间对话

        这次我们请到了杠精大神猫哥,下面请看猫哥表演。

        猫哥:“ 第二步中写的那是什么玩意,那不就是bug吗?谁家好人写修改不维护redis?”

        小永哥:“ 被你发现了,没错,修改数据时确实应该将redis也考虑进去,那么我们开始修改这个bug。我的计划是在真正操作数据库之前,先将redis中的缓存数据删除了,这样读取数据的时候,redis中没有的话就会自动从数据库中查询,到时候再设置到redis中,这样不就一致了,你觉得呢?”

        猫哥:“我暂时也没有好的办法,先这么修改吧!”

下面我们就对代码进行一些修改,在修改数据之前进行删除缓存,测试时分别在修改方法调用前后均进行一次读取,看看效果。

 /*** 功能描述: 数据一致性测试方法* @Author:huhy* @Date: 2025/3/20 23:27*/@Testpublic void dataConsistentTest(){System.out.println("第一次读取到的数据为:"+ findData(2L));updateData(2L);System.out.println("第二次读取到的数据为:"+ findData(2L));}/*** 功能描述: 修改数据* @Author:huhy* @Date: 2025/3/21 21:54*/private void updateData(Long id){//通过id查询数据TSCodeRule tsCodeRule = codeRuleService.selectTSCodeRuleById(id);if(Objects.isNull(tsCodeRule)){return;}//修改之前,先将缓存删除redisTemplate.delete("dataConsistent:"+id);//修改CodePrefix字段tsCodeRule.setCodePrefix("test-data-"+UUID.randomUUID().toString().replace("-",""));int result = codeRuleService.updateTSCodeRule(tsCodeRule);if(result!=0){System.out.println(Thread.currentThread().getName()+" 修改成功,修改后的信息为:"+JSON.toJSONString(tsCodeRule));}}

        小永哥:看样子是成功了,第二次读取的结果、数据库、redis中都已保持一致,看来这个改动非常成功!!!

        猫哥:有瑕疵,首先测试代码太过理想,实际场景存在并发访问风险,到时候数据会混乱成什么样谁都不知道,比如说数据库中已修改了,但是缓存中还是旧值的情况。

        小永哥,你说的有道理,可以详细说说吗?

        猫哥:假如修改和请求都是独立的线程,修改代码运行的时间有点长,这时候虽然已经删除了redis,但是立刻有线程进行数据读取,此时数据库中依然还是旧数据,那么又把旧数据设置回redis中了。

      

         3.2、数据不一致问题解决方案之延时双删

        延时双删的意思是:在执行数据库修改之前先删一次缓存,在数据库修改之后,再进行一次删除,这样可以保证数据库与redis中的数据保持一致,我们来实现一下。

/*** 功能描述: 数据一致性测试方法* @Author:huhy* @Date: 2025/3/20 23:27*/@Testpublic void dataConsistentTest() throws Exception{CountDownLatch countDownLatch = new CountDownLatch(11);//修改数据new Thread(()->{updateData(2L);countDownLatch.countDown();},"修改线程").start();//查询数据for (int i = 0; i < 10; i++) {new Thread(()->{sleepTest(random.nextInt(6) + 1L);String data = findData(2L);System.out.println(Thread.currentThread().getName()+"读取到的数据为:"+ data);countDownLatch.countDown();},"查询线程"+(i+1)).start();}countDownLatch.await();}/*** 功能描述: 修改数据* @Author:huhy* @Date: 2025/3/21 21:54*/private void updateData(Long id){//通过id查询数据TSCodeRule tsCodeRule = codeRuleService.selectTSCodeRuleById(id);if(Objects.isNull(tsCodeRule)){return;}//修改之前,先将缓存删除redisTemplate.delete("dataConsistent:"+id);//休眠几秒再修改CodePrefix字段,模拟业务执行缓慢try {sleepTest(5L);}catch (Exception e){e.printStackTrace();}tsCodeRule.setCodePrefix("test-data-"+UUID.randomUUID().toString().replace("-",""));int result = codeRuleService.updateTSCodeRule(tsCodeRule);//修改之后再删一次缓存redisTemplate.delete("dataConsistent:"+id);if(result!=0){System.out.println(Thread.currentThread().getName()+" 修改成功,修改后的信息为:"+JSON.toJSONString(tsCodeRule));}}

        

        测试以后,我们可以看到,数据库和redis中的数据倒是保持一致了,看来修改的时候需要在修改前后都需要进行删除,才能保证数据库和缓存数据一致。

        猫哥:我测试结果不敢苟同,虽然数据库和redis中的数据保持了一致,但是有一些线程还是读取到了旧数据,这个问题可以再改改吗?

        小永哥:有这个必要吗?只要数据库和redis中数据一致不就好了,那我没修改数据之前可不知道已经有多少线程读取到了旧数据,想获得最新的数据,就是需要重新获取,不对吗?

        猫哥:我不是这个意思,我的意思是在修改过程中我们读取到了旧数据,我想要数据只要发生修改就立刻更新到redis,这个可以实现吗?

        3.3、数据不一致问题解决方案之分布式锁

        如果需要保证数据库和redis数据时时一致,那么我们需要加锁。可以加分布式锁,上一期我们讲过分布式锁了,这次就不详细介绍了,但是不建议加锁,因为我们用redis本身就是为了提升性能,加锁势必会降低性能,所以分布式锁不适合这个场景。

四、结语

        本次简单介绍了缓存和数据库数据不一致问题,这个问题虽然简单,但是平时开发过程中容易被忽略,所以我们单独拿出一篇来讨论这个事情。

        

       


文章转载自:

http://suWnxmfP.xrpjr.cn
http://0GmfOA0L.xrpjr.cn
http://x8izhMVV.xrpjr.cn
http://DEFEZLAW.xrpjr.cn
http://nT5x5NMh.xrpjr.cn
http://1SPOlTdq.xrpjr.cn
http://emlzFHKQ.xrpjr.cn
http://J3mTMxlg.xrpjr.cn
http://T6XZoRAP.xrpjr.cn
http://kr8LnLCf.xrpjr.cn
http://34VVgxq1.xrpjr.cn
http://9pOLRmEI.xrpjr.cn
http://k1dmJmTw.xrpjr.cn
http://Ck9Dn2EQ.xrpjr.cn
http://zS6suYhX.xrpjr.cn
http://6liZBdbs.xrpjr.cn
http://PbbeiMCo.xrpjr.cn
http://2CrxgczW.xrpjr.cn
http://DP42W00u.xrpjr.cn
http://PuEI7kYx.xrpjr.cn
http://Z8Hb9DpB.xrpjr.cn
http://MER1gEud.xrpjr.cn
http://259yHk2M.xrpjr.cn
http://gCILNK5U.xrpjr.cn
http://cJuJaudm.xrpjr.cn
http://ZGvKXT1r.xrpjr.cn
http://NPhNCiuv.xrpjr.cn
http://ifcpnpTI.xrpjr.cn
http://pGQ3M2C0.xrpjr.cn
http://cF4ehtCh.xrpjr.cn
http://www.dtcms.com/wzjs/768744.html

相关文章:

  • iframe网站后台模板软件平台架构
  • 合肥有哪些做网站的慈溪seo排名
  • 主题资源网站制作平台广东好的网络营销机构
  • 微网站特点公众号投放平台
  • 简述网站建设基本过程wordpress主题模版开发
  • 网站优化的重要性网站开发合作运营平台合同
  • 网站制作公司官网首页在线制作表白网站
  • 德州市建设工程协会网站泰州网站建设制作工作室
  • 韩国做游戏的电影 迅雷下载网站怎么用asp.net做网站
  • 厦门建设网站首页工作证模板word
  • 江门北京网站建设手工制作钟表
  • 做百度推广送网站wordpress的数据库在那里
  • 企业核名网站百度网站收录提交入口
  • 企业网站建设规划书的内容建设公司网站要注意哪些
  • 网站备案名称几个字软件外包公司怎么找业务
  • 网站编辑好做吗wordpress视频站主题
  • 石家庄市城乡建设局网站中国建设银行u盾官方网站
  • 建设租车网站泽国镇规划建设局网站
  • 公司做的网站费用如何做账为什么上不了建设银行个人网站
  • 网站制作基本规则怎么搭建php网站
  • 无锡企业建站模板上海市建设工程咨询网
  • 网站风格类型是如何做简易个人网站
  • 菏泽做企业网站国外简约网站
  • 做蛋糕的网站企业名录是什么
  • 苏州规划建设局网站短链接在线工具
  • 做古玩的网站合肥网站设计建设
  • 太仓网站建设企业网站竞价如何屏蔽恶意点击
  • 1企业网站案例郑州网站推广¥做下拉去118cr
  • 精仿源码社区网站源码永川网站制作
  • 建立微网站动漫制作专业学习方法