当前位置:网站首页>Local cache selection (guava/caffeine/ohc) and performance comparison

Local cache selection (guava/caffeine/ohc) and performance comparison

2022-06-24 00:59:00 User 7255712

1 Guava

1.1) Based on using

@Slf4j
public class GuavaCache {

    private static Cache<String, Object> cache = CacheBuilder.newBuilder()
            .maximumSize(1000000)
            .expireAfterWrite(60, TimeUnit.SECONDS)
            .concurrencyLevel(4)
            .initialCapacity(1000)
            // Configuration recordStats,cache.stats() To take effect 
            //.recordStats()
            .removalListener(new RemovalListener<String, Object>() {
                @Override
                public void onRemoval(RemovalNotification<String, Object> rn) {

                }
            }).build();


    /*
     *
     * @desction:  Access to the cache 
     */
    public static Object get(String key) {
        try {
            return StringUtils.isNotEmpty(key) ? cache.getIfPresent(key) : null;
        } catch (Exception e) {
            log.error("local cache by featureId  abnormal ", e);
            return null;
        }
    }

    /*
     *
     * @desction:  Put into cache 
     */
    public static void put(String key, Object value) {
        if (StringUtils.isNotEmpty(key) && value != null) {
            cache.put(key, value);
        }
    }

    /*
     *
     * @desction:  Remove the cache 
     */
    public static void remove(String key) {
        if (StringUtils.isNotEmpty(key)) {
            cache.invalidate(key);
        }
    }

    /*
     *
     * @desction:  Bulk delete cache 
     */
    public static void remove(List<String> keys) {
        if (keys != null && keys.size() > 0) {
            cache.invalidateAll(keys);
        }
    }

    public static CacheStats getStats() {
        return cache.stats();
    }

    /**
     * test
     *
     * @param args
     */

    public static void main(String[] args) {
        long start = System.currentTimeMillis();
        // Test write only 
        for (int j = 0; j < 500000; j++) {
            GuavaCache.put("" + j, j);
        }
        // Test reading and writing 
        for (int j = 0; j < 500000; j++) {
            GuavaCache.get("" + j);
        }
        // Reading and writing + Read as hit 
        for (int j = 0; j < 500000; j++) {
            GuavaCache.get("" + j + "noHits");
        }
        GuavaCache.cache.cleanUp();
        long end = System.currentTimeMillis();
        System.out.println(end - start);
    }

}

2 CaffeineCache

2.1 Based on using

@Slf4j
public class CaffeineCache {

    private static Cache<String, Object> caffeineCache = Caffeine.newBuilder()
            .maximumSize(1000000)
            .expireAfterWrite(60, TimeUnit.SECONDS)
            .initialCapacity(1000)
            // Configuration recordStats,cache.stats() To take effect 
            //.recordStats()
            .removalListener(new RemovalListener<String, Object>() {
                @Override
                public void onRemoval(@Nullable String key, @Nullable Object value, @NonNull RemovalCause cause) {

                }
            })
            .build();


    /*
     *
     * @desction:  Access to the cache 
     */
    public static Object get(String key) {
        try {
            return StringUtils.isNotEmpty(key) ? caffeineCache.getIfPresent(key) : null;
        } catch (Exception e) {
            log.error("local cache by featureId  abnormal ", e);
            return null;
        }
    }

    /*
     *
     * @desction:  Put into cache 
     */
    public static void put(String key, Object value) {
        if (StringUtils.isNotEmpty(key) && value != null) {
            caffeineCache.put(key, value);
        }
    }

    /*
     *
     * @desction:  Remove the cache 
     */
    public static void remove(String key) {
        if (StringUtils.isNotEmpty(key)) {
            caffeineCache.invalidate(key);
        }
    }

    /*
     *
     * @desction:  Bulk delete cache 
     */
    public static void remove(List<String> keys) {
        if (keys != null && keys.size() > 0) {
            caffeineCache.invalidateAll(keys);
        }
    }

    public static CacheStats getStats() {
        return caffeineCache.stats();
    }

    /**
     * test
     *
     * @param args
     */


    public static void main(String[] args) throws Exception {
        long start = System.currentTimeMillis();
        // Test write only 
        for (int j = 0; j < 500000; j++) {
            CaffeineCache.put("" + j, j);
        }
        // Test reading and writing 
        for (int j = 0; j < 500000; j++) {
            CaffeineCache.get("" + j);
        }
        // Reading and writing + Read as hit 
        for (int j = 0; j < 500000; j++) {
            CaffeineCache.get("" + j + "noHits");
        }
        long end = System.currentTimeMillis();
        System.out.println(end - start);
    }
}

3 Off heap caching Ohc

@Slf4j
public class OhcCache {

    private static OHCache<String, String> ohCache = OHCacheBuilder.<String, String>newBuilder()
            .keySerializer(new OhcStringSerializer())
            .valueSerializer(new OhcStringSerializer())
            //.hashMode(HashAlgorithm.CRC32C)
            // Unit is byte , Default 2GB Space 
            .capacity(2 * 1024 * 1024 * 1024L)
            .timeouts(true)
            .defaultTTLmillis(600 * 1000)
            .eviction(Eviction.LRU)
            .build();


    /**
     *  Set the value 
     *
     * @param k
     * @param v
     * @return
     */
    public static boolean put(String k, String v) {
        return put(k, v, 9223372036854775807L);
    }

    public static boolean put(String k, String v, Long time) {
        try {
            return ohCache.put(k, v, time);
        } catch (Exception e) {
            log.error("ohc cache put error", e);
            return false;
        }
    }

    public static String get(String k) {
        return ohCache.get(k);
    }

    public static void main(String[] args) throws Exception {
        long start = System.currentTimeMillis();
        // Test write only 
        for (int j = 0; j < 500000; j++) {
            OhcCache.put("" + j, j + "");
        }
        System.out.println(" Writing takes time :" + (System.currentTimeMillis() - start));
        // Test reading and writing 
        for (int j = 0; j < 500000; j++) {
            OhcCache.get("" + j);
        }
        System.out.println(" Read hit time :" + (System.currentTimeMillis() - start));
        // Reading and writing + Read as hit 
        for (int j = 0; j < 500000; j++) {
            OhcCache.get("" + j + "noHits");
        }
        System.out.println(" Read miss time :" + (System.currentTimeMillis() - start));
        System.out.println(" Total time :" + (System.currentTimeMillis() - start));
    }

}

4 Performance comparison

Comparative data

type

50 Ten thousand words : Time consuming :ms

50 Write +50 read ( Read all hits ): Time consuming :ms

50 Wan write +50 Wan Du ( Full hit )+50 Wan Du ( Not hit ): Time consuming :ms

50 Wan Du +50 Ten thousand misses

Guava

329/340/326/328/328

536/518/546/525/558

647/646/638/668/641

490/501/482/485/492

Caffeine

292/284/270/279/267

414/382/353/385/361

479/513/460/487/481

343/326/333/336/369

Ohc

448/433/430/446/442

763/748/765/741/705

918/947/901/964/903

653/676/607/639/704

Ohc-Obj

1343/1315/1217/1249/1193

1910/1830/1849/1803/1786

1979/1965/1947/1968/1946

1487/1573/1499/1491/1483

summary

 Whether reading or writing ,Caffeine Performance ratio Guava It is better to .

Caffeine be based on java8 A high performance , Near optimal cache Library .

Caffeine Memory cache usage reference provided Google guava Of API.

Caffeine Is based on Google guava and  ConcurrentLinkedHashMap The results of improvement in design experience .

Caffeine yes Spring 5 Default supported Cache, so Spring The importance of it ,Spring abandon Guava Turned to Caffeine.

5 Other advanced uses

5.1 Usage Summary

 Automatically load entities into the cache asynchronously 
 Size based recycling policy 
 Time based recycling strategy 
 Automatically refresh 
key Automatically encapsulate virtual references 
value Automatically encapsulate weak or soft references 
 Notification that an entity has expired or been deleted 
 Write external resources 
 Statistics cumulative access cache 

5.2 Load policy

Manual loading

//  Retrieve one entry, If not, it is null
Graph graph = cache.getIfPresent(key);
//  Retrieve one entry, If entry by null, Through key Create a entry And add cache 
graph = cache.get(key, k -> createExpensiveGraph(key));
//  Insert or update an entity 
cache.put(key, graph);
//  Remove an entity 
cache.invalidate(key);

Synchronous loading

structure Cache When ,build Method passes in a CacheLoader Implementation class . Realization load Method , adopt key load value.

.build(key -> createExpensiveGraph(key));

Load asynchronously

    .buildAsync((key, executor) -> createExpensiveGraphAsync(key, executor));

5.3 Recovery strategy

Caffeine Provides 3 Two recycling strategies : Size based recycling , Time based recycling , Based on reference recycling

5.4  External storage : For writing to the database / Multi level cache synchronization

// adopt CacheWriter  The cache can be written back to external storage .

LoadingCache<Key, Graph> graphs = Caffeine.newBuilder()
  .writer(new CacheWriter<Key, Graph>() {
    @Override public void write(Key key, Graph graph) {
      //  Write to external storage or L2 cache 
    }
    @Override public void delete(Key key, Graph graph, RemovalCause cause) {
      //  Delete external storage or L2 cache 
    }
  })
  .build(key -> createExpensiveGraph(key));

5.5 Statistics of cache usage

 By using Caffeine.recordStats(),  It can be transformed into a set of Statistics .  adopt  Cache.stats()  Return to one CacheStats.
CacheStats Provide the following statistical methods 
ps:// Configuration recordStats----cache.stats() To take effect 

hitRate():  Returns the cache hit ratio 
evictionCount():  Number of cache recycles 
averageLoadPenalty():  Average time to load new values 

6 other : Why? Caffeine Than Guava good

Other pressure measurement references :https://github.com/ben-manes/caffeine/wiki/Benchmarks

原网站

版权声明
本文为[User 7255712]所创,转载请带上原文链接,感谢
https://yzsam.com/2021/11/20211121174411617a.html