多实例下获取Redis分布式锁完成多库并发的定时任务

本文提出了在SpringCloud环境中,利用Redis分布式锁解决多实例多库并发执行定时任务的问题。详细介绍了两种方案:一是不支持Redis集群的解决方案,包括数据库轮询、Redis分布式锁的实现以及SpringBoot的多线程处理;二是支持Redis集群的解决方案,指出在集群环境下需使用原生Redis连接执行Lua脚本。通过这些方法,确保了每个数据库有且仅有一个线程运行任务,避免数据冲突和资源浪费。
摘要由CSDN通过智能技术生成

本篇旨在提供SpringCloud下多实例多库跑定时任务的优化方案

业务场景:

有这样一个需求,需要跑大数据下的定时任务,主要是查表和写表操作,量很大,要支持续跑,并且每个库的数据不一致,所以需要轮询库,假如生产有4台实例,一共有8个库,为了减小服务器的压力,并且能够同时跑8个库的任务。

需要解决几个问题:

1.确保每个库,有且只能有1个线程在跑,如果其他线程也跑了这个库,就会导致数据插入重复,浪费资源。

2.确保每个实例都能够有线程在运行定时任务,让资源充分利用。

3.如果某个任务出现问题,希望可以重跑或者有所记录。

 

方案一(不支持Redis集群下的解决方案):

实现细节:

1.如何轮询生产数据库?

这个就直接在配置文件配置8个库连接,然后根据你传入的库名,来实现切库操作,这个我就不贴代码了。

 

2.如何用Redis实现分布式锁,在网上找到一个不错的方式:

/**
 * @Author: Markful
 * @Description:
 * 1.互斥性。在任意时刻,只有一个客户端能持有锁。
 * 2.不会发生死锁。即使有一个客户端在持有锁的期间崩溃而没有主动解锁,也能保证后续其他客户端能加锁。
 * 3.具有容错性。只要大部分的Redis节点正常运行,客户端就可以加锁和解锁。
 * 4.解铃还须系铃人。加锁和解锁必须是同一个客户端,客户端自己不能把别人加的锁给解了。
 *
 * @Version 1.0
 */
public class RedisTool {

    private static final Long RELEASE_SUCCESS = 1L;

    private static final String LOCK_SUCCESS = "OK";
    private static final String SET_IF_NOT_EXIST = "NX";
    private static final String SET_WITH_EXPIRE_TIME = "EX";


    /**
     * 尝试获取分布式锁
     * @param jedis Redis客户端
     * @param lockKey 锁
     * @param requestId 请求标识
     * @param expireTime 超期时间
     * @return 是否获取成功
     */
    public static boolean tryGetDistributedLock(Jedis jedis,String lockKey, String requestId, int expireTime){

        String result = jedis.set(lockKey,requestId,SET_IF_NOT_EXIST,SET_WITH_EXPIRE_TIME,expireTime);
        if(LOCK_SUCCESS.equals(re
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值