体重秤中lb的意思,电子体重秤unit是什么意思

  

  业内有句话:没有做过运维的程序员不是好的架构师。   

  

  不知道是真是假。   

  

     

  

  

前言

  

  

   MySQL数据库作为各种业务系统的存储介质,在系统中起着非常重要的作用。如果数据库崩溃,读写数据库的操作会受到影响。如果不能快速恢复,对业务的影响会非常大。之前b站不是发生过事故吗?花了2个小时才恢复。详情请看之前写的文章。   

  

  b站塌了。总结“高可用性”和“异地多活动”   

  

  经过上次折腾ELK日志搜索平台,开发环境可以正常查询日志了。最近在做系统高可用相关的工作。这次分享的是MySQL双主Keepalived的高可用性落地和踩坑。   

  

  一文将带你搭建一套ELK栈日志平台。   

  

  

一、方案选择

  

  

  对于MySQL的高可用性,主要分两步。配置MySQL主模式并保持软件有效。拓扑图如下所示:   

  

     

  

  

MySQL 数据库的主主模式

  

  

  两个数据库分别部署在两个服务器上,相互同步数据,但只提供一个数据库供外部访问。当一个数据库宕机时,另一个数据库可以继续提供服务,并且只能在没有keepalived软件帮助的情况下手动切换。   

  

  

keepalived 监测、自动重启、流量切换

  

  

  检测和重启:在两台服务器上都部署了keepalived软件,定期检测mysql服务是否正常。如果数据库服务崩溃,keepalived将尝试使用脚本重新启动MySQL服务。备份:两个keepalived服务都提供虚拟IP供客户端使用,但流量只会转移到一个MySQL服务。虚拟IP:配置IP:keepalived后,会有一个虚拟IP。对于客户端来说,连接的是哪个MySQL并不重要,访问虚拟IP即可。流量切换:如果客户端正在访问的MySQL服务崩溃,keepalived会用我们写的脚本自动重启MySQL。如果重启失败,脚本会主动停止keepalived,这样客户端的流量就不会访问这个服务器上的MySQL服务,后续的访问流量会切换到另一个MySQL服务上。检测和重启的原理如下:   

  

     

  

  所需内容如下:   

  

  在两台Ubuntu服务器上启动MySQL容器。配置MySQL主从复制架构。将MySQL主从改为主-主复制架构。两台服务器设置keepalived环境来监控MySQL并自动重启MySQL。

二、主主复制的原理

  

  

  至于MySQL的master架构,其实原理就是两台服务器互为主从,双向复制。复制的原理如下:   

  

  主从复制主要包括以下过程:   

  

  主库在binlog中记录数据变化;   

  

  从库会在一定的时间间隔内检查主库的binlog,如果有变化,会启动一个I/O线程请求读取主库中的Binlog;   

  

  同时,主库为每个I/O线程启动一个dump线程,用于向其发送二进制事件,并将其存储在从节点的本地中继日志中。从库将启动SQL线程从中继日志中读取二进制日志并在本地重放,使其数据与主节点一致。最后,I/O线程和SQL线程将进入睡眠状态,等待下一次唤醒。   

  

     

  

  白话文是:   

  

  从库会生成两个线程,一个I/O线程,一个SQL线程;   

  

  I/O线程将请求主库的binlog,并将获得的binlog写入本地中继日志文件;   

  

  主库将生成一个转储线程,将binlog传递给从库I/O线程;   

  

  SQL线程,会读取中继日志文件中的日志,解析成SQL语句逐一执行;   

  

  接下来我们先在两台Ubuntu服务器上搭建好MySQL的基础环境,后续的操作都以此为基础。   

  

  

三、配置 MySQL 环境

  

  

  作为演示,我在这台机器上启动了两台Ubuntu虚拟机,安装了docker。因为我们的测试和生产环境是由Docker运行的,所以我将环境的映像打包并恢复到我的虚拟机上。   

  

  

3.1 备份和还原 mysql 镜像

  

  

  保存测试环境的mysql映像   

  

  sudo docker save -o mysql.t   

ar hcr:5000/hschub/hscmysql:0.0.2sudo chmod 777 mysql.tar

  

两台机器导入镜像

  

sudo docker load -i mysql.tar

  

启动容器,需要注意的是需要映射本地文件夹。

  

sudo docker run -p 3306:3306 --name mysql \-v /home/hss/mysql/data:/var/lib/mysql \-v /home/hss/mysql/etc/mysql:/etc/mysql \-e MYSQL_ROOT_PASSWORD='123456' \-d 46b

  

-v 代表映射的文件夹,-d 表示后台运行,46b 代表镜像 id。

  

进入容器,连接 mysql,node1的mysql 密码是 123456,node2 是 123456

  

# 查询容器 iddocker ps# 进入 mysql 容器docker exec -it <容器 id> /bin/bash# 连接 mysqlmysql -u root -p

  

接下来我们配置 MySQL 的主从架构,需要注意的是后续搭建的主主架构是基于主从架构来的,区别就是修改了一部分配置。

  

四、配置 MySQL 的主从架构

拓扑结构:

  

192.168.56.11 node1,主节点

  

192.168.56.12 node2,从节点

  

  

4.1 修改主节点配置文件

修改 /home/hss/mysql/etc/mysql/my.cnf 文件

  

server_id = 11log_bin = /var/lib/mysql/log/mysql-binbinlog-ignore-db=mysqlbinlog_format= mixedsync_binlog=100log_slave_updates = 1binlog_cache_size=32mmax_binlog_cache_size=64mmax_binlog_size=512mrelay_log = /var/lib/mysql/log/relay-binrelay_log_index = /var/lib/mysql/log/relay-bin.indexmaster_info_repository=TABLErelay-log-info-repository=TABLErelay-log-recovery

  

创建 /home/hss/mysql/data/log/mysql-bin 文件夹

  

创建 /home/hss/mysql/data/log/relay-bin 文件夹

  

给两个文件夹加上 777 权限,然后重启 MySQL 容器。

  

4.2 修改从节点配置文件

和主节点配置类似,需要修改 server_id = 12

  

4.3 添加主节点 mysql 账户信息

CREATE USER 'vagrant'@'192.168.56.12' IDENTIFIED BY 'vagrant';ALTER USER 'vagrant'@'192.168.56.12' IDENTIFIED WITH mysql_native_password BY 'vagrant'; GRANT REPLICATION SLAVE ON *.* TO 'vagrant'@'192.168.56.12';FLUSH PRIVILEGES;

  

4.4 锁主库的表

FLUSH TABLES WITH READ LOCK;

  

4.5 查看二进制日志文件的位置

  

记住 File 和 Position,后面会用到。这里 File = mysql-bin.000008,Position = 1020。

  

4.6 备份数据库,导出为脚本文件

cd /var/lib/mysqlmkdir backupmysqldump -uroot -P3306 --all-databases --triggers --routines --events > /var/lib/mysql/backup/all_databases.sql

  

查看挂载目录下是否有生成 all_databases.sql 文件,如下图所示:

  

  

4.7 解除锁定表

UNLOCK TABLES

  

4.8 从节点还原数据库

mysql -uroot -p -hlocalhost -P3306 < /var/lib/mysql/backup/all_databases.sql

  

4.9 设置同步信息

在 MySQL 命令行窗口中执行以下命令设置同步信息。这里就是配置主数据库的 IP 地址、Port、用户名、密码,二进制文件名,偏移量。

  

CHANGE MASTER TO MASTER_HOST='192.168.56.11',MASTER_PORT=3306,MASTER_USER='vagrant',MASTER_PASSWORD='vagrant',MASTER_LOG_FILE='mysql-bin.000008',MASTER_LOG_POS=1020;

  

4.10 启动从数据库的复制线程

在 MySQL 命令行窗口中执行以下命令启动从数据库的复制线程。

  

START salve;

  

4.11 查看从数据库的同步状态

SHOW slave status \G

  

如果 Slave_IO_Running 和 Slave_SQL_Running 显示 Yes,就表示启动同步成功。如下图所示:

  

  

在主库上执行以下命令显示当前连接过来的从库线程。

  

SHOW PROCESSLIST

  

如下所示,Slave has read all relay log; wating for more updates,说明从库已经同步完了。

  

使用上面的两个命令,我们可以判断当前的复制情况。

  

4.12 验证同步功能

下面验证下主从节点之间是否能正常同步数据。

  

主节点创建 testdb 数据库和 member 表。

  

刷新下从节点,发现从节点自动创建了 member 表。如下图所示。

  

然后在主节点插入一条数据,刷新从节点后,发现从节点也自动创建了一条数据。

  

  

五、配置主主架构

5.1 步骤

配置主主架构就是在主从架构中交换下配置信息。步骤如下:

  

在节点 node2 上创建复制账户。

  

查看二进制日志文件和位置信息。

  

在节点 node1 上设置主从复制的信息,包括 ip,port,用户名,密码,二进制日志文件和位置信息。

  

node1 开启主从复制,查看主从复制状态

  

5.2 node2 节点上的操作

5.2.1 停止同步

STOP slave

  

5.2.2 添加主节点 mysql 账户信息

CREATE USER 'vagrant'@'192.168.56.11' IDENTIFIED BY 'vagrant';ALTER USER 'vagrant'@'192.168.56.11' IDENTIFIED WITH mysql_native_password BY 'vagrant'; GRANT REPLICATION SLAVE ON *.* TO 'vagrant'@'192.168.56.11';FLUSH PRIVILEGES;

  

5.2.3 查看二进制日志文件和位置信息

SHOW MASTER STATUS

  

  

5.2.4 开启主从复制

start slave

  

5.2.5 查看同步状态

  

5.3 node 1 节点上的操作

5.3.1 设置同步信息

CHANGE MASTER TO MASTER_HOST='192.168.56.12',MASTER_PORT=3306,MASTER_USER='vagrant',MASTER_PASSWORD='vagrant',MASTER_LOG_FILE='mysql-bin.000001',MASTER_LOG_POS=2453;

  

5.3.2 启动从数据库的复制线程

START salve

  

5.3.3 查看从数据库的同步状态

SHOW slave status \G

  

  

5.4 测试主主同步

node2 的 member 表增加一条数据 (2,zzz),node1 上同步成功

  

  

node 1 的 member 表增加一条数据(3,aaa),node2 上同步成功

  

  

六、搭建 keepalived 环境

6.1 Keepalived 的应用场景

Keepalived 软件在主主架构中,可以配置成两种应用场景:

  

① 当这台服务器上的 keepalived 发现 MySQL 服务崩了后,立刻停掉这台服务器上 keepalived 自己,这样流量就会自动切到另外一台 keepalived 服务器。② 当这台服务器上的 keepalived 发现 MySQL 服务崩了后,立刻尝试重启 MySQL 服务,如果重启失败,则停掉 keepalived 自己。和第一种方案的区别是会尝试重启 MySQL 服务。这里我配置成第二种功能场景,保障 MySQL 服务的高可用。另外可以配置 MySQL 服务异常时,发送邮件给运维或开发人员,由他们检查服务器的状态。

  

6.2 使用 Keepalived 的原理

  

Keepalived 提供了一个虚拟 IP (简称 VIP),对外提供访问。当客户端连接这个虚拟 IP 后,只会访问其中一个 MySQL。MySQL 节点故障后,keepalived 执行脚本进行重启,如果重启失败,脚本自动停掉 keepalived,备用节点自动切换为主节点。

  

keepalived 检测和重启的流程图如下:

  

  

6.3 安装 keepalived 软件

安装依赖、获取 keepalived 安装包、解压安装包、删除安装包。

  

# 安装依赖sudo apt-get install -y libssl-devsudo apt-get install -y openssl sudo apt-get install -y libpopt-devsudo apt-get install -y libnl-devsudo apt-get install -y libnl-3-devsudo apt-get install -y libnl-genl-3.devsudo apt-get install daemonsudo apt-get install libc-devsudo apt-get install libnfnetlink-devsudo apt-get install gcc# 获取 keepalived 安装包cd /usr/localsudo susudo wget https://www.keepalived.org/software/keepalived-2.2.2.tar.gz# 解压安装包sudo tar -zxvf keepalived-2.2.2.tar.gz # 删除安装包mv keepalived-2.2.2 keepalived

  

配置 keepalived 软件

  

cd keepalived./configure --prefix=/usr/local/keepalived --disable-dependency-tracking

  

执行结果如下所示:

  

  

编译 keepalived 软件

  

sudo make && make install

  

执行结果如下所示:

  

  

对于 Ubuntu ,需要做一点特别的改动,创建链接

  

mkdir -p /etc/rc.d/init.dln -s /lib/lsb/init-functions /etc/rc.d/init.d/functions

  

拷贝配置文件

  

sudo mkdir /etc/sysconfigsudo cp /usr/local/keepalived/etc/sysconfig/keepalived /etc/sysconfig/sudo cp /usr/local/keepalived/keepalived/etc/init.d/keepalived /etc/init.d/sudo cp /usr/local/keepalived/sbin/keepalived /sbin/sudo mkdir /etc/keepalivedsudo cp /usr/local/keepalived/etc/keepalived/keepalived.conf /etc/keepalived/

  

修改配置文件 /etc/keepalived/keepalived.conf

  

daemon keepalived ${KEEPALIVED_OPTIONS}

  

改为

  

daemon -- keepalived ${KEEPALIVED_OPTIONS}

  

6.4 添加虚拟 IP

先用 ifconfig 查看当前的网卡,比如我的服务器上是 enp0s8。

  

ip addr del 192.168.56.88 dev enp0s8:1ifconfig enp0s8:1 192.168.56.88 broadcast 192.168.56.255 netmask 255.255.255.0 uproute add -host 192.168.56.88 dev enp0s8:1

  

将命令写到 /usr/local/script/vip.sh文件中。最好将 /usr/local/script/vip.sh文件添加到服务器的开机启动项中,将 Keepalived 服务设置为开机自启动(未写)。

  

6.5 修改配置文件

备份配置文件

  

sudo mv /etc/keepalived/keepalived.conf /etc/keepalived/keepalived.conf.backup

  

修改配置文件

  

sudo vim /etc/keepalived/keepalived.conf

  

配置文件的内容如下:

  

global_defs { router_id MYSQL_HA #当前节点名}vrrp_script restart_mysql { script "/usr/local/keepalived/restart_mysql.sh" #重启 mysql 容器 interval 2 weight 2}vrrp_instance VI_1 { state BACKUP #两台配置节点均为BACKUP interface enp0s8 #绑定虚拟IP的网络接口 virtual_router_id 51 #VRRP组名,两个节点的设置必须一样,以指明各个节点属于同一VRRP组 priority 101 #节点的优先级,另一台优先级改低一点 advert_int 1 #组播信息发送间隔,两个节点设置必须一样 nopreempt #不抢占,只在优先级高的机器上设置即可,优先级低的机器不设置 authentication { #设置验证信息,两个节点必须一致 auth_type PASS auth_pass 123456 } track_script { restart_mysql #检测 mysql 状态,如果失败,则重启 mysql 容器 } virtual_ipaddress { #指定虚拟IP,两个节点设置必须一样 192.168.56.88 }}virtual_server 192.168.56.88 3306 { #linux虚拟服务器(LVS)配置 delay_loop 2 #每个2秒检查一次real_server状态 lb_algo wrr #LVS调度算法,rr|wrr|lc|wlc|lblc|sh|dh lb_kind DR #LVS集群模式 ,NAT|DR|TUN persistence_timeout 60 #会话保持时间 protocol TCP #使用的协议是TCP还是UDP real_server 192.168.56.11 3306 { weight 3 #权重 TCP_CHECK { connect_timeout 10 #连接超时时间 nb_get_retry 3 #重连次数 delay_before_retry 3 #重连间隔时间 connect_port 3306 #健康检查端口 } } }

  

编写异常处理脚本

  

sudo vim /usr/local/keepalived/restart_mysql.sh

  

内容如下,

  

#!/bin/bash# 定义变量,重启 mysql 容器START_MYSQL="docker restart mysql"# 定义变量,停止 mysql 容器STOP_MYSQL="docker stop mysql"# 定义变量,日志文件路径LOG_FILE="/usr/local/keepalived/logs/mysql-check.log"# 定义变量,检查 mysql 服务是否正常的命令HAPS=`ps -C mysqld --no-header |wc -l`# 打印当前时间到日志文件date "+%Y-%m-%d %H:%M:%S" >> $LOG_FILE# 打印提示信息到日志文件echo "check mysql status" >> $LOG_FILE# 检查数据库状态,如何返回 0,则重启 mysql 容器,然后休眠 3s 后,再次检测 mysql 状态,如果还是返回 0,则停止 keepalived。if < $HAPS -eq 0 >;thenecho $START_MYSQL >> $LOG_FILE$START_MYSQL >> $LOG_FILE 2>&1sleep 3if < `ps -C mysqld --no-header |wc -l` -eq 0 >;thenecho "start mysql failed, killall keepalived" >> $LOG_FILEkillall keepalivedfifi

  

给脚本分配权限

  

sudo chmod +x /usr/local/keepalived/restart_mysql.sh

  

创建 logs 文件夹,给 logs 文件夹分配权限

  

sudo mkdir /usr/local/keepalived/logssudo chmod +x /usr/local/keepalived/logs -r

  

重新加载配置文件

  

sudo systemctl daemon-reload

  

6.6 启动 keepalived

6.6.1 启动两台服务器上的 keepalived

启动 node2 节点:

  

sudo pkill keepalivedsudo systemctl start keepalivedsudo systemctl status keepalived

  

启动 node1 节点:

  

pkilll keepalivedsudo systemctl status keepalived

  

我们可以通过这个命令查看 keepalived 进程

  

ps -ef | grep keepalived

  

查看日志

  

sudo cat /var/log/syslog

  

6.7 测试 keepalived 是否会重启 mysql

停止 node2 上的 mysql 容器

  

docker stop 8cc

  

查看 keepalived 状态,提示移除了 mysql 服务。

  

  

因为 keepalived 会每 2s 检查一次 MySQL 的状态,发现 MySQL 异常后,就会重启 mysql 容器。所以过几秒后,重新查看容器状态,会看到 mysql 容器重新启动了。

  

docker ps

  

查看 keepalived 状态,执行 restart_mysql 成功

  

  

查看执行日志

  

  

问题:每 2s 会打印一次,文件可能会很大。需要执行定期删除。

  

6.8 测试 MySQL 节点切换

验证下当 MySQL 重启失败后,keepalived 自动停止后,客户端连接的 MySQL 是否会自动切到另外一个 MySQL 节点上。

  

首先用 mysql 客户端工具 navicat 连接虚拟 ip 地址,账号和密码就是 node 1 和 node2 的 mysql 账号密码(root/123456)

  

  

可以连接上,然后执行以下命令,查看当前虚拟 ip 连接的是哪个数据库

  

SHOW VARIABLES LIKE '%hostname%'

  

可以看到连接的是 node2 的容器的 id,说明 keepalived 已经通过虚拟 ip 连接到 node2 的 mysql 了,是正常工作的,node2 现在是作为主节点,node1 作为备用节点。

  

  

由于本地环境重新启动 MySQL 都是成功的,不会停掉 keepalived 服务。出于演示目的,我就直接停掉 keepalived 服务。

  

pkill keepalived

  

执行下面这个命令可以查看 keepalived 进程,发现已经没有了。(控制台显示的 grep --color=auto keepalived 表示是查找命令)

  

ps -ef | grep keepalived

  

重新查询客户端的连接信息,发现已经切换到 92b (node1)机器上的 mysql 了。

  

SHOW VARIABLES LIKE '%hostname%'

  

再次查看 node1 上 keepalived 上的状态,再发送信息给

  

sudo systemctl status keepalived

  

七、遇到的坑

7.1 密码不正确,无法登录的问题

密码不正确,设置跳过密码验证

  

apt-get updateapt install vim

  

修改 mysql 配置文件

  

vim /etc/mysql/my.cnf

  

添加一行配置,跳过 mysql 密码验证

  

skip-grant-tables

  

重启容器

  

docker restart 9e6

  

重新计入 mysql 容器,连接 mysql,不需要密码就可以连接上 mysql。

  

mysql

  

修改登录密码

  

update mysql.user set authentication_string=PASSWORD('123456') where User='root';

  

重启容器

  

7.2 没有映射 mysql 文件夹

cd /home/hss/mysql/etcsudo chmod 777 mysql -R

  

拷贝 mysql 文件夹

  

7.3 mysql data 文件夹没有权限

sudo chmod 777 /home/hss/mysql/data -R

  

7.4 安装依赖包失败

sudo apt-get install -y libnl-dev libnl-3-dev libnl-genl-3.devReading package lists... DoneBuilding dependency treeReading state information... DoneNote, selecting 'libnl-genl-3-dev' for regex 'libnl-genl-3.dev'Package libnl-dev is not available, but is referred to by another package.This may mean that the package is missing, has been obsoleted, oris only available from another sourceE: Package 'libnl-dev' has no installation candidate

  

解决方案:更新包

  

sudo apt-get -y update

  

7.5 更新包失败

Err:15 https://download.docker.com/linux/ubuntu bionic Release Could not wait for server fd - select (11: Resource temporarily unavailable) Reading package lists... Done E: The repository 'https://download.docker.com/linux/ubuntu bionic Release' no longer has a Release file. N: Updating from such a repository can't be done securely, and is therefore disabled by default. N: See apt-secure(8) manpage for repository creation and user configuration details.

  

解决方案:

  

修改配置文件

  

sudo mv /etc/apt/sources.list /etc/apt/sources.list.backupsudo vim /etc/apt/sources.list

  

配置内容如下:

  

deb http://archive.ubuntu.com/ubuntu/ trusty main restricted universe multiverse deb http://archive.ubuntu.com/ubuntu/ trusty-security main restricted universe multiverse deb http://archive.ubuntu.com/ubuntu/ trusty-updates main restricted universe multiverse deb http://archive.ubuntu.com/ubuntu/ trusty-proposed main restricted universe multiverse deb http://archive.ubuntu.com/ubuntu/ trusty-backports main restricted universe multiverse

  

执行更新

  

sudo apt-get update

  

依赖包版本太高

apt-get install libnl-devThe following packages have unmet dependencies: libnl-3-dev : Depends: libnl-3-200 (= 3.2.21-1ubuntu4.1) but 3.2.29-0ubuntu3 is to be installed Conflicts: libnl-dev but 1.1-8ubuntu1 is to be installed libnl-genl-3-dev : Depends: libnl-genl-3-200 (= 3.2.21-1ubuntu4.1) but 3.2.29-0ubuntu3 is to be installedE: Unable to correct problems, you have held broken packages.

  

解决方案:

  

按照这个报错信息来进行降级,等号后面就是提示信息里括号的版本信息。

  

sudo apt-get install libnl-3-200=3.2.21-1ubuntu4.1sudo apt-get install libnl-genl-3-200=3.2.21-1ubuntu4.1

  

启动 keepalived 报错

root@node1:/usr/local/keepalived/etc/keepalived# service keepalived restartFailed to restart keepalived.service: Unit keepalived.service is masked.root@node1:/usr/local/keepalived/etc/keepalived# systemctl status keepalived.service● keepalived.service Loaded: masked (/dev/null; bad) Active: inactive (dead)Condition: start condition failed at Wed 2022-05-11 02:40:46 UTC; 1 day 3h ago

  

解决方案:

  

systemctl unmask sshd

  

再次启动,提示另外一个错误。

  

  

解决方案,因为 ubuntu 没有这个命令 /etc/rc.d/init.d/functions,所以需要添加一个命令链接

  

mkdir -p /etc/rc.d/init.dln -s /lib/lsb/init-functions /etc/rc.d/init.d/functions

  

install gcc 出现问题

切换回 ubuntu 官方源

  

sudo mv /etc/apt/sources.list /etc/apt/sources.list.backup2sudo mv /etc/apt/sources.list.backup /etc/apt/sources.listsudo apt-get updatesudo apt-get install gcc

  

启动 keepalived 报错 keepalived_script

WARNING - default user 'keepalived_script' for script execution does not exist - please create.

  

解决方案:

  

配置文件的 global_defs 配置里面增加 script_user root

  

global_defs { script_user rot}

  

执行脚本失败

May 16 03:50:54 node1 Keepalived_vrrp<19855>: WARNING - script '/usr/local/keepalived/restart_mysql.sh' is not executable for uid:gid 0:0 - disabling.May 16 03:50:54 node1 Keepalived_vrrp<19855>: SECURITY VIOLATION - scripts are being executed but script_security not enabled.

  

给脚本添加权限。

相关文章