>  기사  >  데이터 베이스  >  카페인_redis를 사용하여 두 번째 수준 캐시를 사용자 정의하는 방법

카페인_redis를 사용하여 두 번째 수준 캐시를 사용자 정의하는 방법

WBOY
WBOY앞으로
2023-05-27 10:08:241199검색

    Questions

    제기된 요구사항에 따르면 주로 다음 두 가지 문제가 있다고 생각합니다.

    • 로컬 캐시가 있기 때문에 데이터 일관성을 보장하는 방법. 한 노드의 데이터가 변경되면 어떻게 다른 노드의 데이터가 무효화되나요?

    • 데이터가 올바르지 않아 다시 동기화해야 합니다. 캐시를 무효화하는 방법은 무엇인가요?

    Flowchart

    다음 단계는 제품 및 다른 개발자와 협력하여 다음과 같은 순서도를 그리는 것입니다.

    • 구성 테이블을 사용하여 캐싱이 필요한지, 그리고 다음과 같은 알림을 받기 위해 캐싱이 활성화되어 있는지 기록합니다. 캐시 오류입니다.

    • 프로젝트 요구 사항은 평균 수준이므로 메시지가 손실되더라도 큰 영향을 미치지 않을 것이므로 결국 다른 노드에 잘못된 로컬 캐시를 알리기 위해 Redis의 구독 및 게시 기능을 선택했습니다.

    Development

    위의 질문도 명확하고, 흐름도도 명확합니다. 그런 다음 버그 작성을 시작할 준비를 하세요. 전반적인 아이디어는 주석 구현 측면을 사용자 정의하고 비즈니스 코드와의 결합을 줄이는 것입니다.

    CacheConfig

    는 비즈니스와 통합할 CacheManager를 정의하는 코드로 주로 설명됩니다. 프로그램 메모리를 너무 많이 점유하여 메모리가 가득 차는 것을 방지하려면 캐시 가능한 최대 항목 수에 특별한 주의를 기울여야 합니다. 물론 적중률 문제도 고려해야 하기 때문에 너무 작을 수는 없다. 따라서 최종 규모는 실제 사업을 토대로 결정되어야 한다.

    @Bean(name = JKDDCX)
    @Primary
    public CacheManager cacheManager() {
         CaffeineCacheManager cacheManager  = new CaffeineCacheManager();
            cacheManager.setCaffeine(Caffeine.newBuilder()
                    // 设置最后一次写入或访问后经过固定时间过期
                    .expireAfterAccess(EXPIRE, TIME_UNIT)
                    //设置本地缓存写入后过期时间
                    .expireAfterWrite(EXPIRE, TIME_UNIT)
                    // 初始的缓存空间大小
                    .initialCapacity(500)
                    // 缓存的最大条数
                    .maximumSize(1000));// 使用人数 * 5 (每个人不同的入参 5 条)\
      return cacheManager;
    }

    @CaffeineCache

    맞춤 주석, 사용 가능한 모든 매개변수를 추가하세요.

    @Target({ ElementType.METHOD ,ElementType.TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface CaffeineCache {
    
         public String moudleId() default "";
        
         //用于在数据库中配置参数
         public String methodId() default "";
         public String cachaName() default "";
        
         //动态切换实际的 CacheManager
         public String cacheManager() default "";
    
    }

    CacheMessageListener

    캐시 리스너는 주로 다중 노드 데이터의 일관성을 보장하는 역할을 담당합니다. 노드 캐시가 업데이트되면 이에 따라 이를 처리하도록 다른 노드에 알림이 전달됩니다. Redis의 게시 및 구독 기능을 사용하고 MessageListener 인터페이스를 구현하여 주요 기술을 구현합니다.

    물론 아래의 또 다른 세부 사항은 일반 프로덕션 환경에서는 Redis#keys 명령이 비활성화되어 있으므로 해당 키를 다른 방법으로 스캔해야 한다는 것입니다.

    public class CacheMessageListener implements MessageListener {
         @Override
        public void onMessage(Message message, byte[] pattern) {
            CacheMessage cacheMessage = (CacheMessage) redisTemplate.getValueSerializer().deserialize(message.getBody());
            logger.info("收到redis清除缓存消息, 开始清除本地缓存, the cacheName is {}, the key is {}", cacheMessage.getCacheName(), cacheMessage.getKey());
    //		redisCaffeineCacheManager.clearLocal(cacheMessage.getCacheName(), cacheMessage.getKey());
    
            /**
             * 如果是一个类上使用了 注解 @CaffeineCache ,那么所有接口都会缓存。
             * 下面的逻辑是:除了当前模块的接口访问的入参 key,其他的 redis 缓存都会被清除
             * (比如此模块的表更新了,但是当前调用此接口只是缓存了当前这个入参的redis,其他的数据删除)
             */
            String prefixKey = RedisConstant.WXYMG_DATA_CACHE + cacheMessage.getCacheName();
            Set<String> keys = redisTemplate.execute((RedisCallback<Set<String>>) connection -> {
                Set<String> keysTmp = new HashSet<>();
                Cursor<byte[]> cursor = connection.scan(new ScanOptions.ScanOptionsBuilder().
                        match(prefixKey + "*").
                        count(50).build());
                while (cursor.hasNext()) {
                    keysTmp.add(new String(cursor.next()));
                }
                return keysTmp;
            });
            Iterator iterator = keys.iterator();
            while (iterator.hasNext()) {
                if (iterator.next().toString().equals(cacheMessage.getKey())) {
                    iterator.remove();
                }
            }
            redisTemplate.delete(keys);
    
            cacheConfig.cacheManager().getCache(cacheMessage.getCacheName()).clear(); //cacheName 下的都删除
        }
    }

    CaffeineCacheAspect

    그런 다음 측면의 논리적 처리가 있습니다. 내부 내용은 순서도와 정확히 동일하지만 코드는 요구 사항을 구현하는 데 사용됩니다.

    그 중: 다음 코드는 Redis 게시 메시지입니다.

    redisTemplate.convertAndSend(CacheConfig.TOPIC, new CacheMessage(caffeineCache.cachaName(), redisKey));

    CacheMessage

    Redis가 메시지를 게시할 때의 메시지 본문입니다. 또한 사용자 정의되었으며 더 많은 매개변수 속성을 추가할 수 있습니다.

    public class CacheMessage implements Serializable {
    
    	private static final long serialVersionUID = -1L;
    
    	private String cacheName;
    
    	private Object key;
    
    	public CacheMessage(String cacheName, Object key) {
    		super();
    		this.cacheName = cacheName;
    		this.key = key;
    	}
    
    }

    위 내용은 카페인_redis를 사용하여 두 번째 수준 캐시를 사용자 정의하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

    성명:
    이 기사는 yisu.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제