Hibernate Distirbuted cache


Hazelcast, Infinispan, etc.


Key Terms



Perfomance - number of operations per unit of time (requests/second)

Perfomance is not Scalability

Scalability can be Vertical and Horizontal

Happy App


more happy App?


Solution?


Cache concept


An area of local memory that holds a copy of 
frequently accessed data that is otherwise 
expensive to get or compute

Cache types:
  • Application cache
  • Second level (L2) cache
  • Hybrid cache

Application cache


l2 cache


Hybrid cache


key cache terms



  • Cache size - defines how many elements a cache can hold;
  • Cache eviction - algorithm defines what to do when the number of elements in cache exceeds the size (LRU, LFU, FIFO) & eviction percentage;
  • Time-to-live - defines time after that a cache key should be remove from the cache (expired);

REPLICATED CACHE VS distributed cache 



Peer-to-peer cluster



Clients and server cluster


Hybrid cluster


frameworks overview



*IMDG - In-Memory Data Grid


Scalable data grid platform
  • open-source - LGPL
  • based on some JBoss Cache code

JBoss Cache
  • clustered caching library

Infinispan has a Map-like API(JSR-107 JCACHE)
  • can be used as Key-Value No-SQL solution
  • has Hibernate4 cache region&provider implementation

POm.xml


         <!--Infinispan-->
        <dependency>
            <groupId>org.infinispan</groupId>
            <artifactId>infinispan-core</artifactId>
            <version>6.0.2.Final</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-infinispan</artifactId>
            <version>${hibernate.version}</version>
        </dependency>
        <dependency>
            <groupId>org.jboss.jbossts</groupId>
            <artifactId>jbossjta</artifactId>
            <version>4.16.4.Final</version>
        </dependency>

Infinispan.xml

<infinispan xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="urn:infinispan:config:6.0 http://www.infinispan.org/schemas/infinispan-config-6.0.xsd"
    xmlns="urn:infinispan:config:6.0">
    <global>
        <transport nodeName="caching" clusterName="caching_cluster" transportClass="org.infinispan.remoting.transport.jgroups.JGroupsTransport">
            <properties> <property name="configurationFile" value="tcp.xml"/>
            </properties>
        </transport>
    </global>
    <default>
        <clustering mode="dist"><async/>
        </clustering>
        <eviction maxEntries="1000" strategy="LRU"/>
    </default>
    <namedCache name="productBrand.region">
        <clustering mode="dist"/>
        <eviction strategy="LRU" maxEntries="5000" threadPolicy="DEFAULT"/>
        <expiration maxIdle="10"/>
    </namedCache>
</infinispan>

datasourceContext-infinispan.xml


cached entity

@Entity
@Table(name = "PRODUCT_CATEGORY")
@Cache(region = "productCategory.region", usage = CacheConcurrencyStrategy.TRANSACTIONAL)
public class ProductCategory {

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(name = "CATEGORY_ID")
    private Long id;

    @Column(name = "NAME")
    private String name;

    @Cache(region = "productCategory.brands.region", usage = CacheConcurrencyStrategy.TRANSACTIONAL)
    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @JoinTable(name = "BRAND_CATEGORY", joinColumns = @JoinColumn(name = "CATEGORY_ID"), inverseJoinColumns = @JoinColumn(name = "BRAND_ID"))
    private List<ProductBrand> brands;
...
}

application cache


Cache<Object, Object> cache = new DefaultCacheManager().getCache();// Add a entry
cache.put("key", "value");
// Remove the entry from the cache
Object v = cache.remove("key");
// And replace it if missing
cache.putIfAbsent("key", "newValue");
cache.clear();
//By default entries are immortal but we can override this on a per-key basis and provide lifespans.
cache.put("key", "value", 5, SECONDS);


Apache license

1 solid Jar file ~3MB + HibernateProvider

Transactional & Secure

IMDG

3-way configuration: XML, Java, Spring

pom.xml


  <dependency>
       <groupId>com.hazelcast</groupId>
       <artifactId>hazelcast</artifactId>
       <version>3.2.1</version>
  </dependency>
  <dependency>
       <groupId>com.hazelcast</groupId>
       <artifactId>hazelcast-hibernate4</artifactId>
       <version>3.2.1</version>
   </dependency>
   <dependency>
       <groupId>com.hazelcast</groupId>
       <artifactId>hazelcast-spring</artifactId>
       <version>3.2.1</version>
   </dependency>

Hazelcast.xml

<hazelcast>
    <group name="dev" password="dev"/>
    <network>
        <port auto-increment="true">5701</port>
        <outbound-ports><ports>0</ports></outbound-ports>
        <join>
            <multicast enabled="false">
                <multicast-group>231.12.21.135</multicast-group>
                <multicast-port>45564</multicast-port>
                <multicast-timeout-seconds>2</multicast-timeout-seconds>
            </multicast>
            <tcp-ip enabled="true"><interface>127.0.0.1</interface></tcp-ip>
        </join>
        <interfaces enabled="true"><interface>127.0.0.*</interface></interfaces>
        <ssl enabled="false"/>
        <socket-interceptor enabled="false"/>
        <symmetric-encryption enabled="false"/>
    </network>
    <partition-group enabled="false"/>
    <executor-service name="default">
        <pool-size>16</pool-size>
        <queue-capacity>0</queue-capacity>
    </executor-service>

HAZELCAST.XML


   <map name="default"/>

    <map name="productCategory.brands.region">
        <in-memory-format>OBJECT</in-memory-format>
        <backup-count>2</backup-count>
        <async-backup-count>0</async-backup-count>
        <time-to-live-seconds>90</time-to-live-seconds>
        <max-idle-seconds>0</max-idle-seconds>
        <eviction-policy>LRU</eviction-policy>
        <max-size policy="PER_NODE">5000</max-size>
        <eviction-percentage>30</eviction-percentage>
        <merge-policy>com.hazelcast.map.merge.PassThroughMergePolicy</merge-policy>
        <read-backup-data>true</read-backup-data>
    </map>
</hazelcast>

DATASOURCECONTEXT-hazelcast.XML



  <!-- SessionFactory bean with Hazelcast Hibernate properties -->
<prop key="hibernate.cache.region.factory_class">com.hazelcast.hibernate.HazelcastCacheRegionFactory</prop>
<prop key="hibernate.cache.hazelcast.configuration_file_path">hazelcast.xml</prop>
<prop key="hibernate.cache.hazelcast.use_lite_member">true</prop>
<prop key="hibernate.cache.hazelcast.shutdown_on_session_factory_close">false</prop>

Cached Entity


 
@Entity
@Table(name = "PRODUCT_CATEGORY")
@Cache(region = "productCategory.region", usage = CacheConcurrencyStrategy.READ_WRITE)
public class ProductCategory {

	...
    @Cache(region = "productCategory.brands.region", usage = CacheConcurrencyStrategy.READ_WRITE)
    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @JoinTable(name = "BRAND_CATEGORY", joinColumns = @JoinColumn(name = "CATEGORY_ID"), inverseJoinColumns = @JoinColumn(name = "BRAND_ID"))
    private List<ProductBrand> brands;
	...
}

Application cache




Config cfg = new Config();
HazelcastInstance instance = Hazelcast.newHazelcastInstance(cfg);
Map<Integer, String> mapCustomers = instance.getMap("customers");
mapCustomers.put(1, "Joe");
mapCustomers.put(2, "Ali");
mapCustomers.put(3, "Avi");

conclusion


Hazelcast wins!


REferences

  • http://docs.oracle.com/cd/E18686_01/coh.37/e18677/cache_intro.htm
  • http://coherence.oracle.com/display/COH31UG/Read-Through,+Write- Through,+Refresh-Ahead+and+Write-Behind+Caching
  • http://blog.tekmindsolutions.com/oracle-coherence-diffrence-between- replicated-cache-vs-partitioneddistributed-cache/
  • http://www.slideshare.net/MaxAlexejev/from-distributed-caches-to- inmemory-data-grids
  • http://www.slideshare.net/jaxlondon2012/clustering-your-application- with-hazelcast
  • http://www.gridgain.com/blog/fyi/cache-data-grid-database/
  • http://gridgaintech.wordpress.com/2013/10/19/distributed-caching-is- dead-long-live/
  • http://www.hazelcast.com/resources/the-book-of-hazelcast/
  • https://labs.consol.de/java-caches/part-3-3-peer-to-peer-with-hazelcast/

hibernate-dist-cache

By Yegor Bondar

hibernate-dist-cache

  • 1,603