Devoxx 2013 - Hazelcast

Post on 28-Aug-2014

133 views 3 download

Tags:

description

www.hazelcast.com

Transcript of Devoxx 2013 - Hazelcast

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