特性介绍
has_agent
功能描述
has_agent是部署在数据库每个主机上,用来启停和监控各个数据库实例进程的数据库管理组件。
主要功能有:
- 数据库实例启动和停止时负责拉起和停止本主机上部署的实例进程。
- 监控本主机上运行的实例状态并将状态上报发送给has Server。
- 执行HAS Server仲裁下发的命令。
命令说明
公共选项:
-V, --version
打印has_agent版本信息,然后退出。
-?, -h,--help
显示关于has_agent命令行参数的帮助信息,然后退出。
日志信息记录的位置选项:
0
记录在设定的日志文件中。
1
记录在syslog文件中。
2
记录在设定的日志文件中。
3
空文件,即不记录日志信息。
启动模式选项:
normal
正常模式启动。
abnormal
非正常模式启动。
has_server
功能描述
has_server是用来进行数据库实例管理和实例仲裁的组件。主要功能有:
- 接收各个节点上has_agent发送的数据库各实例状态。
- 提供数据库实例整体状态的查询功能。
- 监控实例的状态变化并进行仲裁命令的下发。
故障影响:
- has_server主故障后,会自动进行主备切换。has_server全部故障后,数据库实例管理和实例仲裁功能丧失,数据库实例内其他组件按原状态继续运行。
- has_server需要满足多数派才能正常运行,当不满足该条件时可能导致集群异常。
命令说明
公共选项:
-V, --version
打印has_server版本信息,然后退出。
-?, -h,--help
显示关于has_server命令行参数的帮助信息,然后退出。
日志信息记录的位置选项:
0
记录在设定的日志文件中。
1
记录在syslog文件中。
2
记录在设定的日志文件中。
3
空文件,即不记录日志信息。
支持日志管理
功能描述
HAS支持对$GAUSSLOG下的日志进行压缩和删除。
管理对象
$GAUSSLOG路径下表1 日志关键字中对应的日志。
压缩删除时机
enable_log_compress开启后,间隔log_threshold_check_interval。
日志压缩
对于单个目录下相同工具名的日志,除时间戳最新的日志外,剩余日志全部压缩。
日志压缩后与压缩前路径保持一致,压缩文件命名格式为“工具名-日志创建时间.log.gz”。
日志删除
当所有日志总大小超过(log_max_size*95/100)MB时,根据压缩日志文件名时间,依次删除历史压缩日志,直到日志总大小小于(log_max_size*95/100)MB。
当所有日志总个数超过log_max_count,根据压缩日志文件名时间,依次删除超过保留天数log_saved_days的压缩日志,直到日志总个数小于log_max_count。
日志压缩能力受内存限制,最多只能检测到30000个日志文件。总日志量超过30000个文件时,无法保证日志能被正常压缩及删除。可以通过调整log_saved_days和log_threshold_check_interval快速清理已压缩日志文件。
自定义资源
当前has支持对无状态资源(即各资源实例角色平等,不区分主备,或资源自身就能够自行进行主备仲裁)进行监控,主要功能包括:
资源配置
资源配置文件cm_resource.json,文件包含所有自定义资源的相关属性,可以通过
has_ctl res
命令对配置文件修改。不支持动态生效,修改配置文件后需要重启HAS才能生效。客户端
HAS提供客户端动态库给资源进行集成,提供集群状态查询、状态变更通知、集群锁能力。
自动启停资源
资源需要提供脚本,脚本包含启停、检测等能力,脚本路径需要配置在资源配置文件中。
手动启停资源
可以通过has_ctl start/stop -n -I命令实现资源实例的启停操作,详细参见has_ctl工具介绍。
自定义资源状态
自定义资源有四种状态:online,offline,deleted,unknown。可以通过has_ctl查询。
配置方法
安装好自定义资源后,若要使用自定义资源监控功能,需要配置两个文件:
1、资源脚本:主要用于指定资源的启停、状态检查等指令,以下是一个示例:
#!/bin/bash
#set -ex #取消该行注释可帮助调试脚本
#资源名称
resName=sharding
#资源binpath
shardingPath=/home/test/home/apache-shardingsphere-5.1.1-shardingsphere-proxy-bin/bin
#用于过滤资源实例的命令关键词
cmdKey=org.apache.shardingsphere.proxy.Bootstrap
#用于保存首次检测到资源僵死时间的文件
phony_dead_time_file=.sharding_phony_dead_time
#最长僵死时间,单位为s
PHONY_MAX_TIME=20
function exec_start
{
#资源启动命令
sh ${shardingPath}/start.sh; exit $?
}
function exec_stop
{
#资源停止命令
sh ${shardingPath}/stop.sh; exit $?
}
function exec_check
{
#查询资源实例pid
pid=`ps x | grep "$cmdKey" | grep -v grep | awk '{print $1}'`
if [ "${pid}" == "" ]; then
echo "$resName is not running."
exit 1
fi
#查询资源实例进程状态
state=`cat /proc/$pid/status | grep "State" | awk '{print $2}'`
if [ "$state" == "T" ]; then
#僵死检查和处理
if [ ! -f $phony_dead_time_file ]; then
touch ./${phony_dead_time_file}
echo "export firstphonytime=''" > ./${phony_dead_time_file}
fi
source ./$phony_dead_time_file;
curtime=$(date +%s);
if [ "$firstphonytime" == "" ]; then
#首次检测到资源僵死,将首次检测到僵死的时间写入僵死时间存储文件
#firstphonytime为用于保存当前资源实例僵死时间的变量名称,
#若当前节点存在多个自定义资源实例,该名称需要指定为不同的名称
echo "export firstphonytime=$curtime" > ./$phony_dead_time_file;
exit 0;
fi
dead_time=$(( $curtime - $firstphonytime ));
#若僵死时间大于等于用户设定的最大僵死时间,则立即杀死资源实例,否则不做处理正常退出
if [ $dead_time -ge $PHONY_MAX_TIME ]; then
echo "$resName is detected in a state of phony dead(T) and will be forcibly killed!"
kill -9 $pid
rm ./${phony_dead_time_file} -f
sh ${shardingPath}/start.sh; exit $?
else
exit 0
fi
elif [ "$state" == "S" ]; then
#未处于僵死状态清理环境后正常退出
rm ./${phony_dead_time_file} -f
exit 0
fi
}
#以下为固定接口无需更改,必须实现
if [ $1 == '-start' ]; then
exec_start $2
elif [ $1 == '-stop' ]; then
exec_stop $2
elif [ $1 == '-check' ]; then
exec_check $2
elif [ $1 == '-clean' ]; then
exec_stop $2
elif [ $1 == '-reg' ]; then
exit 0
elif [ $1 == '-unreg' ]; then
exit 0
elif [ $1 == '-isreg' ]; then
exit 11
else
echo "Please confirm the input parameters."
exit 1
fi
以上样例可以作为模板使用,用户主要需要修改的地方包括:资源名称、资源binPath、用于过滤资源实例的命令关键词、用于保存首次检测到资源僵死时间的文件(可选)、最长僵死时间、记录首次僵死时间的变量名(如果同一节点存在多个不同的自定义资源实例)。
2、自定义资源配置文件cm_resource.json:该文件位置为cmdir/cm_agent/cm_resource.json,配置该文件后需要重启集群。
{
"resources": [
{
"name": "sharding",
"resource_type": "APP",
"instances": [
{
"node_id": 1,
"res_instance_id": 1
},
{
"node_id": 2,
"res_instance_id": 2
}
],
"script": "/usr2/omm/install/cm/cm_agent/sharding.sh",
"check_interval": 1,
"time_out": 5,
"restart_delay":3,
"restart_period":5,
"restart_times":10
},
{
"name": "test",
"resource_type": "APP",
"instances": [
{
"node_id": 1,
"res_instance_id": 1
},
{
"node_id": 2,
"res_instance_id": 2
}
],
"script": "/usr2/omm/install/cm/cm_agent/test.sh",
"check_interval": 1,
"time_out": 5,
"restart_delay":0,
"restart_period":0,
"restart_times":1000
}
]
}
配置说明:
- resources: 自定义资源对象列表,名称固定不能更改。
- name: 自定义资源对象名称,字符串类型,最大长度为32(包含末尾'\0')。
- resource_type: 资源类型,取值[“APP”, “DN”],APP表示为自定义资源,DN表示为数据库资源
- instances: 自定义资源所在节点列表。
- node_id: 资源实例所在节点的node_id。
- res_instance_id: 资源实例id,大于等于0,同一种资源的不同实例id不同。
- script: 资源脚本位置。
- check_interval: 上报资源状态时间间隔,大于等于0,单位s。
- time_out: 脚本执行的超时时间,大于等于0,单位s。
- restart_delay: 故障之后重启延迟时间,单位为s,取值范围[0,1800]。
- restart_period: 当前时间-最近重启时间若大于restart_period,则再次重启资源重启次数加1。
- restart_times: 周期内最多重启次数,超过则不再重启,并将资源标记为不可用,取值范围[-1,9999],-1表示无限重启。
资源配置文件需要在所有节点上都有,且保持一致。
用户需要保证资源脚本能够正确运行。
资源池化
磁盘心跳
各节点has_agent定时向投票盘写入心跳,has_server获取投票盘中的磁盘心跳,作为主备共享模式下的仲裁依据。
网络心跳
节点间的连通性网络心跳检测的主逻辑在has_agent实现。为了避免频繁建连,心跳采用长连接的方式,即has_agent之间通过TCP长连接,进行心跳交互,由每个has_agent节点定时广播,并周期性将列表信息上报给has_server,此功能依赖各个节点的时钟完全同步。
仲裁最大集群
根据网络心跳数据、磁盘心跳数据、共享盘状态等进行仲裁,选主子集群。
子集群满足以下条件,不满足条件的剔除集群:
实例正常;
相互网络通信正常;
磁盘心跳正常;
子集群仲裁规则:
拥有节点多的子集群胜出;
如果节点数一样多,则节点号小的胜出。
约束:
- 集群节点时钟同步。
- HAS使用的共享盘在安装之前请确保至少150M为空,否则可能会有历史数据影响。
- HAS使用的投票盘在安装之前请确保已清空,否则可能会有历史数据影响。
- 由于心跳是集群所有节点间进行的,在大集群的情况下可能会对网络产生一定影响,因此,最多只会启动64个节点的心跳检测(DMS最多只支持64节点,满足使用要求)。
- 由于HAS集群规模最多只支持8个备机,因此当前部署最多支持9副本的集群。
- Voting disk和share disk确保包括至少1G空间,由HAS独占,其他应用不能使用。
- 在资源池化架构仲裁模式下,才启用磁盘心跳。
支持DN仲裁
HAS支持的DN仲裁模式主要分为:
Quorum 模式:基于多数派模式仲裁,选出同步备
简介:HAS基于Quorum模式进行仲裁,当DN分片处于无主场景时,HAS在多数派DN redo完成后,选择 term和lsn最大的节点(同步备)发送failover升主。
约束:最小满足一主两备集群
共享存储模式:
- 简介:在此场景下,HAS不再进行对DN选主,只负责数据采集,假死检测等。
- HAS配置:dn_arbitrate_mode=share_disk
- 介绍和约束:参考资源池化共享存储。
支持集群信息查询和推送
功能介绍:
通过运行组件CMRestAPI,HAS能够支持:
1、通过http/https服务远程查询到集群的状态,便于管理人员、运维平台等监控集群状态。
2、在数据库集群发生切主事件时,通过http/https服务及时地将集群最新的主备信息推送到应用端注册的接收地址,便于应用端及时的感知到集群的主备变化,从而能够快速的连接到新的主机和备机。
参数说明:
-e:数据库环境变量文件,必须指定。
-w:访问来源ip白名单,如果不需要设置白名单则可以不用指定。启动命令:
java -jar cmrestapi-xxx.jar -e envFile [-w appWhiteList]
接口说明:
1、集群或节点状态查询。
该接口使用GET方法,链接为http://ip:port/CMRestAPI/keyword
。
其中:
- ip为运行CMRestAPI的节点ip。
- port为CMRestAPI服务的监听端口。
keyword为待查询的信息关键词,当前支持查询的信息即关键词包括:
集群状态ClusterStatus,对应链接为
http://ip:port/CMRestAPI/ClusterStatus
。节点状态NodeStatus,对应链接为
http://ip:port/CMRestAPI/NodeStatus[?nodeId=n]
,指定nodeId等于n,则可以查询节点n的状态,若不指定nodeId,则默认返回提供服务的节点即链接中ip所指定节点的状态。
2、注册和更新主备机信息接收地址。
如果应用端想要接收到CMRestAPI推送的集群当前最新的主备信息,需要向CMRestAPI注册一个信息接收地址并且需要在该地址上进行监听。接收到该请求后CMRestAPI会通过dcc将注册的接收地址保存到集群所在环境,dcc存储数据的形式为key-value形式,使用的key为/CMRestAPI/RecvAddrList/ip/app,其中ip为应用端所在机器的ip地址,app为用户自定义的应用名称,主要用于区分同一环境上的多个应用注册的接收地址。如果key已存在,即来源ip和应用名称均相同,则会更新key对应的主备信息接收地址。
该接口需使用PUT方法,链接为http://ip:port/CMRestAPI/RecvAddr
, 需要提供两个参数:
url:待注册的接收地址。
app:应用名称,若不提供该参数则以前缀+应用端ip为key。
3、删除主备机信息接收地址。
该接口使用DELETE方法,链接为http://ip:port/CMRestAPI/RecvAddr
, 需要提供一个参数:
- app:应用名称。若不提供该参数则以
前缀+应用端ip
为key。
4、信息接收地址说明。
信息接收地址示例:http://ip:port/CMRestAPI
,CMRestAPI使用PUT方法,推送主机信息context为MasterInfo,即链接为http://ip:port/CMRestAPI/MasterInfo
, 发送对象类型为String,主机信息格式为ip:port,推送备机context为StanbyInfo,发送对象类型为String,备机信息格式为ip1:port1,ip2:port2,…,ipn:portn。
其他使用说明:
1、安全相关。
(1)CMRestAPI默认使用http服务,支持配置访问白名单,可通过启动参数-w配置访问来源ip的白名单文件,白名单文件配置格式为每行一个ip地址;
(2)若要使用https服务,则可以在启动时jar包时指定系统参数server.ssl相关参数来是CMRestAPI启动https服务,或将相关参数写入application.properties文件然后在启动命令中指定配置文件,或配置源码resource目录下的application.properties文件然后自行编译,自定义配置参数示例:
-Dserver.port=服务监听端口 -Dserver.ssl.key-store=秘钥文件路径 -Dserver.ssl.key-store-password=秘钥文件密码 -Dserver.ssl.key-store-type=秘钥类型
如:
指定参数方式:
--系统参数方式
java -jar -Dserver.port=8443 -Dserver.ssl.key-store=/home/omm/keystore.p12 -Dserver.ssl.key-store-password=Abcdef@123 -Dserver.ssl.key-store-type=PKCS12 cmrestapi-xxx.jar -e envFile
--指定配置文件方式
java -jar -Dspring.config.location=/configpath/application.properties cmrestapi-xxx.jar -e envFile
更多相关配置参数可自行搜索配置。
2、内存相关。
由于本程序使用了springboot框架,默认启动会占用较大内存(约1G左右),若并发量不大不希望该程序占用较大内存,则可以在启动时指定一些系统参数减小内存占用,启动参数示例:
-XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=56m -Xms128m -Xmx128m -Xmn32m -Xss328k -XX:SurvivorRatio=8 -XX:+UseConcMarkSweepGC
如:java -jar -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=56m -Xms128m -Xmx128m -Xmn32m -Xss328k -XX:SurvivorRatio=8 -XX:+UseConcMarkSweepGC cmrestapi-xxx.jar -e envFile
更多相关配置参数可自行搜索配置。
3、自定义资源配置文件。
本程序需要依赖HAS相关进程和指令,所以必须与HAS同时运行,需配置自定义资源配置文件,配置方法详见自定义资源监控特性相关内容。
操作步骤说明:
(1)安装带HAS的数据库集群,配置资源脚本和自定义资源文件,资源脚本cmrestapi.sh示例如下:
#!/bin/bash
#set -ex
#资源名称
resName=CM-RestAPI
#资源binpath
cmrestapiPath=/home/cmrestapi/cmrestapi-3.1.0-RELEASE.jar
#资源启动命令关键词
cmdKey=cmrestapi-3.1.0-RELEASE.jar
#用于保存首次检测到资源假死时间的文件
phony_dead_time_file=.cmrestapi_phony_dead_time
#最长假死时间,单位为s
PHONY_MAX_TIME=20
envFile=/home/cmrestapi/envfile
#appWhiteListFile=/home/cmrestapi/appWhiteListFile
source $envFile
function exec_start
{
nohup java -jar -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=56m -Xms128m -Xmx128m -Xmn32m -Xss328k -XX:SurvivorRatio=8 -XX:+UseConcMarkSweepGC -Dserver.port=8080 $cmrestapiPath -e $envFile >> $GAUSSLOG/cm/cmrestapi/cmrestapi.log 2>&1 &
exit $?
}
function exec_stop
{
ps x | grep "$cmdKey" | grep -v grep | awk '{print $1}' | xargs kill -9; exit $?
}
function exec_check
{
pid=`ps x | grep "$cmdKey" | grep -v grep | awk '{print $1}'`
if [ "${pid}" == "" ]; then
echo "$resName is not running."
exit 1
fi
state=`cat /proc/$pid/status | grep "State" | awk '{print $2}'`
if [ "$state" == "T" ]; then
if [ ! -f $phony_dead_time_file ]; then
touch ./${phony_dead_time_file}
echo "export firstphonytime=''" > ./${phony_dead_time_file}
fi
source ./$phony_dead_time_file;
curtime=$(date +%s);
if [ "$firstphonytime" == "" ]; then
echo "export firstphonytime=$curtime" > ./$phony_dead_time_file;
exit 0;
fi
dead_time=$(( $curtime - $firstphonytime ));
if [ $dead_time -ge $PHONY_MAX_TIME ]; then
echo "$resName is detected in a state of phony dead(T) and will be forcibly killed!"
kill -9 $pid
rm ./${phony_dead_time_file} -f
exec_start
else
exit 0
fi
elif [ "$state" == "S" ]; then
rm ./${phony_dead_time_file} -f
echo "$resName is running normally."
exit 0
fi
}
if [ $1 == '-start' ]; then
exec_start $2
elif [ $1 == '-stop' ]; then
exec_stop $2
elif [ $1 == '-check' ]; then
exec_check $2
elif [ $1 == '-clean' ]; then
exec_stop $2
elif [ $1 == '-reg' ]; then
exit 0
elif [ $1 == '-unreg' ]; then
exit 0
elif [ $1 == '-isreg' ]; then
exit 11
else
echo "Please confirm the input parameters."
exit 1
fi
自定义资源文件cm_resource.json示例如下:
{
"resources": [
{
"name": "CM-RestAPI",
"resource_type": "APP",
"instances": [
{
"node_id": 1,
"res_instance_id": 1
},
{
"node_id": 2,
"res_instance_id": 2
},
{
"node_id": 3,
"res_instance_id": 3
}
],
"script": "/home/cmrestapi/install/cm/cm_agent/cmrestapi.sh",
"check_interval": 1,
"time_out": 10,
"restart_delay":0,
"restart_period":0,
"restart_times":1000
}
]
}
- 使用HAS的自定义资源管理功能需将进程放到后台执行,所以需要将日志输出重定向至日志文件或配置日志输出相关选项,并且使用nohup和&将本程序放置到后台运行。
- 本程序需要运行在有数据库的节点;如果在集群发生切换时需要使用主备信息主动推送功能,则需要将该程序运行在集群中所有数据库节点。
(2)启动集群,即可通过浏览器等访问上述集群或节点信息查询接口查询对应信息。
(3)应用端开发,启动应用端。
(4)注册信息接收地址。
支持一键暂停/恢复HAS服务
特性介绍:
在实际场景中,经常需要管理员或运维人员手动对数据库集群进行运维,但是HAS的自动故障处理功能可能会对运维过程造成干扰,这种情况下,执行一键暂停命令后,可以将HAS对DN的自动仲裁和故障处理功能暂停掉,避免运维操作被干扰,运维操作完成后,再执行一键恢复操作,可以重新恢复HAS的仲裁和故障处理功能。
命令说明:
has_ctl pause #暂停
has_ctl resume #恢复
约束条件:
- 集群各节点间的互信和网络没有问题。
- 暂停操作和扩缩容操作不能同时进行,否则可能会导致扩缩容失败。
- cm暂停功能主要应用于运维场景,在cm暂停场景下,应尽量避免运行业务,以防止业务受到影响。
注意事项:
当前该操作仅支持对整个集群执行,暂不支持节点级暂停。
暂停仅针对DN相关的仲裁和故障处理,并不会影响HAS其他组件has_server、has_agent、has_monitor以及其他用户自定义资源的仲裁和故障恢复。
升级期间执行暂停操作可能会导致升级失败,操作时会发出告警。
网络和互信检查超时时间10s。
建议该操作及后续的运维操作由具有专业运维知识的人员执行。
暂停期间has_ctl工具提供的功能仍可以正常使用。需要额外说明的是:
集群暂停期间,
has_ctl start
操作虽然可以执行,但是由于仲裁被暂停了,启动阶段的仲裁也无法进行,所以执行该操作只能将dn启动为pending状态,无法下发notify和failover命令,所以start操作在等待集群状态变成normal时会超时,所以notify和failover命令需要用户手动执行。 集群暂停期间,dn实例的保活功能失效,如果dn实例异常挂掉或者使用非HAS命令将其停掉,HAS不会自动拉起,并且使用has_ctl start -n nodeid -D datapath
命令也无法拉起,必须执行vb_ctl start -D datapath
命令拉起。