一、扩容方案剖析 1、扩容问题 在项目初期,我们部署了三个数据库A、B、C,此时数据库的规模可以满足我们的业务需求。为了将数据做到平均分配,我们在Service服务层使用uid3进行取模分片,从而将数据平均分配到三个数据库中。 如图所示: 后期随着用户量的增加,用户产生的数据信息被源源不断的添加到数据库中,最终达到数据库的最佳存储容量。如果此时继续向数据库中新增数据,会导致数据库的CRUD等基本操作变慢,进而影响整个服务的响应速度。 这时,我们需要增加新的节点,对数据库进行水平扩容,那么加入新的数据库D后,数据库的规模由原来的3个变为4个。 如图所示: 此时由于分片规则发生了变化(uid3变为uid4),导致大部分的数据,无法命中原有的数据,需要重新进行分配,要做大量的数据迁移处理。例如,之前uid如果是uid3取模330,是分配在A库上,新加入D库后,uid3取模343,分配在D库上。 新增一个节点,大概会有90的数据需要迁移,这样会面临大量的数据压力,并且对服务造成极大的不稳定性。 2、停机方案 发布公告 为了进行数据的重新拆分,在停止服务之前,我们需要提前通知用户,比如:我们的服务会在yyyyMMdd进行升级,给您带来的不便敬请谅解。停止服务 关闭Service。离线数据迁移(拆分,重新分配数据) 将旧库中的数据按照Service层的算法,将数据拆分,重新分配数据。数据校验 开发定制一个程序对旧库和新库中的数据进行校验,比对。更改配置 修改Service层的配置算法,也就是将原来的uid3变为uid4。恢复服务 重启Service服务。回滚预案 针对上述的每个步骤都要有数据回滚预案,一旦某个环节(如:数据迁移,恢复服务等)执行失败,立刻进行回滚,重新再来。 停止服务之后,能够保证迁移工作的正常进行,但是服务停止,伤害用户体验,并造成了时间压力,必须在指定的时间内完成迁移。 3、停写方案 支持读写分离 数据库支持读写分离,在扩容之前,每个数据库都提供了读写功能,数据重新分配的过程中,将每个数据库设置为只读状态,关闭写的功能。升级公告 为了进行数据的重新拆分,在停写之前,我们需要提前通知用户,比如:我们的服务会在yyyyMMdd进行升级,给您带来的不便敬请谅解。中断写操作,隔离写数据源(或拦截返回统一提示) 在Service层对所有的写请求进行拦截,统一返回提示信息,如:服务正在升级中,只对外提供读服务。数据同步处理 将旧库中的数据按照Service层的算法,将数据重新分配,迁移(复制数据)。数据校验 开发定制一个程序对旧库中的数据进行备份,使用备份的数据和重新分配后的数据进行校验,比对。更改配置 通过配置中心,修改Service层的配置算法,也就是将原来的uid3变为uid4,这个过程不需要重启服务。恢复写操作 设置数据库恢复读写功能,去除Service层的拦截提示。数据清理 使用delete语句对冗余数据进行删除。回滚预案 针对上述的每个步骤都要有数据回滚预案,一旦某个环节(如:数据迁移等)执行失败,立刻进行回滚,重新再来。 缺点:在数据的复制过程需要消耗大量的时间,停写时间太长,数据需要先复制,再清理冗余数据。 4、日志方案 核心是通过日志进行数据库的同步迁移,主要操作步骤如下:1)数据迁移之前,业务应用访问旧的数据库节点 2)日志记录 在升级之前,记录对旧数据库上的数据修改的日志(这里修改包括增、删、改),这个日志不需要记录详细的数据信息,主要记录:修改的库;修改的表;修改的唯一主键;修改操作类型。 日志记录不用关注新增了哪些信息,修改的数据格式,只需要记录以上数据信息,这样日志格式是固定的,这样能保证方案的通用性。 服务升级日志记录功能风险较小:写和修改接口是少数,改动点少;升级只是增加了一些日志,采用异步方式实现,对业务功能没有太多影响。3)数据迁移 研发定制数据迁移工具,作用是把旧库中的数据迁移至新库中。 整个过程仍然采用旧库进行对外服务。数据同步工具实现复杂度不高。只对旧库进行读取操作,如果同步出现问题,都可以对新库进行回滚操作。可以限速或分批迁移执行,不会有时间压力。 数据迁移完成之后,并不能切换至新库提供服务。 因为旧库依然对线上提供服务,库中的数据随时会发生变化,但这些变化的数据并没有同步到新库中,旧库和新库数据不一致,所以不能直接进行切换,需要将数据同步完整。4)日志增量迁移 研发一个日志迁移工具,把上面迁移数据过程中的差异数据追平,处理步骤:读取log日志,获取具体是哪个库、表和主键发生了变化修改;把旧库中的主键记录读取出来;根据主键ID,把新库中的记录替换掉。 这样可以最大程度的保障数据的一致性。风险分析:整个过程,仍然是旧库对线上提供服务;日志迁移工具实现的复杂度较低;任何时间发现问题,可以重新再来,有充分的容错空间;可以限速重放处理日志,处理过程不会因为对线上影响造成时间压力。 但是,日志增量同步完成之后,还不能切换到新的数据库。 因为日志增量同步过程中,旧库中可能有数据发生变化,导致数据不一致,所以需要进一步读取日志,追平数据记录;日志增量同步过程随时可能会产生新的数据,新库与旧库的数据追平也会是一个无限逼近的过程。5)数据校验 准备好数据校验工具,将旧库和新库中的数据进行比对,直到数据完全一致。 6)切换新库 数据比对完成之后,将流量转移切换至新库,至此新库提供服务,完成迁移。 但是在极限情况下,即便通过上面的数据校验处理,也有可能出现99。99数据一致,不能保障完全一致,这个时候可以在旧库做一个readonly只读功能,或者将流量屏蔽降级,等待日志增量同步工具完全追平后,再进行新库的切换。 至此,完成日志方案的迁移扩容处理,整个过程能够持续对线上提供服务,只会短暂的影响服务的可用性。 这种方案的弊端,是操作繁琐,需要适配多个同步处理工具,成本较高,需要制定个性化业务的同步处理,不具备普遍性,耗费的时间周期也较长。 5、双写方案(中小型数据) 双写方案可通过canal或mq做实现。增加新库,按照现有节点,增加对应的数量。数据迁移:避免增量影响,先断开主从,再导入(耗时较长),同步完成并做校验增量同步:开启Canal同步服务,监听从节点数据库,再开启主从同步,从节点收到数据后会通过Canal服务,传递至新的DB节点。切换新库:通过Nginx,切换访问流量至新的服务。修复切换异常数据:在切换过程中,如果出现,Canal未同步,但已切换至新库的请求(比如下单,修改了资金,但还未同步),可以通过定制程序,读取检测异常日志,做自动修复或人工处理。针对此种情况,最好是在凌晨用户量小的时候,或专门停止外网访问,进行切换,减少异常数据的产生。数据校验:为保障数据的完全一致,有必要对数据的数量完整性做校验。 6、平滑2N方案(大数据量) 1)线上数据库,为了保障其高可用,一般每台主库会配置一台从库,主库负责读写,从库负责读取。下图所示,A,B是主库,A0和B0是从库。 2)当需要扩容的时候,我们把A0和B0升级为新的主库节点,如此由2个分库变为4个分库。同时在上层的分片配置,做好映射,规则如下:把uid40和uid42的数据分别分配到A和A0主库中。把uid41和uid43的数据分配到B和B0主库中。 3)因为A和A0库的数据相同,B和B0数据相同,此时无需做数据迁移。只需调整变更一下分片配置即可,通过配置中心更新,不需要重启。 由于之前uid2的数据是分配在2个库里面,扩容之后需要分布到4个库中,但由于旧数据仍存在(uid40的节点,还有一半uid42的数据),所以需要对冗余数据做一次清理。 这个清理,并不会影响线上数据的一致性,可以随时随地进行。 4)处理完成之后,为保证数据的高可用,以及将来下一步的扩容需求。 可以为现有的主库再次分配一个从库。 二、平滑2N扩容方案实践 1、实现应用服务级别的动态扩容 扩容前部署架构: 1)MariaDB服务安装切换阿里云镜像服务(YUM安装过慢可以切换)yumyinstallwget备份CentOSBase。repomvetcyum。repos。dCentOSBase。repoetcyum。repos。dCentOSBase。repo。bakwgetOetcyum。repos。dCentOSBase。repohttp:mirrors。aliyun。comrepoCentos7。repowgetPetcyum。repos。dhttp:mirrors。aliyun。comrepoepel7。repoyumcleanallyummakecache配置YUM源vietcyum。repos。dmariadb10。2。repo 增加以下内容:〔mariadb〕nameMariaDBbaseurlhttps:mirrors。ustc。edu。cnmariadbyum10。2centos7amd64gpgkeyhttps:yum。mariadb。orgRPMGPGKEYMariaDBgpgcheck1执行安装yumyinstallmariadbmariadbserverMariaDBclientMariaDBcommon 如果之前已经安装,需要先删除(如果之前没有安装,可以忽略此步骤)停止Mariadb服务〔rootlocalhostyum。repos。d〕psefgrepmysqlroot195410Oct04?00:05:43usrsbinmysqldwsrepnewclusteruserrootroot8952181403007:40pts000:00:00grepcolorautomysql〔rootlocalhostyum。repos。d〕kill1954卸载Mariadb服务yumyremoveMaria删除数据与配置rmrfvarlibmysqlrmrfetcmy。cnf。drmrfetcmy。cnf启动MariaDB后,执行安全配置向导命令,可根据安全配置向导提高数据库的安全性systemctlstartmariadbmysqlsecureinstallation开启用户远程连接权限 将连接用户root开启远程连接权限;mysqlurootp654321 进入MySQL服务,执行以下操作:配置root用户使用密码654321从任何主机都可以连接到mysql服务器GRANTALLPRIVILEGESON。TOrootIDENTIFIEDBY654321WITHGRANTOPTION;FLUSHPRIVILEGES;2)MariaDB双主同步在Server1增加配置 在etcmy。cnf中添加以下配置:〔mysqld〕serverid1logbinmysqlbinrelaylogmysqlrelaybin忽略mysql、informationschema库下对表的操作replicatewildignoretablemysql。replicatewildignoretableinformationschema。默认的情况下mysql是关闭的;logslaveupdateson复制过程中,有任何错误,直接跳过slaveskiperrorsallautoincrementoffset1autoincrementincrement2binlog的格式:STATEMENT,ROW,MIXEDbinlogformatmixed自动过期清理binlog,默认0天,即不自动清理expirelogsdays10 注意,Server1自增为奇数位:autoincrementoffset1主键自增基数,从1开始。autoincrementincrement2主键自增偏移量,每次为2。在Server2增加配置 修改etcmy。cnf:〔mysqld〕serverid2logbinmysqlbinrelaylogmysqlrelaybinreplicatewildignoretablemysql。replicatewildignoretableinformationschema。logslaveupdatesonslaveskiperrorsallautoincrementoffset2autoincrementincrement2binlogformatmixedexpirelogsdays10 Server2自增为偶数位:autoincrementoffset2主键自增基数,从2开始。autoincrementincrement2主键自增偏移量,每次为2。 配置修改完成后,重启数据库。同步授权配置 在Server1创建replica用于主从同步的用户:MariaDB〔(none)〕grantreplicationslave,replicationclienton。 查询日志文件与偏移量,开启同步时需使用:MariaDB〔(none)〕FilePositionBinlogDoDBBinlogIgnoreDBmysqlbin。000001663 同样,在Server2创建replica用于主从同步的用户:MariaDB〔(none)〕grantreplicationslave,replicationclienton。 查询日志文件与偏移量:MariaDB〔(none)〕FilePositionBinlogDoDBBinlogIgnoreDBmysqlbin。000001663配置主从同步信息 在Server1中执行:MariaDB〔(none)〕changemastertomasterhost192。168。116。141,masteruserreplica,masterpasswordreplica,masterport3306,masterlogfilemysqlbin。000007,masterlogpos374,masterconnectretry30; 在Server2中执行:MariaDB〔(none)〕changemastertomasterhost192。168。116。140,masteruserreplica,masterpasswordreplica,masterport3306,masterlogfilemysqlbin。000015,masterlogpos374,masterconnectretry30;开启双主同步 在Server1和Server2中分别执行:MariaDB〔(none)〕QueryOK,0rowsaffected(0。00sec) 在Server1查询同步信息:MariaDB〔(none)〕showslavestatusG;1。rowSlaveIOState:WaitingformastertosendeventMasterHost:10。10。20。126MasterUser:replicaMasterPort:3306ConnectRetry:30MasterLogFile:mysqlbin。000001ReadMasterLogPos:663RelayLogFile:mysqlrelaybin。000002RelayLogPos:555RelayMasterLogFile:mysqlbin。000001SlaveIORunning:YesSlaveSQLRunning:Yes。。。 在Server2查询同步信息:MariaDB〔(none)〕showslavestatusG;1。rowSlaveIOState:WaitingformastertosendeventMasterHost:10。10。20。125MasterUser:replicaMasterPort:3306ConnectRetry:30MasterLogFile:mysqlbin。000001ReadMasterLogPos:663RelayLogFile:mysqlrelaybin。000002RelayLogPos:555RelayMasterLogFile:mysqlbin。000001SlaveIORunning:YesSlaveSQLRunning:Yes。。。 SlaveIORunning和SlaveSQLRunning都是Yes,说明双主同步配置成功。3)KeepAlived安装与高可用配置在Server1与Server2两台节点安装keepalivedyumyinstallkeepalived关闭防火墙systemctlstopfirewalldsystemctldisablefirewalld设置主机名称 Server1节点:hostnamectlsethostnamevip1 Server2节点:hostnamectlsethostnamevip2Server1节点配置etckeepalivedkeepalived。conf:globaldefs{routeridvip1机器标识,和主机名保持一致,运行keepalived服务器的一个标识}vrrpinstanceVI1{vrrp实例定义stateBACKUPlvs的状态模式,MASTER代表主,BACKUP代表备份节点interfaceens33绑定对外访问的网卡,vrrp实例绑定的网卡virtualrouterid111虚拟路由标示,同一个vrrp实例采用唯一标示priority100优先级,100代表最大优先级,数字越大优先级越高advertint1master与backup节点同步检查的时间间隔,单位是秒authentication{设置验证信息authtypePASS有PASS和AH两种authpass6666验证密码,BACKUP密码须相同}virtualipaddress{KeepAlived虚拟的IP地址192。168。116。150}}virtualserver192。168。116。1503306{配置虚拟服务器IP与访问端口delayloop6健康检查时间lbalgorr负载均衡调度算法,rr代表轮询lbkindDR负载均衡转发规则DRNATpersistencetimeout0会话保持时间,这里要做测试,所以设为0,实际可根据session有效时间配置protocolTCP转发协议类型,支持TCP和UDPrealserver192。168。116。1403306{配置服务器节点VIP1notifydownusrlocalshellmariadb。sh当服务挂掉时,会执行此脚本,结束keepalived进程weight1设置权重,越大权重越高TCPCHECK{状态监测设置connecttimeout10超时配置,单位秒retry3重试次数delaybeforeretry3重试间隔connectport3306连接端口,和上面保持一致}}} 创建关闭脚本mariadb。sh usrlocalshellmariadb。sh:pkillkeepalived 加入执行权限:chmodaxmariadb。shServer2节点配置globaldefs{routeridvip2机器标识,和主机名保持一致,运行keepalived服务器的一个标识}vrrpinstanceVI1{vrrp实例定义stateBACKUPlvs的状态模式,MASTER代表主,BACKUP代表备份节点interfaceens33绑定对外访问的网卡virtualrouterid111虚拟路由标示,同一个vrrp实例采用唯一标示priority98优先级,100代表最大优先级,数字越大优先级越高advertint1master与backup节点同步检查的时间间隔,单位是秒authentication{设置验证信息authtypePASS有PASS和AH两种authpass6666验证密码,BACKUP密码须相同}virtualipaddress{KeepAlived虚拟的IP地址192。168。116。150}}virtualserver192。168。116。1503306{配置虚拟服务器IP与访问端口delayloop6健康检查时间lbalgorr负载均衡调度算法,rr代表轮询,可以关闭lbkindDR负载均衡转发规则,可以关闭persistencetimeout0会话保持时间,这里要做测试,所以设为0,实际可根据session有效时间配置protocolTCP转发协议类型,支持TCP和UDPrealserver192。168。116。1413306{配置服务器节点VIP2notifydownusrlocalshellmariadb。sh当服务挂掉时,会执行此脚本,结束keepalived进程weight1设置权重,越大权重越高TCPCHECK{r状态监测设置connecttimeout10超时配置,单位秒retry3重试次数delaybeforeretry3重试间隔connectport3306连接端口,和上面保持一致}}} 和Server1的差异项:routeridvip2机器标识,和主机名保持一致priority98优先级,100代表最大优先级,数字越大优先级越高realserver10。10。20。1263306配置服务器节点VIP2 注意:两台节点都设为BACKUPvirtualrouterid111同一个vrrp实例采用唯一标示stateBACKUP 如果不想重启后,争夺备用节点的VIP,可以设置此项nopreempt不主动抢占资源 注意:这个配置只能设置在backup主机上,而且这个主机优先级要比另外一台高验证高可用 停止主节点MariaDB服务,验证是否自动切换。4)搭建应用服务工程ShardingJDBC的介绍 ShardingJDBC是ShardingSphere下的一个产品,定位为轻量级Java框架,在Java的JDBC层提供的额外服务。它使用客户端直连数据库,以jar包形式提供服务,无需额外部署和依赖,可理解为增强版的JDBC驱动,完全兼容JDBC和各种ORM框架。适用于任何基于JDBC的ORM框架,如:JPA,Hibernate,Mybatis,SpringJDBCTemplate或直接使用JDBC。支持任何第三方的数据库连接池,如:DBCP,C3P0,BoneCP,Druid,HikariCP等。支持任意实现JDBC规范的数据库,目前支持MySQL,Oracle,SQLServer,PostgreSQL以及任何遵循SQL92标准的数据库ShardingJDBC初始化流程 1)配置ShardingRuleConfiguration对象 2)配置表分片规则TableRuleConfiguration对象,设置分库、分表策略 3)通过Factory对象将Rule对象与DataSource对象装配 4)ShardingJDBC使用DataSource对象进行分库 ShardingJDBC集成配置maven依赖规则配置application。yml创建DataSource验证应用服务动态扩容配置两个数据源,分别指向Server1和Server2分片只配置一个数据源动态增加另一个数据源动态数据源配置实现扩容PropertiespropertiesloadPropertiesFile(datasource1。properties);try{log。info(loaddatasourceconfigurl:properties。get(url));DruidDataSourcedruidDataSource(DruidDataSource)DruidDataSourceFactory。createDataSource(properties);druidDataSource。setRemoveAbandoned(true);druidDataSource。setRemoveAbandonedTimeout(600);druidDataSource。setLogAbandoned(true);设置数据源错误重连时间druidDataSource。setTimeBetweenConnectErrorMillis(60000);druidDataSource。init();OrchestrationShardingDataSourcedataSourceSpringContextUtil。getBean(tradeSystemDataSource,OrchestrationShardingDataSource。class);MapString,DataSourcedataSourceMapdataSource。getDataSource()。getDataSourceMap();dataSourceMap。put(DatasourceEnum。DATASOURCE2。getValue(),druidDataSource);MapString,DataSourceConfigurationdataSourceConfigMapnewHashMapString,DataSourceConfiguration();for(Stringkey:dataSourceMap。keySet()){dataSourceConfigMap。put(key,DataSourceConfiguration。getDataSourceConfiguration(dataSourceMap。get(key)));}StringresultSHARDINGRULETABLEORDER。replace(SHARDINGRULEDATASOURCE,newRule);replaceActualDataNodes(result);SHARDINGRULEDATASOURCEnewRdataSource。renew(newDataSourceChangedEvent(DruidSystemDataSourceConfiguration。DYNAMICSHARDINGconfigschemalogicdbdatasource,dataSourceConfigMap));}catch(Exceptione){log。error(e。getMessage(),e);}注意事项 ShardingJDBC,Mycat,Drds等产品都是分布式数据库中间件,相比直接的数据源操作,会存在一些限制,ShardingJDBC在使用时,要注意以下问题:有限支持子查询不支持HAVING不支持OR,UNION和UNIONALL不支持特殊INSERT每条INSERT语句只能插入一条数据,不支持VALUES后有多行数据的语句不支持DISTINCT聚合不支持dual虚拟表查询不支持SELECTLASTINSERTID(),不支持自增序列不支持CASEWHEN 2、实现数据库的秒级平滑2N扩容 扩容部署架构: 1)新增数据库VIP在Server2节点,增加VIP 修改etckeepalivedkeepalived。confglobaldefs{routeridvip2}vrrpinstanceVI1{vrrp实例定义stateBACKUPlvs的状态模式,MASTER代表主,BACKUP代表备份节点interfaceens33绑定对外访问的网卡virtualrouterid112虚拟路由标示,同一个vrrp实例采用唯一标示priority100优先级,100代表最大优先级,数字越大优先级越高advertint1master与backup节点同步检查的时间间隔,单位是秒authentication{设置验证信息authtypePASS有PASS和AH两种authpass6666验证密码,BACKUP密码须相同}virtualipaddress{KeepAlived虚拟的IP地址192。168。116。151}}virtualserver192。168。116。1513306{配置虚拟服务器IP与访问端口delayloop6健康检查时间persistencetimeout0会话保持时间,这里要做测试,所以设为0,实际可根据session有效时间配置protocolTCP转发协议类型,支持TCP和UDPrealserver192。168。116。1413306{配置服务器节点VIP1notifydownusrlocalshellmariadb。shweight1设置权重,越大权重越高TCPCHECK{r状态监测设置connecttimeout10超时配置,单位秒retry3重试次数delaybeforeretry3重试间隔connectport3306连接端口,和上面保持一致}}} 注意配置项:virtualrouterid112虚拟路由标示,同一个vrrp实例采用唯一标示priority100优先级,100代表最大优先级,数字越大优先级越高2)应用服务增加动态数据源修改应用服务配置,增加新的数据源,指向新设置的VIP:192。168。116。151。通过应用服务接口,动态扩容调整。3)解除原双主同步 mysqlurootp654321进入Server1MariaDB〔(none)〕进入Server2MariaDB〔(none)〕通过应用服务接口验证数据是否解除同步4)安装MariaDB扩容服务器新建两台虚拟机,分别为Server3和Server4在Server3和Server4两台节点上安装MariaDB服务 参考上文中MariaDB服务安装。配置Server3与Server1,实现新的双主同步Server3节点,修改etcmy。cnf〔mysqld〕serverid3logbinmysqlbinrelaylogmysqlrelaybinreplicatewildignoretablemysql。replicatewildignoretableinformationschema。logslaveupdatesonslaveskiperrorsallautoincrementoffset2autoincrementincrement2binlogformatmixedexpirelogsdays10重启Server3数据库servicemariadbrestart创建replica用于主从同步的用户MariaDB〔(none)〕grantreplicationslave,replicationclienton。在Server1节点,进行数据全量备份mysqldumpurootp654321routinessingletransactionmasterdata2databasessmoothserver1。sql查看并记录masterstatus信息。。。PositiontostartreplicationorpointintimerecoveryfromCHANGEMASTERTOMASTERLOGFILEmysqlbin。000002,MASTERLOGPOS17748;。。。将备份的server1。sql通过scp命令拷贝至Server3节点scpserver1。sqlroot192。168。116。142:usrlocal将数据还原至Server3节点mysqlurootp654321usrlocalserver1。sql配置主从同步信息 根据上面的masterstatus信息,在Server3中执行:MariaDB〔(none)〕changemastertomasterhost192。168。116。140,masteruserreplica,masterpasswordreplica,masterport3306,masterlogfilemysqlbin。000016,masterlogpos1754,masterconnectretry30;QueryOK,0rowsaffected(0。01sec)开启主从同步MariaDB〔(none)〕QueryOK,0rowsaffected(0。00sec) 如果出现问题,复原主从同步信息:MariaDB〔(none)〕QueryOK,0rowsaffected(0。01sec)检查同步状态信息MariaDB〔(none)〕showslavestatusG1。rowSlaveIOState:WaitingformastertosendeventMasterHost:10。10。20。125MasterUser:replicaMasterPort:3306ConnectRetry:30MasterLogFile:mysqlbin。000004ReadMasterLogPos:11174RelayLogFile:mysqlrelaybin。000002RelayLogPos:1746RelayMasterLogFile:mysqlbin。000004SlaveIORunning:YesSlaveSQLRunning:Yes配置Server1与Server3节点的同步 查看Server3的日志信息:MariaDB〔(none)〕FilePositionBinlogDoDBBinlogIgnoreDBmysqlbin。0000014781 在Server1节点,配置同步信息:MariaDB〔(none)〕QueryOK,0rowsaffected(0。00sec)MariaDB〔(none)〕changemastertomasterhost192。168。116。142,masteruserreplica,masterpasswordreplica,masterport3306,masterlogfilemysqlbin。000005,masterlogpos6931,masterconnectretry30;MariaDB〔(none)〕QueryOK,0rowsaffected(0。00sec)配置Server4与Server2的双主同步Server4节点,修改etcmy。cnf〔mysqld〕serverid4logbinmysqlbinrelaylogmysqlrelaybinreplicatewildignoretablemysql。replicatewildignoretableinformationschema。logslaveupdatesonslaveskiperrorsallautoincrementoffset2autoincrementincrement2binlogformatmixedexpirelogsdays10重启Server4数据库servicemariadbrestart创建replica用于主从同步的用户MariaDB〔(none)〕grantreplicationslave,replicationclienton。在Server2节点,进行数据全量备份mysqldumpurootp654321routinessingletransactionmasterdata2databasessmoothserver2。sql查看并记录masterstatus信息。。。PositiontostartreplicationorpointintimerecoveryfromCHANGEMASTERTOMASTERLOGFILEmysqlbin。000003,MASTERLOGPOS4208;。。。将备份的server2。sql通过scp命令拷贝至Server4节点scpserver2。sqlroot192。168。116。143:usrlocal将数据还原至Server4节点mysqlurootp654321usrlocalserver2。sql配置主从同步信息 根据上面的masterstatus信息,在Server4中执行:MariaDB〔(none)〕changemastertomasterhost192。168。116。141,masteruserreplica,masterpasswordreplica,masterport3306,masterlogfilemysqlbin。000007,masterlogpos3006,masterconnectretry30;QueryOK,0rowsaffected(0。01sec)开启主从同步MariaDB〔(none)〕QueryOK,0rowsaffected(0。00sec) 注意,如果出现问题,复原主从同步信息:MariaDB〔(none)〕QueryOK,0rowsaffected(0。01sec)检查同步状态信息MariaDB〔(none)〕showslavestatusG1。rowSlaveIOState:WaitingformastertosendeventMasterHost:10。10。20。125MasterUser:replicaMasterPort:3306ConnectRetry:30MasterLogFile:mysqlbin。000004ReadMasterLogPos:11174RelayLogFile:mysqlrelaybin。000002RelayLogPos:1746RelayMasterLogFile:mysqlbin。000004SlaveIORunning:YesSlaveSQLRunning:Yes配置Server2与Server4节点的同步 查看Server4的日志信息:MariaDB〔(none)〕FilePositionBinlogDoDBBinlogIgnoreDBmysqlbin。0000013696 在Server2节点,配置同步信息:MariaDB〔(none)〕QueryOK,0rowsaffected(0。00sec)MariaDB〔(none)〕changemastertomasterhost192。168。116。143,masteruserreplica,masterpasswordreplica,masterport3306,masterlogfilemysqlbin。000005,masterlogpos5787,masterconnectretry30;MariaDB〔(none)〕QueryOK,0rowsaffected(0。00sec)5)增加KeepAlived服务实现高可用确保新增的Server3和Server4节点安装Keepalived服务。修改Server3节点配置globaldefs{routeridvip3机器标识,一般设为hostname,故障发生时,邮件通知会使用到。}vrrpinstanceVI1{vrrp实例定义stateBACKUPlvs的状态模式,MASTER代表主,BACKUP代表备份节点interfaceens33绑定对外访问的网卡virtualrouterid111虚拟路由标示,同一个vrrp实例采用唯一标示priority98优先级,100代表最大优先级,数字越大优先级越高advertint1master与backup节点同步检查的时间间隔,单位是秒authentication{设置验证信息authtypePASS有PASS和AH两种authpass6666验证密码,BACKUP密码须相同}virtualipaddress{KeepAlived虚拟的IP地址192。168。116。150}}virtualserver192。168。116。1503306{配置虚拟服务器IP与访问端口delayloop6健康检查时间persistencetimeout0会话保持时间,这里要做测试,所以设为0,实际可根据session有效时间配置protocolTCP转发协议类型,支持TCP和UDPrealserver192。168。116。1423306{配置服务器节点VIP3notifydownusrlocalshellmariadb。shweight1设置权重,越大权重越高TCPCHECK{r状态监测设置connecttimeout10超时配置,单位秒retry3重试次数delaybeforeretry3重试间隔connectport3306连接端口,和上面保持一致}}} 注意里面IP配置正确,修改完成后重启服务。 创建关闭脚本mariadb。sh usrlocalshellmariadb。sh:pkillkeepalived 加入执行权限:chmodaxmariadb。sh修改Server4节点配置globaldefs{routeridvip4机器标识,一般设为hostname,故障发生时,邮件通知会使用到。}vrrpinstanceVI1{vrrp实例定义stateBACKUPlvs的状态模式,MASTER代表主,BACKUP代表备份节点interfaceens33绑定对外访问的网卡virtualrouterid112虚拟路由标示,同一个vrrp实例采用唯一标示priority98优先级,100代表最大优先级,数字越大优先级越高advertint1master与backup节点同步检查的时间间隔,单位是秒authentication{设置验证信息authtypePASS有PASS和AH两种authpass6666验证密码,BACKUP密码须相同}virtualipaddress{KeepAlived虚拟的IP地址192。168。116。151}}virtualserver192。168。116。1513306{配置虚拟服务器IP与访问端口delayloop6健康检查时间persistencetimeout0会话保持时间,这里要做测试,所以设为0,实际可根据session有效时间配置protocolTCP转发协议类型,支持TCP和UDPrealserver192。168。116。1433306{配置服务器节点VIP4notifydownusrlocalshellmariadb。shweight1设置权重,越大权重越高TCPCHECK{r状态监测设置connecttimeout10超时配置,单位秒retry3重试次数delaybeforeretry3重试间隔connectport3306连接端口,和上面保持一致}}} 创建关闭脚本mariadb。sh usrlocalshellmariadb。sh:pkillkeepalived 给所有的用户组加入执行权限:chmodaxmariadb。sh修改完后重启Keepalived服务6)清理数据并验证通过应用服务动态扩容接口做调整和验证在Server1节点清理数据 根据取模规则,保留accountNo为偶数的数据deletefromttradeorderwhereaccountNo2!0在Server2节点清理数据 根据取模规则,保留accountNo为奇数的数据deletefromttradeorderwhereaccountNo2!1 三、keepalived高可用配置大全 在Server1(192。168。116。140)中执行:MariaDB〔(none)〕changemastertomasterhost192。168。116。141,masteruserreplica,masterpasswordreplica,masterport3306,masterlogfilemysqlbin。000005,masterlogpos3207,masterconnectretry30; 在Server2(192。168。116。141)中执行:MariaDB〔(none)〕changemastertomasterhost192。168。116。140,masteruserreplica,masterpasswordreplica,masterport3306,masterlogfilemysqlbin。000012,masterlogpos1951,masterconnectretry30; 在Server3(192。168。116。142)中执行:MariaDB〔(none)〕changemastertomasterhost192。168。116。140,masteruserreplica,masterpasswordreplica,masterport3306,masterlogfilemysqlbin。000013,masterlogpos2781,masterconnectretry30;QueryOK,0rowsaffected(0。01sec) 在Server4(192。168。116。143)中执行:MariaDB〔(none)〕changemastertomasterhost192。168。116。141,masteruserreplica,masterpasswordreplica,masterport3306,masterlogfilemysqlbin。000005,masterlogpos7358,masterconnectretry30;QueryOK,0rowsaffected(0。01sec) 1、Server1和Server2双主关系1)Server1:keepalived。conf vietckeepalivedkeepalived。confglobaldefs{routeridvip1}vrrpinstanceVI1{stateBACKUPinterfaceens33virtualrouterid111priority100advertint1authentication{authtypePASSauthpass6666}virtualipaddress{192。168。116。150}}virtualserver192。168。116。1503306{delayloop6lbalgorrlbkindDRNATDRTUNpersistencetimeout0protocolTCPrealserver192。168。116。1403306{notifydownusrlocalshellmariadb。shweight1TCPCHECK{connecttimeout10retry3delaybeforeretry3connectport3306}}}2)Server2:keepalived。conf vietckeepalivedkeepalived。confglobaldefs{routeridvip2}vrrpinstanceVI1{stateBACKUPinterfaceens33virtualrouterid111priority98advertint1authentication{authtypePASSauthpass6666}virtualipaddress{192。168。116。150}}virtualserver192。168。116。1503306{delayloop6lbalgorrlbkindDRpersistencetimeout0protocolTCPrealserver192。168。116。1413306{notifydownusrlocalshellmariadb。shweight1TCPCHECK{connecttimeout10retry3delaybeforeretry3connectport3306}}} 2、新增数据库VIP1)Server2:keepalived。conf vietckeepalivedkeepalived。confglobaldefs{routeridvip2}vrrpinstanceVI1{stateBACKUPinterfaceens33virtualrouterid112priority100advertint1authentication{authtypePASSauthpass6666}virtualipaddress{192。168。116。151}}virtualserver192。168。116。1513306{delayloop6persistencetimeout0protocolTCPrealserver192。168。116。1413306{notifydownusrlocalshellmariadb。shweight1TCPCHECK{connecttimeout10retry3delaybeforeretry3connectport3306}}} 3、Server1和Server3双主关系1)Server3:keepalived。conf vietckeepalivedkeepalived。confglobaldefs{routeridvip3}vrrpinstanceVI1{stateBACKUPinterfaceens33virtualrouterid111priority98advertint1authentication{authtypePASSauthpass6666}virtualipaddress{192。168。116。150}}virtualserver192。168。116。1503306{delayloop6lbalgorrlbkindDRpersistencetimeout0protocolTCPrealserver192。168。116。1423306{notifydownusrlocalshellmariadb。shweight1TCPCHECK{connecttimeout10retry3delaybeforeretry3connectport3306}}} 4、Server2和Server4双主关系1)Server4:keepalived。conf vietckeepalivedkeepalived。confglobaldefs{routeridvip4}vrrpinstanceVI1{stateBACKUPinterfaceens33virtualrouterid112priority98advertint1authentication{authtypePASSauthpass6666}virtualipaddress{192。168。116。151}}virtualserver192。168。116。1513306{delayloop6lbalgorrlbkindDRpersistencetimeout0protocolTCPrealserver192。168。116。1433306{notifydownusrlocalshellmariadb。shweight1TCPCHECK{connecttimeout10retry3delaybeforeretry3connectport3306}}}