后期随着用户量的增加,用户产生的数据信息被源源不断的添加到数据库中,最终达到数据库的最佳存储容量。如果此时继续向数据库中新增数据,会导致数据库的CRUD等基本操作变慢,进而影响整个服务的响应速度。
这时,我们需要增加新的节点,对数据库进行水平扩容,那么加入新的数据库D后,数据库的规模由原来的3个变为4个。
如图所示:
此时由于分片规则发生了变化(uid%3 变为uid%4),导致大部分的数据,无法命中原有的数据,需要重新进行分配,要做大量的数据迁移处理。
比如之前uid如果是uid=3取模3%3=0, 是分配在A库上,新加入D库后, uid=3取模3%4=3,分配在D库上;
新增一个节点, 大概会有90%的数据需要迁移, 这样会面临大量的数据压力,并且对服务造成极大的不稳定性。
日志记录不用关注新增了哪些信息,修改的数据格式,只需要记录以上数据信息,这样日志格式是固定的, 这样能保证方案的通用性。
服务升级日志记录功能风险较小:
写和修改接口是少数, 改动点少; 升级只是增加了一些日志,采用异步方式实现, 对业务功能没有太多影响。
整个过程仍然采用旧库进行对外服务。 数据同步工具实现复杂度不高。 只对旧库进行读取操作, 如果同步出现问题, 都可以对新库进行回滚操作。 可以限速或分批迁移执行, 不会有时间压力。数据迁移完成之后, 并不能切换至新库提供服务。 因为旧库依然对线上提供服务, 库中的数据随时会发生变化, 但这些变化的数据并没有同步到新库中, 旧库和新库数据不一致, 所以不能直接进行切换, 需要将数据同步完整。
研发一个日志迁移工具,把上面迁移数据过程中的差异数据追平,处理步骤:
读取log日志,获取具体是哪个库、表和主键发生了变化修改; 把旧库中的主键记录读取出来 根据主键ID,把新库中的记录替换掉这样可以最大程度的保障数据的一致性。风险分析:
整个过程, 仍然是旧库对线上提供服务; 日志迁移工具实现的复杂度较低; 任何时间发现问题, 可以重新再来,有充分的容错空间; 可以限速重放处理日志, 处理过程不会因为对线上影响造成时间压力。但是, 日志增量同步完成之后, 还不能切换到新的数据库。 因为日志增量同步过程中,旧库中可能有数据发生变化, 导致数据不一致,所以需要进一步读取日志, 追平数据记录; 日志增量同步过程随时可能会产生新的数据, 新库与旧库的数据追平也会是一个无限逼近的过程。
但是在极限情况下, 即便通过上面的数据校验处理, 也有可能出现99.99%数据一致, 不能保障完全一致,这个时候可以在旧库做一个readonly只读功能, 或者将流量屏蔽降级,等待日志增量同步工具完全追平后, 再进行新库的切换。
至此,完成日志方案的迁移扩容处理, 整个过程能够持续对线上提供服务, 只会短暂的影响服务的可用性。
这种方案的弊端,是操作繁琐,需要适配多个同步处理工具,成本较高, 需要制定个性化业务的同步处理, 不具备普遍性,耗费的时间周期也较长。
双写方案可通过canal或mq做实现。
把uid%4=0和uid%4=2的数据分别分配到A和A0主库中 把uid%4=1和uid%4=3的数据分配到B和B0主库中
由于之前uid%2的数据是分配在2个库里面,扩容之后需要分布到4个库中,但由于旧数据仍存在(uid%4=0的节点,还有一半uid%4=2的数据),所以需要对冗余数据做一次清理。
这个清理,并不会影响线上数据的一致性,可以随时随地进行。
yum -y install wget
## 备份CentOS-Base.repo
mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.bak
wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
wget -P /etc/yum.repos.d/ http://mirrors.aliyun.com/repo/epel-7.repo
yum clean all
yum makecache
vi /etc/yum.repos.d/mariadb-10.2.repo
增加以下内容:
[mariadb]
name = MariaDB
baseurl = https://mirrors.ustc.edu.cn/mariadb/yum/10.2/centos7-amd64
gpgkey=https://yum.mariadb.org/RPM-GPG-KEY-MariaDB
gpgcheck=1
yum -y install mariadb mariadb-server MariaDB-client MariaDB-common
[root@localhost yum.repos.d]# ps -ef | grep mysql
root 1954 1 0 Oct04 ? 00:05:43 /usr/sbin/mysqld --wsrep-new-cluster --user=root
root 89521 81403 0 07:40 pts/0 00:00:00 grep --color=auto mysql
[root@localhost yum.repos.d]# kill 1954
yum -y remove Maria*
rm -rf /var/lib/mysql/*
rm -rf /etc/my.cnf.d/
rm -rf /etc/my.cnf
systemctl start mariadb
mysql_secure_installation
mysql -uroot -p654321
进入MySQL服务, 执行以下操作:
use mysql;
delete from user;
## 配置root用户使用密码654321从任何主机都可以连接到mysql服务器
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY '654321' WITH GRANT OPTION;
FLUSH PRIVILEGES;
[mysqld]
server-id = 1
log-bin=mysql-bin
relay-log = mysql-relay-bin
## 忽略mysql、information_schema库下对表的操作
replicate-wild-ignore-table=mysql.%
replicate-wild-ignore-table=information_schema.%
## 默认的情况下mysql是关闭的;
log-slave-updates=on
## 复制过程中,有任何错误,直接跳过
slave-skip-errors=all
auto-increment-offset=1
auto-increment-increment=2
## binlog的格式:STATEMENT,ROW,MIXED
binlog_format=mixed
## 自动过期清理binlog,默认0天,即不自动清理
expire_logs_days=10
注意, Server1自增为奇数位:
auto-increment-offset=1 主键自增基数, 从1开始。 auto-increment-increment=2 主键自增偏移量,每次为2。
[mysqld]
server-id = 2
log-bin=mysql-bin
relay-log = mysql-relay-bin
replicate-wild-ignore-table=mysql.%
replicate-wild-ignore-table=information_schema.%
log-slave-updates=on
slave-skip-errors=all
auto-increment-offset=2
auto-increment-increment=2
binlog_format=mixed
expire_logs_days=10
Server2自增为偶数位:
auto-increment-offset=2 主键自增基数, 从2开始。 auto-increment-increment=2 主键自增偏移量,每次为2。配置修改完成后, 重启数据库。
MariaDB [(none)]> grant replication slave, replication client on *.* to 'replica'@'%' identified by 'replica';
mysql> flush privileges;
查询日志文件与偏移量,开启同步时需使用:
MariaDB [(none)]> show master status;
+------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000001 | 663 | | |
+------------------+----------+--------------+------------------+
同样, 在Server2创建replica用于主从同步的用户:
MariaDB [(none)]> grant replication slave, replication client on *.* to 'replica'@'%' identified by 'replica';
mysql> flush privileges;
查询日志文件与偏移量:
MariaDB [(none)]> show master status;
+------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000001 | 663 | | |
+------------------+----------+--------------+------------------+
MariaDB [(none)]> change master to master_host='192.168.116.141',master_user='replica', master_password='replica', master_port=3306, master_log_file='mysql-bin.000007', master_log_pos=374, master_connect_retry=30;
在Server2中执行:
MariaDB [(none)]> change master to master_host='192.168.116.140',master_user='replica', master_password='replica', master_port=3306, master_log_file='mysql-bin.000015', master_log_pos=374, master_connect_retry=30;
MariaDB [(none)]> start slave;
Query OK, 0 rows affected (0.00 sec)
在Server1查询同步信息:
MariaDB [(none)]> show slave status\G;
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 10.10.20.126
Master_User: replica
Master_Port: 3306
Connect_Retry: 30
Master_Log_File: mysql-bin.000001
Read_Master_Log_Pos: 663
Relay_Log_File: mysql-relay-bin.000002
Relay_Log_Pos: 555
Relay_Master_Log_File: mysql-bin.000001
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
...
在Server2查询同步信息:
MariaDB [(none)]> show slave status\G;
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 10.10.20.125
Master_User: replica
Master_Port: 3306
Connect_Retry: 30
Master_Log_File: mysql-bin.000001
Read_Master_Log_Pos: 663
Relay_Log_File: mysql-relay-bin.000002
Relay_Log_Pos: 555
Relay_Master_Log_File: mysql-bin.000001
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
...
Slave_IO_Running和Slave_SQL_Running 都是Yes,说明双主同步配置成功。
yum -y install keepalived
systemctl stop firewalld
systemctl disable firewalld
hostnamectl set-hostname vip1
Server2节点:
hostnamectl set-hostname vip2
global_defs {
router_id vip1 # 机器标识,和主机名保持一致,运行keepalived服务器的一个标识
}
vrrp_instance VI_1 { #vrrp实例定义
state BACKUP #lvs的状态模式,MASTER代表主, BACKUP代表备份节点
interface ens33 #绑定对外访问的网卡,vrrp实例绑定的网卡
virtual_router_id 111 #虚拟路由标示,同一个vrrp实例采用唯一标示
priority 100 #优先级,100代表最大优先级, 数字越大优先级越高
advert_int 1 #master与backup节点同步检查的时间间隔,单位是秒
authentication { #设置验证信息
auth_type PASS #有PASS和AH两种
auth_pass 6666 #验证密码,BACKUP密码须相同
}
virtual_ipaddress { #KeepAlived虚拟的IP地址
192.168.116.150
}
}
virtual_server 192.168.116.150 3306 { #配置虚拟服务器IP与访问端口
delay_loop 6 #健康检查时间
lb_algo rr #负载均衡调度算法, rr代表轮询
lb_kind DR #负载均衡转发规则 DR/NAT/
persistence_timeout 0 #会话保持时间,这里要做测试, 所以设为0, 实际可根据session有效时间配置
protocol TCP #转发协议类型,支持TCP和UDP
real_server 192.168.116.140 3306 { #配置服务器节点VIP1
notify_down /usr/local/shell/mariadb.sh #当服务挂掉时, 会执行此脚本,结束keepalived进程
weight 1 #设置权重,越大权重越高
TCP_CHECK { #状态监测设置
connect_timeout 10 #超时配置, 单位秒
retry 3 #重试次数
delay_before_retry 3 #重试间隔
connect_port 3306 #连接端口, 和上面保持一致
}
}
}
创建关闭脚本mariadb.sh
/usr/local/shell/mariadb.sh:
pkill keepalived
加入执行权限:
chmod a+x mariadb.sh
global_defs {
router_id vip2 # 机器标识,和主机名保持一致,运行keepalived服务器的一个标识
}
vrrp_instance VI_1 { #vrrp实例定义
state BACKUP #lvs的状态模式,MASTER代表主, BACKUP代表备份节点
interface ens33 #绑定对外访问的网卡
virtual_router_id 111 #虚拟路由标示,同一个vrrp实例采用唯一标示
priority 98 #优先级,100代表最大优先级, 数字越大优先级越高
advert_int 1 #master与backup节点同步检查的时间间隔,单位是秒
authentication { #设置验证信息
auth_type PASS #有PASS和AH两种
auth_pass 6666 #验证密码,BACKUP密码须相同
}
virtual_ipaddress { #KeepAlived虚拟的IP地址
192.168.116.150
}
}
virtual_server 192.168.116.150 3306 { #配置虚拟服务器IP与访问端口
delay_loop 6 #健康检查时间
lb_algo rr #负载均衡调度算法, rr代表轮询, 可以关闭
lb_kind DR #负载均衡转发规则, 可以关闭
persistence_timeout 0 #会话保持时间,这里要做测试, 所以设为0, 实际可根据session有效时间配置
protocol TCP #转发协议类型,支持TCP和UDP
real_server 192.168.116.141 3306{ #配置服务器节点VIP2
notify_down /usr/local/shell/mariadb.sh #当服务挂掉时, 会执行此脚本,结束keepalived进程
weight 1 #设置权重,越大权重越高
TCP_CHECK { #r状态监测设置
connect_timeout 10 #超时配置, 单位秒
retry 3 #重试次数
delay_before_retry 3 #重试间隔
connect_port 3306 #连接端口, 和上面保持一致
}
}
}
和Server1的差异项:
router_id vip2 # 机器标识,和主机名保持一致
priority 98 #优先级,100代表最大优先级, 数字越大优先级越高
real_server 10.10.20.126 3306 #配置服务器节点VIP2
注意, 两台节点都设为BACKUP
virtual_router_id 111 #同一个vrrp实例采用唯一标示
state BACKUP
如果不想重启后, 争夺备用节点的VIP, 可以设置此项
nopreempt #不主动抢占资源
注意:这个配置只能设置在backup主机上,而且这个主机优先级要比另外一台高
// 动态数据源配置实现扩容
Properties properties = loadPropertiesFile("datasource1.properties");
try {
log.info("load datasource config url: " + properties.get("url"));
DruidDataSource druidDataSource = (DruidDataSource) DruidDataSourceFactory.createDataSource(properties);
druidDataSource.setRemoveAbandoned(true);
druidDataSource.setRemoveAbandonedTimeout(600);
druidDataSource.setLogAbandoned(true);
// 设置数据源错误重连时间
druidDataSource.setTimeBetweenConnectErrorMillis(60000);
druidDataSource.init();
OrchestrationShardingDataSource dataSource = SpringContextUtil.getBean("tradeSystemDataSource", OrchestrationShardingDataSource.class);
Map<String, DataSource> dataSourceMap = dataSource.getDataSource().getDataSourceMap();
dataSourceMap.put(DatasourceEnum.DATASOURCE_2.getValue(), druidDataSource);
Map<String, DataSourceConfiguration> dataSourceConfigMap = new HashMap<String, DataSourceConfiguration>();
for(String key : dataSourceMap.keySet()) {
dataSourceConfigMap.put(key, DataSourceConfiguration.getDataSourceConfiguration(dataSourceMap.get(key)));
}
String result = SHARDING_RULE_TABLE_ORDER.replace(SHARDING_RULE_DATASOURCE, newRule);
replaceActualDataNodes(result);
SHARDING_RULE_DATASOURCE = newRule;
dataSource.renew(new DataSourceChangedEvent(
"/" + DruidSystemDataSourceConfiguration.DYNAMIC_SHARDING + "/config/schema/logic_db/datasource",
dataSourceConfigMap));
return;
} catch (Exception e) {
log.error(e.getMessage(), e);
}
global_defs {
router_id vip2
}
vrrp_instance VI_1 { #vrrp实例定义
state BACKUP #lvs的状态模式,MASTER代表主, BACKUP代表备份节点
interface ens33 #绑定对外访问的网卡
virtual_router_id 112 #虚拟路由标示,同一个vrrp实例采用唯一标示
priority 100 #优先级,100代表最大优先级, 数字越大优先级越高
advert_int 1 #master与backup节点同步检查的时间间隔,单位是秒
authentication { #设置验证信息
auth_type PASS #有PASS和AH两种
auth_pass 6666 #验证密码,BACKUP密码须相同
}
virtual_ipaddress { #KeepAlived虚拟的IP地址
192.168.116.151
}
}
virtual_server 192.168.116.151 3306 { #配置虚拟服务器IP与访问端口
delay_loop 6 #健康检查时间
persistence_timeout 0 #会话保持时间,这里要做测试, 所以设为0, 实际可根据session有效时间配置
protocol TCP #转发协议类型,支持TCP和UDP
real_server 192.168.116.141 3306{ #配置服务器节点VIP1
notify_down /usr/local/shell/mariadb.sh
weight 1 #设置权重,越大权重越高
TCP_CHECK { #r状态监测设置
connect_timeout 10 #超时配置, 单位秒
retry 3 #重试次数
delay_before_retry 3 #重试间隔
connect_port 3306 #连接端口, 和上面保持一致
}
}
}
注意配置项:
virtual_router_id 112 #虚拟路由标示,同一个vrrp实例采用唯一标示
priority 100 #优先级,100代表最大优先级, 数字越大优先级越高
MariaDB [(none)]> stop slave;
MariaDB [(none)]> stop slave;
[mysqld]
server-id = 3
log-bin=mysql-bin
relay-log = mysql-relay-bin
replicate-wild-ignore-table=mysql.%
replicate-wild-ignore-table=information_schema.%
log-slave-updates=on
slave-skip-errors=all
auto-increment-offset=2
auto-increment-increment=2
binlog_format=mixed
expire_logs_days=10
service mariadb restart
MariaDB [(none)]> grant replication slave, replication client on *.* to 'replica'@'%' identified by 'replica';
mysql> flush privileges;
mysqldump -uroot -p654321 --routines --single_transaction --master-data=2 --databases smooth > server1.sql
...
--
-- Position to start replication or point-in-time recovery from
--
-- CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000002', MASTER_LOG_POS=17748;
...
scp server1.sql root@192.168.116.142:/usr/local/
mysql -uroot -p654321 < /usr/local/server1.sql
MariaDB [(none)]> change master to master_host='192.168.116.140',master_user='replica', master_password='replica', master_port=3306, master_log_file='mysql-bin.000016', master_log_pos=1754, master_connect_retry=30;
Query OK, 0 rows affected (0.01 sec)
MariaDB [(none)]> start slave;
Query OK, 0 rows affected (0.00 sec)
如果出现问题, 复原主从同步信息:
MariaDB [(none)]> reset slave;
Query OK, 0 rows affected (0.01 sec)
MariaDB [(none)]> show slave status \G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 10.10.20.125
Master_User: replica
Master_Port: 3306
Connect_Retry: 30
Master_Log_File: mysql-bin.000004
Read_Master_Log_Pos: 11174
Relay_Log_File: mysql-relay-bin.000002
Relay_Log_Pos: 1746
Relay_Master_Log_File: mysql-bin.000004
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
MariaDB [(none)]> show master status;
+------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000001 | 4781 | | |
+------------------+----------+--------------+------------------+
在Server1节点, 配置同步信息:
MariaDB [(none)]> reset slave;
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]> change master to master_host='192.168.116.142',master_user='replica', master_password='replica', master_port=3306, master_log_file='mysql-bin.000005', master_log_pos=6931, master_connect_retry=30;
MariaDB [(none)]> start slave;
Query OK, 0 rows affected (0.00 sec)
[mysqld]
server-id = 4
log-bin=mysql-bin
relay-log = mysql-relay-bin
replicate-wild-ignore-table=mysql.%
replicate-wild-ignore-table=information_schema.%
log-slave-updates=on
slave-skip-errors=all
auto-increment-offset=2
auto-increment-increment=2
binlog_format=mixed
expire_logs_days=10
service mariadb restart
MariaDB [(none)]> grant replication slave, replication client on *.* to 'replica'@'%' identified by 'replica';
mysql> flush privileges;
mysqldump -uroot -p654321 --routines --single_transaction --master-data=2 --databases smooth > server2.sql
...
--
-- Position to start replication or point-in-time recovery from
--
-- CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000003', MASTER_LOG_POS=4208;
...
scp server2.sql root@192.168.116.143:/usr/local/
mysql -uroot -p654321 < /usr/local/server2.sql
MariaDB [(none)]> change master to master_host='192.168.116.141',master_user='replica', master_password='replica', master_port=3306, master_log_file='mysql-bin.000007', master_log_pos=3006, master_connect_retry=30;
Query OK, 0 rows affected (0.01 sec)
MariaDB [(none)]> start slave;
Query OK, 0 rows affected (0.00 sec)
注意, 如果出现问题, 复原主从同步信息:
MariaDB [(none)]> reset slave;
Query OK, 0 rows affected (0.01 sec)
MariaDB [(none)]> show slave status \G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 10.10.20.125
Master_User: replica
Master_Port: 3306
Connect_Retry: 30
Master_Log_File: mysql-bin.000004
Read_Master_Log_Pos: 11174
Relay_Log_File: mysql-relay-bin.000002
Relay_Log_Pos: 1746
Relay_Master_Log_File: mysql-bin.000004
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
MariaDB [(none)]> show master status;
+------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000001 | 3696 | | |
+------------------+----------+--------------+------------------+
在Server2节点, 配置同步信息:
MariaDB [(none)]> reset slave;
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]> change master to master_host='192.168.116.143',master_user='replica', master_password='replica', master_port=3306, master_log_file='mysql-bin.000005', master_log_pos=5787, master_connect_retry=30;
MariaDB [(none)]> start slave;
Query OK, 0 rows affected (0.00 sec)
global_defs {
router_id vip3 # 机器标识,一般设为hostname,故障发生时,邮件通知会使用到。
}
vrrp_instance VI_1 { #vrrp实例定义
state BACKUP #lvs的状态模式,MASTER代表主, BACKUP代表备份节点
interface ens33 #绑定对外访问的网卡
virtual_router_id 111 #虚拟路由标示,同一个vrrp实例采用唯一标示
priority 98 #优先级,100代表最大优先级, 数字越大优先级越高
advert_int 1 #master与backup节点同步检查的时间间隔,单位是秒
authentication { #设置验证信息
auth_type PASS #有PASS和AH两种
auth_pass 6666 #验证密码,BACKUP密码须相同
}
virtual_ipaddress { #KeepAlived虚拟的IP地址
192.168.116.150
}
}
virtual_server 192.168.116.150 3306 { #配置虚拟服务器IP与访问端口
delay_loop 6 #健康检查时间
persistence_timeout 0 #会话保持时间,这里要做测试, 所以设为0, 实际可根据session有效时间配置
protocol TCP #转发协议类型,支持TCP和UDP
real_server 192.168.116.142 3306{ #配置服务器节点VIP3
notify_down /usr/local/shell/mariadb.sh
weight 1 #设置权重,越大权重越高
TCP_CHECK { #r状态监测设置
connect_timeout 10 #超时配置, 单位秒
retry 3 #重试次数
delay_before_retry 3 #重试间隔
connect_port 3306 #连接端口, 和上面保持一致
}
}
}
注意里面IP配置正确, 修改完成后重启服务。
创建关闭脚本mariadb.sh
/usr/local/shell/mariadb.sh:
pkill keepalived
加入执行权限:
chmod a+x mariadb.sh
global_defs {
router_id vip4 # 机器标识,一般设为hostname,故障发生时,邮件通知会使用到。
}
vrrp_instance VI_1 { #vrrp实例定义
state BACKUP #lvs的状态模式,MASTER代表主, BACKUP代表备份节点
interface ens33 #绑定对外访问的网卡
virtual_router_id 112 #虚拟路由标示,同一个vrrp实例采用唯一标示
priority 98 #优先级,100代表最大优先级, 数字越大优先级越高
advert_int 1 #master与backup节点同步检查的时间间隔,单位是秒
authentication { #设置验证信息
auth_type PASS #有PASS和AH两种
auth_pass 6666 #验证密码,BACKUP密码须相同
}
virtual_ipaddress { #KeepAlived虚拟的IP地址
192.168.116.151
}
}
virtual_server 192.168.116.151 3306 { #配置虚拟服务器IP与访问端口
delay_loop 6 #健康检查时间
persistence_timeout 0 #会话保持时间,这里要做测试, 所以设为0, 实际可根据session有效时间配置
protocol TCP #转发协议类型,支持TCP和UDP
real_server 192.168.116.143 3306{ #配置服务器节点VIP4
notify_down /usr/local/shell/mariadb.sh
weight 1 #设置权重,越大权重越高
TCP_CHECK { #r状态监测设置
connect_timeout 10 #超时配置, 单位秒
retry 3 #重试次数
delay_before_retry 3 #重试间隔
connect_port 3306 #连接端口, 和上面保持一致
}
}
}
创建关闭脚本mariadb.sh
/usr/local/shell/mariadb.sh:
pkill keepalived
给所有的用户组加入执行权限:
chmod a+x mariadb.sh
delete from t_trade_order where accountNo % 2 != 0
delete from t_trade_order where accountNo % 2 != 1
MariaDB [(none)]> change master to master_host='192.168.116.141',master_user='replica', master_password='replica', master_port=3306, master_log_file='mysql-bin.000005', master_log_pos=3207, master_connect_retry=30;
在Server2(192.168.116.141)中执行:
MariaDB [(none)]> change master to master_host='192.168.116.140',master_user='replica', master_password='replica', master_port=3306, master_log_file='mysql-bin.000012', master_log_pos=1951, master_connect_retry=30;
在Server3(192.168.116.142)中执行:
MariaDB [(none)]> change master to master_host='192.168.116.140',master_user='replica', master_password='replica', master_port=3306, master_log_file='mysql-bin.000013', master_log_pos=2781, master_connect_retry=30;
Query OK, 0 rows affected (0.01 sec)
在Server4(192.168.116.143)中执行:
MariaDB [(none)]> change master to master_host='192.168.116.141',master_user='replica', master_password='replica', master_port=3306, master_log_file='mysql-bin.000005', master_log_pos=7358, master_connect_retry=30;
Query OK, 0 rows affected (0.01 sec)
global_defs {
router_id vip1
}
vrrp_instance VI_1 {
state BACKUP
interface ens33
virtual_router_id 111
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 6666
}
virtual_ipaddress {
192.168.116.150
}
}
virtual_server 192.168.116.150 3306 {
delay_loop 6
lb_algo rr
lb_kind DR // NAT|DR|TUN
persistence_timeout 0
protocol TCP
real_server 192.168.116.140 3306 {
notify_down /usr/local/shell/mariadb.sh
weight 1
TCP_CHECK {
connect_timeout 10
retry 3
delay_before_retry 3
connect_port 3306
}
}
}
global_defs {
router_id vip2
}
vrrp_instance VI_1 {
state BACKUP
interface ens33
virtual_router_id 111
priority 98
advert_int 1
authentication {
auth_type PASS
auth_pass 6666
}
virtual_ipaddress {
192.168.116.150
}
}
virtual_server 192.168.116.150 3306 {
delay_loop 6
lb_algo rr
lb_kind DR
persistence_timeout 0
protocol TCP
real_server 192.168.116.141 3306{
notify_down /usr/local/shell/mariadb.sh
weight 1
TCP_CHECK {
connect_timeout 10
retry 3
delay_before_retry 3
connect_port 3306
}
}
}
global_defs {
router_id vip2
}
vrrp_instance VI_1 {
state BACKUP
interface ens33
virtual_router_id 112
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 6666
}
virtual_ipaddress {
192.168.116.151
}
}
virtual_server 192.168.116.151 3306 {
delay_loop 6
persistence_timeout 0
protocol TCP
real_server 192.168.116.141 3306{
notify_down /usr/local/shell/mariadb.sh
weight 1
TCP_CHECK {
connect_timeout 10
retry 3
delay_before_retry 3
connect_port 3306
}
}
}
global_defs {
router_id vip3
}
vrrp_instance VI_1 {
state BACKUP
interface ens33
virtual_router_id 111
priority 98
advert_int 1
authentication {
auth_type PASS
auth_pass 6666
}
virtual_ipaddress {
192.168.116.150
}
}
virtual_server 192.168.116.150 3306 {
delay_loop 6
lb_algo rr
lb_kind DR
persistence_timeout 0
protocol TCP
real_server 192.168.116.142 3306 {
notify_down /usr/local/shell/mariadb.sh
weight 1
TCP_CHECK {
connect_timeout 10
retry 3
delay_before_retry 3
connect_port 3306
}
}
}
global_defs {
router_id vip4
}
vrrp_instance VI_1 {
state BACKUP
interface ens33
virtual_router_id 112
priority 98
advert_int 1
authentication {
auth_type PASS
auth_pass 6666
}
virtual_ipaddress {
192.168.116.151
}
}
virtual_server 192.168.116.151 3306 {
delay_loop 6
lb_algo rr
lb_kind DR
persistence_timeout 0
protocol TCP
real_server 192.168.116.143 3306{
notify_down /usr/local/shell/mariadb.sh
weight 1
TCP_CHECK {
connect_timeout 10
retry 3
delay_before_retry 3
connect_port 3306
}
}
}
本文由传智教育博学谷发布。 如果本文对您有帮助,欢迎关注和点赞;如果您有任何建议也可留言评论或私信,您的支持是我坚持创作的动力。 转载请注明出处!
我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i
在MRIRuby中我可以这样做:deftransferinternal_server=self.init_serverpid=forkdointernal_server.runend#Maketheserverprocessrunindependently.Process.detach(pid)internal_client=self.init_client#Dootherstuffwithconnectingtointernal_server...internal_client.post('somedata')ensure#KillserverProcess.kill('KILL',
有时我需要处理键/值数据。我不喜欢使用数组,因为它们在大小上没有限制(很容易不小心添加超过2个项目,而且您最终需要稍后验证大小)。此外,0和1的索引变成了魔数(MagicNumber),并且在传达含义方面做得很差(“当我说0时,我的意思是head...”)。散列也不合适,因为可能会不小心添加额外的条目。我写了下面的类来解决这个问题:classPairattr_accessor:head,:taildefinitialize(h,t)@head,@tail=h,tendend它工作得很好并且解决了问题,但我很想知道:Ruby标准库是否已经带有这样一个类? 最佳
我正在尝试使用Curbgem执行以下POST以解析云curl-XPOST\-H"X-Parse-Application-Id:PARSE_APP_ID"\-H"X-Parse-REST-API-Key:PARSE_API_KEY"\-H"Content-Type:image/jpeg"\--data-binary'@myPicture.jpg'\https://api.parse.com/1/files/pic.jpg用这个:curl=Curl::Easy.new("https://api.parse.com/1/files/lion.jpg")curl.multipart_form_
无论您是想搭建桌面端、WEB端或者移动端APP应用,HOOPSPlatform组件都可以为您提供弹性的3D集成架构,同时,由工业领域3D技术专家组成的HOOPS技术团队也能为您提供技术支持服务。如果您的客户期望有一种在多个平台(桌面/WEB/APP,而且某些客户端是“瘦”客户端)快速、方便地将数据接入到3D应用系统的解决方案,并且当访问数据时,在各个平台上的性能和用户体验保持一致,HOOPSPlatform将帮助您完成。利用HOOPSPlatform,您可以开发在任何环境下的3D基础应用架构。HOOPSPlatform可以帮您打造3D创新型产品,HOOPSSDK包含的技术有:快速且准确的CAD
本教程将在Unity3D中混合Optitrack与数据手套的数据流,在人体运动的基础上,添加双手手指部分的运动。双手手背的角度仍由Optitrack提供,数据手套提供双手手指的角度。 01 客户端软件分别安装MotiveBody与MotionVenus并校准人体与数据手套。MotiveBodyMotionVenus数据手套使用、校准流程参照:https://gitee.com/foheart_1/foheart-h1-data-summary.git02 数据转发打开MotiveBody软件的Streaming,开始向Unity3D广播数据;MotionVenus中设置->选项选择Unit
文章目录一、概述简介原理模块二、配置Mysql使用版本环境要求1.操作系统2.mysql要求三、配置canal-server离线下载在线下载上传解压修改配置单机配置集群配置分库分表配置1.修改全局配置2.实例配置垂直分库水平分库3.修改group-instance.xml4.启动监听四、配置canal-adapter1修改启动配置2配置映射文件3启动ES数据同步查询所有订阅同步数据同步开关启动4.验证五、配置canal-admin一、概述简介canal是Alibaba旗下的一款开源项目,Java开发。基于数据库增量日志解析,提供增量数据订阅&消费。Git地址:https://github.co
我正在尝试在Rails上安装ruby,到目前为止一切都已安装,但是当我尝试使用rakedb:create创建数据库时,我收到一个奇怪的错误:dyld:lazysymbolbindingfailed:Symbolnotfound:_mysql_get_client_infoReferencedfrom:/Library/Ruby/Gems/1.8/gems/mysql2-0.3.11/lib/mysql2/mysql2.bundleExpectedin:flatnamespacedyld:Symbolnotfound:_mysql_get_client_infoReferencedf
文章目录1.开发板选择*用到的资源2.串口通信(个人理解)3.代码分析(注释比较详细)1.主函数2.串口1配置3.串口2配置以及中断函数4.注意问题5.源码链接1.开发板选择我用的是STM32F103RCT6的板子,不过代码大概在F103系列的板子上都可以运行,我试过在野火103的霸道板上也可以,主要看一下串口对应的引脚一不一样就行了,不一样的就更改一下。*用到的资源keil5软件这里用到了两个串口资源,采集数据一个,串口通信一个,板子对应引脚如下:串口1,TX:PA9,RX:PA10串口2,TX:PA2,RX:PA32.串口通信(个人理解)我就从串口采集传感器数据这个过程说一下我自己的理解,
SPI接收数据左移一位问题目录SPI接收数据左移一位问题一、问题描述二、问题分析三、探究原理四、经验总结最近在工作在学习调试SPI的过程中遇到一个问题——接收数据整体向左移了一位(1bit)。SPI数据收发是数据交换,因此接收数据时从第二个字节开始才是有效数据,也就是数据整体向右移一个字节(1byte)。请教前辈之后也没有得到解决,通过在网上查阅前人经验终于解决问题,所以写一个避坑经验总结。实际背景:MCU与一款芯片使用spi通信,MCU作为主机,芯片作为从机。这款芯片采用的是它规定的六线SPI,多了两根线:RDY和INT,这样从机就可以主动请求主机给主机发送数据了。一、问题描述根据从机芯片手