Upgrade to Pro — share decks privately, control downloads, hide ads and more …

[JPoint] JCache и Распределенные Кэши: Беспредел!

[JPoint] JCache и Распределенные Кэши: Беспредел!

Java тормозит. Что же делать?! Вариантов видится несколько:

Паника! (отставить панику)
Молиться на иконы Шипилёва
Всё кэшировать

Даже если второй вариант выглядит заманчиво, мы пойдем третьим путем. Но на все данные серьезных пацанов никакого heap-а не хватит. Но тут на помощь приходит распределенное кэширование вообще, и стандарт JCache в частности. В этом докладе вы узнаете, что такое JCache, и требует ли он чтобы данные хранились в куче (on-heap) или вне кучи (off-heap), на одной Java-машине или на нескольких.

Интрига? Интрига! И это лишь начало. Мы еще поиграем шрифтами распределением данных, не меняя ни строчки в коде, и вот тогда это будет совсем весело!

Viktor Gamov

April 23, 2016
Tweet

More Decks by Viktor Gamov

Other Decks in Programming

Transcript

  1. • Senior Solutions Architect / Hazelcast • Завсегдатай конференций •

    Автор O’Reilly’s «Enterprise Web Development» Viktor Gamov @gamussa
  2. public interface Cache<K, V> { void put(K key, V value);

    V putIfAbsent(K key, V value); V get(K key); long size(); }
  3. public class LocalCache<Integer, Company> implements Cache<Integer, Company> { ConcurrentMap<Integer, Company>

    storage = new ConcurrentHashMap<>(); @Override public void put(Integer key, Company value) { this.storage.put(key, value); } ... }
  4. public class LocalCache<Integer, Company> implements Cache<Integer, Company> { ConcurrentMap<Integer, Company>

    storage = new ConcurrentHashMap<>(); @Override public void put(Integer key, Company value) { this.storage.put(key, value); } ... }
  5. LocalCache<Integer, String> myCache = new LocalCache<>(); // 20 MB String

    value= new String(new char[10000000]); Runtime runtime = Runtime.getRuntime(); int keyCount = 0; int mb = 1024 * 1024; while (true) { myCache.put(keyCount, value); keyCount++; System.out.printf("Unique Puts = %s keyCount : Free Memory (MB) = %s\n", keyCount, runtime.freeMemory() / mb); }
  6. Unique Puts = 1919785 keyCount : Free Memory (MB) =

    2 Exception in thread "main" java.lang.OutOfMemoryError: GC overhead limit exceeded LocalCache<Integer, String> myCache = new LocalCache<>(); // 20 MB String value= new String(new char[10000000]); Runtime runtime = Runtime.getRuntime(); int keyCount = 0; int mb = 1024 * 1024; while (true) { myCache.put(keyCount, value); keyCount++; System.out.printf("Unique Puts = %s keyCount : Free Memory (MB) = %s\n", keyCount, runtime.freeMemory() / mb); }
  7. MutableConfiguration<String, Integer> config = new MutableConfiguration<>(); config.setStoreByValue(true) .setTypes(String.class, Integer.class) .setExpiryPolicyFactory(CreatedExpiryPolicy.factoryOf(TEN_SEC));

    //.setExpiryPolicyFactory(ModifiedExpiryPolicy.factoryOf(TEN_SEC)); //.setExpiryPolicyFactory(TouchedExpiryPolicy.factoryOf(TEN_SEC)); //.setExpiryPolicyFactory(EternalExpiryPolicy.factoryOf(TEN_SEC)); //.setExpiryPolicyFactory(CreatedExpiryPolicy.factoryOf(TEN_SEC)); //.setExpiryPolicyFactory(AccessedExpiryPolicy.factoryOf(TEN_SEC)); Caching.getCachingProvider().getCacheManager().createCache("test", config);
  8. MutableConfiguration<String, Integer> config = new MutableConfiguration<>(); config.setStoreByValue(true) .setTypes(String.class, Integer.class) .setExpiryPolicyFactory(CreatedExpiryPolicy.factoryOf(TEN_SEC));

    //.setExpiryPolicyFactory(ModifiedExpiryPolicy.factoryOf(TEN_SEC)); //.setExpiryPolicyFactory(TouchedExpiryPolicy.factoryOf(TEN_SEC)); //.setExpiryPolicyFactory(EternalExpiryPolicy.factoryOf(TEN_SEC)); //.setExpiryPolicyFactory(CreatedExpiryPolicy.factoryOf(TEN_SEC)); //.setExpiryPolicyFactory(AccessedExpiryPolicy.factoryOf(TEN_SEC)); Caching.getCachingProvider().getCacheManager().createCache("test", config);
  9. MutableConfiguration<String, Integer> config = new MutableConfiguration<>(); config.setStoreByValue(true) .setTypes(String.class, Integer.class) .setExpiryPolicyFactory(CreatedExpiryPolicy.factoryOf(TEN_SEC));

    //.setExpiryPolicyFactory(ModifiedExpiryPolicy.factoryOf(TEN_SEC)); //.setExpiryPolicyFactory(TouchedExpiryPolicy.factoryOf(TEN_SEC)); //.setExpiryPolicyFactory(EternalExpiryPolicy.factoryOf(TEN_SEC)); //.setExpiryPolicyFactory(CreatedExpiryPolicy.factoryOf(TEN_SEC)); //.setExpiryPolicyFactory(AccessedExpiryPolicy.factoryOf(TEN_SEC)); Caching.getCachingProvider().getCacheManager().createCache("test", config);
  10. import javax.cache.Cache; import javax.cache.Caching; Cache<Integer, String> myCache = Caching.getCache("test"); //

    20 MB String value= new String(new char[10000000]); Runtime runtime = Runtime.getRuntime(); int keyCount = 0; int mb = 1024 * 1024; while (true) { myCache.put(keyCount, value); keyCount++; System.out.printf("Unique Puts = %s keyCount : Free Memory (MB) = %s\n", keyCount, runtime.freeMemory() / mb); }
  11. import javax.cache.Cache; import javax.cache.Caching; Cache<Integer, String> myCache = Caching.getCache("test"); //

    20 MB String value= new String(new char[10000000]); Runtime runtime = Runtime.getRuntime(); int keyCount = 0; int mb = 1024 * 1024; while (true) { myCache.put(keyCount, value); keyCount++; System.out.printf("Unique Puts = %s keyCount : Free Memory (MB) = %s\n", keyCount, runtime.freeMemory() / mb); }
  12. import javax.cache.Cache; import javax.cache.Caching; Cache<Integer, String> myCache = Caching.getCache("test"); //

    20 MB String value= new String(new char[10000000]); Runtime runtime = Runtime.getRuntime(); int keyCount = 0; int mb = 1024 * 1024; while (true) { myCache.put(keyCount, value); keyCount++; System.out.printf("Unique Puts = %s keyCount : Free Memory (MB) = %s\n", keyCount, runtime.freeMemory() / mb); }
  13. public class MyCacheEntryListener implements CacheEntryCreatedListener<String, String>, CacheEntryUpdatedListener<String, String> { public

    void onCreated( Iterable<CacheEntryEvent<? extends String, ? extends String>> cacheEntryEvents) throws CacheEntryListenerException { for (CacheEntryEvent entryEvent : cacheEntryEvents) { System.out.println("Created : " + entryEvent.getKey() + " with value : " + entryEvent.getValue()); } } public void onUpdated( Iterable<CacheEntryEvent<? extends String, ? extends String>> cacheEntryEvents) throws CacheEntryListenerException { for (CacheEntryEvent entryEvent : cacheEntryEvents) { System.out.println("Updated : " + entryEvent.getKey() + " with value : " + entryEvent.getValue()); } } }
  14. /** * Sample of a Read Through CacheLoader */ public

    class MyCacheLoader implements CacheLoader<String, String> { public String load(String key) throws CacheLoaderException { if ("Portugal".equals(key)) { return "Lisbon"; } return null; } /** * Async Load Up of a Cache. */ public Map<String, String> loadAll(Iterable<? extends String> keys) throws CacheLoaderException { // Iterate the keys and maybe batch load from a DB, // a Filesystem or some other System completely. return null; } }
  15. /** * Example of a JCache CacheWriter, use this to

    write to a RDBMS or somefink. */ public class MyCacheWriter implements CacheWriter<String, String> { public void write(Cache.Entry<? extends String, ? extends String> entry) throws CacheWriterException { System.out.println("Write Entry : " + entry.getKey()); } public void writeAll(Collection<Cache.Entry<? extends String, ? extends String>> entries) throws CacheWriterException { for (Cache.Entry entry : entries) { System.out.println("Write Entry : " + entry.getKey()); } } public void delete(Object key) throws CacheWriterException { } public void deleteAll(Collection<?> keys) throws CacheWriterException { } }
  16. public class AppConfig { public static interface CityService { public

    String getCity(); } @Bean public CityService getService() { return new CityService() { @Override public String getCity() { // slow code goes here! return result; } }; } }
  17. import javax.cache.annotation.CacheResult; import org.springframework.cache.annotation.EnableCaching; @Configuration @EnableCaching public class AppConfig{ public

    static interface CityService { @CacheResult(cacheName = "city") public String getCity(); } @Bean public CityService getService() { return new CityService() { @Override public String getCity() { // slow code goes here! return result; } }; } }
  18. import javax.cache.annotation.CacheResult; import org.springframework.cache.annotation.EnableCaching; @Configuration @EnableCaching public class AppConfig{ public

    static interface CityService { @CacheResult(cacheName = "city") public String getCity(); } @Bean public CityService getService() { return new CityService() { @Override public String getCity() { // slow code goes here! return result; } }; } }
  19. CachingProvider cachingProvider = Caching.getCachingProvider(); CacheManager cacheManager = cachingProvider.getCacheManager(); Cache<Object, Object>

    cache = cacheManager.getCache("test"); ICache<Object, Object> unwrappedCache = cache.unwrap(ICache.class);
  20. ICache<Integer, String> unwrappedCache = cache.unwrap(ICache.class); ICompletableFuture<String> future = unwrappedCache.getAndPutAsync(1, "value");

    future.andThen(new ExecutionCallback<String>() { public void onResponse(String response) { System.out.println("Previous value: " + response); } public void onFailure(Throwable t) { t.printStackTrace(); } });
  21. public static class CustomCacheMergePolicy implements CacheMergePolicy { @Override public Object

    merge(String cacheName, CacheEntryView mergingEntry, CacheEntryView existingEntry) { if (mergingEntry.getValue() instanceof Integer) { return mergingEntry.getValue(); } return null; } }
  22. ICache iCache1 = cache1.unwrap(ICache.class); iCache1.addPartitionLostListener(new CachePartitionLostListener() { @Override public void

    partitionLost(CachePartitionLostEvent cachePartitionLostEvent) { System.out.println(cachePartitionLostEvent); latch.countDown(); } });