EhCache3 In Memory Caching for Performance Improvement
If you are reading this you already know that caching is mechanism to store static data In-Memory for faster access and avoid expensive database calls or any kind of service calls to get the data.
There are many ways to implement cache in java based applications, starting from very simple Map
EhCache3 Implementation
<dependency>
<groupId>org.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>3.4.0</version>
</dependency>
<dependency> <!-- We need this because ehcache uses slf4j for logging -->
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.25</version>
</dependency>
Item Expiry - If entry in the cache meets the expiry condition, it will be evicted (removed) from the cache. To standard type of expiry conditions are Time-To-Live and Time-To-Idle. I will use Time-To-Live
Cache Max Size - Maximum size up to which the cache can grow. The max size constraint can be set by byte size (KB, MB etc) or no on entries in the cache. I will use no of entries.
<?xml version="1.0" encoding="UTF-8"?>
<config xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
xmlns='http://www.ehcache.org/v3'
xsi:schemaLocation="http://www.ehcache.org/v3 http://www.ehcache.org/schema/ehcache-core.xsd">
<cache alias="PersonCache">
<key-type>java.lang.Integer</key-type>
<value-type>com.rakesh.caching.Person</value-type>
<expiry>
<ttl unit="seconds">30</ttl>
</expiry>
<resources>
<heap unit="entries">5</heap>
</resources>
</cache>
</config>
Person.java
package com.rakesh.caching;
public class Person {
private int personId;
private String firstName;
private String lastName;
public Person(){}
public Person(int personId, String firstName, String lastName) {
super();
this.personId = personId;
this.firstName = firstName;
this.lastName = lastName;
}
public int getPersonId() {
return personId;
}
public void setPersonId(int personId) {
this.personId = personId;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
@Override
public String toString() {
return "Person [personId=" + personId + ", firstName=" + firstName + ", lastName=" + lastName + "]";
}
}
AppCacheManager.java
package com.rakesh.caching;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import org.ehcache.Cache;
import org.ehcache.CacheManager;
import org.ehcache.config.Configuration;
import org.ehcache.config.builders.CacheManagerBuilder;
import org.ehcache.xml.XmlConfiguration;
public class AppCacheManager {
private static AppCacheManager instance = null;
private CacheManager cacheManage = null;
private AppCacheManager() {
try {
URL ehcacheXmlUrl = new File("./resources/ehcache.xml").toURI().toURL();
Configuration xmlConfig = new XmlConfiguration(ehcacheXmlUrl);
cacheManage = CacheManagerBuilder.newCacheManager(xmlConfig);
cacheManage.init();
System.out.println("Cache Initialized");
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
public static AppCacheManager getInstance() {
if (instance == null) {
instance = new AppCacheManager();
}
return instance;
}
public Cache getPersonCache(){
return this.cacheManage.getCache("PersonCache", Integer.class, Person.class);
}
}
MainApp.java
package com.rakesh.caching;
import java.util.Date;
import org.ehcache.Cache;
public class MyMain {
public static void main(String[] args) throws Exception {
new MyMain().doMain();
}
private void doMain() throws Exception{
Cache personCache = AppCacheManager.getInstance().getPersonCache();
Person p;
for(int i=1; i<=7; i++){
p = new Person(i, "firstName-"+1, "lastName-"+i);
personCache.put(p.getPersonId(), p);
}
System.out.println("Entries in the Cache at: " + new Date());
System.out.println("--------------------");
for(int i=1; i<=7; i++){
p = new Person(i, "firstName-"+1, "lastName-"+i);
System.out.println("Key: " + i + ", Value: " +personCache.get(i));
}
System.out.println("\nWaiting for 40 seconds\n");
//Wait for 40 seconds so that we reach cache expiry threshold which is 30 seconds
Thread.sleep(1000*40);
System.out.println("\nAfter 40 seconds wait\n");
System.out.println("Entries in the Cache at: " + new Date());
System.out.println("--------------------");
for(int i=1; i<=7; i++){
p = new Person(i, "firstName-"+1, "lastName-"+i);
System.out.println("Key: " + i + ", Value: " +personCache.get(i));
}
}
}
Output
Cache Initialized
Entries in the Cache at: Sat Jan 06 14:31:04 EST 2018
--------------------
Key: 1, Value: null
Key: 2, Value: null
Key: 3, Value: Person [personId=3, firstName=firstName-1, lastName=lastName-3]
Key: 4, Value: Person [personId=4, firstName=firstName-1, lastName=lastName-4]
Key: 5, Value: Person [personId=5, firstName=firstName-1, lastName=lastName-5]
Key: 6, Value: Person [personId=6, firstName=firstName-1, lastName=lastName-6]
Key: 7, Value: Person [personId=7, firstName=firstName-1, lastName=lastName-7]
After 40 seconds wait
Entries in the Cache at: Sat Jan 06 14:31:44 EST 2018
--------------------
Key: 1, Value: null
Key: 2, Value: null
Key: 3, Value: null
Key: 4, Value: null
Key: 5, Value: null
Key: 6, Value: null
Key: 7, Value: null
Explanation
As always comments and feedback are welcome.
Comments
Post a Comment