缓存机制 ehcache、redis

本文主要记录ehcache和redis实现缓存(redis版本号:5.0.3)java

1、ehcachemysql

  1.ehcache:用来管理Java中缓存的轻量级工具,其核心经过CacheManager使用,通常使用于单机版,能够部署集群,可是不推荐,通常使用redis或者其余框架来实现分布式缓存。redis

  2.缓存过时策略:FIFO(先进先出原则)、LRU(最近最少使用,即目前最久未被使用的优先淘汰)、LFU(最近不经常使用[算法相似于JVM中垃圾回收器的s0和s1区],在一段时间中使用次数最少)算法

  3.使用场景:通常用作一级缓存[单机版],redis作二级缓存[集群版]spring

  4.示列代码(给出核心部分)sql

2、redis(单机版)(如下给出核心代码,须要完整代码在GitHub上获取(连接在首页))数据库

   注意事项:1.在阿里云上购买的服务器,须要在阿里云的安全策略中开启redis的端口,默认是6379。bootstrap

        2.安装时须要将 bind 127.0.0.1 改为 bind 0.0.0.0表示外网访问。网上说注释掉 我用版本5.0.3 不行。缓存

        3.daemonize no 改为daemonize yes 表示后台开启。安全

          4.requirepass 123 表示设置访问密码。

       5.修改pidfile文件路径 pidfile /home/pro_install/redis/stand_alone/pid/redis_6379.pid

       6.修改log路径 logfile /home/pro_install/redis/stand_alone/log/redis.log   redis.log文件由redis本身创建

          7.修改缓存数据路径 dir /home/pro_install/redis/stand_alone/cache_data

       8.须要关闭防火墙。systemctl stop firewalld 表示临时关闭。

       9.启动、中止、重启 比较简单这里再也不赘述了。

     受权对象:0.0.0.0/0 表示任何ip均可以访问。

  

         

 

 

3、redis(主从复制)

   同步原理:

    1:当一个从数据库启动时,会向主数据库发送sync命令。

    2:主数据库接收到sync命令后会开始在后台保存快照(执行rdb操做),并将保存期间接收到的命令缓存起来。

    3:当快照完成后,redis会将快照文件和全部缓存的命令发送给从数据库。

    4:从数据库收到后,会载入快照文件并执行收到的缓存的命令。

            

    搭建:环境为阿里云服务器,搭建一主两备一哨兵,其中端口:6380为master、6385和6386为slave、26379为哨兵监控(因为投票选举策略,搭建哨兵的数量最好为奇数)。

    注意事项:1.在丛服务器中 masterauth + 主服务器的密码。

         2.redis3.2版本以前采用 slaveof 指向主服务器ip,在以后用 eplicaof 指向主机的ip和端口 。

         3.哨兵中sentinel monitor <master-name> <ip> <redis-port> <quorum> 便可,参数依次为: 哨兵名字,主服务器ip,主端口,投票选举数量(eg:2表示,作集群后当主服务宕机后须要几个哨兵选举丛服务器后才能竞选为主服务)。

                             4.其余配置项都比较简单,这里再也不赘述。
    

4、redis(集群版)  3主3从

  因为redis版本升级的问题,按照网上其余教程,可能安装不了,在这里记录下安装过,本文采用redis版本是目前最新的5.0.3。

  1.集群版先不要设置密码,否者在安装卡槽时会出错。

  2.安装ruby:yum install ruby

  3.安装gem:gem update --system 若是报错则按下面方式安装

        报错:gpg2 --keyserver hkp://pool.sks-keyservers.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDBInstalling RVM to /usr/local/rvm

           gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3(这个来源于某博客,忘记名字了,补充一下)

                          

               按照图示刷新配置 source /etc/profile.d/rvm.sh

  4.yum install rubygems 和 gem install redis

  以上是环境转变,下面搭建redis

      分别创建6个保存redis数据文件夹data和6个保存pid的文件夹,若是采用端口来区分的话,能够创建6个redis.config的文件

          

            

           

    修改redis_6390.conf

           

              开启集群  使用rdb或者aof看我的配置了

              建立集群:老版本用的是另外一个启动,在目前的redis中是移除了

             ./redis/src/redis-cli --cluster create 127.0.0.1:6390 127.0.0.1:6391 127.0.0.1:6392 127.0.0.1:6393 127.0.0.1:6394 127.0.0.1:6395 --cluster-replicas 1

             

           以上就搭建成功了。

  注意:若先设置了密码会报一下错误

       

 

 

 

======================================

1、缓存Map(ehcache)

 1 @Component
 2 public class EhcacheMap<K, V> {
 3 
 4     private Map<K, V> echcache = new ConcurrentHashMap<>();
 5     
 6     public void put(K key, V value) {
 7         echcache.put(key, value);
 8     }
 9     
10     public V get(K key) {
11         return echcache.get(key);
12     }
13     
14     public void remove(K key) {
15         echcache.remove(key);
16     }
17 }

ehcache.xml(ehcache)

<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd">

    <diskStore path="java.io.tmpdir/ehcache-rmi-4000" />

    <!-- 多台机器配置 rmiUrls=//192.168.8.32:400002/demoCache|//192.168.5.231:400003/demoCache -->
    <cacheManagerPeerProviderFactory
        class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"
        properties="peerDiscovery=manual,rmiUrls=//127.0.0.1:5000/userCache">
    </cacheManagerPeerProviderFactory>
    <!-- 配置 rmi 集群模式 -->
    <cacheManagerPeerListenerFactory
        class="net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory"
        properties="hostName=127.0.0.1,port=4000,socketTimeoutMillis=120000" />

    <!-- 多播方式配置 搜索某个网段上的缓存 timeToLive 0是限制在同一个服务器 1是限制在同一个子网 32是限制在同一个网站 64是限制在同一个region 
        128是限制在同一个大洲 255是不限制 <cacheManagerPeerProviderFactory class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory" 
        properties="peerDiscovery=automatic, multicastGroupAddress=224.1.1.1, multicastGroupPort=40000, 
        timeToLive=32" /> -->

    <!-- 默认缓存 -->
    <defaultCache maxElementsInMemory="1000" eternal="true"
        timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="true"
        diskSpoolBufferSizeMB="30" maxElementsOnDisk="10000000"
        diskPersistent="true" diskExpiryThreadIntervalSeconds="120"
        memoryStoreEvictionPolicy="LRU">
    </defaultCache>

  <!-- name: Cache的名称,必须是惟一的(ehcache会把这个cache放到HashMap里)。
     maxElementsInMemory:在内存中缓存的element的最大数目。
     maxElementsOnDisk:在磁盘上缓存的element的最大数目,默认值为0,表示不限制。
     eternal:设定缓存的elements是否永远不过时。若是为true,则缓存的数据始终有效,若是为false那么还要根据timeToIdleSeconds,timeToLiveSeconds判断。
     overflowToDisk: 若是内存中数据超过内存限制,是否要缓存到磁盘上。

   -->

    <cache name="userCache" maxElementsInMemory="1000" eternal="false"
        timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="true"
        diskSpoolBufferSizeMB="30" maxElementsOnDisk="10000000"
        diskPersistent="false" diskExpiryThreadIntervalSeconds="120"
        memoryStoreEvictionPolicy="LRU">
        <cacheEventListenerFactory
            class="net.sf.ehcache.distribution.RMICacheReplicatorFactory" />
        <!-- 用于在初始化缓存,以及自动设置 -->
        <bootstrapCacheLoaderFactory
            class="net.sf.ehcache.distribution.RMIBootstrapCacheLoaderFactory" />
    </cache>
</ehcache>

controller(ehcache)

@RestController
public class EhcacheSingleVersionController {
    
    @Autowired
    private UserService userService;
    
    @Autowired
    private CacheManager cacheManager;
    
    @Autowired
    private EhcacheMap<String, String> ehcacheMap;
    
    @RequestMapping("/clear")
    public String clear() {
        
        cacheManager.getCache("userCache").clear();
        
        return "success";
    }
    
    @RequestMapping("/getUser")
    public List<User> getUser(Long id) {
        
        return userService.getUser(id);
    }
    
    @RequestMapping("/save")
    public String save(String name, Long id) {
        
        ehcacheMap.put(id.toString(), name);
        
        return "success";
    }
}

dao(ehcache)

@CacheConfig(cacheNames = "userCache")
public interface UserMapper {

    @Select("SELECT ID ,NAME,AGE FROM user where id=#{id}")
    @Cacheable
    List<User> getUser(@Param("id") Long id);
    
}

手动修改数据库值(ehcache)

2、redis单机版

1.yml配置文件

 1 spring: 
 2   datasource: 
 3     url: jdbc:mysql://localhost:3306/mytest?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC
 4     username: root
 5     password: 123456
 6     driver-class-name: com.mysql.cj.jdbc.Driver
 7     test-while-idle: true
 8     test-on-borrow: true
 9     validation-query: SELECT 1 FROM DUAL
10     time-between-eviction-runs-millis: 300000
11     min-evictable-idle-time-millis: 1800000
12 # 缓存配置
13   cache:
14     type: ehcache
15     ehcache:
16       config: classpath:ehcache.xml
17 # redis
18   redis:
19     database: 0
20     host: xxx
21     port: 6379
22     password: xxx
23     jedis:
24       pool:
25         # 链接池最大链接数(使用负值表示没有限制)
26         max-active: 8
27         # 链接池最大阻塞等待时间(使用负值表示没有限制)
28         max-wait: -1
29         # 链接池中的最大空闲链接
30         max-idle: 8
31         # 链接池中的最小空闲链接
32         min-idle: 0
33     timeout: 10000
34     

 2.redisUtil

 1 @Component
 2 public class RedisUtil {
 3 
 4     @Autowired
 5     private StringRedisTemplate stringRedisTemplate;
 6     
 7     public void set(String key, Object obj, Long timeout) {
 8         if(obj instanceof String) {
 9             setString(key, obj);
10         } else if(obj instanceof Set) {
11             setSet(key, obj);
12         }
13         // 设置有效期
14         if(timeout != null) {
15             stringRedisTemplate.expire(key, timeout, TimeUnit.SECONDS);
16         }
17     }
18     
19     private void setSet(String key, Object obj) {
20         
21         @SuppressWarnings("unchecked")
22         Set<String> value = (Set<String>) obj;
23         for (String str : value) {
24             stringRedisTemplate.opsForSet().add(key, str);
25         }
26     }
27 
28     private void setString(String key, Object obj) {
29         
30         String value = (String)obj;
31         
32         stringRedisTemplate.opsForValue().set(key, value);;
33     }
34     
35 }

3.Controller

 1 @RestController
 2 public class RedisSingleVersionController {
 3 
 4     @Autowired
 5     private RedisUtil redisUtil;
 6     
 7     @RequestMapping("/setStr")
 8     public String setStr(String key, String value) {
 9         
10         String result = "success";
11         
12         try {
13             redisUtil.set(key, value, null);
14         } catch (Exception e) {
15             e.printStackTrace();
16             result = "error";
17         }
18         
19         return result;
20     }
21     
22     @RequestMapping("/set")
23     public String set(String key) {
24         
25         String result = "success";
26         
27         try {
28             Set<String> value = new HashSet<String>();
29             value.add("t1");
30             value.add("t2");
31             value.add("t3");
32             redisUtil.set(key, value, null);
33         } catch (Exception e) {
34             e.printStackTrace();
35             result = "error";
36         }
37         
38         return result;
39     }
40 }

4.运行

相关文章
相关标签/搜索