作者:边城元元​



TiDB 中的高可用实践



一、Haproxy+keepalive 方式的TiDB高可用实践



1.1 拓扑图

TiDB 中的高可用实践_vim

ip

作用

192.168.31.100

虚拟出来的漂移IP(连接tidb 入口IP)

192.168.31.141

真实服务器1,已经部署Haproxy+keepalived ,虚拟IP(192.168.31.100)

192.168.31.142

真实服务器2,已经部署Haproxy+keepalived,虚拟IP(192.168.31.100)

192.168.31.143

真实服务器3,已经部署TiDB集群应用tidb-server1 :4000tidb-server2 :4001tidb-server3 :4002


1.2 安装虚拟机haproxy-1

从纯净版的Centos7.3的虚拟机导出,再导入新建虚拟机 haproxy-1

(导入时,选择vmdk,修改mac地址)



1.2.1 准备工作
  • 进入虚拟机 修改hostname
hostnamectl set-hostname haproxy-1
hostnamectl set-hostname haproxy-2
hostnamectl set-hostname tidb-cluster


手动更新/etc/hosts
vim /etc/hosts
echo "127.0.0.1 haproxy-1">>/etc/hosts
echo "192.168.31.141 haproxy-1">>/etc/hosts

echo "127.0.0.1 haproxy-2">>/etc/hosts
echo "192.168.31.142 haproxy-2">>/etc/hosts

echo "127.0.0.1 tidb-cluster">>/etc/hosts
echo "192.168.31.143 tidb-cluster">>/etc/hosts
  • 修改IP为固定IP 桥接网卡IP(192.168.31.141,192.168.31.142,192.168.31.143)

ifconfig

vim /etc/sysconfig/network-scripts/ifcfg-eth1

DEVICE="eth1" BOOTPROTO="static" IPADDR="192.168.31.141" ONBOOT="yes" TYPE="Ethernet" PERSISTENT_DHCLIENT="yes" IPV6INIT = no DEVICE=eth0 #虚拟机网卡名称。 TYPE=Ethernet #类型为以太网 ONBOOT=yes #开机启用网络配置。 NM_CONTROLLED=yes #是否可以由 Network Manager 工具托管 BOOTPROTO=static #static:静态 ip,dhcp:自动获取 ip 地址, #none:无(不指定) IPADDR=192.168.80.111 #IP 地址 NETMASK=255.255.255.0 #子网掩码,和物理主机一样就可以了。 GATEWAY=192.168.80.2 #网关(与VMnet8段位一致) DNS1=192.168.80.2 #DNS 与网关 ip 一致 HWADDR=00:0c:29:22:05:4c#MAC 地址 IPV6INIT=no #IPv6 没有启动 USERCTL=no #不允许非 root 用户控制此网卡

vim /etc/sysconfig/network-scripts/ifcfg-eth0

本地双网卡:NAT分别使用10.0.2.13,10.0.2.14,10.0.2.15

name="eth0" DEVICE="eth0" BOOTPROTO="static" IPADDR="10.0.2.13" ONBOOT="yes" TYPE="Ethernet" IPV6INIT = no

systemctl restart network


1.2.2 遇到的问题
# centos 虚拟机 Name or service not known 解决方法

vim ifcfg-eth0
#增加网关

NETMASK=255.0.0.0
GATEWAY=10.255.255.255
DNS1= 8.8.8.8
DNS2=8.8.8.4



1.3 安装Haproxy



1.3.1 下载安装Haproxy

下载地址:​​https://src.fedoraproject.org/repo/pkgs/haproxy/​​​ 选择一个版本进行下载,这里我用的是​​haproxy-1.8.25.tar.gz​​版本。

# 需要不能放到vbox格式的磁盘里,
cp ./haproxy-1.8.25.tar.gz /usr/local0/software/
cd /usr/local0/software/
tar -xvf haproxy-1.8.25.tar.gz
cd haproxy-1.8.25
make TARGET=linux31 # uname -r 查看下内核版本,centos7.x是linux31、centos6.x是linux26
sudo make install PREFIX=/usr/local0/haproxy # 安装到指定路径
cd /usr/local0/haproxy
mkdir conf pid # 分别用来存放配置、进程文件



1.3.2 配置Haproxy

vim /usr/local0/haproxy/conf/haproxy.cfg

global
log 127.0.0.1 local0 debug
maxconn 4096
daemon
nbproc 1 # 进程数,创建多个进程,能够减少每个进程的任务队列,但是过多的进程可能会导致进程的崩溃
#nbthread 1 # 最大线程数。线程数的上限与 CPU 数量相同。
pidfile /usr/local0/haproxy/pid/haproxy.pid
defaults
log global # 日志继承全局配置段的设置。
retries 3 # 连接后端服务器失败的次数如果超过这里设置的值,haproxy会将对应的后端服务器标记为不可用
timeout connect 2s
timeout client 30000s
timeout server 30000s
timeout check 5s
# 接入配置
listen tidb-cluster # 配置 database 负载均衡。
bind 0.0.0.0:4000 # 浮动 IP 和 监听端口。
mode tcp # HAProxy 要使用第 4 层的传输层。
balance leastconn # 连接数最少的服务器优先接收连接。`leastconn` 建议用于长会话服务,例如 LDAP、SQL、TSE 等,而不是短会话协议,如 HTTP。该算法是动态的,对于启动慢的服务器,服务器权重会在运行中作调整。
server tidb-4000 192.168.31.143:4000 check inter 2000 rise 2 fall 3 # 检测 4000 端口,检测频率为每 2000 毫秒一次。如果 2 次检测为成功,则认为服务器可用;如果 3 次检测为失败,则认为服务器不可用。
server tidb-4001 192.168.31.143:4001 check inter 2000 rise 2 fall 3
server tidb-4002 192.168.31.143:4002 check inter 2000 rise 2 fall 3


# 监控页面
listen admin_stats
bind 0.0.0.0:11001
mode http
option httplog # 开始启用记录 HTTP 请求的日志功能。
maxconn 10 # 最大并发连接数。
stats refresh 30s
stats uri /admin
stats realm welcome login\ Haproxy
stats auth admin:admin123
stats hide-version # 隐藏监控页面上的 HAProxy 版本信息。
stats admin if TRUE # 通过设置此选项,可以在监控页面上手工启用或禁用后端真实服务器



1.3.3 启动Haproxy
/usr/local0/haproxy/sbin/haproxy -f /usr/local0/haproxy/conf/haproxy.cfg 

netstat -tpln
kill -9 $PID

查看监控页面

​http://192.168.31.141:11001/admin​​​输入前面​​listen​​部分配置的账号密码登录。



1.4 安装 Keepalive

下载地址:​​https://www.keepalived.org/download.html​​​ 选择一个版本进行下载,这里我用的是​​keepalived-1.4.5​​版本。

tar -xvf keepalived-1.4.5.tar.gz
cd keepalived-1.4.5
./configure --prefix=/usr/local0/keepalived


# 如果出现问题 可能缺少组件
# !!! OpenSSL is not properly installed on your system. !!!
#执行yum -y install openssl-devel解决

# *** WARNING - this build will not support IPVS with IPv6. Please install libnl/libnl-3 dev libraries to support IPv6 with IPVS.
# 执行yum -y install libnl libnl-devel解决。

# configure: error: libnfnetlink headers missing
#执行yum install -y libnfnetlink-devel解决。

# 把缺少的组件一起安装
yum -y install openssl-devel libnl libnl-devel libnfnetlink-devel

# 安装好组件后重新 configure
./configure --prefix=/usr/local0/keepalived



make && make install
#centos7 修改yum源为阿里源

# 1.安装base reop源
cd /etc/yum.repos.d

# 接着备份旧的配置文件
mv CentOS-Base.repo CentOS-Base.repo.bak

#下载阿里源的文件
wget -O CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
curl -o CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo

#2 安装epel repo源:
wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
curl -o /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo

#3.清理缓存
yum clean all

# 4.重新生成缓存
yum makecache

yum repolist all

查看监控

​http://192.168.31.141:11001/admin​

输入前面​​listen​​部分配置的账号密码登录(admin=admin123)。



1.4.1 注册Keepalived为系统服务
cp /usr/local0/keepalived/sbin/keepalived /usr/sbin/
# 以下拷贝的原路径要替换成实际安装包解压后的路径
cp /data0/webserver/haproxy/keepalived-1.4.5/keepalived/etc/sysconfig/keepalived /etc/sysconfig/
cp /data0/webserver/haproxy/keepalived-1.4.5/keepalived/etc/init.d/keepalived /etc/init.d/
# 赋予可执行权限
chmod +x /etc/init.d/keepalived
# 重启系统服务
systemctl daemon-reload


# 启动|停止|重启|状态查看
systemctl start|stop|restart|status keepalived

# 开机自动运行
systemctl enable keepalived

# 关闭开机自动运行
systemctl disable keepalived



1.4.2 配置Keepalived

这里只贴出​​keepaliaved​​​抢占式配置,非抢占式没有主备之分,全部都为​​BACKUP​​​,并且配置文件中添加​​nopreempt​​,用来标识为非抢占式。

Keepalived`默认读取配置的路径为`/etc/keepalived/keepalived.conf

vim /etc/keepalived/keepalived.conf
#主机配置

global_defs {
router_id haproxy1 # 虚拟路由名称
}

# HAProxy健康检查配置
vrrp_script chk_haproxy {
script "killall -0 haproxy" # 使用killall -0检查haproxy实例是否存在,性能高于ps命令
interval 2 # 脚本运行周期,秒
}

# 虚拟路由配置
vrrp_instance VI_1 {
state MASTER # 本机实例状态,MASTER/BACKUP,备机配置文件中请写BACKUP
interface eth1 # 本机网卡名称,使用ifconfig命令查看
virtual_router_id 51 # 虚拟路由编号,主备机保持一致
priority 101 # 本机初始权重,备机请填写小于主机的值(例如99)
advert_int 1 # 争抢虚地址的周期,秒
authentication {
auth_type PASS
auth_pass 4gjfethTonUY7kXU # 认证类型和密码主备一样,要不然无法互相认证
}
virtual_ipaddress {
192.168.31.100 # 虚地址IP,主备机保持一致
}
track_script {
chk_haproxy # 对应的健康检查配置
}
}
# 备用机1配置

global_defs {
router_id haproxy2 # 虚拟路由名称
}

# HAProxy健康检查配置
vrrp_script chk_haproxy {
script "killall -0 haproxy" # 使用killall -0检查haproxy实例是否存在,性能高于ps命令
interval 2 # 脚本运行周期,秒
}

# 虚拟路由配置
vrrp_instance VI_1 {
state BACKUP # 本机实例状态,MASTER/BACKUP,备机配置文件中请写BACKUP
# interface ens33 # 本机网卡名称,使用ifconfig命令查看
interface eth1 # 本机网卡名称,使用ifconfig命令查看
virtual_router_id 51 # 虚拟路由编号,主备机保持一致
priority 99 # 本机初始权重,备机请填写小于主机的值(例如99)
advert_int 1 # 争抢虚地址的周期,秒
authentication {
auth_type PASS
auth_pass 4gjfethTonUY7kXU # 认证类型和密码主备一样,要不然无法互相认证
}
virtual_ipaddress {
192.168.31.100 # 虚地址IP,主备机保持一致
}
track_script {
chk_haproxy # 对应的健康检查配置
}
}



1.4.3 启动Keepalived
# 启动Keepalived
systemctl start keepalived

# 查看是否有虚拟ip
# ip addr sh ens33 # ens33是具体网卡名称,可以通过ifconfig查看
ip addr sh eth1 # eth1是具体网卡名称,可以通过ifconfig查看

# 备份的keepalived 使用ip addr sh eth1 没有看到 192.168.31.100的虚拟ip



1.4.4 脚本检测扩展
# vi /etc/keepalived/chk_haproxy.sh

#!/bin/bash
A=`ps -C haproxy --no-header |wc -l`
if [ $A -eq 0 ];then
# su - haproxy -c "/usr/local/haproxy/sbin/haproxy -f /usr/local0/haproxy/conf/haproxy.cfg"
/usr/local0/haproxy/sbin/haproxy -f /usr/local0/haproxy/conf/haproxy.cfg
sleep 10
if [ `ps -C haproxy --no-header |wc -l` -eq 0 ];then
systemctl stop keepalived
fi
fi
# 更改健康检查配置
# HAProxy健康检查配置
vrrp_script chk_haproxy {
script "/etc/keepalived/chk_haproxy.sh" # 执行自定义脚本
interval 2 # 脚本运行周期,秒
}



1.5 部署haproxy-2

1)复制虚拟机haproxy-1 2)启动虚拟机,修改host,ip,重启主机 3)修改keepalived配置



1.5.1 负载&高可用测试
# 1)虚拟ip是否生效
# 2)是否起到负载的效果
客户端通过虚拟ip 192.168.31.100访问主机上的haproxy端口,能访问成功说明虚拟ip已经生效,
此时访问192.168.31.100和访问192.168.31.141效果是一样的。

# 3)故障发生是否发生漂移,并且不影响前端的访问
杀死主机的haproxy进程,如果VIP发生漂移,查看备用机持有VIP就说明主备配置已经生效了。
客户端还是能通过192.168.31.100这个虚拟ip进行服务访问,这就是高可用。



1.6 安装tidbCluster311



1.6.1 TiDB-Cluster311.yml
# cluster311.yml
global:
user: "tidb"
ssh_port: 22
deploy_dir: "/tidb-deploy311"
data_dir: "/tidb-data311"


server_configs:
tidb:
log.slow-threshold: 300
tikv:
readpool.storage.use-unified-pool: false
readpool.coprocessor.use-unified-pool: true
pd:
replication.max-replicas: 1

pd_servers:
- host: 127.0.0.1
client_port: 2379
peer_port: 2380

tidb_servers:
- host: 127.0.0.1
port: 4000
status_port: 10080
# 2
- host: 127.0.0.1
port: 4001
status_port: 10081
# 3
- host: 127.0.0.1
port: 4002
status_port: 10082

tikv_servers:
- host: 127.0.0.1
port: 20160
status_port: 20180



1.6.2 安装TiDB-cluster311
# 安装tiup
curl --proto '=https' --tlsv1.2 -sSf https://tiup-mirrors.pingcap.com/install.sh | sh

```shell
# 1、加载tiup组件
source /root/.bash_profile
# 2、安装cluster组件
tiup cluster
# 更新tiup、更新cluster
tiup update --self && tiup update cluster

# 3、安装cluster111
tiup cluster check ./cluster311.yml --user root -p

# 4、修复部分参数
tiup cluster check --apply ./cluster311.yml --user root -p
tiup cluster deploy cluster311 v5.3.0 ./cluster311.yml --user root -p

#会提示输入密码
#提示输入y/n

# 预估约10多分钟可以安装完毕
# 如果中间有终端可以重复执行 tiup cluster deploy cluster111 v5.3.0 ./cluster111.yml --user root -p

# 提示 “Cluster `cluster111` deployed successfully, you can start it with command: `tiup cluster start cluster111 --init`” 表示安装成功

# 4、通过命令查看集群
tiup cluster list

# 5、初始化集群 不带--init
tiup cluster start cluster311


tiup cluster display cluster311

TiDB 中的高可用实践_vim_02



1.6.3 测试TiDB-Custer311

1、dashboard

​http://192.168.31.143:2379/dashboard/#/overview​

TiDB 中的高可用实践_vim_03

1、连接 192.168.31.143 :4000,4001,4002

1)正常连接4000

mysql -h 192.168.31.143 -P 4000 -uroot

2)正常连接4001

mysql -h 192.168.31.143 -P 4001 -uroot

3)正常连接4002

mysql -h 192.168.31.143 -P 4002 -uroot

4)haproxy的真实ip可以访问这块需要处理,只运行通过浮动ip访问

mysql -h 192.168.31.141 -P 4000 -uroot

mysql -h 192.168.31.142 -P 4000 -uroot

2、连接 192.168.31.100:4000端口

mysql -h 192.168.31.100 -P 4000 -uroot

3、查看haproxy监控

​http://192.168.31.100:11001/admin​​​输入前面​​listen​​部分配置的账号密码登录。

TiDB 中的高可用实践_服务器_04

4、在一个Haproxy节点和多个tidb-server节点挂掉的情况下都可以正常访问TiDB数据库

通过浮动ip访问TIDB

mysql -h 192.168.31.100 -P 4000 -uroot -e "select SESSION_USER();"



二、阿里云CLB(原SLB)做内网Tidb高可用实践

使用阿里云的SLB来构建内网负载均衡,免去了自己搭建高可用负载均衡服务器的环节

1、购买阿里云CLB(原SLB)

2、创建实例

3、配置实例和规则(配置TCP监听)

具体参考:​​https://help.aliyun.com/document_detail/85995.htm?spm=a2c4g.11186623.0.0.69ed72b46Eje3q#task-1563673​



三、总结与思考



总结

  • 本篇文章主要讲了TiDB在生产中多种高可用方案中的自己用到过的2种(HA+Keepalive与CLB)
  • Tidb的高可用方案本质是对tidb-server的负载和中间件本身的高可用,实现tidb高可用的方案还有很多,这里不再说明。
  • 文辞简陋有一些描述不到位的地方,还请多多指教。


思考



1、从虚拟IP(192.168.31.100)访问Tidb时,如何从sql命令端知道连接的哪个 tidb-server节点?

从下面的官方信息中没有查到相关的命令

​https://docs.pingcap.com/zh/tidb/stable/information-functions#​​信息函数

类似的命令有​​mysql -h 192.168.31.100 -P 4000 -uroot -e "select SESSION_USER();"​​ 但是这个查到的是 HaProxy机器的信息不是预期的某个tidb-server节点的信息。如果哪个大神了解这个方面的信息,麻烦不吝赐教!

本文到此结束了,谢谢! 最后想对自己说的是要抽时间看一下tidb源码。