概览
监控模块负责对后端服务的一系列检查,通常检查类型有4种:
- connect:监控模块会连接所有的后端服务,并且将成功/失败的连接记录在mysql_server_connect_log表中。
- ping:监控模块会ping所有的后端数据库服务,并且将成功/失败的ping记录在mysql_server_ping_log表中。一旦达到mysql-monitor_ping_max_failures所配置的次数,那就意味着失去了心跳,监控模块会给MySQL_Hostgroups_Manager发送信号去kill掉这个连接。
- replication lag:监控模块会检查配置的了max_replication_lag > 0 所有后端数据库的seconds_behind_master,并且将检查结果记录到mysql_server_replication_lag_log表中。如果seconds_behind_master > max_replication_lag ,那么就会踢出(此处的踢出只是临时剔除,不分配流量)该节点.直到seconds_behind_master < max_replication_lag在自动加回 。
- read only:监控模块会检查所有在mysql_replication_hostgroups表中额注解的read_only。并且会将检查结果记录在mysql_sevrer_read_only_log表中。如果read_only=1,那么将该节点移动到或者复制到reader_hostgroup,如果read_only=0,那么该节点就会被复制/移动到writer_hostgroup中。
监控相关表
这些表中包含了监控日志数据,这些都由监控模块进行管理。
monitor.mysql_server_connect_log
sql
MySQL [(none)]> show create table monitor.mysql_server_connect_log\G;
*************************** 1. row ***************************
table: mysql_server_connect_log
Create Table: CREATE TABLE mysql_server_connect_log (
hostname VARCHAR NOT NULL,
port INT NOT NULL DEFAULT 3306,
time_start_us INT NOT NULL DEFAULT 0,
connect_success_time_us INT DEFAULT 0,
connect_error VARCHAR,
PRIMARY KEY (hostname, port, time_start_us))
1 row in set (0.002 sec)
monitor.mysql_server_ping_log
sql
MySQL [(none)]> show create table monitor.mysql_server_ping_log\G;
*************************** 1. row ***************************
table: mysql_server_ping_log
Create Table: CREATE TABLE mysql_server_ping_log (
hostname VARCHAR NOT NULL,
port INT NOT NULL DEFAULT 3306,
time_start_us INT NOT NULL DEFAULT 0,
ping_success_time_us INT DEFAULT 0,
ping_error VARCHAR,
PRIMARY KEY (hostname, port, time_start_us))
1 row in set (0.001 sec)
monitor.mysql_server_replication_lag_log
sql
MySQL [(none)]> SHOW CREATE TABLE monitor.mysql_server_replication_lag_log\G
*************************** 1. row ***************************
table: mysql_server_replication_lag_log
Create Table: CREATE TABLE mysql_server_replication_lag_log (
hostname VARCHAR NOT NULL,
port INT NOT NULL DEFAULT 3306,
time_start_us INT NOT NULL DEFAULT 0,
success_time_us INT DEFAULT 0,
repl_lag INT DEFAULT 0,
error VARCHAR,
PRIMARY KEY (hostname, port, time_start_us))
1 row in set (0.001 sec)
monitor.mysql_server_read_only_log
sql
MySQL [(none)]> SHOW CREATE TABLE monitor.mysql_server_read_only_log\G
*************************** 1. row ***************************
table: mysql_server_read_only_log
Create Table: CREATE TABLE mysql_server_read_only_log (
hostname VARCHAR NOT NULL,
port INT NOT NULL DEFAULT 3306,
time_start_us INT NOT NULL DEFAULT 0,
success_time_us INT DEFAULT 0,
read_only INT DEFAULT 1,
error VARCHAR,
PRIMARY KEY (hostname, port, time_start_us))
1 row in set (0.001 sec)
参数/变量
普通参数
- mysql-monitore_username:指定用来链接后端数据库进行监控的用户名,该用户需要USAGE权限连接,ping以及检查read_only。如果需要监控replication_lage还需要REPLICATION CLIENT权限。
- mysql-monitor_password:mysql-monitore_username的密码。
- mysql-monitor_enabled:启用或者禁用MySQL monitor。MySQL的监控有时候会影响到Admin的操作,比如需要将某个节点暂时下线,但是监控到(admin修改成的OFFLINE后)OFFLINE,会自动改成ONLINE,影响admin进行管理,所以这个参数可以临时的禁用MySQL monitor模块。
连接参数
- mysql-monitor_connect_interval:连接数据库进行检查的间隔时间,单位是毫秒
sql
MySQL [(none)]> SHOW VARIABLES LIKE 'mysql-monitor_connect_interval';
+--------------------------------+-------+
| Variable_name | Value |
+--------------------------------+-------+
| mysql-monitor_connect_interval | 60000 |
+--------------------------------+-------+
1 row in set (0.001 sec)
- mysql-monitor_connect_timeout:连接超时参数,单位是毫秒(千分之一秒)。当前是对这个事件进行向上取整,最小是1s,这种懒惰的四舍五入是因为SSL可能会阻塞调用(实际等待时间 ≥ 设定时间).
ping相关参数
- mysql-monitor_ping_interval:多久执行一次ping操作进行检查,单位是毫秒。
- mysql-monitor_ping_timeout:ping超时的时间,单位毫秒。
- mysql-monitor_ping_max_failuers:如果后端数据库的host连续错过mysql-monitor_ping_max_failures记录的次数(也就是ping不通这么多次),MySQL monitor同痣mysql_hostgroup_manager这个节点已经不可达了,并且这个主机的连接会被kill掉。在连接不到后端服务的时候这个非常重要,mysql_monitor会尝试连接,然后进行ping,因此检测节点故障的所需要的时间可能是以下两种情况之一:
- mysql-monitor_ping_max_failures * mysql-monitor_connect_timeout
- mysql-monitor_ping_max_failures * mysql-monitor_ping_timeout
只读相关参数
- mysql-monitor_read_only_interval:多久检查一次只读状态参数,单位毫秒。
- mysql-monitor_read_only_timeout:检查只读时的超时时间,单位毫秒。
- mysql-monitor_writer_is_also_reader:当一个节点的read_only参数从1变成了0,也就意味着从只读变成了可读写,那么这个变量就决定这个节点是否都存在于两个组中:
- false:节点会被移动到写组writer_hostgroup 中,并且会被从读组reader_hostgroup中移除。
- true:节点会被复制到写组writer_hostgroup 中,并且继续保留在读组reader_hostgroup中
Replication lag相关参数
- mysql-monitor_replication_lag_interval:检查这个参数值被执行的频率,单位毫秒
- mysql-monitor_replication_lag_timeout:检查这个参数值时,超时的时间,单位毫秒
其他参数变量
- mysql-monitor_history:为了限制日志表无限制增长,监控模块会自动purge掉超过mysql-monitor_history参数配置的时长的日志记录,单位是毫秒。由于ping检查依赖于历史表的记录来决定一个节点是否失去了心跳,所以如果mysql-monitor_history值小于检查心跳的所需时间就会自动被调整如下:
bash
mysql-monitor_history=(mysql-monitor_ping_max_failures + 1) * mysql-monitor_ping_timeout
保证这个历史记录可以至少多一次本次检查的结果,和历史的进行比较。
主要线程
监控模块有许多内部的线程,主要的有如下5个线程:
- monitor:负责启动和协调其他线程的主线程。
- monitor_connect_thread:负责调度connect检查的主线程。
- monitor_ping_thread:负责调度ping的检查任务主线程。
- monitor_read_only_thread:负责调度read only检查任务主线程。
- monitor_replication_lag:负责调度replication lag检查任务主线程。该线程是专门负责复制延迟检查的主控/调度线程;在 v1.2.0 版本前,这些检查是由其他线程(非 Monitor)兼任完成的,v1.2.0 后进行了职责分离/重构。
线程池
V1.2.0版本的实现存在SSL方面的限制:使用SLLS时,connect()函数是一个阻塞调用,导致线程在执行连接阶段时出现停滞,V1.2.1通过新的实现方法客服这一个限制:
- monitor初始化一个workers线程池,并且创建一个队列
- monitor_connect_thread,monitor_ping_thread, monitor_read_only_thread和monitor_replication_lag_thread 都是生产者队列,他们生成各自的任务然后发送给worker线程,worker线程从这个生产者队列中进行消费。
- woker线程处理和执行请求的操作。
- 如果monitor检测到这个队列增长的太快,那么他就会创建一个新的临时的wokrer线程。
连接清理(purging)
监控模块实现了自己的连接池。目前还在处于alive的连接,如果超过了3 * mysql_thread_monitor_ping_interval 时间,那么该连接会被自动清理。
等待超时
为了防止后端数据库终止连接,监控模块会配置超时时间wait_timeout = mysql_thread_monitor_ping_interval * 10