高效协作处理缓存清理需求:生产者-消费者模式助力多模块缓存管理

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介: 在现代应用系统中,缓存是提高性能和减少数据库负载的重要手段之一。然而,缓存的数据在某些情况下可能会过期或者变得无效,因此需要及时进行清理。在复杂的应用系统中,可能有多个系统、多个模块产生缓存清理需求,而这些系统、模块之间的清理任务需要高效的协作,以避免数据竞争和资源浪费的问题。

在现代应用系统中,缓存是提高性能和减少数据库负载的重要手段之一。然而,缓存的数据在某些情况下可能会过期或者变得无效,因此需要及时进行清理。在复杂的应用系统中,可能有多个系统、多个模块产生缓存清理需求,而这些系统、模块之间的清理任务需要高效的协作,以避免数据竞争和资源浪费的问题。

本文将介绍一种高效处理多模块缓存清理需求的方案,通过使用Redis消息队列,采用生产者-消费者模式,实现了多个系统、多个模块的消息生产和消费任务的合理协作。在这个方案中,多个系统、多个模块可以同时生产清理缓存的消息,消费者定期获取并合并这些消息后,通过多线程进行缓存清理,从而达到高效处理的目的。

生产者-消费者模式

生产者-消费者模式是一种经典的多线程设计模式,用于解决多个生产者和消费者之间的协作问题。生产者负责生成数据,并将其放入共享缓冲区,而消费者则负责从缓冲区中取出数据并进行处理。这种模式的目标是确保生产者和消费者之间的有效沟通和数据交换,从而避免竞态条件和数据不一致问题。

方案介绍

-2023-06-29-2157.png

Redis是一种高性能的内存数据库,同时也是一个强大的消息中间件。Redis支持多种数据结构,包括List(列表)和Queue(队列),这些数据结构可以用于实现消息队列的功能。

在Redis中,多个系统、多个模块可以将清理缓存的消息作为生产者生产,并将这些消息添加到一个特定的Queue中。而缓存清理服务则定期从这个Queue中获取消息,进行合并后再多个消费者进行缓存清理操作。这种模式称为生产者-消费者模式,它实现了生产者和消费者的解耦,使得多个系统、多个模块之间可以独立进行消息的生产,由缓存清理服务统一多线程进行消息的消费,从而提高系统的灵活性和可维护性,使得业务系统于消息缓存系统之间不存在耦合关系。

第一步: 初始化Redis连接和消息队列

首先,需要在应用程序中初始化Redis连接,以便于生产者和消费者能够连接到Redis数据库。同时,创建一个消息队列,用于存储多个系统、多个模块产生的清理缓存的消息。

第二步: 系统或模块生产消息

每个模块可以根据自己的清理缓存需求,产生对应的清理缓存消息,并将消息添加到Redis的消息队列中。

MsgProduct

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Map;
import java.util.Set;

@Service
@Slf4j
public class MsgProduct {
   
   

    private static final String KEY= "xj_test_queue";
    @Resource
    private RedissonCache redissonCache;

    public boolean msgAdd(Map<String, Set<String>> params){
   
   
        //生产消息
        return redissonCache.cacheAdd(KEY,params);
    }
}

第三步: 消费者定期获取并合并消息,多线程缓存清理

消费者定期从Redis消息队列中获取缓存清理消息。获取到的消息可以按照namespace进行分类合并,以便后续多线程消费时能够分别处理不同模块的缓存清理任务。

MsgConsumer

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

@Service
@Slf4j
public class MsgConsumer {
   
   
    private static final String KEY= "xj_test_queue";
    @Resource
    private RedissonCache redissonCache;

    public void poll(){
   
   
        Map<String, Set<String>> params = new LinkedHashMap<>();
        Map<String, Set<String>> msgMap = redissonCache.cachePoll(KEY);
        int batchSize = 500;

        String namespace;
        Set<String> msgSet;
        Set<String> mergedSet;

        while (batchSize > 0 && !ObjectUtils.isEmpty(msgMap)) {
   
   
            // 合并消息
            for (Map.Entry<String, Set<String>> entry : msgMap.entrySet()) {
   
   
                namespace = entry.getKey();
                msgSet = entry.getValue();
                mergedSet = params.getOrDefault(namespace, new HashSet<>());
                mergedSet.addAll(msgSet);
                params.put(namespace, mergedSet);
            }
            batchSize--;
            msgMap = redissonCache.cachePoll(KEY);
        }

        // 创建线程池
        ThreadPoolExecutor executor = new ThreadPoolExecutor(
                10,
                15,
                60L,
                TimeUnit.MILLISECONDS,
                new ArrayBlockingQueue<>(10)
        );
        for (Map.Entry<String, Set<String>> entry : params.entrySet()) {
   
   
            executor.execute(()-> this.doFlush(entry.getKey(),entry.getValue()) );
        }

    }

    public void doFlush(String namespace,Set<String> provinces){
   
   
        try {
   
   
            //执行缓存清理逻辑
            log.info("清理缓存的接口编码为:{},省份编码为:{}",namespace,provinces);
        }catch (Exception e){
   
   
            //缓存清理失败处理逻辑
            log.error("清理缓存失败",e);
        }

    }

}

优势与收益

采用基于Redis消息队列的生产者-消费者模式,我们成功解决了多个模块缓存清理的高效协作问题。这种模式的优势在于:

  1. 提高性能与并发处理能力: 多线程并发消费消息,加速缓存清理任务的执行,提高系统的整体性能。

  2. 灵活扩展: 不同模块可以独立生产和消费消息,系统的可扩展性大大增强。

  3. 数据一致性: 通过合理的消息合并策略,保证缓存清理任务的数据一致性。

  4. 资源节约: 避免资源浪费和重复清理,提高系统的资源利用率。

结语

在复杂的应用系统中,多个系统、多个模块可能会同时产生缓存清理需求。基于Redis消息队列的生产者-消费者模式为这种场景提供了一种高效协作处理方案。通过生产者生产消息、消费者定期获取合并消息并进行多线程消费,系统可以高效处理缓存清理任务,保证数据的一致性和并发安全性。这种设计模式在当今大数据和高并发的背景下尤其重要,对于提升系统性能和稳定性具有积极意义。

目录
相关文章
|
缓存 Java
java开发常用模块——缓存模块
java开发常用模块——缓存模块
107 0
|
3月前
|
缓存 监控 Linux
Linux系统清理缓存(buff/cache)的有效方法。
总结而言,在大多数情形下你不必担心Linux中buffer与cache占用过多内存在影响到其他程序运行;因为当程序请求更多内存在没有足够可用资源时,Linux会自行调整其占有量。只有当你明确知道当前环境与需求并希望立即回收这部分资源给即将运行重负载任务之前才考虑上述方法去主动干预。
1505 10
|
11月前
|
存储 缓存 监控
Linux缓存管理:如何安全地清理系统缓存
在Linux系统中,内存管理至关重要。本文详细介绍了如何安全地清理系统缓存,特别是通过使用`/proc/sys/vm/drop_caches`接口。内容包括清理缓存的原因、步骤、注意事项和最佳实践,帮助你在必要时优化系统性能。
1118 78
|
缓存 Java Shell
Android 系统缓存扫描与清理方法分析
Android 系统缓存从原理探索到实现。
484 15
Android 系统缓存扫描与清理方法分析
|
存储 缓存 NoSQL
大数据-38 Redis 高并发下的分布式缓存 Redis简介 缓存场景 读写模式 旁路模式 穿透模式 缓存模式 基本概念等
大数据-38 Redis 高并发下的分布式缓存 Redis简介 缓存场景 读写模式 旁路模式 穿透模式 缓存模式 基本概念等
346 4
|
缓存 Python
在Python中,`functools`模块提供了一个非常有用的装饰器`lru_cache()`,它实现了最近最少使用(Least Recently Used, LRU)缓存策略。
在Python中,`functools`模块提供了一个非常有用的装饰器`lru_cache()`,它实现了最近最少使用(Least Recently Used, LRU)缓存策略。
236 10
|
SQL 缓存 监控
实时计算 Flink版产品使用问题之怎么手动清理缓存或废弃文件
实时计算Flink版作为一种强大的流处理和批处理统一的计算框架,广泛应用于各种需要实时数据处理和分析的场景。实时计算Flink版通常结合SQL接口、DataStream API、以及与上下游数据源和存储系统的丰富连接器,提供了一套全面的解决方案,以应对各种实时计算需求。其低延迟、高吞吐、容错性强的特点,使其成为众多企业和组织实时数据处理首选的技术平台。以下是实时计算Flink版的一些典型使用合集。
|
缓存 分布式计算 关系型数据库
数据管理DMS操作报错合集之当进行RDS实例的可用区迁移时,提示“缓存清理”是什么意思
数据管理DMS(Data Management Service)是阿里云提供的数据库管理和运维服务,它支持多种数据库类型,包括RDS、PolarDB、MongoDB等。在使用DMS进行数据库操作时,可能会遇到各种报错情况。以下是一些常见的DMS操作报错及其可能的原因与解决措施的合集。
264 3
|
缓存 NoSQL 中间件
【后端面经】【缓存】36|Redis 单线程:为什么 Redis 用单线程而 Memcached 用多线程?epoll、poll和select + Reactor模式
【5月更文挑战第19天】`epoll`、`poll`和`select`是Linux下多路复用IO的三种方式。`select`需要主动调用检查文件描述符,而`epoll`能实现回调,即使不调用`epoll_wait`也能处理就绪事件。`poll`与`select`类似,但支持更多文件描述符。面试时,重点讲解`epoll`的高效性和`Reactor`模式,该模式包括一个分发器和多个处理器,用于处理连接和读写事件。Redis采用单线程模型结合`epoll`的Reactor模式,确保高性能。在Redis 6.0后引入多线程,但基本原理保持不变。
207 2
|
canal 缓存 NoSQL
【后端面经】【缓存】33|缓存模式:缓存模式能不能解决缓存一致性问题?-03 Refresh Ahead + SingleFlight + 删除缓存 + 延迟双删
【5月更文挑战第11天】Refresh Ahead模式通过CDC异步刷新缓存,但面临缓存一致性问题,可借鉴Write Back策略解决。SingleFlight限制并发加载,减少数据库压力,适合热点数据。删除缓存模式在更新数据库后删除缓存,一致性问题源于读写线程冲突。延迟双删模式两次删除,理论上减少不一致,但可能降低缓存命中率。选用模式需权衡优劣,延迟双删在低并发下较优。装饰器模式可用于实现多种缓存模式,无侵入地增强现有缓存系统。
337 2