蜗牛技术团队redis

【Hazelcast系列一】Hazelcast 概览

2018-09-01  本文已影响618人  大哥你先走
hazelcast IMDG Logo

声明

本系列文章为学习Hazelcast的笔记,内容大部分都为官方文档翻译,如果对Hazelcast感兴趣,可移步Hazelcast查看官方原版文档。

学习目的

公司项目服务化改造后,缺少一种在微服务多个实例间广播、多播的机制,为了解决这个问题决定引入Vert.x Event Bus(cluster)来实现,在学习使用Event Bus的过程中了解到Event Bus的默认ClusterManager基于Hazelcast项目,简单看了一下感觉还不错,决定整体学习一遍扩展视野。

1.1 Hazelcast是什么

Hazelcast是基于内存的数据网格开源项目,同时也是该公司的名称。Hazelcast提供弹性可扩展的分布式内存计算,Hazelcast被公认是提高应用程序性能和扩展性最好的方案。Hazelcast通过开放源码的方式提供以上服务。更重要的是,Hazelcast通过提供对开发者友好的Map、Queue、ExecutorService、Lock和JCache接口使分布式计算变得更加简单。例如,Map接口提供了内存中的键值存储,这在开发人员友好性和开发人员生产力方面提供了NoSQL的许多优点。

除了在内存中存储数据外,Hazelcast还提供了一组方便的api来访问集群中的cpu,以获得最大的处理速度。轻量化和简单易用是Hazelcast的设计目标。Hazelcast以Jar包的方式发布,因此除Java语言外Hazelcast没有任何依赖。Hazelcast可以轻松地内嵌已有的项目或应用中,并提供分布式数据结构和分布式计算工具。

Hazelcast 具有高可扩展性和高可用性(100%可用,从不失败)。分布式应用程序可以使用Hazelcast进行分布式缓存、同步、集群、处理、发布/订阅消息等。Hazelcast基于Java实现,并提供C/C++,.NET,REST,Python、Go和Node.js客户端。Hazelcast遵守内存缓存协议,可以内嵌到Hibernate框架,并且可以和任何现有的数据库系统一起使用。
Hazelcast的整体架构如下:


Hazelcast整体架构

Hazelcast的架构不对开发者暴露

如果你正在寻找基于内存的、高速的、可弹性扩展的、对开发者友好的NoSQL,Hazelcast是一个很棒的选择。

1.2 Hazelcast的特点

1.3 Hazelcast中的分片

Hazelcast中的分片也称为分区,Hazelcast默认271个分区。Hazlecast通常也会对分区备份,并将副本分布到集群的不同节点上,通过数据冗余提高可靠性,这种数据的存储方式和kafka、Redis Cluster类似。给定一个key,在Hazelcast集群中查找key对应数据的过程如下图所示:


Value查找过程

1.4 Hazelcast的拓扑结构

Hazelcast集群有两种部署模式:内嵌模式,客户端/服务器模式。

1.5 为什么选择Hazelcast

      1.5.1传统的数据一致性方案

数据是软件系统的核心,在传统的架构中,通常使用关系型数据库存储并提供数据访问服务。应用程序直接和数据交互,数据库在另外的机器上通常存在一个备份。为了提高性能,需要对数据库调优或购买更高性能的服务器,这需要大量的投资和努力。

架构通常的做法是在更加靠近数据库的地方保存一份数据的备份,通常采用外部K-V存储技术或二级缓存来降低数据库访问压力。然而,当数据的性能达到极限或应用程序更多的请求是写请求时,这种方案对降低数据库的访问压力无能为力,因为不管是K-V存储还是二级多级缓存方案都只能降低数据库读压力。即便应用程序大多数是读请求,上述方案也有很多问题:当数据变化后,对缓存的影响是什么,缓存如何处理数据变化(目前公司的项目也在考虑方案解决整个问题),在这种条件下缓存存活时间(TTL)和直写缓存(Write-through )的概念诞生了。

考虑TTL的情况,如果访问的频率比TTL更低(TTL=30s,每次请求间隔35S),则每次访问的数据都不在缓存中,都需要从数据库读取数据,缓存每次都被穿透。另一方面,考虑直写缓存场景,如果集群中缓存的数据有多份,同样会面临数据一致性问题。数据一致问题可以通过节点间的互相通信解决,当一个数据不可用时,该消息可以在集群内的节点之间传播。

基于TTL和直写缓存可以设计一个理想的缓存模型,在该领域已经有缓存服务器和内存数据库等。然而,这些解决方案都是具有由其他技术提供的分布式机制的独立的单机实例(本质不是分布式集群,只是通过其他技术附加了集群特性)。回到问题的起点,如果产品是单节点,或者发行版没有提供一致性,总有一天会遇到容量问题。

      1.5.2Hazelcast的一致性解决方案

围绕分布式思想设计的Hazelcast提供一种全新访问处理数据的方法。为了提高灵活性和性能,Hazelcast在集群周围共享数据。Hazelcast基于内存的数据网格为分布式数据提供集群和高可扩展性。

集群无主节点是Hazelcast的一个主要特性,从功能上来讲,集群内每个节点都被配置为对等。第一个加入集群的节点负责管理集群内其他所有节点,例如数据自动平衡、分区表更新广播。如果第一个节点下线,第二个加入集群的节点负责管理集群其他节点。第一个节点故障切换方式如下图所示:


集群自治

数据完全基于内存存储、访问速度快是Hazelcast的另外一个特点。由于Hazelcast将数据的副本分布到集群中的其他节点上,所以在故障条件下(节点宕机)也不会有数据丢失。Hazelcast提供很多分布式数据结构和分布式计算工具,增强分布式集群内存的访问并通过CPU最大化分布式计算的速度。

      1.5.3Hazelcast的优势

1.6 数据分区

Hazelcast中的分片也叫做分区,分区是一个内存段,分区中存储数百或数千数据实体,分区的存储容量取决于节点自身的存储能力。

Hazelcast默认提供271个分区,类似Redis拥有16384个槽位。当启动只有一个节点的Hazelcast集群时,节点拥有全部271个分区。Hazelcast集群只有一个节点的条件下的分区分布如下图所示:


单节点分区分布

Hazelcast集群新增加一个节点,或启动一个包含两个节点的Hazelcast集群,分区的分布情况如下图所示:


两节点分区分布

黑色字体表示的分区为主分区,蓝色字体表示主分区的副本。

不断加入新的节点,Hazelcast会一个一个的把主分区和主分区副本迁移到新加入的节点上,保证主备分区的一致性和冗余性。当集群有四个节点时, 集群分区的一种可能方案如下:


四节点集群分区分布

Hazelcast将分区均匀的分布到集群的各个节点,Hazelcast自动创建分区的副本,并将副本分布到各个节点来提供可靠性。以上图片展示的Hazelcast分区仅仅是为了方便和清晰的描述Hazelcast分区机制。通常来说分区的分布不是有序的,Hazelcast使用一种随机的方式分布各个分区。这里重点说明Hazelcast均匀的分布分区和分区副本。Hazelcast 3.6版本引入轻量化节点(存储轻量化节点),轻量化节点是一种新的节点类型,轻量化节点不持有任何分区数据。轻量化节点主要用于计算型任务和监听器注册,尽管轻量化节点不保存分区数据,但是轻量化节点可以访问集群中其他节点所持有的分区数据。

      1.6.1 数据如何被分区

Hazelcast使用一种哈希算法将数据分布到特定分区。给定一个key,分区计算过程如下:

同一个key的分区ID必须保持一致。

      1.6.2 分区表

启动集群内的一个节点时,该节点会自动创建一个分区表。分区表存储分区ID和集群内其他的节点信息。分区表的主要目的是让集群内的所有节点(包括轻量节点)了解分区信息,确保每个节点都知道数据存储在哪个分区,哪个节点上。最早加入集群的节点周期性的向集群内其他节点发送分区表。通过这种方式,当分区关系发生变化时,集群内的所有节点都可以感知该变化。当一个节点加入或离开集群时,分区关系就会发生变化。
当集群内最早加入的节点故障时,剩余节点中最早加入集群的节点负责周期性的向其他节点发送分区表
发送分区表的周期默认是15S,如果想修改周期,可以通过设置环境变量hazelcast.partition.table.send.interval来进行修改。

      1.6.3 重分区

重分区是Hazelcast重新分配分区关系的过程,以下两种情况会触发Hazelcast执行重分区动作。

1.7 使用场景

上一篇下一篇

猜你喜欢

热点阅读