【译】TC Server Array 架构

原文:http://www.terracotta.org/documentation/terracotta-server-array/server-arrays

介绍:这个文档将会向你展示如何使一个TC服务阵列达到集群可靠性、可用性以及可扩展性。

TC服务整列是可以从一个基本的双节点阵列变化到一个多节的阵列,以此达到扩展的可用性,高性能以及失效转移的深层次的覆盖。TC服务阵列的产品特性包括:

1.低复杂度的扩展:通过加入服务器实例的简单配置,来满足增长的需求以及促进容量变化的需求。

2.高可用性:为持续的正常运行和服务提供即时的实效转移。

3.可配置状态监控:TC的HealthChecker为内部节点进行监控。

4.持久的应用状态:为所有当前shared的数据(在内存中)进行自动的永久存储。

5.节点自动重连:在没有人干涉的情况下,使短暂性断开的服务性和客户端重新自动加入集群。

文章中可能会用L2来代替TC SERVER 实例,用L1来代替TC CLIENT实例。这些在TC配置文件里面会以缩写的形式被应用。

定义和功能特点:

TC安装的主要组件有如下:

1.集群:所有的TC SERVER实例和客户端实例,在一起工作,共享应用状态或者一个数据的设置。

2.TC SERVER ARRAY:这个平台,在一个集群里,包含所有的TC SERVER实例。集群的数据,也就是所谓的存储在内存里面的数据,或者共享的数据,是当前为Active状态的Server进行管理来达到持久化的目的。

3.TC镜像组:一个在TC SERVER阵列里面的单元,有些时候称为:。一个镜像组是有一个在活跃的Server和至少一个”待机“的TC SERVER实例组成。那个Active Server管理并且持久化那些被镜像组拆分的那些共享数据,并且每个在镜像组处于Standby状态的服务实例镜像出那些被Active Server管理的共享的数据。镜像组为集群增加容量。那些Standby Servers是可选的,但是提供了高性能的失效转移。

4.TC SERVER实例:一个单独的TC SERVER.一个Active Server管理TC 客户端,是共享的对象和持久化的数据协调统一。服务实例对在TC client端集群的应用是没有意识的。Standby的服务器是一个备选服务,它能够持续的复制在Active Server里面共享的数据,并且在Activer Server实效的时候立马替换为Active Server.Standby Server在一个镜像组里面是用来提供失效转移覆盖率。

5.TC CLIENT:TC CLIENT是在应用服务器上运行的,与那些被集群的应用一起工作。客户端是用来管理live shared-object graphs.

集群中另外的一个组件就是嵌入式数据库。TC server阵列使用的是一个已经认证的数据库,叫BerkeleyDB,用来备份所有的共享(分布的)数据。为了将Apache Derby 转换为嵌入式数据库,只需要简单的加入如下的属性到TC配置文件<tc-properties>块儿中,然后重启TC SERVER ARRAY.

<property name="l2.db.factory.name" value="com.tc.objectserver.storage.derby.DerbyDBFactory" />

通过在<tc-properties>块中的<property>元素,你可以设置额外的Apache Derby的属性。比如,如果要设置属性derby.storage.pageCacheSize=10000,只需要简单的添加l2.derbydb到属性名里面:

<property name="l2.derbydb.derby.storage.pageCacheSize" value="10000" />

如果要重置到默认的嵌入式数据库,那么从TC的配置文件中移除所有与Derby相关的属性,并且重启TC服务阵列。

如果你是使用TC3.5.1或者之后的版本,并且想从你的环境何总完全移除BerkeleyDB,从TC的安装路径下的lib文件中,删掉je-4.1.7.jar

第一幅图展示了一个有三个镜像组的TC集群。每个镜像组有一个Active的Server和一个Standy的Server,在集群中,管理1/3的共享数据。

一个TC集群它会有如下的功能特点:

  •  每个镜像组自动推选一个Active的TC Server实例。在每个镜像组中,绝对不可能会出现多于一个的Active的Server,但是可以有多个Standby的Server。在第一幅图中,镜像组1有两个Standby,镜像组3中可能有4个Standby。然而,当添加更多的Standby的时候,性能开销这个问题就会变得很明显,因为每一个Standby要加载数据,与Active上面的数据保持同步。
  • 在集群中,每个镜像组,在起作用之前,必须有一个TC服务实例是处于Active模式的。
  • 在集群中共享的数据是自动被分片的,并且被分不到不同的镜像组中。被分的片段是与镜像组的个数相等的。在图片1中,每个镜像组将会管理集群中1/3的数据。
  • 镜像组不能提供为各自提供实效转移。实效转移是在每个镜像内部进行的,不能跨镜像组。这是因为,通过在集群中管理分离区域的共享数据,镜像组能够实现扩展,他们不能复制彼此。在图片1中,如果镜像组1不工作了,那么集群将立即停止,直到镜像组1能完好无损的重新管理所属的共享数据。
  • Actives在集群中是各自协调工作的。不用特定的配置文件来协调它们。
  • 在一个镜像组中,只有bring down的可以转化为Active的。在图片1中,L2 Passive(Standby)的服务可以被关掉并且被替换,这些都不会影响集群的功能。不过,如果是添加或者移除镜像组,那么集群将会失效。并且要注意,在这种情况下,原始的TC配置文件依旧是有效的,新的服务此时不会被加进去。被替换的Standby必须要有与之前相同的地址(IP或Hostname)。如果你必须替换成一个配置不一样的,并且当前是企业版的TC,那么参考:Changing Cluster Topology in a Live Cluster.

Server Array配置要点

通过使用TC配置文件,为了成功配置TC Server Array,注意以下要点:

  • 两个或多个服务器应该在 <servers> 段中进行定义
  • <l2-group-port>是一个TC Server之间用来通信的一个端口。
  • <ha>段是紧接在<server>段后面的,或者是在<mirror-groups>段里面,应该定义成"networked-active-passive"的模式。

active-passive 模式"disk-based-active-passive" ,如果不是目的性的说明,或者一个网络连接不是弹性的,是不推荐使用的。参考集群架构部分: Terracotta Concept and Architecture Guide获取更多关于“disk-based-active-passive”的信息。<networked-active-passive> 子部分有一个配置参数是<election-time>,这个参数的单位是秒。<election-time>是用来设置选取Active Server的时间,通常会考虑到网络延和者服务加载。默认值是5秒。

当定义为networked-active-passive模式的时候,TC 服务实例不准共享数据路径。每一个服务的<data>元素ing该指向不同的本地数据路径。

  • 在Active 和 Passive 之间丢失连接的时候,一个重连接机制重存储它们丢失的连接。参考 Automatic Server Instance Reconnect获取更多。
  • 在TC client 和 TC server之间丢失连接的时候,一个重连接机制重存储它们丢失的连接。参考Automatic Client Reconnect获取更多。
  • 为了数据安全,Server Array的持久化配置应该指定为“permanent-store”。“permanent-store”以为这应用的状态,或者在内存中的共享数据要持久到硬盘上。万一TC 服务失败,它可以自动将数据进行存储。共享的数据,当它不在任何客户端内存中存储的时候会从硬盘中删除。

注:所有的服务端和客户端都应该在相同版本的JDK和TC下运行。

更多信心请参考:

备份持久化共享数据

TC的某些版本提供创建TC服务阵列的disk store 的备份的工具。参考 Terracotta Operations CenterDatabase Backup Utility (backup-data) 获取更多信息。

客户端断开连接

每个TC服务阵列都会处理基于HealthCheckerAutomatic Client Reconnect 机制的当前连接客户端的断开连接(比如网络断开,client长时间的GC,或者是节点断开)。在基于这些基础的情况下,一个失去连接的客户端也会尝试着重新李连杰。客户端首先会重连到initial server,然后再到其它服务商安装TC的配置。为了保留数据集成,客户端会因为有些还没有收到服务认可而重新发送传输。

更多关于客户端的操作请参考:Cluster Structure and Behavior.

客户端结构和行为

TC集群在部署阶段和产品可以在服务端配置成多种安装形式。注意,在多安装的情况下,失效转移的特征会被HA的配置影响(参考 Configuring Terracotta Clusters For High Availability)。

在开发阶段的TC集群:

Persistence: No | Failover: No | Scale: No

在一个开发环境下,持久化共享数据是没有必要的,并且也是不方便的。当积累的数据会填满硬盘或者阻止自动重启Server的时候,它会给Server添加更重的负担,并且需要人为的干涉。为了创造一个更高效的开发环境,运行只有一个Server,并且没有持久化的TC集群是一个不错的解决方案。

默认下,一个单独的TC server在"temporary-swap-mode"模式下,也意味着是没有持久功能的。它的配置可能如下:

<?xml version="1.0" encoding="UTF-8" ?>
<tc:tc-config xmlns:tc="http://www.terracotta.org/config"
xmlns:xsi
="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation
="http://www.terracotta.org/schema/terracotta-5.xsd">
<servers>
<server name="Server1">
<data>/opt/terracotta/server1-data</data>
<l2-group-port>9530</l2-group-port>
</server>
<servers>
...
</tc:tc-config>

Server重启

如果这个Server失效了,所有在共享堆里的应用状态(所有的集群数据)将会丢失。除此之外,当server重新工作后,所有的客户端必须重启然后加入集群。

有可靠性的集群

Persistence: Yes | Failover: No | Scale: No

在开发环境下的TC集群,“不可靠”的配置可能会对开发有好处。但是如果在内存中的共享数据必须持久化,那么Server的配置必须扩展:

<?xml version="1.0" encoding="UTF-8" ?>
<tc:tc-config xmlns:tc="http://www.terracotta.org/config"
xmlns:xsi
="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation
="http://www.terracotta.org/schema/terracotta-5.xsd">
<servers>
<server name="Server1">
<data>/opt/terracotta/server1-data</data>
<l2-group-port>9530</l2-group-port>
<dso>

<!-- The persistence mode is "temporary-swap-only" by default, so it must be changed explicitly. -->
<persistence>
<mode>permanent-store</mode>
</persistence>

</dso>
</server>
</servers>
...
</tc:tc-config>

<persistence>元素里的子元素<mode>在默认下是"temporary-swap-only"。如果改成了"permanent-store", 服务器将会备份所有在内存中的数据到硬盘上。

如果服务重启,在共享堆里的应用状态(所有的集群数据)将会被重新存入。

除此之外,在window设置下,先前连接的客户端,通过<client-reconnect-window> 元素,是允许重新加入到集群。

<?xml version="1.0" encoding="UTF-8" ?>
<tc:tc-config xmlns:tc="http://www.terracotta.org/config"
xmlns:xsi
="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation
="http://www.terracotta.org/schema/terracotta-5.xsd">
<servers>
<server name="Server1">
<data>/opt/terracotta/server1-data</data>
<l2-group-port>9530</l2-group-port>
<dso>
<!-- By default the window is 120 seconds. -->
<client-reconnect-window>120</client-reconnect-window>
<!-- The persistence mode is "temporary-swap-only" by default, so it must be changed explicitly. -->
<persistence>
<mode>permanent-store</mode>
</persistence>

</dso>
</server>
</servers>
...
</tc:tc-config>

当<client-reconnect-window>的默认值是可以接受的情况下,它是不用被重新设置的,然而,在一个单独服务器的集群环境下,如果持久化模式被配置成"permanent-store", <client-reconnect-window>是会对集群产生影响的。

具有高可用性的TC Server阵列

Persistence: Yes | Failover: Yes | Scale: No

图片3中的粒子说明了一个可靠但不是高HA的集群。如果服务器实效,集群也就实效,没有多余的server提供实效转移。添加一个standby来增强可用性,因为standby的失效转移。

在这个阵列下,如果Active的TC server实例失效了,那么standby的实例会立即接管,并且集群将会持续工作,不会有数据丢失。

下面的TC配置文件说明了怎样去配置一个有两个server的阵列:

<?xml version="1.0" encoding="UTF-8" ?>
<tc:tc-config xmlns:tc="http://www.terracotta.org/config"
xmlns:xsi
="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation
="http://www.terracotta.org/schema/terracotta-5.xsd">
<servers>
<server name="Server1">
<data>/opt/terracotta/server1-data</data>
<l2-group-port>9530</l2-group-port>
<dso>
<persistence>
<mode>permanent-store</mode>
</persistence>
</dso>
</server>
<server name="Server2">
<data>/opt/terracotta/server2-data</data>
<l2-group-port>9530</l2-group-port>
<dso>
<persistence>
<mode>permanent-store</mode>
</persistence>
</dso>
</server>
<ha>
<mode>networked-active-passive</mode>
<networked-active-passive>
<election-time>5</election-time>
</networked-active-passive>
</ha>
</servers>
...
</tc:tc-config>

在<HA>中的<mode>推荐的配置是"networked-active-passive",因为他允许active和passive的服务直接同步,没有依赖于硬盘。

你可以通过添加更多的<server>段到这个配置文件中来增加更多standby的服务器。然而,此时性能开销这个问题就会变得很明显,因为每一个Standby要加载数据,与Active上面的数据保持同步。

启动服务器

服务实例在启动时如何工作取决于在集群的生命期里,他们是如何启动的。

在一个单服务的配置里,当服务器启动了,它会按照启动的流程变化,然后才会正常工作(即状态变为Active).如果在集群中有多个服务实例同时启动,那么将会有一个被选为Active状态(即ACTIVE-COORDINATOR的状态),然后其他的实例将会作为Standby的状态。推选的结果将会在服务器的日志中记录下来。

当已经有一个Active 实例呈现时,再启动一个服务实例,那么这个新启动的服务将会根据Active状态同不到Standby的状态。Active 和 Standby的状态必须同步。Standby服务会经历以下几个状态:

1.PASSIVE-UNINITIALIZED :Standby开始进行启动顺序,并且当active实效或者关闭的时,还没有具备失效转移的能力。服务状态的标志在控制台里是从红到黄。

2.INITIALIZING :Standby正与active进行状态同步,并且当active实效或者关闭的时,还没有具备失效转移的能力。服务状态的标志在控制台里是从黄到橘黄。

3.PASSIVE-STANDBY:Standby已经与active状态同步,并且当active实效或者关闭的时,具备失效转移的能力。服务状态的标志在控制台里是从橘黄到天蓝。

再同步处理过程中,Active服务实例将状态加载发送到standby。同步的时间取决于集群的数据量以及当前在集群中的负荷。Active服务实例和Standby应该在配置相同的机器上会更好的处理,并且能够避免以为同时启动出现不必要的同步问题。

失效转移

如果Active服务实例实效了,并且有多余两个的Standby是可用的,那么将选择一个新的Active.从Standby到Active完成成功的失效转移,只有当至少有一个standby的Server是与Active彻底完成同步的时候,只有当server完成失效转移的时候,客户端才会完成失效转移(迁移到新的Active).如果Standby没有完全同步Active就将Active给关闭了,那么将导致集群实效。

当在TC配置中原先的Standby的<Server>段与替换是一致的,那么Standby是可以被热转换的。比如。新的Standby是必须使用同样的主机名和IP来替换原先的那个Standby的时候,如果你必须替换一个不一样的,那么你必须使用企业搬到TC.

在有些情况下,Standby可能会实效,并且自动将数据给清理掉,无法完成重启并且抛出异常。在这种情况下,数据路径必须手动删除。

即使Standby的数据清楚了,对他的复制还是安全的。默认下,复制的数量是受限制的。随着时间的推移,重启会频繁,当共享的数据量较大,那么这些复制将会消耗掉大量的硬盘。你可以手动删除这些文件,他们保存在 /dirty-objectdb-backup/dirty-objectdb-<timestamp>. 你可以通过添加下面的语句到tc.properties来设置复制的次数:

<property name="l2.nha.dirtydb.rolling" value="<myValue>" />

在这里,myValue是整数。

当所有的服务都失效后,集群的数据是持久化的。最后一个为Active的服务应尽量避免错误和数据丢失。通过检查日志,确定哪一个是最后Active服务。(在数据还没有进行持久化的时候进行启动,意味着持久模式是"temporary-swap-only", 那么就没有数据保存,也没有服务启动)。

安全失效转移的流程

为了将一个客户在不停止集群服务的条件下转移到standby服务上,应该按照下面的流程:

1.如果当前集群是没有开启的,那么通过start-tc-service脚本将standby启动,并且standby必须在当前的tc 配置文件中指定。

2.确保standby的状态已经转换具备是失效转移的能力(即状态转为PASSIVE-STANDBY )。

3.通过脚本将Active服务关掉。客户端并须能够连接到新的active服务实例上。

4.在reconnection window配置项规定的时间内,重启那些没有连上新Active的所有的客户端。

5.如果是在持久化的模式下运行,再重启之前,请将之前active上的数据删掉。之前的active现在加入集群将会变为standby。

安全关闭集群的流程

在持久化模式下的集群,安全关闭集群的流程如下:

1.通过stop service脚本文件关闭所有standby。

2.关闭TC客户端。当你关闭你的应用的时候,你的客户端就相当于关闭了。

3.通过stop service脚本文件关闭active。

为了重启集群,首先启动最后那个为active的服务。如果集群的数据不是持久化的,并且首先服务启动的时候没有数据冲突,这种情况是可能发生的。

Split Brain 场景

在一个TC集群中,“Split Brain”场景是指,有两个server都出现Active的状态(即ACTIVE-COORDINATOR)。这种情况会出现在当由于网络问题而无法让active和Standby链接的情况下,这将会导致让standby同时发生变成active状态和为客户端重新建立一个链接。(<client-reconnect-window>).

如果两个server间的链接再也没有恢复,那么两个独立的集群此时都会发生作用,这不是“Split Brain”的情况,但是如果链接建立了,那么将会导致下面的情况;

1.没有任何客户端会链接到新的active server:原先那个active会攻击新的active,导致新的active重启,并且删除了集群数据,此时将会被同步为standby的状态。

2.只有一小部分的客户端会连接到active:

 

 


 

 

原文地址:https://www.cnblogs.com/michelleAnn2011/p/2288847.html