数据库架构之【MySQL8+MyCat2+Keepalived】RDBMS 读写分离和分库分表集群方案

MyCat 是一款开源(遵循 Apache License 2.0 协议)的大数据库集群中间件,用于搭建 MySQL 数据库的分布式集群,实现分库分表功能,解决数据库中海量数据存储和查询性能的问题。MyCat 还是一个 MySQL 数据库的集群中间件,主要实现 RDBMS 数据库集群的故障转移、负载均衡、读写分离等功能。MyCat 2.0 使用了全新架构。

Keepalived 是一款基于 VRRP 协议的轻量级服务高可用和负载均衡方案,提供避免服务器单点故障和请求分流的能力。

本方案基于CentOS8系统设计,建议在RedHat/CentOS系统中使用。部署数据库集群使用服务器及网络资源较多,建议在实施前做好规划工作,有利于部署工作顺利、有序进行。

目录

1.前言

2.集群部署拓扑图

3.MySQL8 + Replication 主备库部署方案

4.MyCat 集群中间件的安装和配置

5.Keepalived 高可用中间件的安装和配置

6.MyCat 监控中间件的安装和配置


1.前言

1、分库分表

MyCat 的关键技术是分库分表,它通过将 MySQL 数据库中物理表中的数据切分成多个表分片,并将表分片存储在多个数据库节点上,从而构建分布式存储架构,提升巨表关联、排序、分组聚合等 OLAP 的能力。

分库分表的工作原理:拦截客户端提交的SQL语句并进行分析(如:分片分析、路由分析、读写分离分析、缓存分析等),然后将此SQL发往后端的真实数据库,并将返回的结果处理(如:数据合并)后再返回给客户端。如下图:


单个规则匹配
多个规则匹配

2、读写分离集群

MyCat 还是一个位于 MySQL 数据库和客户端之间,主要实现读写分离功能的集群中间件。主要解决在业务系统存在大量的读并发时,通过负载均衡提高查询请求吞吐量,并将多个数据库节点集群化管理,在多主集群中单点数据库故障时候选主节点切换。

MySQL 数据库集群

3、运维监控

MyCat 提供运维监控系统,能够实现对 MyCat 的 JVM、线程、后端 RDBMS 数据库、服务器(CPU、内存、磁盘、网络)的监控服务。

运维监控

4、应用场景

1)适用于 MySQL 数据库集群的读写分离、候选主节点切换、负载均衡等高可用模式;

2)适用于 MySQL 数据库集群的分表分库,对于单表数据超过1000 万的物理表进行分片,最大支持1000亿数据的单表分片;

3)适用于多租户应用,通过分库分表实现应用数据按照租户划分物理数据库存储。从租户的角度来看,个人应用的数据集约存储在独立的空间,从应用角度看,分布式数据库有利于海量数据的分析和查询;

4)适用于海量数据的统计、分析、研判等 OLAP 能力的支撑数据库,分库分表能够快速完成巨表关联、排序、分组聚合等数据计算功能;

5) 适用于海量数据的实时查询,如:百亿数据频繁查询的记录需要在3秒内反馈结果,包括主键查询、范围查询或其他属性查询的情况;

6)不适用物理表无法分片、分布式事务强一致性、分布式数据 JOIN 查询的应用场景。

5、关键特性

  • 支持 SQL92 标准;
  • 支持 MySQL、Oracle、DB2、SQL Server、PostgreSQL 等 DB 的常见 SQL 语法;
  • 遵守 MySQL 原生协议,跨语言,跨平台,跨数据库的通用中间件代理;
  • 基于心跳的自动故障切换,支持读写分离,支持 MySQL 主从库,以及 Galera Cluster 集群;
  • 支持 Galera for MySQL 集群,Percona Cluster 或者 MariaDB cluster;
  • 基于 Nio 实现,有效管理线程,解决高并发问题;
  • 支持数据的多片自动路由与聚合,支持 sum、count、max 等常用的聚合函数,支持跨库分页;
  • 支持单库内部任意 JOIN,支持跨库2表 JOIN,甚至基于 Caltlet 的多表 JOIN;
  • 支持通过全局表,ER 关系的分片策略,实现了高效的多表 JOIN 查询;
  • 支持多租户方案;
  • 支持 XA 分布式事务(1.6.5);
  • 支持全局序列号,解决分布式下的主键生成问题;
  • 分片规则丰富,插件化开发,易于扩展;
  • 强大的 Web 监控系统,命令行监控;
  • 支持前端作为 MySQL 通用代理,后端 JDBC 方式支持 Oracle、DB2、SQL Server 、 MongoDB 、巨杉;
  • 支持密码加密;
  • 支持服务降级;
  • 支持 IP 白名单;
  • 支持 SQL 黑名单、SQL 注入攻击拦截;
  • 支持 Prepare 预编译指令(1.6);
  • 支持非堆内存(Direct Memory)聚合计算(1.6);
  • 支持 PostgreSQL 的 Native 协议(1.6);
  • 支持 MySQL 和 Oracle 存储过程,out 参数、多结果集返回(1.6);
  • 支持 Zookeeper 协调主从切换、zk 序列、配置 zk 化(1.6);
  • 支持库内分表(1.6);
  • 集群基于 ZooKeeper 管理,在线升级,扩容,智能优化,大数据处理(2.0开发版)。

6、基本概念

1)物理库和物理表:在数据库实例上部署的物理数据库(如:MySQL 数据库)和库中的表;

2)逻辑表:MyCat 定义的表,MyCat 将逻辑表的操作解释为物理库表的操作,一个逻辑表可能对应多个物理库表;

3)逻辑库:MyCat 定义的逻辑表集合。


2.数据库集群部署拓扑图

部署拓扑图

网络资源规划:

1、MySQL 主从库

节点名 主机名 IP:PORT 程序 操作系统
数据库-1 DB-M 192.168.0.20:3306 MySQL 8 CentOS8
数据库-2 DB-S1 192.168.0.21:3306 MySQL 8 CentOS8
数据库≥3 DB-S2 192.168.0.22:3306 MySQL 8 CentOS8

2、MyCat + Keepalived 高可用集群

节点名 主机名 IP:PORT 程序 操作系统
集群节点-1 CLS-1 192.168.0.31:8066 / 112 MyCat / Keepalived CentOS8
集群节点≥2 CLS-2 192.168.0.32:8066 / 112 MyCat / Keepalived CentOS8

Keepalived Virtual IP:192.168.0.30。

3、MyCat 监控节点

  • 主机名:Monitor
  • IP 地址:192.168.0.40:8082
  • 程序:MyCat-Web,Zookeeper
  • 系统:CentOS8

4、客户端:同一网段计算机,部署 HeidiSQL 或应用系统的调用程序模块。


3.MySQL8 + Replication 主备库部署方案

1、在 MySQL 主从库的节点上安装 MySQL8 数据库。

有关如何安装 MySQL8 数据库,请阅读文章《RedHat/CentOS8【MySQL8】安装、配置和管理》,文章地址【https://www.jianshu.com/p/b68e2120a068】。

2、部署 MySQL 主从库。

有关如何部署 MySQL8 主从数据库,请阅读文章《数据库架构之【MySQL8+Replication】RDBMS 主从库读写分离方案》,文章地址【https://www.jianshu.com/p/af9d16ce00f9】。


4.MyCat 集群中间件的安装和配置

以 "MyCat + Keepalived 高可用集群" 中的 "集群节点-1" 为例:

1、安装 OpenJDK 1.8 或 OracleJDK 1.8。

1)使用 YUM 源安装OpenJDK 1.8。

[centos@CLS-1 ~]$ sudo dnf install java-1.8.0-openjdk

2)验证Java运行环境。

[centos@CLS-1 ~]$ java -vserion
openjdk version "1.8.0_252"
OpenJDK Runtime Environment (build 1.8.0_252-b09)
OpenJDK 64-Bit Server VM (build 25.252-b09, mixed mode)

2、打开 MyCat 下载页面【http://dl.mycat.org.cn/】,下载 MyCat 的编译程序 tar 包到用户主目录中。

MyCat 下载页面

3、解压缩编译程序 tar 包到"/usr/local"目录中。

[centos@CLS-1 ~]$ sudo tar xvf mycat2-1.11-05.tar.gz -C /usr/local
[centos@CLS-1 ~]$ ll /usr/local
drwxr-xr-x. 7 root root    67 5月  11 22:31 mycat

4、创建 MyCat 管理用户和组,并设置为程序安装目录的拥有者。

[centos@CLS-1 ~]$ sudo id mycat
id: “mycat”:无此用户
[centos@CLS-1 ~]$ sudo groupadd mycat
[centos@CLS-1 ~]$ sudo useradd -g mycat -s /bin/false mycat
[centos@CLS-1 ~]$ sudo chown -R mycat:mycat /usr/local/mycat

5、设置 MyCat 的配置文件参数。

使用文本编辑器打开配置文件:

[centos@CLS-1 ~]$ sudo gedit /usr/local/mycat/conf/mycat.yml

修改或验证文件中的以下参数并保存:

# 元数据
metadata:
  # 逻辑库,可以设置多个逻辑库
  schemas: [ { 
    # 逻辑库名称
    schemaName: 'db',
    # 逻辑库映射的数据源或读写分离集群
    targetName: 'repli',
    # 定义全局表(各个节点的数据是一致的,主要用于读写分离)
    globalTables: {
      # 全局表名称
      tbl_global: {
        # 建库脚本(用于 MyCat 分析数据结构)
        createTableSQL: 'CREATE TABLE `tbl_global` (`uid` INT NOT NULL AUTO_INCREMENT,`name` VARCHAR(50) NOT NULL,PRIMARY KEY (`uid`))',
        # 全局表映射的数据源节点集合
        #【targetName】全局表映射的数据源名称
        #【schemaName】全局表映射的物理数据库名称
        #【tableName】全局表映射的物理表名称
        dataNodes: [
          { targetName: 'ds1',schemaName: 'testdb', tableName: 'tbl_global' }
        ]
      }
    },
    # 定义分片表(数据分布存储在各个节点的同构表中,主要用于并发计算)
    # MyCat 提供按固定、枚举、时间、范围等十余种分片规则,以下只示例了固定分片和枚举分片规则,更多规则可参见:
    # https://github.com/MyCATApache/Mycat2/blob/master/doc/17-partitioning-algorithm.md
    shadingTables: {
      # 固定分片
      tbl_shad: {
        # 分片规则:
        #【columnName】用于划分数据分片的字段
        #【shardingType】分片的类型:NATURE_DATABASE_TABLE 表示固定分片,即根据一列(支持)或者多个列(暂不支持)的值映射成一个值,再根据该值通过单维度的分片算法计算出数据分片范围;
        #【function】PartitionByLong 分片算法:
        # 分片长度是分片范围的一种度量,总量是1024,每个 dataNode (分片节点)可以占有一个范围的分片长度。
        # 其中:partitionCount 是分片数量的数组,partitionLength 是每个分片长度的数组。
        # 本例:1024 = 2X256+1X512
        columns: [ { 
          columnName: 'uid',
          shardingType: 'NATURE_DATABASE_TABLE',
          function: { clazz: 'io.mycat.router.function.PartitionByLong', name: 'partitionByLong', properties: {partitionCount: '1,2', partitionLength: '512,256'}, ranges: {}}
        } ],
        # 建库脚本(用于 MyCat 分析数据结构)
        createTableSQL: 'CREATE TABLE `tbl_shad` (`uid` INT NOT NULL AUTO_INCREMENT,`name` VARCHAR(50) NOT NULL,PRIMARY KEY (`uid`))',
        # 分片表映射的数据源节点集合
        #【targetName】分片表映射的数据源名称
        #【schemaName】分片表映射的物理数据库名称
        #【tableName】分片表映射的物理表名称
        dataNodes: [
          { targetName: 'ds1',schemaName: 'shaddb1', tableName: 'tbl_shad' },
          { targetName: 'ds1',schemaName: 'shaddb2', tableName: 'tbl_shad' },
          { targetName: 'ds1',schemaName: 'shaddb3', tableName: 'tbl_shad' }
        ]
      },
      # 枚举分片
      tbl_shad_em: {
        # 分片规则:
        #【columnName】用于划分数据分片的字段
        #【function】PartitionByFileMap 分片算法:
        # 按照指定的数据字典进行分片路由,一般应用于按照租户账号或区域的方式计算数据分片范围。
        # 其中:type 是分片字段的类型,可以是:Integer,Byte,Char,String,Long,Double,Float,Short,Boolean,BigInteger,BigDecimal;
        # defaultNode 是无匹配字典时默认路由的分片,<0表示不进行路由;
        # ranges 是字段值对应的 dataNodes 数组序号
        # 本例:当 shad 字段的值是 10001 时,将此脚本路由到 shaddb1 库的 tbl_shad_em 表上。
        columns: [ { 
          columnName: 'shad',
          function: { clazz: 'io.mycat.router.function.PartitionByFileMap', name: 'PartitionByFileMap', properties: { type: Integer, defaultNode: -1 }, ranges: { 10001: 0, 10002: 1, 10003: 2 }}
        } ],
        createTableSQL: 'CREATE TABLE `tbl_shad_em` (`uid` INT NOT NULL AUTO_INCREMENT,`name` VARCHAR(50) NOT NULL,`shad` INT NOT NULL, PRIMARY KEY (`uid`))',
        dataNodes: [
          { targetName: 'ds1',schemaName: 'shaddb1', tableName: 'tbl_shad_em' },
          { targetName: 'ds1',schemaName: 'shaddb2', tableName: 'tbl_shad_em' },
          { targetName: 'ds1',schemaName: 'shaddb3', tableName: 'tbl_shad_em' }
        ]
      }
     }
  } ]
# 用户认证和SQL脚本匹配拦截器
interceptors: [ {
  # 用户拦截器
  #【ip】客户端IP,支持正则表达式
  #【username】登录用户
  #【password】登录用户口令
  user:{ ip: '.',username: 'root',password: 'password' },
  # 事务模式,可选项为:xa 和 proxy,默认是 proxy
  # transactionType: proxy
} ]
# 数据源
datasource:
  # 数据源集合
  datasources: [{
    # 数据源名称
    name: 'ds1', 
    # 数据库IP地址
    ip: '192.168.0.20',
    # 数据库服务端口
    port: '3306',
    # 数据库登录用户
    user: 'root',
    # 数据库登录用户口令
    password: 'password',
    # 最大连接数
    maxCon: 10000,
    # 最小连接数
    minCon: 0,
    # 连接重试次数
    maxRetryCount: 3,
    # 连接超时时间,单位:毫秒
    maxConnectTimeout: 10000, 
    # 数据库类型,可选项:mysql 或 jdbc
    dbType: 'mysql', 
    # 数据库连接字符串
    url: 'jdbc:mysql://192.168.0.20:3306?characterEncoding=utf8&useSSL=true&allowMultiQueries=true',
    # 负载均衡权重
    weight: 1, 
    # 与后端数据库建立连接后执行的初始化 SQL 脚本,如:"use mysql"
    initSqls: [],  
    # READ,WRITE,READ_WRITE ,集群信息中是主节点,则默认为读写,副本则为读,此属性可以强制指定可写
    instanceType: ,
    # JDBC 每次获取连接是否都执行 initSqls 脚本
    initSqlsGetConnection: true
  },
  {
    name: 'ds2', 
    ip: '192.168.0.21',
    port: '3306',
    user: 'root',
    password: 'password',
    maxCon: 10000,
    minCon: 0,
    maxRetryCount: 3,
    maxConnectTimeout: 10000, 
    dbType: 'mysql', 
    url: 'jdbc:mysql://192.168.0.21:3306?characterEncoding=utf8&useSSL=true&allowMultiQueries=true',
    weight: 1, 
    initSqls: [],  
    instanceType: ,
    initSqlsGetConnection: true
  },
  {
    name: 'ds3', 
    ip: '192.168.0.22',
    port: '3306',
    user: 'root',
    password: 'password',
    maxCon: 10000,
    minCon: 0,
    maxRetryCount: 3,
    maxConnectTimeout: 10000, 
    dbType: 'mysql', 
    url: 'jdbc:mysql://192.168.0.22:3306?characterEncoding=utf8&useSSL=true&allowMultiQueries=true',
    weight: 1, 
    initSqls: [],  
    instanceType: ,
    initSqlsGetConnection: true
  } ]
  # MyCat 数据源实现类
  datasourceProviderClass: 'io.mycat.datasource.jdbc.datasourceProvider.AtomikosDatasourceProvider'
  # 心跳定时器,表示 MyCat 启动后,延迟 initialDelay 秒后连接后端数据源。
  timer: {initialDelay: 0, period: 3, timeUnit: 'SECONDS'}
# 读写分离集群
cluster:
  # 关闭集群心跳,此时集群认为所有数据源都是可用的,可以通过 MyCat 提供的外部接口设置数据源可用信息达到相同效果
  close: true
  # 集群集合
  clusters: [ {
    # 集群名称
    name: 'repli',
    # 集群类型:SINGLE_NODE(单一节点),MASTER_SLAVE(主从集群) ,GARELA_CLUSTER(多主集群)
    replicaType: 'MASTER_SLAVE', 
    # 切换类型:NOT_SWITCH(不进行主从切换),SWITCH(进行主从切换)
    switchType: 'SWITCH', 
    # 查询请求的负载均衡类型,BALANCE_ALL(所有数据源参与负载均衡),BALANCE_ALL_READ(从库数据源参与负载均衡),BALANCE_NONE:(无负载均衡)
    readBalanceType: 'BALANCE_ALL', 
    # 查询请求的负载均衡插件
    readBalanceName: 'BalanceRoundRobin',  
    # 修改请求的负载均衡插件
    writeBalanceName: 'BalanceRoundRobin',  
    # 主节点列表,普通主从,当主失去连接后,依次选择列表中存活的作为主节点
    masters: [ 'ds1', 'ds2' ],  
    # 从节点列表
    replicas: [ 'ds3' ], 
    # 集群最占用大连接限制
    maxCon: , 
    # 心跳设置
    heartbeat: {
      # 心跳重试次数
      maxRetry: 3, 
      # 最小主从切换间隔
      minSwitchTimeInterval: 120000, 
      # 心跳超时值,单位(毫秒)
      heartbeatTimeout: 100000,
      # MySQL 二进制日志(binlog)延迟值
      slaveThreshold: 0, 
      # 进行心跳的方式,mysql或者jdbc两种
      requestType: 'mysql'
    }
  } ]
  timer: { initialDelay: 10, period: 5, timeUnit: 'SECONDS' }
# 插件
plug:
  # 负载均衡算法实现类
  # BalanceLeastActive
  # 最少正在使用的连接数的 MySQL 数据源被选中,如果连接数相同,则从连接数相同的数据源中的随机,使慢的机器收到更少。
  # BalanceRandom
  # 利用随机算法产生随机数,然后从活跃的mysql数据源中进行选取。
  # BalanceRoundRobin
  # 加权轮训算法,记录轮训的权值,每次访问加一,得到n,然后对 MySQL 数据源进行轮训,如果权值已经为零,则跳过,如果非零则减一,n减1,直n为零则选中的节点就是需要访问的mysql数据源节点。
  # BalanceRunOnReplica
  # 把请求尽量发往从节点,不会把请求发到不可读(根据延迟值判断)与不可用的从节点
  loadBalance:
    defaultLoadBalance: 'balanceRandom'
    loadBalances: [
      { name: 'BalanceRunOnMaster', clazz: 'io.mycat.plug.loadBalance.BalanceRunOnMaster' },
      { name: 'BalanceLeastActive', clazz: 'io.mycat.plug.loadBalance.BalanceLeastActive' },
      { name: 'BalanceRoundRobin', clazz: 'io.mycat.plug.loadBalance.BalanceRoundRobin' },
      { name: 'BalanceRunOnReplica', clazz: 'io.mycat.plug.loadBalance.BalanceRunOnReplica' },
      { name: 'BalanceRunOnRandomMaster', clazz: 'io.mycat.plug.loadBalance.BalanceRunOnRandomMaster' }
    ]
# 服务器
server:
  # 监听 IP 地址
  ip: 0.0.0.0
  # 监控服务端口
  port: 8066
  reactorNumber: 1
properties:
  key: 'value'

#lib start
#lib end

MyCat 配置相关资料:
https://gitee.com/cos9527/Mycat2/blob/master/doc/00-mycat-readme.md
https://www.ctolib.com/MyCATApache-Mycat2.html#articleHeader7
https://github.com/MyCATApache/Mycat2/blob/master/doc

6、配置 MyCat 服务开机自启动。

使用文本编辑器创建配置文件:

[centos@CLS-1 ~]$ sudo gedit /usr/lib/systemd/system/mycat.service

编写文件内容并保存如下:

[Unit]
Description=MyCat2 Server
After=syslog.target network.target

[Service]
Type=forking
User=mycat
Group=mycat

ExecStart=/usr/local/mycat/bin/mycat start
ExecStop=/usr/local/mycat/bin/mycat stop
ExecReload=/usr/local/mycat/bin/mycat restart

[Install]
WantedBy=multi-user.target

设置开机启动:

[centos@CLS-1 ~]$ sudo systemctl daemon-reload
[centos@CLS-1 ~]$ sudo systemctl enable mycat.service

7、启动 MyCat 服务。

[centos@CLS-1 ~]$ sudo systemctl start mycat.service

8、设置防火墙端口(CentOS8默认安装firewall防火墙),允许"8066"端口(MyCat 默认端口)访问服务器。

[centos@CLS-1 ~]$ sudo firewall-cmd --zone=public --add-port=8066/tcp --permanent
[centos@CLS-1 ~]$ sudo firewall-cmd --reload

注意:其他"MyCat + Keepalived 高可用集群"节点上全部需要按照以上步骤配置。

9、MyCat 运维管理

1)启动 MyCat 服务(任选一种方式)

[centos@CLS-1 ~]$ sudo systemctl start mycat.service

或者

[centos@CLS-1 ~]$ sudo -u mycat /usr/local/mycat/bin/mycat start

2)停止 MyCat 服务(任选一种方式)

[centos@CLS-1 ~]$ sudo systemctl stop mycat.service

或者

[centos@CLS-1 ~]$ sudo -u mycat /usr/local/mycat/bin/mycat stop

3)重启 MyCat 服务

[centos@CLS-1 ~]$ sudo systemctl restart mycat.service

或者

[centos@CLS-1 ~]$ sudo -u mycat /usr/local/mycat/bin/mycat restart

4)查看 MyCat 服务状态

[centos@CLS-1 ~]$ sudo systemctl status mycat.service

或者

[centos@CLS-1 ~]$ sudo netstat -ntap | grep 8066
tcp6       0      0 :::8066                 :::*                    LISTEN      9688/java

5)启动 MyCat 服务开机自启动

[centos@CLS-1 ~]$ sudo systemctl enable mycat.service

6)禁用 MyCat 服务开机自启动

[centos@CLS-1 ~]$ sudo systemctl disable mycat.service

5.Keepalived 高可用中间件的安装和配置

以 "MyCat + Keepalived 高可用集群" 中的 "集群节点-1" 为例:

1、安装 EPEL 的 Yum源。

使用文本编辑器创建仓库配置文件:

[centos@CLS-1 ~ ]$ sudo gedit /etc/yum.repos.d/epel.repo

在文件中编写以下内容并保存:

[epel-modular]
name=Extra Packages for Enterprise Linux Modular $releasever - $basearch
baseurl=http://mirrors.aliyun.com/epel/$releasever/Modular/$basearch
enabled=1
gpgcheck=1
gpgkey=http://mirrors.aliyun.com/epel/RPM-GPG-KEY-EPEL-8

[epel]
name=Extra Packages for Enterprise Linux $releasever - $basearch
baseurl=http://mirrors.aliyun.com/epel/$releasever/Everything/$basearch
enabled=1
gpgcheck=1
gpgkey=http://mirrors.aliyun.com/epel/RPM-GPG-KEY-EPEL-8

更新 Yum 源:

[centos@CLS-1 ~]$ sudo dnf clean all
[centos@CLS-1 ~]$ sudo dnf makecache
Extra Packages for Enterprise Linux Modular 8 - 429 kB/s | 118 kB     00:00    
Extra Packages for Enterprise Linux 8 - x86_64  3.7 MB/s | 6.9 MB     00:01    
元数据缓存已建立。

EPEL(Extra Packages for Enterprise Linux)是企业级 Linux 操作系统的扩展包仓库,为 Redhat/CentOS系统提供大量的额外软件包。

2、安装 Keepalived。

[centos@CLS-1 ~]$ sudo dnf install keepalived

程序安装目录是"/usr/sbin",配置文件目录是"/etc/keepalived"。

3、设置 Keepalived 配置文件参数。

使用文本编辑器打开配置文件:

[centos@CLS-1 ~ ]$ sudo gedit /etc/keepalived/keepalived.conf

在文件中编写以下内容并保存:

# 定义全局配置
global_defs {
    # 本地节点 ID 标识,一般设置为主机名。
    router_id mycat-1
}

# 定义周期性执行的脚本,脚本的退出状态码会被调用它的所有的 vrrp_instance 记录。
vrrp_script chk_mycat {
    # 执行脚本的路径。
    script "/etc/keepalived/mycat_check.sh"
    # 脚本执行的间隔(单位是秒)。默认为1s。
    interval 2
    # 当脚本调整优先级,从 -254 到 254。默认为2。
    # 1. 如果脚本执行成功(退出状态码为0),weight大于0,则priority增加。
    # 2. 如果脚本执行失败(退出状态码为非0),weight小于0,则priority减少。
    # 3. 其他情况下,priority不变。
    weight -20
    # 当脚本执行超过时长(单位是秒)则被认为执行失败。
    # 运行脚本的用户和组。
    user root root
    # timeout 30
    # 当脚本执行成功到设定次数时,才认为是成功。
    # rise 1
    # 当脚本执行失败到设定次数时,才认为是失败。
    # fall 3
}

# 定义虚拟路由,可以定义多个。
vrrp_instance VI_1 {
    # 本地节点初始状态,包括 MASTER(主节点) 和 BACKUP (备节点)。
    state MASTER
    # 本地节点绑定虚拟 IP 的网络接口。
    interface ens33
    # 本地节点优先级,优先级高的节点将动态变成 MASTER 节点,接管 VIP 。初始状态下,MASTER 节点的优先级必须高于 BACKUP 节点。
    priority 100
    # VRRP 实例 ID,范围是0-255。同一集群的所有节点应设置一致的值。
    virtual_router_id 216
    # 组播信息发送时间间隔。同一集群的所有节点必须设置一样,默认为1秒。
    advert_int 1
    # 设置验证信息。同一集群的所有节点必须一致
    authentication {
        # 指定认证方式。PASS 表示简单密码认证(推荐);AH:IPSEC认证(不推荐)。
        auth_type PASS
        # 指定认证所使用的密码,最多8位。
        auth_pass 1111
    }

    # 声明调用已定义的 vrrp_script 脚本。
    track_script {
        chk_mycat
    }

    # 定义虚拟 IP 地址。
    virtual_ipaddress {
        192.168.0.30
    }
}

# 定义对外提供服务 LVS (负载均衡)的 VIP 和 端口(当端口号设置为【0】时,表示所有端口),只实现高可用时可不配置。
virtual_server 192.168.0.30 8066 {  
    # 设置健康检查时间,单位是秒
    delay_loop 6 
    #负载均衡调度算法
    lb_algo rr
    # 设置LVS实现负载的机制,有NAT、TUN、DR三个模式    
    lb_kind DR
    # VIP 子网掩码
    nat_mask 255.255.255.0
    # 会话保持时间,一定时间之内用户无响应则下一次用户请求时需重新路由,一般设为0,表示不需要    
    persistence_timeout 0
    # 网络协议
    protocol TCP
    # 定义后端 RealServer 的真实服务器属性,IP 地址和端口(当端口号设置为【0】时,表示所有端口)
    real_server 192.168.0.31 8066 { 
        # 配置节点权值,数字越大权重越高 
        weight 1
        TCP_CHECK {  
            connect_timeout 10         
            nb_get_retry 3  
            delay_before_retry 3  
            connect_port 8066
        }  
    }  
    real_server 192.168.0.32 8066 {
        weight 1
        TCP_CHECK {  
            connect_timeout 10  
            nb_get_retry 3  
            delay_before_retry 3  
            connect_port 8066
        }  
    }
}

初始化的主节点和备节点的区别体现在以下参数中:

  • 初始主节点
vrrp_instance VI_1 {
    # 必须设置为 MASTER 。
    state MASTER
    # 必须设置为最大值。
    priority 100
}
  • 初始备节点
vrrp_instance VI_1 {
    # 必须设置为 BACKUP 。
    state BACKUP
    # 必须设置为小于主节点的值。
    priority 90
}

4、创建或编辑 MyCat 检测脚本文件。文件路径对应配置文件中 vrrp_script 的 script 设置值。

使用文本编辑器创建脚本文件:

[centos@CLS-1 ~ ]$ sudo gedit /etc/keepalived/mycat_check.sh

在脚本文件中编写以下内容并保存:

#!/bin/bash
if [ ! -f "/usr/local/mycat/logs/mycat.pid" ]; then
    sudo -u mycat /usr/local/mycat/bin/mycat restart
    sleep 2
    if [ ! -f "/usr/local/mycat/logs/mycat.pid" ]; then
        killall -9 keepalived
    fi
fi

给脚本文件增加可执行权限:

[centos@CLS-1 ~ ]$ sudo chmod 755 /etc/keepalived/mycat_check.sh

5、配置 Keepalived 系统服务。

使用文本编辑器创建配置文件:

[centos@CLS-1 ~ ]$ sudo gedit /usr/lib/systemd/system/keepalived.service

验证或修改文件内容并保存如下:

[Unit]
Description=LVS and VRRP High Availability Monitor
After=network-online.target syslog.target
Wants=network-online.target

[Service]
Type=forking
User=root
Group=root
PIDFile=/var/run/keepalived.pid
KillMode=process
EnvironmentFile=-/etc/sysconfig/keepalived
ExecStart=/usr/sbin/keepalived $KEEPALIVED_OPTIONS
ExecReload=/bin/kill -HUP $MAINPID
ExecStop=/bin/kill -HUP $MAINPID

[Install]
WantedBy=multi-user.target

重新加载系统服务管理器:

[centos@CLS-1 ~ ]$ sudo systemctl daemon-reload

6、设置防火墙端口(CentOS8默认安装firewall防火墙),允许"112"端口(Keepalived 默认端口)访问服务器。

[centos@CLS-1 ~ ]$ sudo firewall-cmd --zone=public --add-port=112/tcp --permanent
[centos@CLS-1 ~ ]$ sudo firewall-cmd --reload

7、启动/重启 Keepalived 服务(不建议设置为开机自启动)。

启动 Keepalived 服务之前,应确保已正确启动了各节点的 MyCat 服务。各节点的启动或重启的顺序为:① 启动 Keepalived 主节点;② 依次启动 Keepalived 备节点。

[centos@CLS-1 ~ ]$ sudo systemctl restart keepalived.service

8、启动 Keepalived 可能因为各种未知的原因失败,主要是由于引发了 SELinux 异常。有关如何解决 SELinux 引起的异常,请阅读文章《RedHat/CentOS8【SELinux】引起的安全策略问题解决方案》,文章地址【https://www.jianshu.com/p/a13f974f8bae】。

注意:其他"MyCat + Keepalived 高可用集群"节点上全部需要按照以上步骤配置。


6.MyCat 监控中间件的安装和配置

1、安装 OpenJDK 1.8 或 OracleJDK 1.8。

1)使用 YUM 源安装OpenJDK 1.8。

[centos@Monitor ~]$ sudo dnf install java-1.8.0-openjdk

2)验证Java运行环境。

[centos@Monitor ~]$ java -vserion
openjdk version "1.8.0_252"
OpenJDK Runtime Environment (build 1.8.0_252-b09)
OpenJDK 64-Bit Server VM (build 25.252-b09, mixed mode)

2、打开 MyCat 下载页面【http://dl.mycat.org.cn/】,下载 MyCat-Web 和 Zookeeper 的编译程序 tar 包到用户主目录中。

MyCat-Web 和 Zookeeper 下载页面

3、解压缩 Zookeeper 编译程序 tar 包到"/usr/local"目录中。

[centos@Monitor ~]$ sudo tar xvf zookeeper-3.4.6.tar.gz -C /usr/local
[centos@Monitor ~]$ ll /usr/local
drwxr-xr-x. 10 root root  4096 2月  20 2014 zookeeper-3.4.6

4、从模板创建 Zookeeper 配置文件。

[centos@Monitor ~]$ sudo cp /usr/local/zookeeper-3.4.6/conf/zoo_sample.cfg /usr/local/zookeeper-3.4.6/conf/zoo.cfg

5、配置 Zookeeper 服务开机自启动。

使用文本编辑器创建配置文件:

[centos@Monitor ~]$ sudo gedit /usr/lib/systemd/system/zookeeper.service

编写文件内容并保存如下:

[Unit]
Description=Zookeeper Server
After=syslog.target network.target

[Service]
Type=forking
User=root
Group=root

ExecStart=/usr/local/zookeeper-3.4.6/bin/zkServer.sh start
ExecStop=/usr/local/zookeeper-3.4.6/bin/zkServer.sh stop
ExecReload=/usr/local/zookeeper-3.4.6/bin/zkServer.sh restart

[Install]
WantedBy=multi-user.target

设置开机启动:

[centos@Monitor ~]$ sudo systemctl daemon-reload
[centos@Monitor ~]$ sudo systemctl enable zookeeper.service

6、启动 Zookeeper 服务。

[centos@Monitor ~]$ sudo systemctl start zookeeper.service

7、设置防火墙端口(CentOS8默认安装firewall防火墙),允许"2181"端口(Zookeeper 默认端口)访问服务器。

[centos@Monitor ~ ]$ sudo firewall-cmd --zone=public --add-port=2181/tcp --permanent
[centos@Monitor ~ ]$ sudo firewall-cmd --reload

8、解压缩 MyCat-Web 编译程序 tar 包到"/usr/local"目录中。

[centos@Monitor ~]$ sudo tar xvf Mycat-web-1.0-SNAPSHOT-20170102153329-linux.tar.gz -C /usr/local
[centos@Monitor ~]$ ll /usr/local
drwxrwxrwx. 5 root  root     96 10月 20 2015 mycat-web

9、设置 MyCat-Web 配置文件参数。

使用文本编辑器打开配置文件:

[centos@Monitor ~ ]$ sudo gedit /usr/local/mycat-web/mycat-web/WEB-INF/classes/mycat.properties

在文件中编写以下内容并保存:

show.period=3000000
# Zookeeper 服务器IP和端口号
zookeeper=127.0.0.1:2181

mycat_warn_mail=[{"cc"\:"sohudo@mycat.io","index"\:1,"mangerPort"\:"465","smtpHost"\:"smtp.139.com","smtpPassword"\:"123456","smtpProtocol"\:"smtp","smtpUser"\:"agile_louie@139.com","to"\:"9183838@qq.com"}]
##sql\u4E0A\u7EBF\u76F8\u5173\u914D\u7F6E

# MyCat 服务器IP地址
sqlonline.server=192.168.0.20
# MyCat 登录用户
sqlonline.user=root
# MyCat 登录用户口令
sqlonline.passwd=123456a?

10、设置防火墙端口(CentOS8默认安装firewall防火墙),允许"8082"端口(MyCat-Web 默认端口)访问服务器。

[centos@Monitor ~ ]$ sudo firewall-cmd --zone=public --add-port=8082/tcp --permanent
[centos@Monitor ~ ]$ sudo firewall-cmd --reload

11、启动 MyCat-Web 服务。

[centos@Monitor ~]$ cd /usr/local/mycat-web
[centos@Monitor mycat-web]$ ./start.sh

12、验证 MyCat-Web 服务正常运行。使用浏览器客户端访问 MyCat-Web 的 Http 服务接口进行测试,输入:http://<IP>:<PORT>/mycat,默认端口是【8082】。

MyCat-Web 正常访问页面

13、MyCat Web 运维管理

1)启动 MyCat Web 服务(任选一种方式)

[centos@Monitor ~]$ cd /usr/local/mycat-web
[centos@Monitor mycat-web]$ ./start.sh

2)停止 MyCat 服务(任选一种方式)

[centos@Monitor ~]$ sudo netstat -ntap | grep 8082
tcp6       0      0 :::8082                 :::*                    LISTEN      78278/java
[centos@Monitor ~]$ sudo kill -9 78278

3)重启 MyCat 服务

[centos@Monitor ~]$ sudo netstat -ntap | grep 8082
tcp6       0      0 :::8082                 :::*                    LISTEN      78278/java
[centos@Monitor ~]$ sudo kill -9 78278
[centos@Monitor ~]$ cd /usr/local/mycat-web
[centos@Monitor mycat-web]$ ./start.sh

4)查看 MyCat 服务状态

[centos@Monitor ~]$ sudo netstat -ntap | grep 8082
tcp6       0      0 :::8082                 :::*                    LISTEN      78278/java
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,088评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,715评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,361评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,099评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 60,987评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,063评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,486评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,175评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,440评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,518评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,305评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,190评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,550评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,880评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,152评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,451评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,637评论 2 335