Site Overlay

Redis同步mysql实现解决方案

需求

redis中数据同步到mysql中数据,如果在更新途中redis又更新了,按照Redis中最新的数据进行更新。

实现思路:存储redis数据用RedisTemplate.opsForValue进行数据存储,在数据发生改变的时候,优先向redis中更新数据,然后先一个set集合中add新的数据的key值。业务端的操作就结束了,接下来通过一个专门的定时任务服务,通过设置@Scheduled(fixedDelay = 500)设置一个任务专门从上面的存放key值的set中pop出key值,然后从redis中查询出来,再通过这个key值更新到对应的mysql数据库中,这个任务从启动就开始执行,执行结束后等待fixedDelay后设置的毫秒时间,又接着执行下一次该任务。以此往复,就会将前台发送至set中的key对应的redis数据更新至mysql中,以实现数据同步。

实现代码:

/**
     * 更新Redis中User信息
     * @param userUid 用户uid
     * @param user  User对象
     */
    public void saveUser(int userUid,User user){
        try {
            redisLockUtil.lock("userLock-uid:" + userUid);
            log.info("userLock-uid: " + userUid + "上锁");
            String userData = JSONObject.toJSONString(user);
            redisTemplate.opsForValue().set("user-uid:" + userUid, userData, 7, TimeUnit.DAYS);
            redisTemplate.opsForSet().add("redis-update-queue", "user-uid:"+userUid);
            //向更新列表set中发送需要更新的数据的key
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        } finally {
            redisLockUtil.unlock("userLock-uid:" + userUid);
            log.info("userLock-uid: " + 10135 + "解锁");
        }
    }

在定时任务中还可以采用自定义线程池的方式手动设置线程数量等参数,以达到最优的更新mysql的效率。

@EnableAsync
@Configuration
@Slf4j
public class UserDataUpdateQueue {
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private UserDao userDao;

    @Async("taskExecutor")
    @Scheduled(fixedDelay = 500)
    public void getUserUpdateQueue() {
        log.info("------getUserUpdateQueue------");
        while (redisTemplate.opsForSet().size("xyddz-redis-update-queue") > 0) {
            List<Object> pop = redisTemplate.opsForSet().pop("xyddz-redis-update-queue", 10);
            for (Object userData : pop) {
                String userStr = (String) redisTemplate.opsForValue().get(userData.toString());
                if (!StringUtils.isEmpty(userStr)) {
                    User user = JSONObject.parseObject(userStr, User.class);
                    userDao.save(user);
                    log.info("更新User-Uid:" + user.getUid());
                }
            }
        }
    }
}

发表回复

您的电子邮箱地址不会被公开。

A beliving heart is your magic My heart
欢迎来到Diuut的个人博客,这里是我的一些零零碎碎的知识汇总,希望有能帮到你的内容。 | 蜀ICP备2021011635号-1 | Copyright © 2025 Diuut. All Rights Reserved.