`

Redis的事务机制实现定时类工具任务的高可用

阅读更多

        系统中目前有些工具包含了一些定时任务,但是为了保证工具不出现单点故障,在部署多台服务器时,会只在一台服务器上开启定时任务,其他服务器关闭,但是在版本迭代部署过程中,因为配置文件的差异导致容易出现问题,一不小心就导致多台服务器同时开启了定时任务,或者多台服务器都没执行异步任务,说到底,还是因为工具无法做到完全一致。

       说到底,还是因为没有一个机制保证一模一样的工具,无法实现定时类任务只在一台服务器运行。

       后来经过思考,可以借鉴Redis的事物和Watch机制来实现,逻辑很简单:

       1)所有服务器配置一样,每台服务器都可以定时启动任务

       2)但是在任务启动的开始,判断是否已经有当前执行时间点的信息存储至Redis的Set里面去

             比如,任务执行时间串为: 0 */1 * * *  (cron4j)

             那么到了整点的时候,先判断 set中是否存在 yyyyMMddHH

             如果存在,则表示其他实例已经抢先运行了

             否则,使用watch、multi命令来往redis的set中插入数据,

             哪个插入成功,则该实例可以执行具体的任务了,

             插入失败则不执行。

       看代码:

/**
	 * 设置信号量(用于决定当前工具实例是否有资格去执行任务)
	 * @param taskName
	 * @return
	 * @throws Exception 
	 */
	public boolean setRedisSemaphore(){
		try {
			//1、先判断信号量是否存在(信号量的值以  quartz:{taskName}  yyyyMMdd 或者 yyyyMMddHH (由任务对应的执行周期决定) 的形式存储)
			String key = "quartz:" + taskName;
			String format = getFormat();
			if(StringUtils.isBlank(format)){
				return true;
			}else{
				SimpleDateFormat sdf = new SimpleDateFormat(format);
				String value = sdf.format(new Date());
				if(redisService.sismember(RedisName_Biz, key, value)){
					return false;
				}else{
					boolean keyExists = redisService.exists(RedisName_Biz, key);
					//2、如果存在则返回,否则设置信号量,设置成功就继续处理,设置失败,本次任务结束
					Jedis jedis = redisService.getJedisByKey(RedisName_Biz);
					Pipeline p = jedis.pipelined();
					p.watch(key);
					p.multi();
					p.sadd(key, value);
					p.exec();
					List<Object> list = p.syncAndReturnAll();
					String result = list.get(list.size() - 1).toString();
						
					if(!keyExists){
						redisService.expire(RedisName_Biz, key, 7 * 24 * 60 * 60);
					}
						
					redisService.returnJedisByKey(RedisName_Biz, jedis);
						
					return result.equals("[1]");
				}
			}
		} catch (Exception e) {
			logger.info(String.format("任务【%s】设置信号量出现异常:", this.taskName) + e);
		}
		return false;
	}

        

       虽然我们开发了一个工具框架集成了这个机制,但是目前这个方式只能实现工具多实例同时运行的高可用机制,无法保证针对一批数据有多个实例同时去处理(队列性质的除外,因为队列性质的数据源不需要这个机制来保障)。

       之前项目组使用过淘宝的开源框架TBSchedule,但是上线后遇到了各种各样的问题,还导致过现网故障,而由于TbSchedule设计的太过完美,功能比较丰富、复杂,在解决问题的过程中也遇到了不少麻烦,后来干脆直接把TbSchedule给抛弃了。 不过它的思路是非常优秀的,使用分配任务项的方式来决定实例需要处理哪些处理,而且不会造成数据的重复处理,同时增加实例、减少实例,都会及时的进行数据重新分配。

后续会继续研究下它的思路来时间一个精简版的高可用工具框架。

       附:淘宝开源框架有兴趣的话见如下地址:

              http://code.taobao.org/p/tbschedule/wiki/index/

分享到:
评论

相关推荐

    聊聊高并发高可用那些事(Kafka、Redis、MySQL)

    7. **Redis事务**:使用`MULTI`、`EXEC`确保原子性。 8. **双写一致性**:Redis与MySQL之间的数据同步需要考虑一致性问题。 9. **集群模式**:Sentinel监控和自动故障恢复,Cluster实现数据分片。 10. **键槽与槽...

    redis-连接工具-【服务端客户端】

    4. 主从复制:为了实现高可用性,Redis支持主从复制,通过配置从服务器连接到主服务器,同步数据。在主服务器故障时,可以从服务器接管服务。 二、Redis 客户端 1. redis-cli:这是Redis自带的命令行客户端,通过...

    Redis.rar redis管理工具

    Redis是一款开源、高性能的键值对数据存储系统,常用于数据缓存、消息队列以及数据库功能。这个“Redis.rar”压缩包很可能包含了用于管理和操作Redis服务器的各种工具和资源。 Redis的核心特性包括: 1. **数据...

    redisStudy.zip

    基本回答:Rediscluster是一个高可用集群,它基于分片(对key进行crc16,然后对16384取余)的原理,可以把他理解为是由多组哨兵集群组成,但是它不依赖哨兵 6.缓存穿透 缓存穿透指的是使用不存在的key进行大量的...

    redis学习笔记+练习springboot-redisdemo

    Redis是一款高性能的键值对数据库,常用于缓存、消息队列、计数器等多种场景。本资源包包含了关于Redis的学习笔记以及一个基于SpringBoot整合Redis的实战项目——"springboot-redisdemo",旨在帮助你深入理解和应用...

    Redis实现分析

    Redis基于2.8.7版本的架构设计包括单线程模型、内存管理、哈希字典、ServerCron、阻塞操作、事务实现、数据持久化方式(RDB和AOF)以及复制机制。 #### 单线程模型的实现(AE) Redis采用单线程模型来处理命令请求...

    redis-6.2.5-x64-windows.zip

    Redis是一款高性能的键值存储系统,它被广泛用于数据库、缓存和消息中间件等领域。这个压缩包"redis-6.2.5-x64-windows.zip"提供了适用于...通过正确配置和优化,可以在Windows服务器上实现高可用、高性能的Redis服务。

    60道关于Redis的常见面试题.pdf

    - **定义**:Sentinel 是 Redis 的高可用方案之一,主要用于监控主服务器的状态、在主服务器故障时自动转移从服务器为新的主服务器,并通知客户端。 - **配置和使用**: - 在`sentinel.conf`配置文件中指定监控的主...

    Redis资料.zip

    主从复制是Redis高可用的一种常见方式,通过复制主节点的数据到多个从节点,实现读写分离和数据备份。故障时,可以快速切换主从角色。 五、哨兵(Sentinel)系统 哨兵系统是Redis的高可用解决方案,负责监控主从节点...

    redis面试题及答案

    答:主从复制是Redis的高可用性方案之一。从服务器定期与主服务器同步数据,当主服务器故障时,可以切换到从服务器继续服务。Redis 6.0引入了半同步复制和多线程复制,提高了复制性能。 **面试题7:Redis集群如何...

    redis缓存服务器

    - Redis Cluster 提供了数据分区和高可用性,支持多个节点间的自动数据迁移。 9. **限流与锁(Keyspace Notifications, Redis Locks)**: - 可用于实现限流策略,避免资源过度消耗。 - 使用 SETNX 或 REDIS-...

    redis-windows-7.0.6.zip

    七、Redis事务 Redis支持简单的事务,可以一次执行多个命令,保证原子性。 八、Redis Cluster Redis Cluster是Redis的分布式解决方案,通过哈希槽划分数据,实现数据在多节点间的自动分布和故障转移。 九、Redis...

    Redis面试知识点.pdf

    Redis集群是一种分布式的部署方案,通过分区(sharding)和复制(replication)机制实现数据的水平扩展和高可用性。每个节点负责一部分数据,客户端请求会被重定向到正确的节点。集群中的节点间通过Gossip协议维护元...

    redis数据库,解压安装

    - 高可用方案:主从复制是构建高可用Redis集群的基础,配合哨兵(Sentinel)系统可以实现故障自动切换。 6. 发布/订阅: - Redis的发布/订阅功能允许客户端订阅特定频道,当有消息发布到这些频道时,订阅者会接收到...

    redis_2021.zip

    Redis是一款高性能的键值对数据库,常用于数据缓存、消息队列以及数据持久化等场景。"redis_2021.zip" 是一个包含了 Redis 集成环境的压缩包,特别适合在Windows系统上快速搭建Redis服务。无需复杂的安装步骤,只需...

    redis相关学习文档

    5. **Redis事务**: Redis的事务支持多条命令的原子执行,通过`MULTI`、`EXEC`命令包裹来实现。 6. **发布/订阅(Pub/Sub)**: Redis提供发布订阅模式,允许客户端订阅感兴趣的主题,当有其他客户端发布消息到该...

    redis-5.0.7.tar.gz & redis-desktop-manager-0.8.8.384.exe

    Redis 是一个高性能的键值数据库,常用于存储缓存、会话管理以及分布式消息队列等场景。在提供的文件中,我们有两个与 Redis 相关的组件:`redis-5.0.7.tar.gz` 和 `redis-desktop-manager-0.8.8.384.exe`。 `redis...

    Redis,快看看这40道面试题.pdf

    - Redis支持主从复制和哨兵模式,主从复制实现数据备份和读写分离,哨兵模式用于高可用性和故障转移。 15. **Pipeline的好处** - **减少网络往返时间**:通过将多个命令打包成一个请求发送,减少了网络往返次数。...

    redis 安装包 + 教程

    当需要处理大量数据或高可用性时,可以搭建 Redis 集群。集群支持数据分片,自动故障转移,但需要额外的配置和管理。 以上就是 Redis 的安装和基本使用教程。通过这个过程,您应该能够顺利地在您的系统上运行 ...

    redis延时队列.zip

    同时,为了保证高可用性和一致性,生产者可能还会使用Redis事务或者lua脚本来确保操作的原子性。 而DelayDataConsumer.java则扮演着消费者的角色,它的职责是不断地检查是否有到期的任务需要处理。这通常是通过执行...

Global site tag (gtag.js) - Google Analytics