A brief introduction and use of GuavaCache Memcache Ehcache

Copyright: code word is not easy, please indicate the source ~~ https://blog.csdn.net/m0_37190495/article/details/86525908
Reproduced, please indicate the source:
Original starting in: http://www.zhangruibin.com
article from RebornChang's blog

He said data storage, database aside persistent storage means oracle, MySQL, etc., and then set aside a non-persistent database redis etc., and then excluded disk storage, which is the mainstream of this chapter simply under the catch: GuavaCache Memcache Ehcache.

GuavaCache Memcache Ehcache Profile

GuavaCache

1. Packaging the get, put operation, it is possible to integrate data sources. General cache cache and data source will operate in two parts of our operations in the business. For example: When you put the data, insert and then delete the original DB cache, when get data, first check the cache hit is returned, there is no need to query the DB hit, then the query results in the cache. Guava encapsulates so many steps, just call once get / put methods can be.
2. The cache is thread-safe, and ConcurrentMap similar, but the former added more elements expiration policy, which can only display remove elements.
3. GuavaCache recovery supports four ways: (1) based on the capacity recovery (Size-based Eviction); ( 2) based on the recovery time (Timed Eviction); (3) based on the reference type of recovery Reference-based Eviction); (4 ) manual recovery.
4. It can monitor load / shooting situation.

Memcache

memcache is a high-performance, distributed memory object caching system for dynamic Web applications in order to reduce the burden on the database. It is by caching the data objects in memory and to reduce the number read from the database. Thus improving dynamic, database-driven website speed.

memcache by maintaining a unified memory in a huge hash table, it can be used to store data in various formats, including images, videos, and other files, and the results of a database search. memcache mainly for sharing database negative pressure, memcache calls data into memory, and then read from memory, thus greatly improving the reading speed.

EHCache

EHCache from SourceForge ( http://ehcache.sourceforge.net/) open source project, and it is pure Java simple, fast Cache component implementation. EHCache support for memory and disk caching, support for LRU, LFU and FIFO out of a variety of algorithms, support for distributed Cache, Hibernate can be used as a cache plugin. It also provides the basis Filter Cache, the Filter can cache the content of the response and improve the response speed using Gzip compression.

Compare the pros and cons of Point Cache

过期时间

容量规划(重要)

清除策略(重要)

命中率统计

Performance Comparison - Memcache Ehcache

project Memcache ehcache
distributed Incomplete, does not implement the default cluster stand by
Clusters Can be achieved by the client Support (default synchronous or asynchronous)
Endurance of Can be achieved through third-party applications stand by. Persisted to the local hard disk, and .index generate a .data file. cache will automatically find these two files when initializing the data into the cache
effectiveness high Higher than Memcache
Disaster Recovery It can be achieved by end customers. stand by
Fashion cache data Memcached server is cached in memory to the system application, Can be cached in memory (JVM), the hard disk can also be cached. By CacheManager Management cache.
Cache expiration removal policy LRU LRU (default), FIFO, LFU
Shortcoming Function is not perfect, low efficiency relative to Ehcache Only applies to java system, only using java client
advantage Simple, flexible, cross-platform High efficiency and powerful.

Glossary

缓存移除策略(三种常见):
     FIFO(First In First Out):先进先出算法,即先放入缓存的先被移除;

     LRU(Least Recently Used):最久未使用算法,使用时间距离现在最久的那个被移除;

     LFU(Least Frequently Used):最近最少使用算法,一定时间段内使用次数(频率)最少的那个被移除。
  
Expirations有三种方式:
	1.永不失效:Expirations.noExpiration();
	
    2. TTL(Time To Live):存活期,即从缓存中创建时间点开始直到它到期的一个时间段(不管在这个时间段内有没有访问都将过期);
    例子
    :Expirations.timeToLiveExpiration(Duration.of(10,TimeUnit.MINUTES));
    
    3. TTI(Time To Idle):空闲期,即一个数据多久没被访问将从缓存中移除的时间。
    
    例子:
    Expirations.timeToIdleExpiration(Duration.of(5, TimeUnit.MINUTES));
    
    另外,Ehcache 中还可以通过自行实现Expiry接口来自定义缓存失效策略。

GuavaCache use

1.maven add dependencies:

		<dependency>
			<groupId>com.google.guava</groupId>
			<artifactId>guava</artifactId>
			<version>23.0</version>
		</dependency>

2. Code layer GuavaCacheTest .java

package com.example.demo.gitBooks.catchAnalysis.guavaCacheAnalysis;

import com.example.entity.User;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;

/*
* @ClassName GuavaCacheTest
*@Description TODO
*@Author zhangrui
*@Date 14:04 14:04
*@Version 
* */
public class GuavaCacheTest {
    private static  Logger logger = LoggerFactory.getLogger(GuavaCacheTest.class);
    public static void main(String[] args) {
        Cache<Object,Object> cache = CacheBuilder
                .newBuilder()
                //设置并发级别
                .concurrencyLevel(10)
                //设置缓存有效时间,超时的话会被回收
                .expireAfterAccess(10, TimeUnit.MINUTES)
                //设置缓存条数
                .maximumSize(100)
                .build();
        final Integer userId = 10001;
        try {
            //
            User user = (User)cache.get(userId, new Callable<User>() {
                @Override
                public User call() throws Exception {
                    return getUserInfoByUserId(userId);
                }
            });
            System.out.println(user.getName() == null?"没有獲取到了用戶":"獲取到了用戶:"+user);
            logger.info("执行上述成功!!");
        } catch (ExecutionException e) {
            e.printStackTrace();
            logger.info("抛出了异常!!");
        }
    }
    public static User getUserInfoByUserId(Integer userAge) {
        User user1 = new User("张三",  10001);
        User user2 = new User("李四", 10002);
        User user3 = new User("王五", 10003);
        List<User> userList = new ArrayList<>();
        userList.add(user1);
        userList.add(user2);
        userList.add(user3);
        User user = new User();
        for (User userTemp : userList){
            if (userTemp.getAge() == userAge){
                user = userTemp;
            }
        }
        return user;
    }
}

Ehcache use

1.maven add dependencies

		<!--ehcache缓存-->
		<dependency>
			<groupId>org.ehcache</groupId>
			<artifactId>ehcache</artifactId>
			<version>3.3.1</version>
		</dependency>

Code layer

EhcacheTest.java

import com.example.entity.User;
import org.ehcache.Cache;
import org.ehcache.PersistentCacheManager;
import org.ehcache.config.CacheConfiguration;
import org.ehcache.config.builders.CacheConfigurationBuilder;
import org.ehcache.config.builders.CacheManagerBuilder;
import org.ehcache.config.builders.CacheManagerConfiguration;
import org.ehcache.config.builders.ResourcePoolsBuilder;
import org.ehcache.config.units.MemoryUnit;
import org.ehcache.expiry.Duration;
import org.ehcache.expiry.Expirations;

import java.io.File;
import java.util.concurrent.TimeUnit;

/*
* @ClassName EhcacheTest
*@Description TODO 同时初始化堆缓存,堆外缓存,磁盘缓存,
* TODO 其中:heap + offheap 的组合,offheap 就是 Authoritative Tier,heap,就是 Caching Tier;
*TODO 对于heap + offheap + disk 的组合,disk 层就是 Authoritative Tier,heap + offheap 就是 CachingTier。
*@Author zhangrui
*@Date 10:47 10:47
*@Version 
* */
public class EhcacheTest {
    public static void main(String[] args) {
        //声明持久化(persistence)的磁盘位置为g盘
        //TODO 在Linux下需要修改
        CacheManagerConfiguration<PersistentCacheManager> persistentManagerConfig = CacheManagerBuilder
                .persistence(new File("g:\\", "ehcache-test"));
        PersistentCacheManager persistentCacheManager = CacheManagerBuilder.newCacheManagerBuilder()
                .with(persistentManagerConfig).build();
        // 手动初始化
        persistentCacheManager.init();
        // 空间大小 heap < offheap < disk,否则会报错java.lang.IllegalArgumentException
        //第三个参数设置为true,支持持久化
        ResourcePoolsBuilder resource = ResourcePoolsBuilder.newResourcePoolsBuilder()
                .heap(10, MemoryUnit.MB)
                .offheap(100, MemoryUnit.MB)
                .disk(500, MemoryUnit.MB, true);
        //写入缓存
        CacheConfiguration<Long, User> config = CacheConfigurationBuilder.newCacheConfigurationBuilder(Long.class, User.class, resource)
                //设置Caching Tier缓存有效时间,因为存入缓存是直接存到比 AuthoritativeTier中,所以,Caching Tier失效也不会影响数据
                .withExpiry(Expirations.timeToLiveExpiration(Duration.of(10, TimeUnit.SECONDS)))
                .build();
        Cache<Long, User> cache = persistentCacheManager.createCache("userInfoCache", CacheConfigurationBuilder.newCacheConfigurationBuilder(config));
        //写入缓存
        cache.put(10001L, new User("张三",  1));
        cache.put(10002L, new User("李四",  2));
        cache.put(10003L, new User("王五",  3));
        //读取缓存,如果要读取的是未存放放的,不会抛出异常,返回为null
        User user1 = new User();
        user1 = cache.get(10001L);
        User user2 = new User();
        user2 = cache.get(10002L);
        User user3 = new User();
        user3 = cache.get(10003L);
        //输出缓存
        System.out.println(user1 == null ? "获取失败,以为没有成功放入缓存,其实是堆溢出清除!!" : "成功的获取了缓存:" + "**************" + user1 + "***********");
        System.out.println("成功的获取了缓存:" + "**************" + user2 + "***********");
        System.out.println(user3 == null ? "获取失败,以为没有成功放入缓存,可能的原因为声明的heap值过小!!" : "成功的获取了缓存:" + "**************" + user3 + "***********");
        // 再程序关闭前,需要手动释放资源
        persistentCacheManager.close();
    }
}

CacheManagerTest.java

import com.example.entity.User;
import org.ehcache.Cache;
import org.ehcache.CacheManager;
import org.ehcache.config.CacheConfiguration;
import org.ehcache.config.builders.CacheConfigurationBuilder;
import org.ehcache.config.builders.CacheManagerBuilder;
import org.ehcache.config.builders.ResourcePoolsBuilder;
import org.ehcache.config.units.EntryUnit;
import org.ehcache.config.units.MemoryUnit;

/*
* @ClassName CacheManagerTest
*@Description TODO 声明的缓存heap大小是一定的,当后续加入缓存区满了之后,再继续加入的话则会遵从栈存储原则,堆底元素出堆消亡
*@Author zhangrui
*@Date 10:47 10:47
*@Version 
* */
public class CacheManagerTest {
    public static void main(String[] args) {
        CacheManager cacheManager = CacheManagerBuilder.newCacheManagerBuilder().build();
        //手动初始化
        cacheManager.init();
        ResourcePoolsBuilder resourcePoolsBuilder = ResourcePoolsBuilder.heap(2);
        //1.按照存储的条目数进行初始化
        ResourcePoolsBuilder resourcePoolsBuilder1 = ResourcePoolsBuilder.newResourcePoolsBuilder().heap(2, EntryUnit.ENTRIES);
        //2.按照存储的条目数进行初始化的简写方式
        ResourcePoolsBuilder resourcePoolsBuilder2 = ResourcePoolsBuilder.newResourcePoolsBuilder().heap(2);
        //3.按照存储空间大小初始化
        ResourcePoolsBuilder resourcePoolsBuilder3 = ResourcePoolsBuilder.newResourcePoolsBuilder().heap(2, MemoryUnit.GB);
        CacheConfiguration<Integer, User> configuration = CacheConfigurationBuilder.newCacheConfigurationBuilder(Integer.class, User.class,
                ResourcePoolsBuilder.newResourcePoolsBuilder()
                        .heap(10, MemoryUnit.KB)
                        .offheap(10, MemoryUnit.MB))
                .withSizeOfMaxObjectGraph(3)
                .withSizeOfMaxObjectSize(4, MemoryUnit.KB)
                .build();
        //创建缓存对象
        Cache<Integer, User> cache = cacheManager.createCache("userInfo", CacheConfigurationBuilder.newCacheConfigurationBuilder(configuration));
        //写入缓存
        cache.put(10001, new User("张三",  1));
        cache.put(10002, new User("李四",  2));
        cache.put(10003, new User("王五",3));
        //读取缓存
        User user1 = new User();
        user1 = cache.get(10001);
        User user2 = new User();
        user2 = cache.get(10002);
        User user3 = new User();
        user3 = cache.get(10003);
        //输出缓存
        System.out.println(user1 == null ? "获取失败,以为没有成功放入缓存,其实是堆溢出清除!!" : "成功的获取了缓存:" + "**************" + user1 + "***********");
        System.out.println("成功的获取了缓存:" + "**************" + user2 + "***********");
        System.out.println(user3 == null ? "获取失败,以为没有成功放入缓存,可能的原因为声明的heap值过小!!" : "成功的获取了缓存:" + "**************" + user3 + "***********");
        //再程序关闭前,需要手动释放资源
        //不用手动removeCache,根据打印日志,会自动清除;
        cacheManager.removeCache("userInfo");
        cacheManager.close();
    }
}

PS:
. 1.memcache what you need to configure the server installation, Bo prime suspect tedious, no alley, so no code shows here.
2. The Bowen code has been uploaded to the bloggers GitHub, code address:
RebornChang's GitHub
3. Bowen part of the resources taken from the network, if similar, please forgive me.
Over!

Guess you like

Origin blog.csdn.net/m0_37190495/article/details/86525908