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

[Geekout] Distributed Caching With Jcache And Beyond

[Geekout] Distributed Caching With Jcache And Beyond

Do you need more performance from your Java applications? Is latency causing you a stress? If so, let’s look at JCache, the Java caching API. JCache (JSR 107) is a vendor-neutral caching specification for Java. No need for proprietary non-standard caching solutions in Java land anymore. This code-driven session demonstrates how to integrate JCache into your Java applications.
In this talk, Viktor will cover:
How distributed caching works in general.
Capabilities of JCache API.
Use cases, best practices and the future of JCache.
As a bonus, you will see how JCache support already integrated into many popular open source frameworks!

Viktor Gamov

June 09, 2016
Tweet

More Decks by Viktor Gamov

Other Decks in Technology

Transcript

  1. whoiam
    Señor Solutions Architect @Hazelcast
    @gAmUssA on the internetz

    View full-size slide

  2. Business Application (instance 2)
    Business Application (instance 1)
    Service Service Service
    RDBMS Mainframe MongoDB
    NoSQL
    REST

    View full-size slide

  3. •Performance
    •Offload expensive parts of your architecture
    •Scale up – get the most out of one machine
    •Scale out – add more capacity with more machines
    •Usually very fast and easy to apply
    Cache is good for…

    View full-size slide

  4. Business Application (instance 2) Local
    cache
    Business Application (instance 1)
    Service Service Service
    RDBMS Mainframe MongoDB
    NoSQL
    REST
    Local
    cache

    View full-size slide

  5. 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

  6. 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

  7. 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

  8. 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

  9. 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

  10. CACHES
    CACHES EVERYWHERE
    https://xkcd.com/927/

    View full-size slide

  11. import javax.cache.Caching;
    import javax.cache.configuration.MutableConfiguration;
    MutableConfiguration config = new MutableConfiguration<>();
    config.setStoreByValue(true)
    .setTypes(String.class, Integer.class)
    .setExpiryPolicyFactory(CreatedExpiryPolicy.factoryOf(TEN_SEC));
    Caching.getCachingProvider().getCacheManager().createCache("test", config);

    View full-size slide

  12. import javax.cache.Caching;
    import javax.cache.configuration.MutableConfiguration;
    MutableConfiguration config = new MutableConfiguration<>();
    config.setStoreByValue(true)
    .setTypes(String.class, Integer.class)
    .setExpiryPolicyFactory(CreatedExpiryPolicy.factoryOf(TEN_SEC));
    Caching.getCachingProvider().getCacheManager().createCache("test", config);

    View full-size slide

  13. import javax.cache.Caching;
    import javax.cache.configuration.MutableConfiguration;
    MutableConfiguration config = new MutableConfiguration<>();
    config.setStoreByValue(true)
    .setTypes(String.class, Integer.class)
    .setExpiryPolicyFactory(CreatedExpiryPolicy.factoryOf(TEN_SEC));
    Caching.getCachingProvider().getCacheManager().createCache("test", config);

    View full-size slide

  14. 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

  15. 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

  16. 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

  17. Caching
    «SPI Loader»
    CachingProvider
    «SPI Implementation»
    CacheManager
    «Manages caches»
    Cache
    «Cache interface»

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  20. dependencies {
    // JCache API
    compile "javax.cache:cache-api:1.0.0"
    // JCache Implementation
    compile "com.hazelcast:hazelcast:3.6.3"
    }

    View full-size slide

  21. java.util.Map
    Key-Value Based API
    Supports Atomic Updates
    Entries Don’t Expire
    Entries Aren’t Evicted
    Entries Stored On-Heap
    Store-By-Reference
    javax.cache.Cache
    Key-Value Based API
    Supports Atomic Updates
    Entries May Expire
    Entries May Be Evicted
    Supports Observation (ie: Listeners)
    Supports Integration (ie: Loaders/Writers)
    Store-By-Value and Store-By-Reference
    Entry Processors
    Annotations
    Entries Stored Anywhere (ie: topologies)
    Statistics and Management

    View full-size slide

  22. public class MyCacheEntryListener
    implements CacheEntryCreatedListener {
    public void onCreated(
    Iterable> events)
    throws CacheEntryListenerException {
    for (CacheEntryEvent event : events) {
    log("Created : " + event.getKey()
    + " with value : " + event.getValue());
    }
    }
    }

    View full-size slide

  23. Business Application
    Service Service Service
    RDBMS Mainframe MongoDB
    NoSQL
    REST
    Scaling
    JCACHE
    read through cache
    write through cache

    View full-size slide

  24. import javax.cache.integration.CacheLoader;
    import javax.cache.integration.CacheLoaderException;
    public class MyCacheLoader implements CacheLoader {
    public String load(String key) throws CacheLoaderException {
    return getCapitalsDao().get(key);
    }
    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.
    Map result = new HashMap<>();
    keys.forEach(key -> {
    result.put(key, getCapitalsDao().get(key));
    });
    return result;
    }
    ...
    }

    View full-size slide

  25. package javax.cache.integration;
    public interface CacheWriter {
    void write(Cache.Entry extends K, ? extends V> entry)
    throws CacheWriterException;
    void writeAll(CollectionV>> entries) throws
    CacheWriterException;
    void delete(Object key) throws CacheWriterException;
    void deleteAll(Collection> keys) throws
    CacheWriterException;
    }

    View full-size slide

  26. Application
    Cache
    Cache
    Application
    EntryProcessor for atomic updates

    View full-size slide

  27. Spring and JCache
    Demo

    View full-size slide

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

  29. 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

  30. 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

  31. JCache With Java EE
    • Java EE
    - Application can use JCache
    • Java EE 8
    - JCache added to EE8
    - Add JCache Annotations. Payara and TomEE provide support
    - Other integration possibilities:
    •ejb timer store
    •jbatch store
    •JPA

    View full-size slide

  32. Entries Stored Anywhere
    (ie: topologies)

    View full-size slide

  33. Great for early stages of rapid
    application development and iteration
    and for OEM.
    Necessary for scale-up or scale-out
    deployments
    – decouples upgrading of clients and cluster
    for long term TCO
    Embedded Mode
    Node 1
    Applications
    Java API
    Client-Server Mode
    Node 3
    Java API
    Applications
    .Net API
    Applications
    C++ API
    Applications
    Node 2
    Node 1
    Node 2
    Applications
    Java API
    Node 3
    Applications
    Java API
    Topologies

    View full-size slide

  34. Green
    Primary
    Green
    Backup
    Green
    Shard

    View full-size slide

  35. Business Application
    Service Service Service
    RDBMS Mainframe MongoDB
    NoSQL
    REST
    Scaling
    JCACHE
    Near cache Near cache Near cache

    View full-size slide

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

    View full-size slide

  37. 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

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

    View full-size slide

  39. 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


  40. 3
    READ_WRITE


    cache-quorum

    View full-size slide

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

    View full-size slide

  42. JCache 1.1
    • CDDL GPL with Class Path Exception License to the spec API
    or UPL.
    • Errata
    • TCK Challenges
    • Very Close – should be Summer 2016

    View full-size slide

  43. JCache 2.0
    • Enterprise Features
    - Transactions
    - Annotations Integration for EE
    - Servlet 4.0 Integration / Session Caching
    • Core
    - Java 8
    - Java 9 Modularity
    - Async API
    - Distributed java.util.stream
    - Basic cache profile: - listener, -integration, - EntryProcessor.

    View full-size slide