MoHA 部署文档

MoHA部署

概览

通过自动的 master 失败检测和秒级的主从切换,MoHA 提供了跨数据中心的 MySQL 集群的高可用(HA)。它的特点包括:

  • 高可用
    MoHA 对 MySQL 的失败检测和 failover 策略可以保证 MySQL 集群的高可用

  • 无脑裂
    MoHA 采用 lease 机制,通过配置合理的 lease 长度,可以确保 MySQL 集群无脑裂

  • 跨数据中心
    MoHA 采用 etcd 实现服务的注册和发现,避免了 VIP 的局限,可以搭建跨数据中心的 MySQL 集群

  • 一主多从
    MoHA 支持搭建一主多从的 MySQL 集群,并且在 Failover 时会指定数据最新的从库作为新主

  • 单主模式
    在集群内只有一个 MySQL 节点存活时,即使 MoHA 与 etcd 通信中断,单节点 MySQL 依然可以提供服务。
    单主模式支持自动进入和自动退出

  • 在线主从切换
    MoHA 支持通过API实现在线的主从切换,安全的将当前运行的master切换到新master上

  • 监控
    MoHA 提供监控针对agent以及数据库运行状态的API接口,可以方便对接公司数据库管理平台,实现Paas化监控

MoHA 架构图

1 配置信息相关介绍

1.1 etcd相关配置

dockername IPAddress EtcdName MachineCPU MachineMem Machine SystemVersion
etcd1 127.0.0.1 production-etcd-1 4核+ 8G+ SSD100G+ Centos 7.0+
etcd2 127.0.0.2 production-etcd-2 4核+ 8G+ SSD100G+ Centos 7.0+
etcd3 127.0.0.3 production-etcd-3 4核+ 8G+ SSD100G+ Centos 7.0+

  • 线上环境建议5节点部署,并且不要和其它业务混合部署,防止其它业务负载攀升,造成etcd节点不稳定
  • 如果数据库采用同机房部署方式,推荐etcd集群和数据库集群同网段
  • 如果数据库采用两地三中心部署方式,推荐etcd集群同样使用两地三中心部署(最佳实践:AZ1:2,AZ2:2,AZ3:1 AZ3为异地机房)
  • 推荐使用docker-compose部署方式,并使用高版本操作系统

1.2 MoHA相关配置

dockername IPAddress MoHA Name MachineCPU MachineMem Machine SystemVersion
3306_moha20 127.0.0.4 3306_moha20 4核+ 8G+ SSD100G+ Centos 7.0+
3306_moha20 127.0.0.5 3306_moha20 4核+ 8G+ SSD100G+ Centos 7.0+
3306_moha20 127.0.0.6 3306_moha20 4核+ 8G+ SSD100G+ Centos 7.0+

  • 配置表中数据库机器CPU/MEM/Storage 应根据线上数据库配置来定;MoHA进程占用的资源很小
  • MoHA支持单机房部署与跨机房部署
  • MoHA推荐主从节点总数量大于2,仅部署一个节点时,进入单主模式
  • MoHA支持单机多实例部署方式,通过端口区分不通实例组
  • 数据库数据文件目录映射到物理机,容器故障不影响数据文件
  • 推荐使用docker-compose部署方式,并使用高版本操作系统

2 ETCD部署

2.1 docker 安装及启动

yum install -y docker docker-compose  && systemctl start docker

2.2 pull etcd 镜像

docker pull quay.io/coreos/etcd:v3.2.18

2.3 etcd docker-compose 配置文件编写

#only first etcd configure demaon
---
version: '3.2'

services:
  etcd1:
    image: quay.io/coreos/etcd:v3.2.18
    #suggest etcd version > V3.0
    container_name: production-etcd-1
    restart: always
    network_mode: host
    environment:
      - ETCD_NAME=production-etcd-1
      - ETCD_LISTEN_CLIENT_URLS=http://0.0.0.0:2379
      - ETCD_DATA_DIR=/var/lib/etcd/default.etcd
      - ETCD_LISTEN_PEER_URLS=http://0.0.0.0:2380
      - ETCD_QUOTA_BACKEND_BYTES=10737418240
      #etcd  backend db max size
      - ETCD_INITIAL_ADVERTISE_PEER_URLS=http://127.0.0.1:2380
      - ETCD_ADVERTISE_CLIENT_URLS=http://127.0.0.1:2379
      - ETCD_INITIAL_CLUSTER=production-etcd-1=http://127.0.0.1:2380,production-etcd-2=http://127.0.0.2:2380,production-etcd-3=http://127.0.0.3:2380
      - ETCD_INITIAL_CLUSTER_TOKEN="moha-group-etcd"
      - ETCD_INITIAL_CLUSTER_STATE=new
      - ETCD_AUTO_COMPACTION_RETENTION=2 #hour
    logging:
      driver: "json-file"
      options:
        max-size: "50m"
        max-file: "10"
    volumes:
      - /data/etcd_database:/var/lib/etcd
    ports:
      - 2379:2379
      - 2380:2380

  • 推荐使用etcd官方镜像
  • 新建集群是ETCD_INITIAL_CLUSTER_STATE设置为new,新增节点时,ETCD_INITIAL_CLUSTER_STATE设置为existing
  • Volumes中需要新建本地目录,并映射到/var/lib/etcd中
  • 推荐设置ETCD_AUTO_COMPACTION_RETENTION,该参数作用:mvcc键值存储的自动压缩

2.4 启动etcd集群

登录到每台etcd机器,依次执行启动命令

#启动
docker-compose -f sys_etcd_compose.yml up -d
#查看是否启动成功
docker ps

2.5 查看etcd集群状态信息

[root@production-database-controller ~]# etcdctl --endpoints="http://127.0.0.1:2379,http://127.0.0.2:2379,http://127.0.0.3:2379" endpoint status --write-out=table
+------------------------+------------------+---------+---------+-----------+-----------+------------+--------------------+--------+
|        ENDPOINT        |        ID        | VERSION | DB SIZE | IS LEADER | RAFT TERM | RAFT INDEX | RAFT APPLIED INDEX | ERRORS |
+------------------------+------------------+---------+---------+-----------+-----------+------------+--------------------+--------+
|  http://127.0.0.1:2379 | e150377084e7269c |  3.2.18 |   25 kB |     false |         2 |        171 |                  0 |        |
|  http://127.0.0.2:2379 | 70273bc2b66e5a6d |  3.2.18 |   25 kB |     false |         2 |        171 |                  0 |        |
|  http://127.0.0.3:2379 | 124af500f66e3f4e |  3.2.18 |   25 kB |      true |         2 |        171 |                  0 |        |
+------------------------+------------------+---------+---------+-----------+-----------+------------+--------------------+--------+

2.6 创建用户与赋予权限

#add user
etcdctl --endpoints="http://127.0.0.1:2379,http://127.0.0.2:2379,http://127.0.0.3:2379"  user add "root:D1hmWnE29PU4wJNr"
#add role
etcdctl --endpoints="http://127.0.0.1:2379,http://127.0.0.2:2379,http://127.0.0.3:2379"  role add root
#grant root to moha
etcdctl --endpoints="http://127.0.0.1:2379,http://127.0.0.2:2379,http://127.0.0.3:2379" user grant-role root root
#enable auth
etcdctl --endpoints="http://127.0.0.1:2379,http://127.0.0.2:2379,http://127.0.0.3:2379" auth enable

2.7 读写测试

export ETCDCTL_API=3
etcdctl --endpoints="http://127.0.0.1:2379,http://127.0.0.2:2379,http://127.0.0.3:2379" --user root:D1hmWnE29PU4wJNr put /mobike mobike123
OK
etcdctl --endpoints="http://127.0.0.1:2379,http://127.0.0.2:2379,http://127.0.0.3:2379" --user root:D1hmWnE29PU4wJNr get /mobike
/mobike
mobike123

2.8 监控增加

#参考官方介绍,并增加监控告警策略
https://coreos.com/etcd/docs/latest/op-guide/monitoring.html

3 MoHA实例部署

3.1 下载安装镜像

下载MoHA代码,本地编译moctl下的conf.go代码,参考conf.toml修改配置文件,生成docker-compose/

docker push moiot/moha:v2.6.1

3.2 下载源代码,并编译moha/moctl/conf.go

docker push moiot/moha:v2.6.1

3.3 修改demon配置文件

[mysql]
hostaddress     = "127.0.0.4"
port            = "3306"
instancename     = "moha_github"
bufferpool      = "1G"
sqlmode      = "STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"
datadir      = "/data1/mysql/"

[agent]
hostaddress = "127.0.0.4"
port        = "3306"
instancename = "moha_github"
proxyname = "moha_kaiyuan"
etcdurl = "http://127.0.0.1:2379,http://127.0.0.2:2379,http://127.0.0.3:2379"
etcduser = "root"
etcdpasswd = "D1hmWnE29PU4wJNr" #your etcd passwd
agentuser = "agent"
agentpasswd = "youragentpasswd"
mysqlrepluser = "repl"
mysqlreplpasswd = "yourreplpasswd"
datadir      = "/data1/mysql/"

[docker]
port        = "3306"
instancename = "moha_github"
version  = "v2.6.1"
datadir      = "/data1/mysql/"
agentuser = "agent"
agentpasswd = "youragentpasswd"
mysqlrepluser = "repl"
mysqlreplpasswd = "yourreplpasswd"
mysqlrootpasswd = "yourrootpasswd"

  • 测试过程中,一定要将hostaddress修改为服务器内网IP地址
  • 各项配置按需修改,部分参数在代码中已经hardcode,如果需要修改,可以直接修改conf.go中的参数或者修改生成后的配置文件
  • 配置文件生成也可参考etc/docker-compose/deploy-example 中的例子自行编写
  • 企业实战中,建议开发数据库管理平台,在页面中进行各项参数配置并生成配置文件,通过salt调度部署新实例

3.4 配置文件生成

配置文件生成在/etc目录下,启动前可查看生成的各项配置是否符合预期

./conf -config conf.toml

3.5 MoHA 节点启动

docker-compose -f /etc/3306_docker-compose.yml up -d

3.6 查看MoHA节点是否启动成功

#查看容器是否正常启动
docker ps
#查看mysql 是否正常启动
ps -ef | grep mysqld
#查看supervise日志是否正常
tail -fn 20 ${datadir}/${port}_agent/supervise.log
[3306_agentlog]# tail -fn 20 supervise.log
2019-01-15 20:50:37 INFO  supervise/supervise.c:221: epoll_wait returns 1 count
2019-01-15 20:50:37 INFO  supervise/supervise.c:263: /agent/mysql-agent is still alive, from detect_child_alive
2019-01-15 20:50:38 INFO  supervise/supervise.c:221: epoll_wait returns 1 count
2019-01-15 20:50:38 INFO  supervise/supervise.c:263: /agent/mysql-agent is still alive, from detect_child_alive
#查看agent日志是否成功
[3306_agentlog]# tail -fn 20 mysql-agent.log
2019/01/15 20:51:06.563 agent/registry.go:80 [info] register slave/127.0.0.4:3306 to etcd with ttl 10
2019/01/15 20:51:10.564 agent/registry.go:80 [info] register slave/127.0.0.4:3306 to etcd with ttl 10
2019/01/15 20:51:14.562 agent/registry.go:80 [info] register slave/127.0.0.4:3306 to etcd with ttl 10
2019/01/15 20:51:16.061 agent/single_point.go:188 [info] server 127.0.0.4:3306 is still in single point master mode
#仅增加一个节点时,数据库进入单主模式,不会发生切换动作

3.7 etcd中 MoHA集群的展现

 etcdctl --endpoints="http://127.0.0.1:2379,http://127.0.0.2:2379,http://127.0.0.3:2379" --user root:D1hmWnE29PU4wJNr get /  --prefix
 /dbproxy/moha_kaiyuan/ks_cfg/nodes/3306_moha_github/election #目录下记录切换相关信息
 /dbproxy/moha_kaiyuan/ks_cfg/nodes/3306_moha_github/master #记录当前实例主库信息
 127.0.0.2:3306
 /dbproxy/moha_kaiyuan/ks_cfg/nodes/3306_moha_github/slave/127.0.0.2:3306 #记录当前MoHA实例组所有的节点
 {"NodeID":"127.0.0.2:3306","InternalHost":"127.0.0.2:3306","ExternalHost":"127.0.0.2:3306","LatestPos":{"File":"","Pos":"","GTID":"","UUID":""}}
 /dbproxy/moha_kaiyuan/ks_cfg/nodes/3306_moha_github/slave/127.0.0.3:3306 #记录当前MoHA实例组所有的节点
 {"NodeID":"127.0.0.3:3306","InternalHost":"127.0.0.3:3306","ExternalHost":"127.0.0.3:3306","LatestPos":{"File":"","Pos":"","GTID":"","UUID":""}}

4 计划内切换

agent 提供以下的 HTTP 服务

  • /changeMaster 主从切换
  • /setReadOnly 将当前节点的 MySQL,如果是 Master 的话,设为只读
  • /setReadWrite 将当前节点的 MySQL,如果是 Master 的话,设为可读写
  • /setOnlyFollow?onlyFollow=true/false 设置为true时,不参与抢主;设置为false时,参与选主

4.1 计划内切换

编译moha/moctl目录下的switch.go
主从切换需要先执行 /setReadOnly,如果可以进行主从切换,则执行 /changeMaster
否则执行 /setReadWrite 使集群恢复可读写。

# ./switch -instanceport 3306 #需要在实例所在的服务器运行
127.0.0.2:3306 master running thread is below 100,check continue
127.0.0.3:3306 Slave_IO_Running and Slave_SQL_Running thread is ok,check continue
127.0.0.3:3306 Seconds_Behind_Master is below 20s,check OK
127.0.0.3:3306 slave is approve master,check OK

5 计划外切换

  • 编译moha/moctl目录下的recovery.go
  • 在故障主机上Myflash https://github.com/Meituan-Dianping/MyFlash
  • 在故障主机运行recovery -instanceport 3306 -binlogbackupdir "/data/backup/binlog"
  • recovery会生成一个padder.toml的文件,修改文件中需要补偿的数据库名称
  • 运行./padder -config padder.toml

6 haproxy接入

6.1 安装haproxy

yum -y install haproxy

6.2 编写配置文件

#write haproxy 
global
    maxconn 100

defaults
    log global
    mode tcp
    retries 2
    timeout client 30m
    timeout connect 4s
    timeout server 30m
    timeout check 5s

listen stats
    mode http
    bind *:7000
    stats enable
    stats uri /

listen mysql
    bind *:5000
    option httpchk /masterCheck
    http-check expect status 200
    default-server inter 3s fall 3 rise 2 on-marked-down shutdown-sessions
    server mysql-node-1 127.0.0.4:3306 maxconn 100 check port 13306
    server mysql-node-2 127.0.0.5:3306 maxconn 100 check port 13306
    server mysql-node-3 127.0.0.6:3306 maxconn 100 check port 13306
# read haproxy
global
    maxconn 100

defaults
    log global
    mode tcp
    retries 2
    timeout client 30m
    timeout connect 4s
    timeout server 30m
    timeout check 5s

listen stats
    mode http
    bind *:5000 #diff machine
    stats enable
    stats uri /

listen mysql
    bind *:5000
    option httpchk /slaveCheck
    http-check expect status 200
    default-server inter 3s fall 3 rise 2 on-marked-down shutdown-sessions
    server mysql-node-1 127.0.0.4:3306 maxconn 100 check port 13306
    server mysql-node-2 127.0.0.5:3306 maxconn 100 check port 13306
    server mysql-node-3 127.0.0.6:3306 maxconn 100 check port 13306

6.3 启动haproxy

haproxy -f /etc/haproxy.cfg 

6.4 验证

mysql -u root -h 127.0.0.1 -P 5000
#验证m-haproxy上的请求是否发送到主库,s-haproxy上的读请求是否发送到slave 相当于dns的读写域名

7 监控

agent 内置了 pmm-client
如果已有 pmm-server 的话可以执行

    docker exec <agent-container> pmm-admin config --server <pmm-server-ip>
    docker exec <agent-container> pmm-admin add mysql --user <username> --password <password> <mysql-instance-name>

将 MySQL 加入 pmm-server 的监控。
如果没有 pmm-server 可以参考 etc/docker-compose/docker-compose.yaml
里面的 pmm-server 进行搭建。

agent 的监控可以通过修改 pmm-server 内的 prometheus 配置进行添加。具体步骤可以参考
Makefilemonitor 部分。

8 mobike MoHA 架构

Mobike MoHA 架构图

  • 建议单独运行一套监控程序读取etcd中MoHA的节点信息,通过MoHA集群的主从切换事件,实现报警以及主从切换后信息
  • 建议通过Pass化的管理,生成conf的配置文件,通过salt远程调用,实现自动化部署
  • 建议通过golang封装备份脚本,实现定时备份以及备份上传到远程存储,解决备份的环境依赖问题
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,490评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,581评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,830评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,957评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,974评论 6 393
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,754评论 1 307
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,464评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,357评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,847评论 1 317
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,995评论 3 338
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,137评论 1 351
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,819评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,482评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,023评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,149评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,409评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,086评论 2 355

推荐阅读更多精彩内容