Upload
hazelcast
View
141
Download
3
Tags:
Embed Size (px)
DESCRIPTION
www.hazelcast.com
Citation preview
@PeterVeentjer#DV13-{session hashtag}
Distributed Systems Using Hazelcast
Peter Veentjer
@PeterVeentjer#DV13-{session hashtag}
• Working for Hazelcast
• Senior developer
• Solution architect
• Author of ‘Pragmatic Guide to Hazelcast 3'
• 13 years Java experience
• Big love
• Concurrency control
• Distributed computing
Whoami
@PeterVeentjer#DV13-{session hashtag}
@PeterVeentjer#DV13-{session hashtag}
What is Hazelcast?
@PeterVeentjer#DV13-{session hashtag}
What is Hazelcast?
• Leading Open Source Java In Memory Data/Compute Grid
• Main goal is to simplify development of:
• Scalable systems
• Highly available systems
@PeterVeentjer#DV13-{session hashtag}
Why Hazelcast?
• 2.5 MByte JAR
• no other dependencies!
• no need to install software!
• Its a library, not an application framework
• Scale at the application level
• Apache 2 License
• Free to use
• no limitations
@PeterVeentjer#DV13-{session hashtag}
Distributed Data-structures
• IAtomicLong
• IdGenerator
• Lock/Condition
• CountDownLatch
• Semaphore
• Queue
• Map
• MultiMap
• Set
• List
• Topic
• Executor
• TransactionalMap/Q/S…
• Write your own!
@PeterVeentjer#DV13-{session hashtag}
So what can I do with it?
@PeterVeentjer#DV13-{session hashtag}
Scale up
@PeterVeentjer#DV13-{session hashtag}
Scale Out
@PeterVeentjer#DV13-{session hashtag}
High Availability
@PeterVeentjer#DV13-{session hashtag}
Raspberry Pi Cluster
@PeterVeentjer#DV13-{session hashtag}
When?• Messaging Solution
• Event processing
• Clustered Scheduling
• Job Processing
• Cluster management
• HTTP session clustering
• Caching
@PeterVeentjer#DV13-{session hashtag}
Which companies
• Financials
• JP Morgan, Morgan Stanley, HSBC, Deutsche Bank
• Telco’s
• AT&T, Ericsson
• Gaming
• Ubisoft/Blue Byte
• E-Commerce
• Apple, eBay
@PeterVeentjer#DV13-{session hashtag}
Which Open Source Projects
• WSO2 Carbon
• Mule ESB
• Vert.x
• Apache Camel
• Apache Shiro
• OrientDB
• Alfresco
• Karaf
@PeterVeentjer#DV13-{session hashtag}
NO SQL FAMILY
Hazelcast
Coherence
Infinispan
Gigaspaces
Datagrids Key Value Stores Document DB’s Column DB’s
Mongo
MarkLogic
CassandraRedis
CouchDB
HBaseRiak
Voldimort
Graph DB’s
Neo4J
@PeterVeentjer#DV13-{session hashtag}
How Often
• In October 2013
• 3M startups
• 48K unique
@PeterVeentjer#DV13-{session hashtag}
Where is the code!
@PeterVeentjer#DV13-{session hashtag}
HazelcastInstance hz = Hazelcast.newHazelcastInstance();
Creating Hazelcast Cluster
@PeterVeentjer#DV13-{session hashtag}
<hazelcast> <network>…</network> <map name=“m”>…</map> <queue name=“q”>…</queue> <… </hazelcast>
XML Configuration
@PeterVeentjer#DV13-{session hashtag}
Config config = new Config(); … make config modifications HazelcastInstance hz = Hazelcast.newHazelcastInstance(config);
Programmatic Configuration
Demo
@PeterVeentjer#DV13-{session hashtag}
@PeterVeentjer#DV13-{session hashtag}
Map<String,String> products = new HashMap(); map.put("1","IPhone");
Map
@PeterVeentjer#DV13-{session hashtag}
Map<String,String> products = new ConcurrentHashMap(); map.put("1","IPhone");
Map
@PeterVeentjer#DV13-{session hashtag}
HazelcastInstance hz = Hazelcast.newHazelcastInstance(); Map<String,String> products = hz.getMap("products"); cities.put("1","IPhone");
Map
Demo
@PeterVeentjer#DV13-{session hashtag}
@PeterVeentjer#DV13-{session hashtag}
!<map name="products"> <time-‐to-‐live-‐seconds>4</time-‐to-‐live-‐seconds> <indexes> <index>name</index> </indexes> <..> </map>
Map Configuration
@PeterVeentjer#DV13-{session hashtag}
Map Scalability and High Availability
271 Partitions
partitionid = hash(key) % partitioncount
…
@PeterVeentjer#DV13-{session hashtag}
Map Scalability and High Availability
Member 1
@PeterVeentjer#DV13-{session hashtag}
Map Scalability and High Availability
Member 1
Member 2
Member 3
@PeterVeentjer#DV13-{session hashtag}
Map Scalability and High Availability
Member 1
Member 2
Member 3
@PeterVeentjer#DV13-{session hashtag}
Map Scalability and High Availability
Member 1
Member 2
Member 3
@PeterVeentjer#DV13-{session hashtag}
Map Scalability and High Availability
Member 1
Member 2
Demo
@PeterVeentjer#DV13-{session hashtag}
@PeterVeentjer#DV13-{session hashtag}
Map Persistence
• Data Connection
• MapLoader
• MapStore
!
• Write through
• Write behind
@PeterVeentjer#DV13-{session hashtag}
Multimap
• Collection as value
• Serialization Overhead
• Lost update
Demo
@PeterVeentjer#DV13-{session hashtag}
@PeterVeentjer#DV13-{session hashtag}
BlockingQueue queue = new LinkedBlockingQueue(); queue.offer("1"); Object item = queue.take();
Queue
@PeterVeentjer#DV13-{session hashtag}
!HazelcastInstance hz = Hazelcast.newHazelcastInstance(); BlockingQueue queue = hz.getQueue("queue"); queue.offer("1"); Object item = queue.take();
Queue
Demo
@PeterVeentjer#DV13-{session hashtag}
@PeterVeentjer#DV13-{session hashtag}
ITopic topic = hz.getTopic("topic"); //publishing topic.publish(msg); !//subscribing topic.addMessageListener(new TopicSubscriber()); !public class TopicSubscriber implements MessageListener<String> { public void onMessage(Message<String> m) { System.out.println(m.getMessageObject()); } }
Topic
@PeterVeentjer#DV13-{session hashtag}
Client
• Simplified
• Encryption
• Load Balance Policy
• C++ and C# version
@PeterVeentjer#DV13-{session hashtag}
HazelcastInstance client = HazelcastClient.newHazelcastClient();
Client
@PeterVeentjer#DV13-{session hashtag}
Network Communication
• Cluster Discovery
• Multicast
• TCP/IP Cluster
• AWS Cluster
• Normal Network Communication
• TCP/IP
@PeterVeentjer#DV13-{session hashtag}
Advanced Hazelcast
@PeterVeentjer#DV13-{session hashtag}
IMap map1 = hz.getMap(“map1”); IMap map2 = hz.getMap(“map2”);<map name=“map1”> <time-‐to-‐live-‐seconds>10</time-‐to-‐live-‐seconds> </map> !<map name=“map2”> <time-‐to-‐live-‐seconds>10</time-‐to-‐live-‐seconds> </map>
Wildcard configuration
@PeterVeentjer#DV13-{session hashtag}
IMap map1 = hz.getMap(“map1”); IMap map2 = hz.getMap(“map2”); !<map name=“map*”> <time-‐to-‐live-‐seconds>10</time-‐to-‐live-‐seconds> </map>
Wildcard configuration
@PeterVeentjer#DV13-{session hashtag}
<map name=“map”> <time-‐to-‐live-‐seconds>${ttl}</time-‐to-‐live-‐seconds> </map>
XML Variables
@PeterVeentjer#DV13-{session hashtag}
Map: In Memory Format
• 2 Options
• BINARY
• OBJECT
• Predicates
• EntryProcessor
@PeterVeentjer#DV13-{session hashtag}
!ILock lock = hz.getLock(“someLock”); IAtomicLong counter = getAtomicLong(“someCounter”); IMap map = hz.getMap(“someMap”); map.put(“somePerson”,new Person()); map.get(“somePerson”);
Data Locality: Problem
@PeterVeentjer#DV13-{session hashtag}
Member 1
Member 2
Member 3
SomeLock
SomeCounter
SomePerson
@PeterVeentjer#DV13-{session hashtag}
name@partitionkey
name
@PeterVeentjer#DV13-{session hashtag}
ILock lock = hz.getLock(“someLock@foo”);IAtomicLong counter = hz.getAtomicLong(“someCounter@foo”); IMap map = hz.getMap(“someMap”); map.put(“somePerson@foo”, new Person()); Person p = map.get(“somePerson@foo”);
Data Locality: Fixed
@PeterVeentjer#DV13-{session hashtag}
Member 1
Member 2
Member 3
SomeLock
SomeCounter
SomePerson
Foo Partition
@PeterVeentjer#DV13-{session hashtag}
IAtomicLong c1 = … IAtomicLong c2 = hz.getAtomicLong(“c2@“+c1.getPartitionKey());
Adding object in same partition
@PeterVeentjer#DV13-{session hashtag}
Executor
• Execute task anywhere
• Execute task on key owner
• Execute task
• one/all/subset members
• Synchronisation
• ExecutionCallback
• Futures
Demo
@PeterVeentjer#DV13-{session hashtag}
@PeterVeentjer#DV13-{session hashtag}
Concurrency Control
• Locks
• TransactionalMap.getForUpdate
• Map.Lock
Demo
@PeterVeentjer#DV13-{session hashtag}
@PeterVeentjer#DV13-{session hashtag}
public void increment(int accountId,int amount){ Account account = accounts.get(accountId); account.balance+=amount; accounts.put(accountId, account); }
Race problem
@PeterVeentjer#DV13-{session hashtag}
public void increment(int accountId,int amount){ accounts.lock(accountId); try{ Account account = accounts.get(accountId); account.balance+=amount; accounts.put(accountId, account); }finally{ accounts.unlock(accountId); } }
Pessimistic Increment
@PeterVeentjer#DV13-{session hashtag}
public void increment(int accountId,int amount){ accounts.lock(accountId); try{ Account account = accounts.get(accountId); account.balance+=amount; accounts.put(accountId, account); }finally{ accounts.unlock(accountId); } }
Pessimistic Increment
@PeterVeentjer#DV13-{session hashtag}
public void increment(int accountId,int amount){ for(;;){ Account oldAccount = accounts.get(accountId); Account newAccount = new Account(oldAccount); newAccount.balance+=amount; if(accounts.replace(accountId, oldAccount,newAccount)){ return; } } }
Optimistic Increment
@PeterVeentjer#DV13-{session hashtag}
public void increment(int accountId,int amount){ for(;;){ Account oldAccount = accounts.get(accountId); Account newAccount = new Account(oldAccount); newAccount.balance+=amount; if(accounts.replace(accountId, oldAccount,newAccount)){ return; } } }
Optimistic Increment
@PeterVeentjer#DV13-{session hashtag}
DATA
Bad: Send Data to Function
DATA
Good: Send Function to Data
Read Data
Write Data
Write Function
@PeterVeentjer#DV13-{session hashtag}
private class BalanceTask implements Runnable,Serializable{ private int accountId, amount; ! public void run() { for(;;){ Account oldAccount = accounts.get(accountId); Account newAccount = new Account(oldAccount); newAccount.balance+=amount; if(accounts.replace(accountId, oldAccount,newAccount)){ return; } } } }
Increment with runnable
@PeterVeentjer#DV13-{session hashtag}
public void increment(int accountId, int amount){ BalanceTask task = new BalanceTask(accountId,amount); executorService.executeOnKeyOwner(task,accountId); }
Increment with runnable
@PeterVeentjer#DV13-{session hashtag}
class BalanceProcessor extends AbstractEntryProcessor<Integer,Account>{ int amount; BalanceProcessor(int amount) { this.amount = amount; } ! @Override public Object process(Map.Entry<Integer, Account> entry) { entry.getValue().balance+=amount; return null; } }
Increment with EntryProcessor
@PeterVeentjer#DV13-{session hashtag}
public void increment(int accountId, int amount){ BalanceProcessor processor = new BalanceProcessor(amount); accounts.executeOnKey(accountId, processor); }
Using entry processor
@PeterVeentjer#DV13-{session hashtag}
SPI• You can write your own distributed data-structures
• Examples
• Distributed Actors implementation
• Remote interfaces
@PeterVeentjer#DV13-{session hashtag}
Serialization API
• Serializable/Externalizable
• Portable
• ByteArraySerializable
• StreamSerializer
• Kryo
• Jackson Smile
• Protobuf
@PeterVeentjer#DV13-{session hashtag}
!boolean compress = …; !SerializerConfig serialiserCfg = new SerializerConfig() .setTypeClass(Product.class) .setImplementation(new ProductSerializer(compress)); !Config config = new Config(); config.getSerializationConfig().addSerializerConfig(serializerCfg); HazelcastInstance hz = Hazelcast.newHazelcastInstance(config);
Pluggable Serialization
@PeterVeentjer#DV13-{session hashtag}
Kryo SerializationSi
ze in
Byt
es
0
5,000
10,000
15,000
20,000
Serialization Kryo Kryp + Compr
@PeterVeentjer#DV13-{session hashtag}
IExecutorService executor = hz.getExecutor(“executor”); executor.execute(()-‐>System.out.println”hello”)); !//configuration SerializerConfig sc = new SerializerConfig(). setImplementation(new KryoSerializer(false)). setTypeClass(Runnable.class); Config config = new Config(); config.getSerializationConfig().addSerializerConfig(sc);
Kryo: Lambda expression
@PeterVeentjer#DV13-{session hashtag}
IMap<Integer,Account> accounts = hz.getMap(“accounts”); Map<Integer,Integer> result = accounts .map(new AccountSumMapper()) .reduce(new AccountSumReducer()) .submit()
Hazelcast 3.2? Map Reduce
@PeterVeentjer#DV13-{session hashtag}
Enterprise vs Community edition
• Support contracts
• Elastic Memory
• Security
• Management Center
@PeterVeentjer#DV13-{session hashtag}
The Future
• Topologies
• Hosted Management Center
• Dynamic Creation
• Map of Maps
• Tiered storage
@PeterVeentjer#DV13-{session hashtag}
We are hiring!
@PeterVeentjer#DV13-{session hashtag}
Questions?
You can find us at the Hazelcast booth!
Good Question? Get a Hazelcast
book!