HAZELCAST
OU
LE CLUSTERING FACILE !

BBL – février 2014
A propos…
! 

Sylvain Wallez
Architecte et dev expert freelance
Web/Java/Scala
!  2014 - Fondateur de Actoboard
!  2011 - Backend architect de Sigfox
!  2008 - CTO de Goojet/Scoop.it
!  2006 - Backend architect Joost
!  2003 - Premier VP Apache français
!  2000 - Cofondateur & CTO Anyware Technologies
sylvain@bluxte.net
http://bluxte.net
Twitter: @bluxte
! 
Mise en bouche
Une appli distribuée en 5 lignes !
Mise en bouche
! 

La Map classique
public static void main(String[] args) {	
	
	
Map<String, String> map = new HashMap<>();	
	
map.put("hello", "world");	
String value = map.get("hello");	
	
	
}
Mise en bouche
! 

La ConcurrentMap
public static void main(String[] args) {	
	
	
ConcurrentMap<String, String> map = new ConcurrentHashMap<>();	
	
map.put("hello", "world");	
String value = map.get("hello");	
	
String previous = map.putIfAbsent("goodbye", "marylou");	
}
Mise en bouche
! 

La ConcurrentMap distribuée
public static void main(String[] args) {	
HazelcastInstance hz = Hazelcast.newHazelcastInstance();	
	
ConcurrentMap<String, String> map = hz.getMap("mymap");	
	
map.put("hello", "world");	
String value = map.get("hello");	
	
String previous = map.putIfAbsent("goodbye", "marylou");	
}
Mise en bouche

Démo
Hazelcast features
Mais que vient-on de voir ?
Buzzword bingo !
In-memory data grid
!  Open source, Apache Licence
!  P2P elastic cache
!  Distributed event bus
!  NoSQL datastore
!  Cluster coordination
!  Distributed computing
! 
La concurrence
Oracle Coherence
!  IBM Extreme Scale
!  VMware Gemfire
!  Gigaspaces
!  JBoss Infinispan
!  Gridgain
!  Terracotta
! 
In-memory data grid
! 

La Map classique, plus des bonus
	
	
	

Asynchrone

	
	
	

HazelcastInstance hz = Hazelcast.newHazelcastInstance();	
IMap<String, String> map = hz.getMap("mymap");	
map.put("hello", "world");	
String value = map.get("hello");	
Future<String> future = map.getAsync("hello");	

Expiration

map.put("goodbye", "marylou", 10, TimeUnit.MINUTES);	
Set<Entry<String, String>> set = map.entrySet(new Predicate<String, String>() {	
public boolean apply(Entry<String, String> entry) {	
return entry.getKey().contains("z");	
}	
});	

Filtrage « in grid »
P2P elastic cache
! 

Partitionnement et réplication automatiques
P2P elastic cache
! 

Ajout dynamique de nouveaux noeuds

New!

Multicast
P2P elastic cache
! 

Redistribution des données
P2P elastic cache
! 

Redistribution des données
P2P elastic cache
! 

Redistribution des données
P2P event bus
! 

Les topics : broadcast à tous les listeners
	
	
	

ITopic<String> topic = hz.getTopic("alerts");	
topic.addMessageListener(new MessageListener<String>() {	
public void onMessage(Message<String> message) {	

	

}	

	

println("Received " + message.getMessageObject() +	
" from " + message.getPublishingMember());	

});	

Nœud d’origine
du message
P2P event bus
! 

Les queues
	

	

	
BlockingQueue<String> queue = hz.getQueue("jobs");	
	
queue.offer("Make me a sandwich");	
	

	
BlockingQueue<String> queue = hz.getQueue("jobs");

	

while(true) {	
String job = queue.take();	
println("Now working on " + job);	
}	

(Aussi en asynchrone avec poll() et les listeners)
NoSQL datastore
! 

Stockage persistant
NoSQL datastore
! 

La Map « interrogeable »

Indexation des
propriétés

	
	
	

IMap<Long, Employee> map = hz.getMap("employee");	
map.addIndex("active", true);	
map.addIndex("age", true);	
Collection<Employee> employees =	
map.values(new SqlPredicate("active AND age < 30"));	

Sous ensemble de SQL sur
les propriétés JavaBean
Cluster coordination
! 

Compteurs distribués
	
	
	

	

IAtomicLong reqCount = hz.getAtomicLong("users");	
// Start request	
long count = reqCount.incrementAndGet();	
try {	
// Do some stuff	
println("There are " + count + " request in progress");	
} finally {	
// End request	
reqCount.decrementAndGet();	
}
Cluster coordination
! 

Locks distribués (à utiliser avec parcimonie)
	

	
	

Lock lock = hz.getLock("maintenance_mode");	
lock.lock();	
try {	
// There can be only one in the cluster	
} finally {	
lock.unlock();	
}	

ILock lock = hz.getLock("maintenance_mode");	
lock.lock(10, TimeUnit.SECONDS);	
try {	
// There can be only one in the cluster	
} finally {	
lock.unlock();	
}	

Protection :
durée limitée
Distributed computing
! 

Un ExecutorService distribué
	

ExecutorService executor = hz.getExecutorService("compute");	
	
Runnable job = null;	
Callable<String> jobWithResult = null;	
	
executor.execute(job);	
Future<String> future = executor.submit(jobWithResult);
Distributed computing
! 

Un ExecutorService distribué
!  Fonctions

Data
locality

avancées de IExecutorService

IExecutorService executor = hz.getExecutorService("compute");	
	
Runnable job = null;	
Callable<String> jobWithResult = null;	
Choix explicite
	
du noeud
executor.executeOnKeyOwner(job, 42);	
	
Member member = hz.getPartitionService().getPartition(42).getOwner();	
println("Submitting to IP address " + member.getInetSocketAddress());	
	
executor.submitToMember(jobWithResult, member, new ExecutionCallback<String>() {	
public void onResponse(String response) {	
println("Result is " + response);	
}	
	
Callback
public void onFailure(Throwable t) {	
println("Job failed");	
asynchrone
}	
});	
	
	
}
Administration
Administration
JMX
!  API de statistiques sur Cluster et Member
!  Webapp Management Center
! 
Management Center
Management Center
Management Center
Merci !

Questions ?
Réponses !

Brown Bag Lunch sur Hazelcast

  • 1.
    HAZELCAST OU LE CLUSTERING FACILE! BBL – février 2014
  • 2.
    A propos… !  Sylvain Wallez Architecteet dev expert freelance Web/Java/Scala !  2014 - Fondateur de Actoboard !  2011 - Backend architect de Sigfox !  2008 - CTO de Goojet/Scoop.it !  2006 - Backend architect Joost !  2003 - Premier VP Apache français !  2000 - Cofondateur & CTO Anyware Technologies sylvain@bluxte.net http://bluxte.net Twitter: @bluxte ! 
  • 3.
    Mise en bouche Uneappli distribuée en 5 lignes !
  • 4.
    Mise en bouche !  LaMap classique public static void main(String[] args) { Map<String, String> map = new HashMap<>(); map.put("hello", "world"); String value = map.get("hello"); }
  • 5.
    Mise en bouche !  LaConcurrentMap public static void main(String[] args) { ConcurrentMap<String, String> map = new ConcurrentHashMap<>(); map.put("hello", "world"); String value = map.get("hello"); String previous = map.putIfAbsent("goodbye", "marylou"); }
  • 6.
    Mise en bouche !  LaConcurrentMap distribuée public static void main(String[] args) { HazelcastInstance hz = Hazelcast.newHazelcastInstance(); ConcurrentMap<String, String> map = hz.getMap("mymap"); map.put("hello", "world"); String value = map.get("hello"); String previous = map.putIfAbsent("goodbye", "marylou"); }
  • 7.
  • 8.
    Hazelcast features Mais quevient-on de voir ?
  • 9.
    Buzzword bingo ! In-memorydata grid !  Open source, Apache Licence !  P2P elastic cache !  Distributed event bus !  NoSQL datastore !  Cluster coordination !  Distributed computing ! 
  • 10.
    La concurrence Oracle Coherence ! IBM Extreme Scale !  VMware Gemfire !  Gigaspaces !  JBoss Infinispan !  Gridgain !  Terracotta ! 
  • 11.
    In-memory data grid !  LaMap classique, plus des bonus Asynchrone HazelcastInstance hz = Hazelcast.newHazelcastInstance(); IMap<String, String> map = hz.getMap("mymap"); map.put("hello", "world"); String value = map.get("hello"); Future<String> future = map.getAsync("hello"); Expiration map.put("goodbye", "marylou", 10, TimeUnit.MINUTES); Set<Entry<String, String>> set = map.entrySet(new Predicate<String, String>() { public boolean apply(Entry<String, String> entry) { return entry.getKey().contains("z"); } }); Filtrage « in grid »
  • 12.
    P2P elastic cache !  Partitionnementet réplication automatiques
  • 13.
    P2P elastic cache !  Ajoutdynamique de nouveaux noeuds New! Multicast
  • 14.
  • 15.
  • 16.
  • 17.
    P2P event bus !  Lestopics : broadcast à tous les listeners ITopic<String> topic = hz.getTopic("alerts"); topic.addMessageListener(new MessageListener<String>() { public void onMessage(Message<String> message) { } println("Received " + message.getMessageObject() + " from " + message.getPublishingMember()); }); Nœud d’origine du message
  • 18.
    P2P event bus !  Lesqueues BlockingQueue<String> queue = hz.getQueue("jobs"); queue.offer("Make me a sandwich"); BlockingQueue<String> queue = hz.getQueue("jobs"); while(true) { String job = queue.take(); println("Now working on " + job); } (Aussi en asynchrone avec poll() et les listeners)
  • 19.
  • 20.
    NoSQL datastore !  La Map« interrogeable » Indexation des propriétés IMap<Long, Employee> map = hz.getMap("employee"); map.addIndex("active", true); map.addIndex("age", true); Collection<Employee> employees = map.values(new SqlPredicate("active AND age < 30")); Sous ensemble de SQL sur les propriétés JavaBean
  • 21.
    Cluster coordination !  Compteurs distribués IAtomicLongreqCount = hz.getAtomicLong("users"); // Start request long count = reqCount.incrementAndGet(); try { // Do some stuff println("There are " + count + " request in progress"); } finally { // End request reqCount.decrementAndGet(); }
  • 22.
    Cluster coordination !  Locks distribués(à utiliser avec parcimonie) Lock lock = hz.getLock("maintenance_mode"); lock.lock(); try { // There can be only one in the cluster } finally { lock.unlock(); } ILock lock = hz.getLock("maintenance_mode"); lock.lock(10, TimeUnit.SECONDS); try { // There can be only one in the cluster } finally { lock.unlock(); } Protection : durée limitée
  • 23.
    Distributed computing !  Un ExecutorServicedistribué ExecutorService executor = hz.getExecutorService("compute"); Runnable job = null; Callable<String> jobWithResult = null; executor.execute(job); Future<String> future = executor.submit(jobWithResult);
  • 24.
    Distributed computing !  Un ExecutorServicedistribué !  Fonctions Data locality avancées de IExecutorService IExecutorService executor = hz.getExecutorService("compute"); Runnable job = null; Callable<String> jobWithResult = null; Choix explicite du noeud executor.executeOnKeyOwner(job, 42); Member member = hz.getPartitionService().getPartition(42).getOwner(); println("Submitting to IP address " + member.getInetSocketAddress()); executor.submitToMember(jobWithResult, member, new ExecutionCallback<String>() { public void onResponse(String response) { println("Result is " + response); } Callback public void onFailure(Throwable t) { println("Job failed"); asynchrone } }); }
  • 25.
  • 26.
    Administration JMX !  API destatistiques sur Cluster et Member !  Webapp Management Center ! 
  • 27.
  • 28.
  • 29.
  • 30.