springboot+redis+mysql+quartz-使用pipeline+lua技术将缓存数据定时更新到数据库

这篇具有很好参考价值的文章主要介绍了springboot+redis+mysql+quartz-使用pipeline+lua技术将缓存数据定时更新到数据库。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、重点

代码讲解:7.3点赞功能-定时持久化到数据库-Java程序整合pipeline+lua_哔哩哔哩_bilibili

https://www.bilibili.com/video/BV1Lg4y1w7U9

代码:

blogLike_schedule/like08 · xin麒/XinQiUtilsOrDemo - 码云 - 开源中国 (gitee.com)

https://gitee.com/flowers-bloom-is-the-sea/XinQiUtilsOrDemo/tree/master/blogLike_schedule/like08

数据库表:
blogLike_schedule · xin麒/XinQiUtilsOrDemo - 码云 - 开源中国 (gitee.com)

二、实现过程:

这里主要是开2个定时任务,一个是平时的缓存数据持久化操作就是要pipeline技术;

另一个时间就使用lua脚本向redis缓存获取缓存数据再更新到数据库。

1、对lua脚本任务执行:

@Slf4j
public class LikeTaskAtNight extends QuartzJobBean {
    @Autowired
    BlogService blogService;

    @Autowired
    StringRedisTemplate stringRedisTemplate;

    /**
     * 用来从redis中的zset中获取点赞缓存的键值对,间隔时间存入mysql
     * 这里就夜间执行吧,因为lua会阻塞redis其他操作,选择夜间流量低时进行执行
     * @param context
     * @throws JobExecutionException
     */
    @Override
    protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
        int hour = LocalTime.now().getHour();
//        int minute = LocalTime.now().getMinute();
        if (hour == 3){
            // 要执行的内容就写在这个函数中
//        blogService.updateAllLikeListToDatabase();//这个没使用pipeline技术,效果应该是明显低于updateAllLikeListToDatabaseByPipeline1
            log.debug("LikeTaskAtNight - time is {}",System.currentTimeMillis());
//        blogService.updateAllLikeListToDatabaseByPipeline1();//这个使用了pipeline技术,但是还有优化空间,比如书对sql的更新可以说批量更新
            blogService.updateAllLikeListToDatabaseByLua();//这个使用了lua技术,但是还有优化空间,比如书对sql的更新可以说批量更新

        }
    }

}

配置文件:

import com.xinqi.task.LikeTask;
import com.xinqi.task.LikeTaskAtNight;
import org.quartz.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class QuartzConfig {
    @Bean
    public JobDetail quartzDetail_1(){
        // withIdentity指定的是这个job的id
        return JobBuilder.newJob(LikeTask.class)
                .withIdentity("LIKE_TASK_IDENTITY")
                .storeDurably()
                .build();
    }


    @Bean
    public Trigger quartzTrigger_1(){ //触发器
        SimpleScheduleBuilder scheduleBuilder = SimpleScheduleBuilder.simpleSchedule()
                .withIntervalInSeconds(20)  //设置时间周期单位秒
//                .withIntervalInHours(2)  //两个小时执行一次
                .repeatForever();
        return TriggerBuilder.newTrigger().forJob(quartzDetail_1())
//                .forJob(quartzDetail_2())
                .withIdentity("LikeTask_TRENDS_TRIGGER")
                .withSchedule(scheduleBuilder)
                .build();
    }

    @Bean
    public JobDetail quartzDetail_LikeTaskAtNight(){
        // withIdentity指定的是这个job的id
        return JobBuilder.newJob(LikeTaskAtNight.class)
                .withIdentity("LikeTaskAtNight_IDENTITY")
                .storeDurably()
                .build();
    }


    @Bean
    public Trigger quartzTrigger_2(){ //触发器
        SimpleScheduleBuilder scheduleBuilder = SimpleScheduleBuilder.simpleSchedule()
//                .withIntervalInSeconds(35)  //设置时间周期单位秒
                .withIntervalInHours(1)  //两个小时执行一次
                .repeatForever();
        return TriggerBuilder.newTrigger().forJob(quartzDetail_LikeTaskAtNight())
//                .forJob(quartzDetail_2())
                .withIdentity("LikeTaskAtNight_USER_TRENDS_TRIGGER")
                .withSchedule(scheduleBuilder)
                .build();
    }

}

updateAllLikeListToDatabaseByLua执行的内容:

@Override
public void updateAllLikeListToDatabaseByLua() {
    String prefix = "BLOG_LIKED_KEY";

    Map<Long, Map<String, String>> maps = getMapsByLuaUseJedis(prefix);
    if (maps == null || maps.size() == 0) return;

    for (Map.Entry<Long, Map<String, String>> entry : maps.entrySet()) {
        Long blogId = entry.getKey();
        Map<String, String> likeList = entry.getValue();
        updateLikeListByBlogId(blogId, likeList);
    }
}
public Map<Long, Map<String, String>> getMapsByLuaUseJedis(String prefix) {
    Map<Long, Map<String, String>> maps = null;
    String script = "local prefix = KEYS[1]; \n" +
            "local redisKeys = redis.call('keys',prefix ..'*');\n" +
            "\n" +
            "if(not redisKeys) \n" +
            "    then    \n" +
            "    \treturn (nil);\n" +
            "end;\n" +
            "\n" +
            "local maps = {};\n" +
            "\n" +
            "for i, v in pairs(redisKeys) do\n" +
            "    local blogId = string.sub(v,string.len(prefix) + 1,string.len(v));\n" +
            "    local zset = redis.call('zrange',v,'0','-1','withscores');\n" +
            "    table.insert(maps,blogId);\n" +
            "    table.insert(maps,zset);    \n" +
            "end;\n" +
            "\n" +
            "return maps;";

    List result = null;

    result = getResultByLuaUseJedis(script, prefix);

    maps = parseLuaResultToMaps(result);

    return maps;

}
    private List getResultByLuaUseJedis(String script, String prefix) {
        Jedis jedis = null;

        List result = null;
        int failTime = 0;//执行失败的次数
        boolean flag = true;//如果为true就说明报错

        while (flag && failTime < 2) {
            try {
                jedis = jedisPool.getResource();
                result = (List) jedis.eval(script, Arrays.asList(prefix), new ArrayList<>());//https://blog.csdn.net/EnjoyFight/article/details/127808971
                System.out.println("result is " + result);//result is [1, [1, 1688218686914]]
/*        log.debug("result is ",result);//不知道为什么无法显示
        log.debug("result is null?{}",result==null);
        String s = JSONUtil.toJsonStr(result);
        log.debug("s is ",s);
        log.debug("s is null? {}",s==null);
        log.debug("s .len is  {}",s.length());*/

                flag = false;
            } catch (Exception e) {
                e.printStackTrace();
                failTime++;
            } finally {
                if (jedis != null) jedis.close();
            }

        }

        return result;
    }

2、pipeline技术定时任务

看这篇文章吧:(108条消息) springboot+redis+mysql+quartz-通过Java操作jedis使用pipeline获取缓存数据定时更新数据库_xin麒的博客-CSDN博客

三、其他

本文章的具体内容基本上都是在视频里面了,就不多描述了。

其他类似的文章:

(108条消息) springboot+redis+mysql+quartz-通过Java操作redis的KEYS*命令获取缓存数据定时更新数据库_xin麒的博客-CSDN博客

(108条消息) springboot+redis+mysql+quartz-通过Java操作jedis定时使用lua脚本获取缓存数据并更新数据库_xin麒的博客-CSDN博客

(108条消息) lua脚本获取table类型-Java使用lua脚本操作redis获取zset元素的集合_xin麒的博客-CSDN博客

(108条消息) springboot+redis+mysql+quartz-通过Java操作jedis使用pipeline获取缓存数据定时更新数据库_xin麒的博客-CSDN博客

(108条消息) springboot+redis+mysql+quartz-通过Java操作jedis的scan命令获取缓存数据定时更新数据库_xin麒的博客-CSDN博客文章来源地址https://www.toymoban.com/news/detail-539923.html

到了这里,关于springboot+redis+mysql+quartz-使用pipeline+lua技术将缓存数据定时更新到数据库的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 在Springboot项目中使用Redis提供给Lua的脚本

    在Spring Boot项目中,你可以使用RedisTemplate来执行Lua脚本。RedisTemplate是Spring Data Redis提供的一个Redis客户端,它可以方便地与Redis进行交互。以下是使用RedisTemplate执行Lua脚本的一般步骤: 添加Spring Data Redis依赖: 首先,确保你的Spring Boot项目中已经添加了Spring Data Redis依赖。你可

    2024年02月07日
    浏览(23)
  • redis(12):springboot使用redis注解做缓存

    1 新建springboot项目   2 相关注解 @EnableCaching 在启动类上加上注解启动缓存 #作用在你要缓存的数据上 @Cacheable(key=\\\"#id\\\",cacheNames=\\\"com.sxt.service.impl.MenuServiceImpl\\\") @Cacheput 解决脏读 @CachEvict(解决脏读) @Cacheconfig(全局的配置缓存) 3 修改yml

    2024年02月15日
    浏览(30)
  • SpringBoot整合定时任务技术Quartz

    个人简介:Java领域新星创作者;阿里云技术博主、星级博主、专家博主;正在Java学习的路上摸爬滚打,记录学习的过程~ 个人主页:.29.的博客 学习社区:进去逛一逛~ # 一、SpringBoot整合定时任务技术Quartz 🚀Quartz应用场景 Spring Boot整合Quartz的定时任务技术可以应用于许多不同

    2024年02月09日
    浏览(29)
  • springboot:缓存不止redis,学会使用本地缓存ehcache

    随着redis的普及,更多的同学对redis分布式缓存更加熟悉,但在一些实际场景中,其实并不需要用到redis,使用更加简单的本地缓存即可实现我们的缓存需求。 今天,我们一起来看看本地缓存组件ehcache ehcache是基于java开发的本地缓存组件,无需单独安装部署,只要引入jar包就

    2024年02月01日
    浏览(24)
  • SpringBoot 如何使用 Redis 作为缓存?

    在今天的互联网应用中,缓存是一个非常重要的概念。缓存可以减轻数据库的负担,提高系统的性能。Redis 是一个非常流行的内存数据库,它可以用作缓存,提供快速的读写速度和高可用性。在本文中,我们将介绍如何在 SpringBoot 中使用 Redis 作为缓存。 Redis 是一个高性能的

    2024年02月11日
    浏览(28)
  • SpringBoot使用redis作为缓存的实例

    目录 什么是缓存?  缓存的作用? 缓存的成本? 实际项目中的应用  代码展示 缓存 就是数据交换的缓冲区(称作 Cache [ kæʃ ] ),是存贮数据的临时地方,一般读写性能较高。         降低后端负载         提高读写效率,降低响应时间         数据一致性成本

    2024年02月14日
    浏览(30)
  • SpringBoot 集成 Quartz + MySQL

    Quartz 简单使用 Java SpringBoot 中,动态执行 bean 对象中的方法 源代码地址 = https://gitee.com/VipSoft/VipBoot/tree/develop/vipsoft-quartz 只要配置好 DataSource Quartz 会自动进行表的数据操作, 添加 Quartz Job 任务 保存 QRTZ_JOB_DETAILS、QRTZ_TRIGGERS = QRTZ_CRON_TRIGGERS 详见: org.quartz.impl.jdbcjobstore.StdJD

    2023年04月18日
    浏览(22)
  • SpringBoot使用Redis实现分布式缓存

    ✅作者简介:2022年 博客新星 第八 。热爱国学的Java后端开发者,修心和技术同步精进。 🍎个人主页:Java Fans的博客 🍊个人信条:不迁怒,不贰过。小知识,大智慧。 💞当前专栏:SpringBoot 框架从入门到精通 ✨特色专栏:国学周更-心性养成之路 🥭本文内容:SpringBoot使用

    2023年04月09日
    浏览(26)
  • SpringBoot使用Redis作为缓存器缓存数据的操作步骤以及避坑方案

    2.1使用之前要明确使用的业务场景 例如我们在登录时,可以让redis缓存验证码,又如在分类下显示菜品数据时,我们可以对分类和菜品进行缓存数据等等。 2.2导入Redis相关依赖 2.3在使用的controller层导入RedisTemplate 例如: 说明一下:这里为什么使用@Resource注解而不使用@Autowi

    2024年02月16日
    浏览(33)
  • mysql使用redis+canal实现缓存一致性

    目录 一、开启binlog日志 1.首先查看是否开启了binlog 2、开启binlog日志,并重启mysql服务 二、授权 canal 链接 MySQL 账号具有作为 MySQL slave 的权限 三、下载配置canal 1、下载 canal, 访问 release 页面 , 选择需要的包下载, 如以 1.0.17 版本为例 2、 修改confexample文件夹下instance.propert

    2024年02月13日
    浏览(31)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包