reids定时异常

1、最近业务总是报redis异常,而且总是凌晨1点左右


16/07/18 01:02:30 ERROR ShardedDaoImpl: sharded redis lrange:
redis.clients.jedis.exceptions.JedisConnectionException: java.net.ConnectException: Connection timed out
	at redis.clients.jedis.Connection.connect(Connection.java:148)
	at redis.clients.jedis.BinaryClient.connect(BinaryClient.java:75)
	at redis.clients.jedis.Connection.sendCommand(Connection.java:77)
	at redis.clients.jedis.BinaryClient.lrange(BinaryClient.java:293)
	at redis.clients.jedis.Client.lrange(Client.java:214)
	at redis.clients.jedis.Jedis.lrange(Jedis.java:995)
	at redis.clients.jedis.ShardedJedis.lrange(ShardedJedis.java:291)





2、redis监控,显示有问题,于是怀疑是网络问题,于是添加网络监控



,网络都是通的,但是redis端口不通,于是找到运维,结果运维兄弟说做了定期持久化,而且用了save方式,因为save是阻塞的,于是让他们改成bgsave方式





### 使用 Redis 实现定时任务的方案 Redis 本身并未直接提供定时任务的功能,但可以通过其数据结构和操作特性,结合业务逻辑实现分布式定时任务的调度。以下是几种常见的实现方式。 #### 1. 利用 Redis 的有序集合(Sorted Set)实现任务队列 Redis 的 ZADD 命令可以将任务按时间戳作为 score 插入有序集合,定时轮询该集合,取出已到达执行时间的任务进行处理。这种方式适用于任务执行时间明确且需要持久化的场景。 ```java // 示例:添加任务到 Redis 有序集合 jedis.zadd("delayed_queue", System.currentTimeMillis() + 60000, "task_1"); ``` 定时线程定期查询当前时间戳对应的任务并执行: ```java Set<String> tasks = jedis.zrangeByScore("delayed_queue", 0, System.currentTimeMillis(), 0, 1); if (!tasks.isEmpty()) { String task = tasks.iterator().next(); // 执行任务逻辑 // ... // 执行完成后删除任务 jedis.zrem("delayed_queue", task); } ``` 这种方式适用于任务数量不大且执行频率较低的场景,能够有效控制任务调度的粒度[^1]。 #### 2. 结合 Redis 锁实现分布式定时任务 在分布式系统中,多个服务实例可能同时尝试执行同一个定时任务,因此需要引入分布式锁机制来保证任务只被一个实例执行。通过 Redis 的 SETNX(SET if Not eXists)命令或 Lua 脚本实现加锁,确保任务在多个节点中只被调度一次。 ```java // 获取锁 public boolean getLock(String key, long expireTime) { Long result = jedis.setnx(key, "locked"); if (result == 1) { jedis.expire(key, (int) expireTime); return true; } return false; } // 释放锁 public void delLock(String key) { jedis.del(key); } ``` 在定时任务中使用锁的示例如下: ```java @Scheduled(cron = "0/5 * * * * *") public void start() { try { Boolean lock = redisLockUtils.getLock("test", 3000); if (lock) { log.info("任务启动了!当前时间 [{}]", LocalDateTime.now()); Thread.sleep(1000); } else { log.error("获取锁失败,其他服务正在执行任务"); } } catch (Exception e) { log.info("获取锁异常"); } finally { redisLockUtils.delLock("test"); } } ``` 该方式适用于多节点部署场景,能够有效避免任务重复执行的问题[^1]。 #### 3. 使用 Redis + 消息队列实现延迟任务 结合 Redis 的过期键通知机制与消息队列(如 Kafka、RabbitMQ),可以实现延迟任务调度。将任务写入 Redis 并设置过期时间,当键过期时触发通知,由消费者监听并执行任务。 启用 Redis 的键空间通知功能: ```bash redis-cli config set notify-keyspace-events Ex ``` 监听过期事件: ```python import redis r = redis.Redis() p = r.pubsub() p.psubscribe('__keyevent@0__:expired') for message in p.listen(): print(f"Expired key: {message['channel'].decode()}") ``` 这种方式适用于对延迟精度要求较高的场景,结合消息队列可以实现高并发下的任务调度与执行。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值