79
@PeterVeentjer #DV13-{session hashtag} Distributed Systems Using Hazelcast Peter Veentjer

Devoxx 2013 - Hazelcast

Embed Size (px)

DESCRIPTION

www.hazelcast.com

Citation preview

Page 1: Devoxx 2013 - Hazelcast

@PeterVeentjer#DV13-{session hashtag}

Distributed Systems Using Hazelcast

Peter Veentjer

Page 2: Devoxx 2013 - Hazelcast

@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

Page 3: Devoxx 2013 - Hazelcast

@PeterVeentjer#DV13-{session hashtag}

Page 4: Devoxx 2013 - Hazelcast

@PeterVeentjer#DV13-{session hashtag}

What is Hazelcast?

Page 5: Devoxx 2013 - 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

Page 6: Devoxx 2013 - Hazelcast

@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

Page 7: Devoxx 2013 - Hazelcast

@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!

Page 8: Devoxx 2013 - Hazelcast

@PeterVeentjer#DV13-{session hashtag}

So what can I do with it?

Page 9: Devoxx 2013 - Hazelcast

@PeterVeentjer#DV13-{session hashtag}

Scale up

Page 10: Devoxx 2013 - Hazelcast

@PeterVeentjer#DV13-{session hashtag}

Scale Out

Page 11: Devoxx 2013 - Hazelcast

@PeterVeentjer#DV13-{session hashtag}

High Availability

Page 12: Devoxx 2013 - Hazelcast

@PeterVeentjer#DV13-{session hashtag}

Raspberry Pi Cluster

Page 13: Devoxx 2013 - Hazelcast

@PeterVeentjer#DV13-{session hashtag}

When?• Messaging Solution

• Event processing

• Clustered Scheduling

• Job Processing

• Cluster management

• HTTP session clustering

• Caching

Page 14: Devoxx 2013 - Hazelcast

@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

Page 15: Devoxx 2013 - Hazelcast

@PeterVeentjer#DV13-{session hashtag}

Which Open Source Projects

• WSO2 Carbon

• Mule ESB

• Vert.x

• Apache Camel

• Apache Shiro

• OrientDB

• Alfresco

• Karaf

Page 16: Devoxx 2013 - Hazelcast

@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

Page 17: Devoxx 2013 - Hazelcast

@PeterVeentjer#DV13-{session hashtag}

How Often

• In October 2013

• 3M startups

• 48K unique

Page 18: Devoxx 2013 - Hazelcast

@PeterVeentjer#DV13-{session hashtag}

Where is the code!

Page 19: Devoxx 2013 - Hazelcast

@PeterVeentjer#DV13-{session hashtag}

HazelcastInstance  hz  =  Hazelcast.newHazelcastInstance();

Creating Hazelcast Cluster

Page 20: Devoxx 2013 - Hazelcast

@PeterVeentjer#DV13-{session hashtag}

<hazelcast>          <network>…</network>          <map  name=“m”>…</map>          <queue  name=“q”>…</queue>          <…  </hazelcast>

XML Configuration

Page 21: Devoxx 2013 - Hazelcast

@PeterVeentjer#DV13-{session hashtag}

Config  config  =  new  Config();  …  make  config  modifications  HazelcastInstance  hz  =  Hazelcast.newHazelcastInstance(config);

Programmatic Configuration

Page 22: Devoxx 2013 - Hazelcast

Demo

@PeterVeentjer#DV13-{session hashtag}

Page 23: Devoxx 2013 - Hazelcast

@PeterVeentjer#DV13-{session hashtag}

Map<String,String>  products  =  new  HashMap();  map.put("1","IPhone");

Map

Page 24: Devoxx 2013 - Hazelcast

@PeterVeentjer#DV13-{session hashtag}

Map<String,String>  products  =  new  ConcurrentHashMap();  map.put("1","IPhone");

Map

Page 25: Devoxx 2013 - Hazelcast

@PeterVeentjer#DV13-{session hashtag}

HazelcastInstance  hz  =  Hazelcast.newHazelcastInstance();  Map<String,String>  products  =  hz.getMap("products");  cities.put("1","IPhone");  

Map

Page 26: Devoxx 2013 - Hazelcast

Demo

@PeterVeentjer#DV13-{session hashtag}

Page 27: Devoxx 2013 - Hazelcast

@PeterVeentjer#DV13-{session hashtag}

!<map  name="products">        <time-­‐to-­‐live-­‐seconds>4</time-­‐to-­‐live-­‐seconds>        <indexes>                <index>name</index>        </indexes>        <..>  </map>

Map Configuration

Page 28: Devoxx 2013 - Hazelcast

@PeterVeentjer#DV13-{session hashtag}

Map Scalability and High Availability

271 Partitions

partitionid = hash(key) % partitioncount

Page 29: Devoxx 2013 - Hazelcast

@PeterVeentjer#DV13-{session hashtag}

Map Scalability and High Availability

Member 1

Page 30: Devoxx 2013 - Hazelcast

@PeterVeentjer#DV13-{session hashtag}

Map Scalability and High Availability

Member 1

Member 2

Member 3

Page 31: Devoxx 2013 - Hazelcast

@PeterVeentjer#DV13-{session hashtag}

Map Scalability and High Availability

Member 1

Member 2

Member 3

Page 32: Devoxx 2013 - Hazelcast

@PeterVeentjer#DV13-{session hashtag}

Map Scalability and High Availability

Member 1

Member 2

Member 3

Page 33: Devoxx 2013 - Hazelcast

@PeterVeentjer#DV13-{session hashtag}

Map Scalability and High Availability

Member 1

Member 2

Page 34: Devoxx 2013 - Hazelcast

Demo

@PeterVeentjer#DV13-{session hashtag}

Page 35: Devoxx 2013 - Hazelcast

@PeterVeentjer#DV13-{session hashtag}

Map Persistence

• Data Connection

• MapLoader

• MapStore

!

• Write through

• Write behind

Page 36: Devoxx 2013 - Hazelcast

@PeterVeentjer#DV13-{session hashtag}

Multimap

• Collection as value

• Serialization Overhead

• Lost update

Page 37: Devoxx 2013 - Hazelcast

Demo

@PeterVeentjer#DV13-{session hashtag}

Page 38: Devoxx 2013 - Hazelcast

@PeterVeentjer#DV13-{session hashtag}

BlockingQueue  queue  =  new  LinkedBlockingQueue();  queue.offer("1");  Object  item  =  queue.take();  

Queue

Page 39: Devoxx 2013 - Hazelcast

@PeterVeentjer#DV13-{session hashtag}

!HazelcastInstance  hz  =  Hazelcast.newHazelcastInstance();  BlockingQueue  queue  =  hz.getQueue("queue");  queue.offer("1");  Object  item  =  queue.take();

Queue

Page 40: Devoxx 2013 - Hazelcast

Demo

@PeterVeentjer#DV13-{session hashtag}

Page 41: Devoxx 2013 - Hazelcast

@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

Page 42: Devoxx 2013 - Hazelcast

@PeterVeentjer#DV13-{session hashtag}

Client

• Simplified

• Encryption

• Load Balance Policy

• C++ and C# version

Page 43: Devoxx 2013 - Hazelcast

@PeterVeentjer#DV13-{session hashtag}

HazelcastInstance  client  =  HazelcastClient.newHazelcastClient();  

Client

Page 44: Devoxx 2013 - Hazelcast

@PeterVeentjer#DV13-{session hashtag}

Network Communication

• Cluster Discovery

• Multicast

• TCP/IP Cluster

• AWS Cluster

• Normal Network Communication

• TCP/IP

Page 45: Devoxx 2013 - Hazelcast

@PeterVeentjer#DV13-{session hashtag}

Advanced Hazelcast

Page 46: Devoxx 2013 - 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

Page 47: Devoxx 2013 - Hazelcast

@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

Page 48: Devoxx 2013 - Hazelcast

@PeterVeentjer#DV13-{session hashtag}

<map  name=“map”>          <time-­‐to-­‐live-­‐seconds>${ttl}</time-­‐to-­‐live-­‐seconds>  </map>

XML Variables

Page 49: Devoxx 2013 - Hazelcast

@PeterVeentjer#DV13-{session hashtag}

Map: In Memory Format

• 2 Options

• BINARY

• OBJECT

• Predicates

• EntryProcessor

Page 50: Devoxx 2013 - Hazelcast

@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

Page 51: Devoxx 2013 - Hazelcast

@PeterVeentjer#DV13-{session hashtag}

Member 1

Member 2

Member 3

SomeLock

SomeCounter

SomePerson

Page 52: Devoxx 2013 - Hazelcast

@PeterVeentjer#DV13-{session hashtag}

name@partitionkey

name

Page 53: Devoxx 2013 - Hazelcast

@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

Page 54: Devoxx 2013 - Hazelcast

@PeterVeentjer#DV13-{session hashtag}

Member 1

Member 2

Member 3

SomeLock

SomeCounter

SomePerson

Foo Partition

Page 55: Devoxx 2013 - Hazelcast

@PeterVeentjer#DV13-{session hashtag}

IAtomicLong  c1  =  …  IAtomicLong  c2  =  hz.getAtomicLong(“c2@“+c1.getPartitionKey());

Adding object in same partition

Page 56: Devoxx 2013 - Hazelcast

@PeterVeentjer#DV13-{session hashtag}

Executor

• Execute task anywhere

• Execute task on key owner

• Execute task

• one/all/subset members

• Synchronisation

• ExecutionCallback

• Futures

Page 57: Devoxx 2013 - Hazelcast

Demo

@PeterVeentjer#DV13-{session hashtag}

Page 58: Devoxx 2013 - Hazelcast

@PeterVeentjer#DV13-{session hashtag}

Concurrency Control

• Locks

• TransactionalMap.getForUpdate

• Map.Lock

Page 59: Devoxx 2013 - Hazelcast

Demo

@PeterVeentjer#DV13-{session hashtag}

Page 60: Devoxx 2013 - Hazelcast

@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

Page 61: Devoxx 2013 - Hazelcast

@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

Page 62: Devoxx 2013 - Hazelcast

@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

Page 63: Devoxx 2013 - Hazelcast

@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

Page 64: Devoxx 2013 - Hazelcast

@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

Page 65: Devoxx 2013 - Hazelcast

@PeterVeentjer#DV13-{session hashtag}

DATA

Bad: Send Data to Function

DATA

Good: Send Function to Data

Read Data

Write Data

Write Function

Page 66: Devoxx 2013 - Hazelcast

@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

Page 67: Devoxx 2013 - Hazelcast

@PeterVeentjer#DV13-{session hashtag}

public  void  increment(int  accountId,  int  amount){          BalanceTask  task  =  new  BalanceTask(accountId,amount);          executorService.executeOnKeyOwner(task,accountId);  }

Increment with runnable

Page 68: Devoxx 2013 - Hazelcast

@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

Page 69: Devoxx 2013 - Hazelcast

@PeterVeentjer#DV13-{session hashtag}

public  void  increment(int  accountId,  int  amount){          BalanceProcessor  processor  =  new  BalanceProcessor(amount);          accounts.executeOnKey(accountId,  processor);  }  

Using entry processor

Page 70: Devoxx 2013 - Hazelcast

@PeterVeentjer#DV13-{session hashtag}

SPI• You can write your own distributed data-structures

• Examples

• Distributed Actors implementation

• Remote interfaces

Page 71: Devoxx 2013 - Hazelcast

@PeterVeentjer#DV13-{session hashtag}

Serialization API

• Serializable/Externalizable

• Portable

• ByteArraySerializable

• StreamSerializer

• Kryo

• Jackson Smile

• Protobuf

Page 72: Devoxx 2013 - Hazelcast

@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

Page 73: Devoxx 2013 - Hazelcast

@PeterVeentjer#DV13-{session hashtag}

Kryo SerializationSi

ze in

Byt

es

0

5,000

10,000

15,000

20,000

Serialization Kryo Kryp + Compr

Page 74: Devoxx 2013 - Hazelcast

@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

Page 75: Devoxx 2013 - Hazelcast

@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

Page 76: Devoxx 2013 - Hazelcast

@PeterVeentjer#DV13-{session hashtag}

Enterprise vs Community edition

• Support contracts

• Elastic Memory

• Security

• Management Center

Page 77: Devoxx 2013 - Hazelcast

@PeterVeentjer#DV13-{session hashtag}

The Future

• Topologies

• Hosted Management Center

• Dynamic Creation

• Map of Maps

• Tiered storage

Page 78: Devoxx 2013 - Hazelcast

@PeterVeentjer#DV13-{session hashtag}

We are hiring!

Page 79: Devoxx 2013 - Hazelcast

@PeterVeentjer#DV13-{session hashtag}

Questions?

You can find us at the Hazelcast booth!

Good Question? Get a Hazelcast

book!