数据库应用——MySQL主从复制和Atlas读写分离

MySQL主从复制和读写分离

  • MySQL在企业中的拓扑图
  • MySQL主从复制
    • MySQL主从复制的类型
    • 主从复制的工作过程
    • MySQL主从复制步骤
      • 安装MySQL
      • 建立时间同步环境
      • 配置主从复制
        • 主节点配置
        • 从节点配置
        • 验证
  • MySQL读写分离
    • MySQL读写分离原理
    • Atlas的简介
    • 安装并配置Atlas
      • 配置读写分离
    • 测试

MySQL在企业中的拓扑图

在企业网站中,后端MySQL数据库只有一台时,会有以下问题

  • 单点故障,服务不可用
  • 无法处理大量的并发数据请求
  • 数据丢失—大灾难

改造方法

  • 增加MySQL数据库服务器,对数据进行备份,形成主备
  • 确保主备MySQL数据库服务器数据是一样的
  • 主服务器宕机了,备份服务器继续工作,数据有保障

更好的解决方案

  • 通过主从复制的方式来同步数据,再通过读写分离来提升数据库的并发负载能力
    数据库应用——MySQL主从复制和Atlas读写分离_第1张图片

MySQL主从复制

MySQL主从复制的类型

  • 基于语句的复制(默认,一般都是用这种类型)

    • 在主服务器上执行的语句,从服务器执行同样的语句
  • 基于行的复制

    • 把改变的内容复制到从服务器
  • 混合类型的复制

    • 一旦发现基于语句无法精确复制时,就会采用基于行的复制

主从复制的工作过程

数据库应用——MySQL主从复制和Atlas读写分离_第2张图片

  1. 每个事务更新数据完成之前,master在二进制日志记录这些改变。写入二进制日志完成后,master通知存储引擎提交事务。
  2. slave将master的Binary log复制到其中继日志(Relay log)。首先,slave开始一个工作线程——I/O线程,I/O线程在master上打开一个普通连接,开始binlog dump process。binlog dump process从master的二进制日志中读取事件,如果已经跟上master,它会睡眠并等待master产生新的事件。I/O线程将这些事件写入中继日志
  3. sql slave thread(sql从线程)处理该过程最后一步。sql线程从中继日志读取事件,并重放其中的事件而更新 slave的数据。使其与master中的数据一致。只要该线程与I/O线程保持一致,中继日志通常会位于OS的缓存中,所以中继日志的开销很小
  4. 复制过程中有一个重要限制,即复制在slave上是串行化的,也就是说master上的并行更新操作不能在slave上并行操作

MySQL主从复制步骤

主机 ip
主MySQL服务器 192.168.188.65
从MySQL服务器1 192.168.188.66
从MySQL服务器2 192.168.188.67

安装MySQL

我们通过二进制包安装
tar xf mysql-5.7.25-el7-x86_64.tar.gz  -C /usr/local/
mv mysql-5.7.25-el7-x86_64  mysql

groupadd mysql
useradd -M -s /sbin/nologin mysql -g mysql
chown -R mysql.mysql /usr/local/mysql

vim /etc/my.cnf

[mysqld]
user=mysql
basedir=/usr/local/mysql
datadir=/usr/local/mysql/data
server_id=1
port=3306
socket=/tmp/mysql.sock
[mysql]
socket=/tmp/mysql.sock
prompt=mysql [\\d]>

添加环境变量
echo 'export PATH=$PATH:/usr/local/mysql/bin' >> /etc/profile
source /etc/profile

初始化
mysqld --initialize-insecure  --user=mysql --basedir=/usr/local/mysql --datadir=/usr/local/mysql/data

如果报错可以
yum install -y libaio

使用systemd管理mysql
vim /etc/systemd/system/mysqld.service 

[Unit]
Description=MySQL Server
After=network.target
After=syslog.target
[Install]
WantedBy=multi-user.target
[Service]
User=mysql
Group=mysql
ExecStart=/usr/local/mysql/bin/mysqld --defaults-file=/etc/my.cnf
LimitNOFILE = 5000

systemctl daemon-reload
systemctl start mysqld
netstat -lnt

设置密码
mysqladmin -uroot  password '123'

登陆验证
mysql -uroot -p123 

保证三台服务器都完整安装MySQL

建立时间同步环境

在主节点上搭建时间同步服务器

安装NTP(关闭防火墙/selinux)
yum -y install ntp

配置NTP
vim /etc/ntp.conf 

# local clock
server 127.127.1.0		# 本地时间供给源
fudge  127.127.1.0 stratum 8	# 设置时区为+08区

重启服务并设置为开机启动
systemctl enable ntpd --now

在从节点上进行时间同步
yum -y install ntpdate
ntpdate 192.168.188.65

在这里插入图片描述
将时间误差缩小到0.00以下就行

配置主从复制

主节点配置

修改主节点配置
vim /etc/my.cnf

server_id = 1		# 服务器编号
log_bin = master-bin	# 开启二进制日志
log-slave-updates = true	# 开启从机复制

重启mysqld
systemctl restart mysqld
进入mysql查看二进制日志是否开启
show variables like 'log_bin';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| log_bin       | ON    |
+---------------+-------+
1 row in set (0.00 sec)

给服务器授权
GRANT REPLICATION SLAVE ON *.* TO 'slave'@'192.168.188.%' IDENTIFIED BY '123';
刷新权限
FLUSH PRIVILEGES;
获取日志名及偏移量
show master status;

从节点配置

修改从节点配置
vim /etc/my.cnf
server_id = 2		# 每个服务器编号不一样
relay-log=relay-log-bin		# 开启中继日志
relay-log-index=slave-relay-bin.index	# 开启索引记录

重启mysqld
systemctl restart mysqld
在从服务器上配置同步
change master to master_host='192.168.188.65',master_user='slave',master_password='123',master_log_file='maste
r-bin.000001',master_log_pos=604;	--这个数字就是在主服务器上 show master status; 查出来的

开启同步(stop slave是停止)
start slave;

备注;  解决UUID重复的问题:
mv /usr/local/mysql/data/auto.cnf /usr/local/mysql/data/auto.cnf.bak

数据库应用——MySQL主从复制和Atlas读写分离_第3张图片

验证

进入主MySQL
show slave hosts;

数据库应用——MySQL主从复制和Atlas读写分离_第4张图片

新建一个测试库school
CREATE DATABASE IF NOT EXISTS `school`;
-- 创建一个school数据库
USE `school`;-- 创建学生表
DROP TABLE IF EXISTS `student`;
CREATE TABLE `student`(
	`studentno` INT(4) NOT NULL COMMENT '学号',
    `loginpwd` VARCHAR(20) DEFAULT NULL,
    `studentname` VARCHAR(20) DEFAULT NULL COMMENT '学生姓名',
    `gender` varchar(2) NOT NULL DEFAULT '女' COMMENT '性别',
    `gradeid` INT(11) DEFAULT NULL COMMENT '年级编号',
    `phone` VARCHAR(50) NOT NULL COMMENT '联系电话,允许为空',
    `address` VARCHAR(255) NOT NULL COMMENT '地址,允许为空',
    `borndate` DATETIME DEFAULT NULL COMMENT '出生时间',
    `email` VARCHAR (50) NOT NULL COMMENT '邮箱账号允许为空',
    `identitycard` VARCHAR(18) DEFAULT NULL COMMENT '身份证号',
    PRIMARY KEY (`studentno`),
    UNIQUE KEY `identitycard`(`identitycard`),
    KEY `email` (`email`)
)ENGINE=MYISAM DEFAULT CHARSET=utf8;

INSERT INTO `student` (`studentno`,`loginpwd`,`studentname`,`gender`,`gradeid`,`phone`,`address`,`borndate`,`email`,`identitycard`)
VALUES
(1000,'123456','唐嘉','女',2,'13800001234','北京朝阳','1980-5-2','[email protected]','123456198001011298'),
(1001,'123456','刘美玲','女',1,'13800002222','广东深圳','1991-6-4','[email protected]','123456199001011191'),
(1002,'123456','潘辰','男',1,'13800002111','四川成都','1992-7-6','[email protected]','123456199001011333'),
(1003,'123456','小田','男',2,'13800002333','四川成都','1993-8-8','[email protected]','123456199001011555'),
(1004,'123456','胡杨','男',3,'13800002555','浙江杭州','1994-9-10','[email protected]','123456199001011777'),
(1005,'123456','猫猫','女',2,'13800002666','日本东京','1995-1-12','[email protected]','123456199001011888'),
(1006,'123456','飞飞','男',2,'13800002666','上海浦东','1997-7-12','[email protected]','123456199001011666');

在从机上查看
数据库应用——MySQL主从复制和Atlas读写分离_第5张图片

MySQL读写分离

MySQL读写分离原理

只在主服务器上写,只在从服务器上读
基本原理是让主数据库处理事务性查询,而从数据库处理select查询

  • 实现方式
  1. 程序代码实现
  2. 基于中间代理层实现

Atlas的简介

Atlas是由 Qihoo 360公司Web平台部基础架构团队开发维护的一个基于MySQL协议的数据中间层项目。
主要功能:

  1. 读写分离

  2. 从库负载均衡

  3. IP过滤

  4. 自动分表

  5. DBA可平滑上下线DB

  6. 自动摘除宕机的DB

Atlas相对于官方MySQL-Proxy的优势

  1. 将主流程中所有Lua代码用C重写,Lua仅用于管理接口

  2. 重写网络模型、线程模型

  3. 实现了真正意义上的连接池

  4. 优化了锁机制,性能提高数十倍

主机 ip
主MySQL服务器 192.168.188.65
从MySQL服务器1 192.168.188.66
从MySQL服务器2 192.168.188.67
从MySQL服务器3 192.168.188.69
Atlas 中间代理服务器 192.168.188.68

安装并配置Atlas

rpm -ivh https://github.com/Qihoo360/Atlas/releases/download/2.2.1/Atlas-2.2.1.el6.x86_64.rpm

补充:
安装后,它会默认在”/usr/local/mysql-proxy”下生成4个文件夹,以及需要配置的文件

bin目录下放的都是可执行文件

  1. “encrypt”是用来生成MySQL密码加密的,在配置的时候会用到
  2. “mysql-proxy”是MySQL自己的读写分离代理
  3. “mysql-proxyd”是360的,后面有个“d”,服务的启动、重启、停止。都是用他来执行的

conf目录下放的是配置文件

  • “test.cnf”只有一个文件,用来配置代理的,可以使用vim来编辑

lib目录下放的是一些包,以及Atlas的依赖
log目录下放的是日志,如报错等错误信息的记录

配置读写分离

配置master,slave1,slave2,slave3中开放权限给atlas:
grant all on *.* to mao@'192.168.188.%' identified by '123';
flush privileges;
加密用户名密码                                                                                      
进入bin目录,使用encrypt来对数据库的密码进行加密,我的MySQL数据的用户名是mao,密码是123,我需要对密码进行加密
cd /usr/local/mysql-proxy/bin
./encrypt 123
3yb5jEku5h4=	# 加密的字符就是写在配置文件里的
编辑test.cnf配置文件
vim /usr/local/mysql-proxy/conf/test.cnf

[mysql-proxy]

#带#号的为非必需的配置项目
admin-username = atlas	# 自定义

#管理接口的密码
admin-password = 123

#Atlas后端连接的MySQL主库的IP和端口,可设置多项,用逗号分隔
proxy-backend-addresses = 192.168.188.65:3306

#Atlas后端连接的MySQL从库的IP和端口,@后面的数字代表权重,用来作负载均衡,若省略则默认为1,可设置多项,用逗号分隔
#proxy-read-only-backend-addresses = 127.0.0.1:3305@1
proxy-read-only-backend-addresses = 192.168.188.66:3306@1,192.168.188.67:3306@1,192.168.188.69:3306@1

#用户名与其对应的加密过的MySQL密码,密码使用PREFIX/bin目录下的加密程序encrypt加密
pwds = mao:3yb5jEku5h4=

# 守护进程
daemon = true

keepalive = true

#工作线程数,对Atlas的性能有很大影响,可根据情况适当设置
event-threads = 4

#日志级别,分为message、warning、critical、error、debug五个级别
log-level = message

#日志存放的路径
log-path = /usr/local/mysql-proxy/log

#sql-log = OFF

#慢日志输出设置。当设置了该参数时,则日志只输出执行时间超过sql-log-slow(单位:ms)的日志记录。不设置该参数则输出全部日志。
#sql-log-slow = 10

#实例名称,用于同一台机器上多个Atlas实例间的区分
#instance = test

#Atlas监听的工作接口IP和端口
proxy-address = 0.0.0.0:1234

#Atlas监听的管理接口IP和端口
admin-address = 0.0.0.0:2345

#分表设置,此例中person为库名,mt为表名,id为分表字段,3为子表数量,可设置多项,以逗号分隔,若不分表则不需要设置该项
#tables = person.mt.id.3

#默认字符集,设置该项后客户端不再需要执行SET NAMES语句
#charset = utf8

#允许连接Atlas的客户端的IP,可以是精确IP,也可以是IP段,以逗号分隔,若不设置该项则允许所有IP连接,否则只允许列表中的IP连接
#client-ips = 127.0.0.1, 192.168.1

#Atlas前面挂接的LVS的物理网卡的IP(注意不是虚IP),若有LVS且设置了client-ips则此项必须设置,否则可以不设置
#lvs-ips = 192.168.1.1

配置无误后,启动Atlas软件

/usr/local/mysql-proxy/bin/mysql-proxyd test start

测试

在Atlas 代理服务器上

yum -y install mysql

mysql -h127.0.0.1 -P2345 -uatlas -p123	# 这里用户和密码就是配置文件里面写的

select * from help;		# 可以查看帮助

select * from backends;		# 查看目前的主从复制

数据库应用——MySQL主从复制和Atlas读写分离_第6张图片

通过代理访问Mysql
mysql -h192.168.188.68 -P1234  -umao -p123	# 这里用户名和密码就是之前授权的账号

进入数据库后可以查询到主MySQL的所有库和表
select * from school.student;

在MASTER/测试机上创建一个库和表

CREATE DATABASE IF NOT EXISTS `test`;
create table student (
    -> id int(4) not null auto_increment comment '学号',
    -> name varchar(30) default null comment '姓名',
    -> gender varchar(2) not null default '女' comment '性别',
    -> primary key (id)
    -> )
    -> engine=innodb default charset=utf8;


分别在两台从服务器上停止复制。
stop slave;

在主服务器上,插入数据
insert into student (id,name,gender)
    -> values
    -> (1,'猫猫','女');

在从服务器1上,手动插入一条内容
insert into student (id,name,gender)
values (2,'猪猪','男');

在从服务器2上,手动插入一条内容
insert into student (id,name,gender)
values (3,'牛牛','男');

在从服务器3上,手动插入一条内容
insert into student (id,name,gender)
    -> values (4,'小宋','女');

测试读操作

在测试机上第一次查询结果	`
在测试机上第二次查询结果
在测试机上第三次查询结果
在Atlas主机上插入一条语句:
insert into student (id,name,gender)
values (5,'小田','男');


在Atlas上查询不到,最终只有在MASTER上才能看到这条语句内容,说明写操作只能在Master上。
由此验证:已经实现了MYSQL读写分离,目前所有的写操作都在MASTER主服务器上,用来避免数据的不同步,所有的读操作都分摊给了slave从服务器,用来分担数据库压力。

你可能感兴趣的:(MySQL,数据库,mysql,主从复制,读写分离,atlas)