IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> SpringBoot整合Lua脚本,实现对Redis的原子操作 -> 正文阅读

[Java知识库]SpringBoot整合Lua脚本,实现对Redis的原子操作

前言

最近笔者在鱼皮的网站面试鸭上看到了这么一道题目:怎么实现一个点赞功能?

相信各位读者第一时间应该都是能够想到使用redis来实现这一个功能的,因为对于点赞这一种高频的操作,肯定是不能够直接去访问数据库的,容易将整个数据库压垮,因此需要在用户与数据库之间增加一层缓存,当用户进行点赞操作时,首先会在redis上进行操作,然后再通过定时任务redis中的数据持久化到mysql中就可以实现点赞的功能。

但就在笔者自认为自己很机智的时候,突然被评论区的一位老哥打了脸,这位老哥给出的方案是通过 redis + lua 脚本来实现点赞的功能,笔者看到这个评论的一瞬间先是楞了几秒钟,紧接着就发出了没见过大世面的夺命三连问——lua是个什么东西?为什么需要使用它?我刚刚的方案不是已经很完美了吗?

带着疑问向度娘询问了下lua脚本后,笔者才恍然大悟,还是自己太年轻了。虽然redis默认是单线程,但对于多个key的操作,仍然有可能发生数据不一致的问题,而lua脚本就可以避免这一问题的发生,因为redis每次只能执行一个lua脚本,因此在lua脚本上的redis操作都被捆绑成了一个整体(原子),要么一起执行成功,要么一起执行失败。并且将多个redis的操作捆绑在一起还减少了多次网络请求传递的开销。总之就是一句话,lua脚本很香~!

接下来就由笔者为各位读者分享一下,如何在springboot中使用lua脚本实现一个简易的视频点赞功能。当然,使用lua脚本的前提,还需要各位读者对redis的基本命令以及lua的基本语法都有一定的了解,如果你不够熟悉,可以通过以下的链接先进行学习


1.导入依赖

因为redis默认支持lua脚本,所以我们如果要使用lua脚本,就无需再导入其他的包了,直接导入redis的依赖即可。

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

2.测试代码

执行lua脚本前,需要先实例化DefaultRedisScript对象,通过该对象来执行lua脚本。需要注意的是,在执行execute方法时,第一个参数是脚本的操作对象;第二个参数是redis的key集合,在lua脚本中可以通过KEYS[i]来获取,其中i从1开始数起;后面的所有参数都是value值,在lua脚本中可以通过ARGV[i]获取,同样的,i也是从1开始数起的。

@SpringBootTest
class LuaTestApplicationTests {
    @Autowired
    void setRedisTemplate(RedisTemplate redisTemplate) {
        LuaTestApplicationTests.redisTemplate = redisTemplate;
    }
    private static RedisTemplate redisTemplate;

    @Test
    void contextLoads() {
        // 实例化脚本对象
        DefaultRedisScript<Boolean> lua = new DefaultRedisScript<>();
        // 设置脚本的返回值
        lua.setResultType(Boolean.class);
        // 载入lua脚本
        lua.setLocation(new ClassPathResource("thumbs.lua"));
        // key的集合
        List<String> keys = Arrays.asList("user_set", "nums");
        // 执行lua脚本
        System.out.println(redisTemplate.execute(lua, keys, 1));
    }

    @Scheduled(cron = "0 0/10 * * * ? ")
    void toMysql() {
        // 同步到mysql的具体代码.....
    }
}

3.Lua脚本

这里简单解读一下这个脚本的逻辑:首先是通过KEYS[i]ARGV[i]分别接收传递过来的key值和value值,然后判断user_set集合中是否存在当前用户的user_id如果存在,则证明该用户曾对这一视频进行过点赞了,需要执行的是取消点赞的操作,因此需要将该用户的user_iduser_set集合中移除,并且将该视频的总点赞数nums减一;user_set集合中 如果不存在 该用户的user_id,则证明该用户还未对该视频点赞,因此需要将该用户的user_id存入到user_set集合中,并将该视频的总点赞数nums加一;

-- 用于存储点赞用户id的集合
local user_set = KEYS[1]
-- 记录该视频的点赞数
local nums = KEYS[2]
-- 当前执行点赞操作的用户id
local user_id = ARGV[1]

-- 判断set中是否存在此用户的id
if redis.call('sismember', user_set, user_id) == 1 then
    -- 该用户已经点过赞了,因此需要执行取消点赞的操作,总点赞数减一,并将该用户的id移除
    redis.call('srem', user_set, user_id)
    redis.call('decr', nums)
else
    -- 该用户还未点赞,总点赞数加一,并将该用户的id加入集合中
    redis.call('sadd', user_set, user_id)
    redis.call('incr', nums)
end
return true;

这样一来,一个使用 sprinboot + redis + lua 实现的简易点赞功能就完成了~!!

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-05-10 11:43:27  更:2022-05-10 11:46:00 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 22:55:29-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码