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

    View full-size slide

  2. public interface Cache {
    void put(K key, V value);
    V putIfAbsent(K key, V value);
    V get(K key);
    long size();
    }

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  5. LocalCache 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);
    }

    View full-size slide

  6. Unique Puts = 1919785 keyCount : Free Memory (MB) = 2
    Exception in thread "main" java.lang.OutOfMemoryError: GC overhead limit exceeded
    LocalCache 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);
    }

    View full-size slide

  7. MutableConfiguration 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);

    View full-size slide

  8. MutableConfiguration 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);

    View full-size slide

  9. MutableConfiguration 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);

    View full-size slide

  10. import javax.cache.Cache;
    import javax.cache.Caching;
    Cache 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);
    }

    View full-size slide

  11. import javax.cache.Cache;
    import javax.cache.Caching;
    Cache 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);
    }

    View full-size slide

  12. import javax.cache.Cache;
    import javax.cache.Caching;
    Cache 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);
    }

    View full-size slide

  13. public class MyCacheEntryListener
    implements CacheEntryCreatedListener,
    CacheEntryUpdatedListener {
    public void onCreated(
    Iterable> cacheEntryEvents)
    throws CacheEntryListenerException {
    for (CacheEntryEvent entryEvent : cacheEntryEvents) {
    System.out.println("Created : " + entryEvent.getKey() + " with value : " +
    entryEvent.getValue());
    }
    }
    public void onUpdated(
    Iterable> cacheEntryEvents)
    throws CacheEntryListenerException {
    for (CacheEntryEvent entryEvent : cacheEntryEvents) {
    System.out.println("Updated : " + entryEvent.getKey() + " with value : " +
    entryEvent.getValue());
    }
    }
    }

    View full-size slide

  14. Бизнес-приложение
    сервис сервис сервис
    RDBMS Mainframe MongoDB
    NoSQL
    REST
    Масштабирование
    JCACHE
    read through cache
    write through cache

    View full-size slide

  15. /**
    * Sample of a Read Through CacheLoader
    */
    public class MyCacheLoader implements CacheLoader {
    public String load(String key) throws CacheLoaderException {
    if ("Portugal".equals(key)) {
    return "Lisbon";
    }
    return null;
    }
    /**
    * Async Load Up of a Cache.
    */
    public Map 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;
    }
    }

    View full-size slide

  16. /**
    * Example of a JCache CacheWriter, use this to write to a RDBMS or somefink.
    */
    public class MyCacheWriter implements CacheWriter {
    public void write(Cache.Entry extends String, ? extends String> entry)
    throws CacheWriterException {
    System.out.println("Write Entry : " + entry.getKey());
    }
    public void writeAll(Collection>
    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 {
    }
    }

    View full-size slide

  17. 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;
    }
    };
    }
    }

    View full-size slide

  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;
    }
    };
    }
    }

    View full-size slide

  19. 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;
    }
    };
    }
    }

    View full-size slide

  20. http://fc07.deviantart.net/fs71/i/2012/156/3/b/bruce_banner_by _lightning_stroke-d52er xe.png

    View full-size slide

  21. Caching
    «загрузчик»
    CachingProvider
    «Реализация SPI»
    CacheManager
    «управоляет кэшами»
    Cache
    «интерфейс к кэшу»

    View full-size slide

  22. CachingProvider cachingProvider = Caching.getCachingProvider();
    CacheManager cacheManager = cachingProvider.getCacheManager();
    Cache cache = cacheManager.getCache("test");

    View full-size slide

  23. Cache cache = Caching.getCache("test");

    View full-size slide

  24. CachingProvider cachingProvider = Caching.getCachingProvider();
    CacheManager cacheManager = cachingProvider.getCacheManager();
    Cache cache = cacheManager.getCache("test");
    ICache unwrappedCache = cache.unwrap(ICache.class);

    View full-size slide

  25. Cache cache = Caching.getCache("test");
    ICache unwrappedCache = cache.unwrap(ICache.class);

    View full-size slide

  26. ICache unwrappedCache = cache.unwrap(ICache.class);
    ICompletableFuture future = unwrappedCache.getAndPutAsync(1, "value");
    future.andThen(new ExecutionCallback() {
    public void onResponse(String response) {
    System.out.println("Previous value: " + response);
    }
    public void onFailure(Throwable t) {
    t.printStackTrace();
    }
    });

    View full-size slide

  27. Green
    Primary
    Green
    Backup
    Green
    Shard

    View full-size slide

  28. 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;
    }
    }

    View full-size slide

  29. ICache iCache1 = cache1.unwrap(ICache.class);
    iCache1.addPartitionLostListener(new
    CachePartitionLostListener() {
    @Override
    public void partitionLost(CachePartitionLostEvent
    cachePartitionLostEvent) {
    System.out.println(cachePartitionLostEvent);
    latch.countDown();
    }
    });

    View full-size slide

  30. Вместо окончания

    View full-size slide