クエリのパフォーマンスを最適化するために、春Ehcacheの二次キャッシュを使用します

最近の時間でシステムを最適化したためにその一部のクエリが遅いクエリの効率、時間のかかる長いです、

これは、消費性能のデータベースクエリ、クエリのRedisを消費し、圧力を測定してい

データベース:接続プールは限られており、単一のクエリは、IOの多くを取って、接続プールを大量に消費することはできませんが、それ以外の場合はアクセスを防止し、異常なIO接続プールと異常な圧力の全体のアプリケーションとデータベース関連のパフォーマンスが発生します

Redisの:reidisクエリの多くは、異常が発生し、IO遅いクエリ、Redisの混雑、Redisのクラッシュやその他の問題をRedisのためにつながることができますキャッシュをアクセスする場合は、シングルスレッドです。

注: 以下の図に関連した変換は、データのより少ない頻度の変更に適している、しかし、関連インフラの多くは、頻繁にデータをアクセスされます、

以下のような  データの一貫性と高いのデータ遅延のためのデータの高ダイナミックな要件に適していない画像、広告、基本的なデータ、構成データ、データディクショナリやその他の関連データ、

 図は、最適化前のコールの模式図です。

最適化の概略図

Redisのは、キャッシュが配布され、別のキーに応じてIO性能を消費する必要があり、高い発電事業環境の場合は、サーバーの帯域幅はIOある特定のコンテンツにデータを照会し、しかし、その分散型の、ネットワークへのアクセスを必要とすることができますテスト

Ehcacheのキャッシュメモリとして使用する、優先アクセス・メモリ・キャッシュ、ケースが存在しない場合、優先されますRedisのキャッシュデータキャッシュにehcacheにEhcacheのライフサイクルを構成することによってのみ、各アプリケーションは、自動的かつ定期的に達成するために、パフォーマンスを向上させるためにキャッシュをきれいにの

整流のビジネス、整流プロセス、キャッシュデータ構造のRedisを測定したとき圧力をもたらす、フォームHSETを用いRedisの元のデータ構造に変更を加えながらEhcacheの、Redisのを使用して、最適化され、濃縮KEY異常のRedisもたらす同じサーバは、取得したので、この設定されたフォームに、キーRedisの分散処理は、もはや、同じキー上に集光されないようにするように、より改善された性能

 

そんなにナンセンス、導入のアクセスにehcacheにその焦点を指示

主に基本的なデータアクセスのための変換、

1:ehcache.xmlのためのリソース構成ファイルの増加

<?xml version="1.0" encoding="UTF-8"?>
<ehcache>
    <!-- 磁盘缓存位置 -->
    <diskStore path="java.io.tmpdir/ehcache"/>
    <!-- 默认缓存 -->
    <defaultCache
            maxEntriesLocalHeap="10000"
            eternal="false"
            timeToIdleSeconds="120"
            timeToLiveSeconds="120"
            maxEntriesLocalDisk="10000000"
            diskExpiryThreadIntervalSeconds="120"
            memoryStoreEvictionPolicy="LRU"/>
    <cache name="configInfo"
           maxElementsInMemory="50000"
           eternal="false"
           timeToIdleSeconds="30"
           timeToLiveSeconds="30"
           overflowToDisk="false"
           memoryStoreEvictionPolicy="LRU"/>
</ehcache>

 ehcache的相关配置参数:

diskStore    :指定数据存储位置,可指定磁盘中的文件夹位置
defaultCache :默认的管理策略
以下属性是必须的:
name  :Cache的名称,必须是唯一的(ehcache会把这个cache放到HashMap里).maxElementsInMemory:在内存中缓存的element的最大数目.
maxElementsOnDisk:在磁盘上缓存的element的最大数目,默认值为0,表示不限制.
eternal:设定缓存的elements是否永远不过期.如果为true,则缓存的数据始终有效,如果为false那么还要根据timeToIdleSeconds,timeToLiveSeconds判断.
overflowToDisk:如果内存中数据超过内存限制,是否要缓存到磁盘上.
以下属性是可选的:
timeToIdleSeconds:对象空闲时间,指对象在多长时间没有被访问就会失效.只对eternal为false的有效.默认值0,表示一直可以访问.
timeToLiveSeconds:对象存活时间,指对象从创建到失效所需要的时间.只对eternal为false的有效.默认值0,表示一直可以访问.
diskPersistent:是否在磁盘上持久化.指重启jvm后,数据是否有效.默认为false.
diskExpiryThreadIntervalSeconds:对象检测线程运行时间间隔.标识对象状态的线程多长时间运行一次.
diskSpoolBufferSizeMB: DiskStore使用的磁盘大小,默认值30MB.每个cache使用各自的DiskStore.
memoryStoreEvictionPolicy:如果内存中数据超过内存限制,向磁盘缓存时的策略.默认值LRU,可选FIFO、LFU.
缓存的3种清空策略:
FIFO ,first in first out(先进先出).
LFU  , Less Frequently Used(最少使用),意思是一直以来最少被使用的.缓存的元素有一个HIT属性,HIT值最小的将会被清出缓存.
LRU  ,Least Recently Used(最近最少使用)(EHCACHE 默认值).缓存的元素有一个时间戳,当缓存容量满了,而又需要腾出地方来缓存新的元素的时候,
那么现有缓存元素中时间戳离当前时间最远的元素将被清出缓存.

注意:
timeToIdleSeconds:

指对象在多长时间没有被访问就会失效.只对eternal为false的有效.默认值0,表示一直可以访问,如果配置了timeToIdleSeconds不为0,且timeToLiveSeconds也不为0,则在这个timeToIdleSeconds时间内没有被访问,也同时会过期释放
timeToLiveSeconds:
指对象从创建到失效所需要的时间.只对eternal为false的有效.默认值0,表示一直可以访问.
如果仅仅配置timeToLiveSeconds,而timeToIdleSeconds配置为0,则表示缓存一直活跃,但是到了这个周期,则自动失效

举例:
timeToIdleSeconds 20 ,timeToLiveSeconds 30 说明:在20秒内,如果没有被访问,则自动过期,如果一直有被访问,在30秒内,依然过期.
timeToIdleSeconds 0 ,timeToLiveSeconds 30 说明:无论有没有被访问,在30秒内,自动过期.

 

 2:在建一个spring-ehcache.xml,  并引用到applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:cache="http://www.springframework.org/schema/cache"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation=" http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context-3.0.xsd
       http://www.springframework.org/schema/cache
       http://www.springframework.org/schema/cache/spring-cache-3.1.xsd">

    <!-- 自动扫描注解的bean -->
    <context:component-scan base-package="com.beijing.cache" />
    <!-- 注册EhCache注解驱动,使spring能识别EhCache的注解 -->
    <cache:annotation-driven cache-manager="cacheManager" />
    <!-- 注册EhCache缓存管理器 -->
    <bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager">
        <property name="cacheManager" ref="ehcache"/>
    </bean>
    <!-- 构建EhCache的缓存管理工厂 -->
    <bean id="ehcache" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
        <property name="configLocation" value="classpath:conf/ehcache.xml"/>
    </bean>
</beans>

3:配置注解,构建需要对缓存的方法(以下代码只是示例) 

    @Cacheable(value = "configInfo") 
    public String queryNameByParam(String typeName,String param){ 
        String name = null;
        if(StringUtils.isBlank(typeName) || StringUtils.isBlank(param)){
            return null;
        }
        String key = getRedisKey(typeName,param);//先查询redis缓存,如果redis缓存存在,则使用redis缓存
        name = redisClient.get(key);
        if(StringUtils.isBlank(name)){
            User user = getUserInfo(typeName,param);//查询数据库,查询配置
            if(null!=user && StringUtils.isNotBlank(user.getName())){
                name = user.getName();
                redisBean.set(key,name,60*60*24);//存储到redis中
            }
        }
        return name;
    }

 

关键字 :

@Cacheable(value = "config") ,configInfo必须要与ehcache中的配置要一致,否则会抛出异常等情况

Spring 使用@Cacheable添加缓存是基于面向切面的思想做的, 实际上就是使用Java动态代理,创建实例的时候注入的是代理对象,在代理对象里调用实际的对象,这样就可以在实际的方法执行前,处理一下缓存的逻辑:没有找到缓存就往下执行,执行完把结果加入到缓存中;找到缓存则直接返回缓存的结果,不调用执行实际的方法。

关于Ehcache注解不生效的坑

一个方法A调同一个类里的另一个有缓存注解的方法B,这样是不走缓存的。

使用@Cacheable添加缓存实际上就是使用动态代理做的,在代理的方法前后做缓存的相应处理。单独的去调方法B是有缓存的,但是如果调方法A,A里面再去调B方法,哪怕B方法配置了缓存,也是不会生效的。

解决方法:
 a、不使用注解的方式,直接取 Ehcache 的 CacheManger 对象,把需要缓存的数据放到里面,类似于使用 Map,缓存的逻辑自己控制
 b、把方法A和方法B放到两个不同的类里面,例如:如果两个方法都在service接口里,把方法B放到另一个service里面,这样A方法里调B方法,就可以使用B方法的缓存

 

 4:按照以上方式,那么基本就完成了EHCACHE的基本配置了,EHCACHE就能缓存,可以通过debug的方式进行测试或者加入日志的方式进行测试

 

おすすめ

転載: www.cnblogs.com/lewisat/p/11202714.html