Cloudify的基本部署单元是Processing Unit(处理单元),一旦处理单元部署到运行环境(Service Grid)。Processing Unit完成Processing Unit的配置,提供实例到运行环境的基础设施下,并保证它正确运行。
Service Grid由下列组件构成:
GSA是一个守护进程,能够启动和停止其他运行的组件(在处理/JVM层面)。GSA随托管的主机启动而启动,使用GSA可以非常容易的启动整个集群,并且随意启动和停止GSC、GSM和LUS服务。
GSA可以看作一个管理进程,产生并管理Service Grid进程(操作系统级别进程),如GSM,GSC,LUS.通常每个机器运行一个GSA,GSA允许产生GSM,GSC,LUS和一些自定义进程。一旦产生,GSA分配一个唯一的ID给产生的实例并管理它的生命周期。实例出现异常(如内存溢出异常),GSA将重启这个进程。可以使用Administration and Monitoring API或GigaSpaces UI 来启动、重启和终止进程。
虽然GSM、GSC和LUS可以通过各自的脚本启动,但是最好是通过GSA来启动,那样可以简单的监控和管理它们。GSA管理操作系统进程,有两类管理进程:本地和全局的。
本地进程(例如GSC)简单启动进程类型而不考虑运行在其他GSAs的其他进程类型。
全局进程考虑运行在其他GSAs(在相同的lookup groups或lookup locators)上的进程类型的数量(例如GSM)。它将在所有不同的GSAs(最多一个GSA一个进程类型)上自动尝试运行至少X个进程。如果GSA运行一个失败的全局管理进程类型,另一个GSA将确认失败并启动这个进程维持至少X个全局的进程类型。
为了启动GSA可以使用脚本CloudifyROOT/bin/gs-agent.(sh/bat),GSA默认启动2个本地GSC,管理2个全局GSM和2个全局LUS。
所有组件共享的JVM参数(系统特性,堆设置等)使用EXT_JAVA_OPTIONS环境变量。
#Wrapper Script LINUX export GSA_JAVA_OPTIONS=-Xmx256m export GSC_JAVA_OPTIONS=-Xmx2048m export GSM_JAVA_OPTIONS=-Xmx1024m export LUS_JAVA_OPTIONS=-Xmx1024m #call gs-agent.sh . ./gs-agent.sh
@rem Wrapper Script WINDOWS @set GSA_JAVA_OPTIONS=-Xmx256m @set GSC_JAVA_OPTIONS=-Xmx2048m @set GSM_JAVA_OPTIONS=-Xmx1024m @set LUS_JAVA_OPTIONS=-Xmx1024m @rem call gs-agent.bat call gs-agent.bat
GSA参数包括控制多少个GSA产生和启动(每个进程类型)的本地进程,维持全局管理进程GSA的数量(和其他GSAs协作)
默认情况下,GSA启动2个本地GSCs,管理2个全局GSM和2个全局LUS,相当于下面的启动参数:
gs-agent.(sh/bat) gsa.gsc 2 gsa.global.gsm 2 gsa.global.lus 2例如,启动3个本地GSC,2个全局GSM和0个LUS,则启动命令为:
gs-agent.(sh/bat) gsa.gsc 3 gsa.global.gsm 2 gsa.global.lus 0
通常,gsa.[进程类型]后跟着通过GSA产生的控制本地进程的数量和特定进程类型,gsa.global.[进程类型]后跟着全局管理进程数量和特定类型。
GSA管理不同的进程类型,在<CloudifyHOME>\config\gsa下的xml文件(gsc.xml、gsm.xml、lus.xml、gsm_lus.xml、esm.xml)定义每个进程类型。以gsc.xml为例:
<process initial-instances="script" shutdown-class="com.gigaspaces.grid.gsa.GigaSpacesShutdownProcessHandler" restart-on-exit="always"> <script enable="true" work-dir="${com.gs.home}/bin" windows="${com.gs.home}/bin/gsc.bat" unix="${com.gs.home}/bin/gsc.sh"> <argument></argument> </script> <vm enable="true" work-dir="${com.gs.home}/bin" main-class="com.gigaspaces.start.SystemBoot"> <input-argument></input-argument> <argument>com.gigaspaces.start.services="GSC"</argument> </vm> <restart-regex>.*OutOfMemoryError.*</restart-regex> </process>
GSA可以产生一个基本进程或者但参数的纯JVM进程。以GSC为例,允许产生两种类型的进程。
gs-agent.(sh/bat) gsa.global.lus 0 gsa.lus 1
不运行LUS则使用:
gs-agent.(sh/bat) gsa.global.lus 0
当处理单元已经部署,它的实例将运行在Gigaspaces容器内,GSC提供一个隔离的运行环境来运行处理单元实例,并暴露它的状态给GSM。
GSC是一个寄宿处理单元实例的容器(已部署的处理单元示例),GSC被认为是在网格中由GSM控制的一个节点。GSM提供在GSC中部署和解除部署处理单元实例的命令。GSC报告实例的状态给GSM。另一方面,GSC可以寄宿处理单元,GSC类加载等级确保在同一个GSC下的处理单元实例相互隔离。通常在同一个物理机中启动几个GSC,个数取决于机器CPU和内存资源。
部署多个GSC在一个或多个机器上构成一个虚拟的服务网格。实际上,GSC提供机器物理顶层的抽象层,这个概念支撑企业数据中心和公有云多样化的部署拓扑结构集群的需求。
启动GSC最好的方式是使用GSA,GSC也可以使用自身脚本[CloudifyHOME]/bin/gsc.(bat/sh)
使用系统特性来配置GSC(其他系统级别的服务,如通信层)#Wrapper Script LINUX export GSC_JAVA_OPTIONS=-Xmx1024m #call gsc.sh . ./gsc.sh
@rem Wrapper Script windows @set GSC_JAVA_OPTIONS=-Xmx1024m @rem call gsc.bat call gsc.bat
在一个典型的部署中一般有2-3个GSM服务,当其中一个失败,则其他的GSM接管。在任何给定的时间点,每个已部署的处理单元都被某个GSM管理,其他GSM作为这个服务单元的热备份。如果因为某些原因GSM失败,则热备份中的一个GSM接管并启动管理和监控失败的GSM管理的处理单元。
这个上下文下另一个重要属性是lookup group。lookup group是一个同集群环境的所有组件的逻辑组。通过lookup group,可以运行相同物理基础设施下同一个运行单元的多个部署,而不互相干扰。
ESM和GSM一起管理 Elastic Processing Unit (弹性处理单元)。
ESM是一个Elastic Middleware Services High-Level Overview描述的特征的实现,它构建在Administration and Monitoring API暴露的GigaSpaces的组件,如果内置功能不适合你的需求,你可以重写自定义行为。
一种可能是使用暴露
Elastic Scale Handler钩子来扩展和收缩,一个自定义实现,例如可以发送警告触发手动进程来增加新机器。
GSA管理LUS、GSM和ESM,ESM部署一个弹性data-grid部署,ESM和GSM同时工作 。部署过程转嫁到GSM来管理,ESM监控部署过程,执行弹性运行管理(自动伸缩,再均衡和增强SLAs)。ESM使用任何可用的机器,启动一个GSC来容纳部署请求。如果没有机器可用,它会请求扩张一个新机器。Elastic Scale Handler的实现来完成扩展一个新机器的过程。通过启动一个单独的GSA(no GSCs)来发现一个机器,在这个机器下,ESM将请求GSA来启动一个新的GSC,伸缩请求出现在部署折衷或违反SLA。
基本的设置最少由1一个GSA管理2个机器,其中一个GSA全局管理LUS、ESM和GSM。为了部署一个弹性data-grid服务,使用administrative API来定位和部署ESM。
默认Elastic Scale Handler钩子没有任何实现除了日志请求。当需要一个新机器时,简单运行一个GSA并且它会考虑空余资源。 我们展示一个例子来解释Elastic Scale Handler,通过网络发送SSH命令到空闲机器来启动代理。
ESM的日志级别由 org.openspaces.grid.esm的日志配置属性来控制<GigaSpaces>/config/gs_logging.properties
org.openspaces.grid.esm.level = INFO
可以通过管理界面Admin UI来访问不同组件的日志。
我们通过GSA来启动基本组件---ESM、LUS和GSM,所有这些组件被全局管理(这意味着,只要其中一个失败,GSA会自动启动一个新实例)
<GigaSpaces>/bin/gs-agent gsa.global.esm 1 gsa.gsc 0
gsa.global.esm 1 - 在同一lookup group/locators,通过服务网格代理全局管理一个ESM实例
gsa.gsc 0 - 将重写默认实现而不启动一个新的服务网格容器。原因很简单,ESM将随需求来启动对应数量的GSC,此外ESM启动分配特定区域的GSC。
注意:gsa.global.lus 2 gsa.global.gsm 2 gs-agent脚本默认忽略了,在同一lookup group/locators下通过GSA全局管理2个LUS和2个GSM。
首先使用administrative API发现ESM
Admin admin = new AdminFactory().createAdmin();
ElasticServiceManager esm = admin.getElasticServiceManagers().waitForAtLeastOne();
一旦取得ESM实例,可以使用它来部署弹性data-grid
ProcessingUnit pu = esm.deploy( new ElasticDataGridDeployment("mygrid"));
等待部署
Space space = pu.getSpace(); space.waitFor(pu.getSpace().getTotalNumberOfInstances()); GigaSpace gigaSpace = space.getGigaSpace();
默认情况下,它会部署一个容量为1-10GB、名为mygrid的高可用data-grid,每个GSC使用512MB。这个请求会映射到10个分区集群(十个实例,每个备份一个),没有自动伸缩策略。这意味需要手动启动机器来实现增长。
当需要一个新机器(要么是占据备份要么扩展),简单启动一个单独的代理。
<GigaSpaces>/bin/gs-agent gsa.gsc 0
注意我们使用gsa.gsc 0来重写默认实现,不启动新的GSC。
可以在处理单元配置中重写所有${...}来修改上下文部署时属性,例如,部署一个镜像服务,需要指定一个集群属性。
new ElasticDataGridDeployment("mygrid") .addContextProperty("cluster-config.mirror-service.enabled", "true")
内存容量通过两个参数来控制,一个最小容量,一个最大容量来限制伸缩范围,默认容量为1-10GB。
new ElasticDataGridDeployment("mygrid") .capacity("1g", "10g")
JVM初始和最大内存大小是GSC的JVM固定内存大小,默认情况下,每个初始和最大内存大小为512MB,分别使用-Xmn和-Xmx来指定。
new ElasticDataGridDeployment("mygrid") .initialJavaHeapSize("512m").maximumJavaHeapSize("512m")
可以将额外的JVM参数传递给启动时的GSC
new ElasticDataGridDeployment("mygrid") .vmInputArgument("-XX:-PrintGC").vmInputArgument("-XX:SurvivorRatio=8")
专用(Dedicated) - 限制部署data-grid不共享其他部署过程。 这个选项允许分配某个特定的部署data-grid最大资源数,不允许其他data-grid在同一个机器上部署,这是默认模式。
共享(Shared) - 同一个租户ID,允许data-grid部署和其他部署过程共享同一个机器的资源,这个选项允许同一个租户ID共享硬件资源
公共(Public) - 允许data-grid部署和其他部署过程共存,共享同一个机器的资源,这个选项允许利用硬件资源完成所有data-grid实例的部署,这个选项不会分配专用的资源完成特定的data-grid部署。
下面是怎样设置这些选项:
new ElasticDataGridDeployment("mygrid") .dedicatedDeploymentIsolation();
new ElasticDataGridDeployment("mygrid") .sharedDeploymentIsolation("tenant X");
new ElasticDataGridDeployment("mygrid") .publicDeploymentIsolation();
内置扩展SLAs可以添加到部署中,例如,内存SLA,违反指定阈值会触发扩展。
如果内存使用量超过阈值,实例要么迁移到另一个GSC(一个已存在的机器的新GSC),要么请求一个新的机器启动GSC。如果内存第一阈值,实例将迁移到另一个GSC,请求移除没有GSC的多余机器。
new ElasticDataGridDeployment("mygrid") .addSla(new MemorySla("75%"))
通过计算预定义子集平均大小得到内存使用量。默认情况,这个值为6,6个采样点,每隔5秒采样一次,总共展示30秒的窗口。这个子集的大小可以重写MemorySla结构体来配置。
new ElasticDataGridDeployment("mygrid") .addSla(new MemorySla("75%", 6))
为了更精确的统计内存,可以考虑安装Sigar,详细请看 "Using the SIGAR Library to Monitor Machine-Level Statistics"
默认情况下集群是高可用的,每个分区一个备份是总容量的一部分。一个备份需要一个独立的机器来容灾。那么,需要至少2个可用机器来启动。
new ElasticDataGridDeployment("mygrid") .highlyAvailable(true)
扩展处理器定义伸缩的方法。默认扩展处理器不采用任何措施,只是简单调用API输出日志。每个组件的部署都需要配置扩展处理器。
首先编写自定义方法来实现ElasticScaleHandler接口,属性可以在这个实现类部署期间传递。例如,可以指定哪些机器在这个处理池中。下面是MyElasticScaleHandler类获取机器列表。
new ElasticDataGridDeployment("mygrid") .elasticScaleHandler( new ElasticScaleHandlerConfig(MyElasticScaleHandler.class.getName()) .addProperty("machines", "lab-12,lab-13,lab-36,lab-37"))
ElasticScaleHandler(弹性扩展处理接口)由下面简单的API组成。
public void init(ElasticScaleConfig config);
public boolean accept(Machine machine);
public void scaleOut(ElasticScaleHandlerContext context);
public void scaleIn(Machine machine);
实现类和可能的使用到的jar都放在以下库文件夹:
<GigaSpace>/lib/platform/esm
参考Custom Elastic Scale Handler Example的具体实现,发送SSH命令启动在实验机器的代理。
参考Capacity Planning了解有关容量规划和最好的实现的详细信息
容量和堆内存等部署参数决定分区集群的大小。内存最大容量除以JVM最大容量得到分区数,如果实现高可用,分区数再除以2得到备份数,则总内存是请求的最大内存容量的一半。
例如,capacity("1g", "10g").maximumJavaHeapSize("512m").highlyAvailable(true) 产生10个分区的集群。
计算过程: (10 gigabytes)除以(512 megabytes) = 20 ==> 再除以2得到备份数= 10分区数(每个分区一个备份)
对32位系统,建议使用2GB堆内存;对于64位系统,推荐使用4-10GB堆内存。
对于性能优化,可以初始化堆内存为最大堆内存大小
为了满足初始化容量,启动最小数量的GSCs。最小内存容量大小除以最大JVM大小得到初始化GSCs内存大小。例如,1 gigabytes 除以512 megabytes的JVM内存大小,产生2个GSCs。
最大内存容量除以最大JVM内存大小得到GSCs最大数。例如,最大容量10GB除以512MB的JVM大小,产生20个GSCs。
为了达到容量限制,每个GSC扩展一个实例。对于一个有10个分区的集群,即20个GSCs,每个GSC运行一个实例。GSCs的最大数除以GSCs的初始数得到扩展因子。扩展因子限制每个GSC中实例数。例如,一个10分区的集群,在同一个GSC里面不会启动超过10个实例。
高级用户可以设置分区大小来覆盖默认的分区数计算值,在高可用的部署中表示主实例的个数。例如,设置分区数为5:
//Request to deploy mygrid 5,1 capacity: 1g - 2g - DEDICATED ProcessingUnit pu = esm.deploy(new ElasticDataGridDeployment("mygrid") .capacity("1g", "2g") .maximumJavaHeapSize("250m") .highlyAvailable(true) .setPartitions(5));