Hazelcast Internals 1: Threads
In this section, we will go over the Hazelcast's internal threads, the client threads executing Hazelcast API and how these threads work together in Hazelcast. When developing Hazelcast, you should know which thread will execute your code, which variables are local to that thread, and how you should interact with other threads.
-
Client Threads:
Client threads are your threads, user's application threads, and or user's application/web server's threads that are executing Hazelcast API. User's threads that are client to Hazelcast. For example,Hazelcast.getQueue("myqueue"), map.put(key, value), set.size()
calls are initiated and finalized in the client threads. Serialization of the objects also happens in the client threads. This also eliminates the problems associated with classloaders. Client threads initiate the calls, serialize the objects into Hazelcastcom.hazelcast.nio.Data
object which holds a list ofjava.nio.ByteBuffer
.Data
object is the binary representation of the application objects (key, value, item, callable objects). All Hazelcast threads such as ServiceThread, InThread and OutThread work withData
objects; they don't know anything about the actual application objects. When the calls are finalized, if the return type is an object,Data
object is returned to the client thread and client thread then will deserialize theData
(binary representation) back to the application objects.For each client thread, there is a
com.hazelcast.impl.ThreadContext
thread-local instance attached which contains thread context information such as transaction. -
ServiceThread:
ServiceThread, implemented atcom.hazelcast.impl.ClusterService
, is the most significant thread in Hazelcast. Almost all none-IO operations happens in this thread. ServiceThread serves to local client calls and the calls from other members.If you look at the ClusterService class you will see it is constantly dequeueing its queue and processing local and remote events. ClusterService queue receives local events in the form of
com.hazelcast.impl.BaseManager.Processable
instances and remote events in the form ofcom.hazelcast.nio.PacketQueue.Packet
instances from InThread.All distributed data structures (queue, map, set) are eventually modified in this thread so there is -no- synchronization needed when data structures are accessed/modified.
It is important to understand that client threads initiates/finalizes the calls, in/out threads handles the socket read/writes and service thread does the actually manipulation of the data structures. There is no other threads allowed to touch the data structures (maps, queues) so that there is no need to protect the data structures from multithread access: no synchronization when accessing data structures.
It may sound inefficient to allow only one thread to do all data structure updates but here is the logic behind it [please note that numbers given here are not exact but should give you an idea.]: If there is only one member (no IO), ServiceThread utilization will be about 95% and it will process between 30K and 120K operations per second, depending on the server. As the number of members in the cluster increases, IO Threads will be using more CPU and eventually ServiceThread will go down to 35% CPU utilization so ServiceThread will process between 10K and 40K operations per second. ServiceThread CPU utilization will be at about 35% regardless of the size of the cluster. [The only thing that can affect that would be the network utilization.] This also means that total number of operations processed by the entire cluster will be between N*10K and N*40K; N being the number of nodes in the cluster. About half of these operations will be backup operations (assuming one backup) so client threads will realize between N*5K and N*20K operations per second in total. Since there is only one thread accessing the data structures, increase in the number of nodes doesn't create any contention so access to the data structures will be always at the same speed. This is very important for Hazelcast's scalability.
This also makes writing code super easy because significant portion of the code is actually single-threaded so it is less error-prone and easily maintainable.
No synchronization or long running jobs are allowed in this thread. All operations running in this thread have to complete in microseconds.
-
InThread and OutThread:
Hazelcast separates reads and writes by having two separate threads; one for reading, and the other for writing. Eache IO thread uses its own NIO selector instance. InThread handles OP_ACCEPT and OP_READ socket operations while OutThread handles OP_CONNECT and OP_WRITE operations.Each thread has its queue that they dequeue to register these operations with their selectors so operation registrations and operation processing happens in the same threads.
InThread's runnable is the
com.hazelcast.nio.InSelector
andOutThread
's runnable is the com.hazelcast.nio.OutSelector. They both extends SelectorBase which constantly processes its registration queue ('selectorQueue') and the selectedKeys.Members are connected to each other via TCP/IP. If there are N number of members in the cluster then there will be N * (N-1) connection end point and (N * (N-1))/2 connections. There can be only one connection between two members, meaning, if m2 creates a connection to m1, m1 doesn't create another connection to m2 and the rule here is that new members connect to the older members.
If you look at the
com.hazelcast.nio.Connection
, you will see that each connection is representing a socket channel and hascom.hazelcast.nio.ReadHandler
andWriteHandler
instances which are attached to the socket channel's OP_READ and OP_WRITE operation selectionKeys respectively. When InSelector selects OP_READ selection key (when this operation is ready for the selector), InSelector will get the attached ReadHandler instance from the selectionKey and call itsReadHandler.handle()
method. Same for the OutSelector. When OutSelector selects OP_WRITE selection key (when this operation is ready for the selector), OutSelector will get the attached WriteHandler instance from the selectionKey and call itsWriteHandler.handle()
method.When ServiceThread wants to send an Invocation instance to a member, it will
- get the Connection for this member by calling
com.hazelcast.nio.ConnectionManager.get().getConnection(address)
- check if the connection is live; Connection.live()
- if live, it will get the WriteHandler instance of the Connection
- enqueue the invocation into the WriteHandler's queue
- and add registration task into OutSelector's queue, if necessary
- OutSelector processes the OP_WRITE operation registration with its selector
- when the selector is ready for the OP_WRITE operation, OutSelector will get the WriteHandler instance from selectionKey and call its
WriteHandler.handle()
.
see
com.hazelcast.impl.BaseManager.send(Packet, Address)
.
seecom.hazelcast.nio.SelectorBase.run()
.Connections are always registered/interested for OP_READ operations. When InSelector is ready for reading from a socket channel, it will get the ReadHandler instance from the selectionKey and call its handle() method. handle() method will read Invocation instances from the underlying socket and when an Invocation instance is fully read, it will enqueue it into ServiceThread's (ClusterService class) queue to be processed.
- get the Connection for this member by calling
-
MulticastThread:
If multicast discovery is enabled (this is the default), and node is the master (oldest member) in the cluster then MulticastThread is started to listen for join requests from the new members. When it receives join request (com.hazelcast.nio.MulticastService.JoinInfo
class), it will check if the node is allowed to join, if so, it will send its address to the sender so that the sender node can create a TCP/IP connection to the master and send a JoinRequest. -
Executor Threads:
Each node employs a local ExecutorService threads which handle the event listener calls and distributed executions. Number of core and max threads can be configured.
Coming up next: Life cycle of a map.put() call.
相关推荐
Spring Boot和Hazelcast使用详解 Spring Boot和Hazelcast使用详解是指如何将Hazelcast集成到Spring Boot项目中,以提高应用程序的性能。Hazelcast是一个内存分布式计算平台,用于管理数据并并行执行应用程序。它...
Hazelcast集群部署手册 Hazelcast是Java中的一种分布式内存数据网格(In-Memory Data Grid),提供了高可用性、可扩展性和高性能的数据存储解决方案。下面是Hazelcast集群部署手册的相关知识点: 一、下载和安装...
赠送jar包:hazelcast-3.7.2.jar; 赠送原API文档:hazelcast-3.7.2-javadoc.jar; 赠送源代码:hazelcast-3.7.2-sources.jar; 赠送Maven依赖信息文件:hazelcast-3.7.2.pom; 包含翻译后的API文档:hazelcast-...
Hazelcast是一个开源的内存数据网格(In-Memory Data Grid, IMDG)解决方案,它提供分布式内存计算、缓存和消息队列功能。Hazelcast 4.1.1是这个项目的其中一个版本,包含了对先前版本的改进和新特性。在深入探讨...
Hazelcast 配置说明文件 Hazelcast 配置可以通过声明式配置(XML)或编程式配置(API)或两者的混合方式进行。下面是对 Hazelcast 配置的详细说明: 一、声明式配置 声明式配置是指通过 XML 文件来配置 Hazelcast...
OpenFire 使用 HazelCast 集群 OpenFire 是一款流行的即时通信服务器软件,而 HazelCast 是一个高性能的分布式内存数据网格。OpenFire 使用 HazelCast 集群可以提高系统的可扩展性和高可用性。本文将从集群概念、两...
标题 "hazelcast-3.5.5.tar.gz Mac OS" 指示这是一个针对Mac OS操作系统的Hazelcast版本的压缩包文件。Hazelcast是一个开源的内存数据网格,常用于提供分布式内存缓存、分布式计算以及分布式事件处理等功能。版本号...
Hazelcast是一款开源的内存数据网格(In-Memory Data Grid, IMDG)解决方案,它提供分布式内存计算和存储,能够显著提升应用的性能和可扩展性。Hazelcast 3.12.2是该软件的一个版本,包含了对之前版本的改进和修复。...
Hazelcast是一款专为Java设计的集群化和高度可扩展的数据分发平台。Hazelcast可以帮助架构师和开发人员轻松地设计和开发出更快、高度可扩展和可靠的业务应用程序。Hazelcast的核心特性包括In-Memory Data Grid(IMDG...
Hazelcast 是一款面向 Java 平台的开源分布式计算平台,提供高性能的分布式数据结构和集群服务。其设计宗旨是为开发人员提供简单而直接的方式构建可扩展的应用程序,通过分布式缓存、数据分发、消息队列等功能,降低...
赠送jar包:hazelcast-3.7.2.jar; 赠送原API文档:hazelcast-3.7.2-javadoc.jar; 赠送源代码:hazelcast-3.7.2-sources.jar; 赠送Maven依赖信息文件:hazelcast-3.7.2.pom; 包含翻译后的API文档:hazelcast-...
[Packt Publishing] Hazelcast 入门教程 (英文版) [Packt Publishing] Getting Started with Hazelcast (E-Book) ☆ 图书概要:☆ An easy-to-follow and hands-on introduction to the highly scalable data ...
Hazelcast Management Center 3.11.1 是一个用于管理 Hazelcast 分布式内存数据网格实例的重要工具。Hazelcast 是一个开源的内存数据网格平台,它提供内存存储和计算,增强了应用程序的性能和可扩展性。Management ...
《Hazelcast 文档 version 3 2》深入解析了Hazelcast这一开源集群与高度可扩展的数据分发平台在Java虚拟机(JVM)环境中的应用与优势。Hazelcast旨在解决现代服务器端应用程序面临的关键挑战,尤其是在云计算普及的...
Hazelcast API 是一款强大的开源框架,主要用于构建分布式数据存储和计算解决方案。它提供了一整套API,使得开发者能够在集群环境中轻松实现缓存、队列、地图、话题、事件监听等分布式服务。以下是对Hazelcast API ...
Hazelcast是一个开源的内存数据网格,它提供了一个分布式的内存计算平台,广泛用于提升应用程序的性能和可扩展性。Hazelcast 3.8.9 版本是该技术的一个稳定版本,从官方站点hazelcast.org下载,旨在提供可靠的服务和...
在实际项目中,可以将MyBatis的Mapper接口和XML配置与Hazelcast结合,将经常访问的数据存入Hazelcast缓存,从而提升应用性能。同时,利用SpringMVC的DispatcherServlet和Controller,可以优雅地处理HTTP请求,将处理...
Hazelcast Management Center 是一个强大的工具,用于管理和监控 Hazelcast 集群。这个压缩包 "hazelcast-management-center-4.0.1.zip" 包含了版本为 4.0.1 的管理中心软件,它允许用户直观地查看和控制他们的 ...
赠送jar包:shiro-hazelcast-1.4.0.jar; 赠送原API文档:shiro-hazelcast-1.4.0-javadoc.jar; 赠送源代码:shiro-hazelcast-1.4.0-sources.jar; 赠送Maven依赖信息文件:shiro-hazelcast-1.4.0.pom; 包含翻译后...
Hazelcast Management Center是Hazelcast分布式计算平台的重要组件,主要负责监控、管理和配置Hazelcast集群。Hazelcast是一个开源内存数据网格,提供分布式内存计算能力,包括内存存储、分布式计算、分布式事件处理...