Payara Server Lite Nodes

Photo of Fabio Turizo by Fabio Turizo

As part of the new features introduced with the release of Payara Server 162, you can now form a cluster of Payara Server instances using the concept of Hazelcast “Lite Nodes”. This can help you create more flexible cluster topologies.

 

Lite Members

Payara Server Lite members are instances that behave in the same way as any common server instance, but they don’t store or persist any data (either using JCache or Web session storage for example), so they are effectively fully stateless in nature. These Lite members are based on the Hazelcast Lite member concept, so they have the following characteristics:

  • Better performance than native members.
  • Can register listeners for events.
  • Do not have partitions, but can access partitions held by other non-Lite members
  • Can use the Near cache

Benefits and Restrictions

So what are Lite members good for? Since Lite members don’t store information with them, you can’t use them to store web session or JCache data, so you can’t use them to store business data that needs to survive failover or instances failing in the cluster. With this restriction in mind, you can use Lite members for tasks like the following:

  • Exposing web services or stateless beans that contact data stores (like separate cache stores, databases or file storage services).
  • Hosting beans that execute heavy computational tasks or data crunching.
  • Handling event listener registrations, using Payara’s own CDI Outbound events for example.

Keep in mind that since Lite members don’t store data, a proper cluster of ONLY Lite members cannot be formed. Since Hazelcast’s partition information needs to be stored somewhere for the cluster to be properly managed, then at least one of the members of a cluster must NOT be a Lite member! Keep this in mind when preparing your cluster topology.

 

Implementation and Configuration

In order to configure a Payara Server instance as a Lite member, there are several options available (remember that Hazelcast must be enabled as well):

 

1. In the admin console, under the Hazelcast configuration panel check the Lite Cluster Member:

 Lite_Nodes_Blog.png

 

 

2. Change the configuration element in the domain.xml file:

<hazelcast-runtime-configuration lite="true" enabled="true"></hazelcast-runtime-configuration> 
./asadmin set-hazelcast-configuration --lite=true

You will notice that when the server’s domain starts, the instance will report itself as part of the cluster and will be labeled as a Lite member:

 

INFO: [192.168.1.100]:5900 [development] [3.6.2] Starting with 2 generic operation threads and 4 partition operation threads.
INFO: [192.168.1.100]:5900 [development] [3.6.2] Creating MulticastJoiner
INFO: [192.168.1.100]:5900 [development] [3.6.2] Address [192.168.1.100]:5900 is STARTING
INFO: [192.168.1.100]:5900 [development] [3.6.2] TcpIpConnectionManager configured with Non-Blocking IO-threading model: 3 input threads and 3 output threads
INFO: [192.168.1.100]:5900 [development] [3.6.2] 
Members [1] {
    Member [192.168.1.100]:5900 this lite
}
INFO: [192.168.1.100]:5900 [development] [3.6.2] Hazelcast JMX agent enabled.
INFO: [192.168.1.100]:5900 [development] [3.6.2] Address [192.168.1.100]:5900 is STARTED 

 

And what about Payara Micro? Configuring a micro instance to become a Lite member is simple as well. Just use the Lite option:

 

java -jar payara-micro.jar --lite

 

Download Payara Micro

 

You will notice that, since Lite members don’t store partition data, they don’t trigger Hazelcast repartitioning. On a non-Lite member, you will see this log message when the server starts or a new node joins:

 

[2016-07-28T19:39:37.894-0500] [Payara Micro 4.1] [INFO] [] [com.hazelcast.partition.InternalPartitionService] [tid: _ThreadID=51 _ThreadName=hz._hzInstance_1_development.migration] [timeMillis: 1469752777894] [levelValue: 800] [192.168.1.100]:5900 [development] [3.6.2] Partition balance is ok, no need to re-partition cluster data...

 

While on a Lite member you will see these messages instead:

 

[2016-07-28T19:51:05.341-0500] [Payara Micro 4.1] [INFO] [] [com.hazelcast.nio.tcp.TcpIpConnectionManager] [tid: _ThreadID=55 _ThreadName=cached3] [timeMillis: 1469753465341] [levelValue: 800] [192.168.1.100]:5901 [development] [3.6.2] Established socket connection between /192.168.1.100:5901 and /192.168.1.100:53802

 

[2016-07-28T19:51:05.461-0500] [Payara Micro 4.1] [INFO] [] [com.hazelcast.cluster.impl.MulticastJoiner] [tid: _ThreadID=1 _ThreadName=main] [timeMillis: 1469753465461]

[levelValue: 800] [192.168.1.100]:5901 [development] [3.6.2] Trying to join to discovered node: Address[192.168.1.100]:5900

 

[2016-07-28T19:51:10.514-0500] [Payara Micro 4.1] [WARNING] [] [com.hazelcast.partition.InternalPartitionService] [tid: _ThreadID=44 _ThreadName=hz._hzInstance_1_development.generic-operation.thread-0] [timeMillis: 1469753470514] [levelValue: 900] [192.168.1.100]:5901 [development] [3.6.2] Ignoring received partition table, startup is not completed yet. Sender: Address[192.168.1.100]:5900

 

Keep in mind as we previously said that you cannot form a cluster of only Lite members. In this case when starting a Payara Micro instance like this for example, the instance will not start correctly:

 

[2016-07-28T20:15:08.914-0500] [Payara Micro 4.1] [SEVERE] [NCLS-CORE-00014] [javax.enterprise.system.core] [tid: _ThreadID=1 _ThreadName=main] [timeMillis: 1469754908914] [levelValue: 1000] [[Shutdown required
MultiException stack 1 of 1
MultiException stack 1 of 2
com.hazelcast.partition.NoDataMemberInClusterException: Partitions can't be assigned since all nodes in the cluster are lite members
        at com.hazelcast.spi.impl.operationservice.impl.Invocation.notifyWithExceptionWhenTargetIsNull(Invocation.java:347)
        at com.hazelcast.spi.impl.operationservice.impl.Invocation.initInvocationTarget(Invocation.java:304)
        at com.hazelcast.spi.impl.operationservice.impl.Invocation.doInvoke(Invocation.java:234)
        at com.hazelcast.spi.impl.operationservice.impl.Invocation.invokeInternal(Invocation.java:210)
        at com.hazelcast.spi.impl.operationservice.impl.Invocation.invoke(Invocation.java:180)
        at com.hazelcast.spi.impl.operationservice.impl.InvocationBuilderImpl.invoke(InvocationBuilderImpl.java:46)
        at com.hazelcast.map.impl.proxy.MapProxySupport.invokeOperation(MapProxySupport.java:316)
        at com.hazelcast.map.impl.proxy.MapProxySupport.setInternal(MapProxySupport.java:367)
        at com.hazelcast.map.impl.proxy.MapProxyImpl.set(MapProxyImpl.java:180)
        at com.hazelcast.map.impl.proxy.MapProxyImpl.set(MapProxyImpl.java:170)
        at fish.payara.nucleus.store.ClusteredStore.set(ClusteredStore.java:55)

]]

 

Real World Scenario

So now that we know how to start a Payara Server or Micro instance as a Lite member of a cluster, what can we do with it? Let us help by providing a real world example that can help you understand the benefits of Lite members.

Imagine that you want to create a heavy transactional application with the following components:

 

  • A REST endpoint that exposes a service to execute a heavy transactional operation. You’ll implement this endpoint as a @RequestScoped CDI bean in this case:
@Path(/transactional)
@RequestScoped
public class MyTransactionalService{

    @GET
	@Path(/)
	public Response heavyOperation(){
		//Call services here
	}
}

 

Since this is a request scoped bean, our Lite members don’t need to be concerned with storing information.

 

  • A Stateless EJB defined to interact with a relational database using the JPA API:
@Stateless
public class EJBService{

@PersistenceContext(unitName = "LiteTest")
private EntityManager em;

public void transactionalOperation(String value){
    Entity entity = new Entity(value);
	em.persist(entity);
}
}

 

In a real production scenario, you will have multiple stateless beans that will model your transactional services. This services will constitute well-defined boundaries that can be injected into your defined REST endpoints using @Inject. Remember that the purpose of these services is to move data to and from the database, so each service is lightweight.

 

With these components defined and once you have your application packaged up, start your service cluster using Payara Micro:

 

java -jar payara-micro-4.1.1.162.jar --clusterName myService-cluster --deploy myServiceApplication.war

 

This first “node” needs to be started as a native member since we need at least one member in the cluster to store Hazelcast partition data. Then, start as many Lite members you need to form your cluster:

 

java -jar payara-micro-4.1.1.162.jar --lite --clusterName myService-cluster --deploy myServiceApplication.war

 

Since your services are defined in a stateless manner, you can scale them up in an easier way since Lite members perform better and don’t store any information. Better yet, you can restructure your application as a series of Microservices without much effort since all components are stateless.

 

Conclusion

Payara Server integration with Hazelcast Lite members can help you define a lightweight cluster topology ideal for true stateless services. The main advantage of having a server being a Lite member of a cluster is that this server won’t concern itself with storing any information in memory, so it can focus on executing heavy transactional tasks. In particular Payara Micro can be a really potent tool when structuring a micro service architecture since you can easily start Lite members and deploy simple Microservices using JAX-RS, CDI and Stateless EJBs.

 

 

 Payara Server Clustering  click for more articles

 

 

 

Comments