MySQL-day12-Atlas配置读写分离
文章目录
MySQL读写分离
一、读写分离简介
1.1常见高并发场景
随着一个网站的业务不断扩展,数据不断增加,数据库的压力也会越来越大,对数据库或者SQL的基本优化可能达不到最终的效果,此时可以考虑通过添加数据库节点来使其达到提升性能的目的通常有以下常见几种方案!
-
读写分离
打开一个帖子内容页,需要select帖子表,和帖子评论表,每个耗时10ms的话。每秒1000次查询就是这个数据库的极限了。也就是说,这个论坛只能承载每秒500次访问。那么我们就可以对这个数据库做读写分离,来成倍提高数据库的读性能。 -
水平分表
交易历史,这种表。因为很少查询1年前的信息。所以,我们可以按年份来进行水平分表。将今年的表优先对待。就减少了要查询的表的大小。 -
分库
如果我们的系统非常大了,功能非常多,就会有很多类型的数据库表,例如营销活动的表,和用户账号的表是没有关联的,那么我们就可以将他们分到两个数据库中,然后放到不同的独立的数据库服务器,就能使数据库吞吐量成倍增加。 -
垂直分表
- 典型的应用场景是在文章列表这样的场景,一般来讲,我们的文章表会有title、userId、Content等字段,其中的Content字段一般是Text或者LongText类型,而其它的字段都是固定长度的数据类型。我们知道一个数据库优化规则是:
- 如果一个表的所有字段都是固定长度类型的,那么它就是定长表,定长表比动态长度表查询性能要高
那么,我们就可以使用垂直分表来将文章表分成文章表和文章内容表。于是文章列表页面所需的查询,就只需要查询一张定长表了。
- 如果一个表的所有字段都是固定长度类型的,那么它就是定长表,定长表比动态长度表查询性能要高
- 典型的应用场景是在文章列表这样的场景,一般来讲,我们的文章表会有title、userId、Content等字段,其中的Content字段一般是Text或者LongText类型,而其它的字段都是固定长度的数据类型。我们知道一个数据库优化规则是:
-
引入Cache
通常来说即使前者的数据库架构做得再好,对于定时抢购/抽奖/等,这种类似高密度密集访问的场景也是力不从心,最好的方法还是在服务层和数据库层添加一个缓存层用,使其让请求命中至缓存层,数据层只持久化变更的数据即可。
1.2 读写分离原理
- 只在主服务器上写
- 只在从服务器上读
MySQL的主从复制和MySQL的读写分离两者有着紧密联系,首先部署主从复制,只有主从复制完了,才能在此基础上进行数据的读写分离。简单来说,读写分离就是只在主服务器上写,只在从服务器上读,基本的原理是让主数据库处理事务性查询,而从数据库处理select查询。当业务量非常大时,一台服务器的性能无法满足需求,就可以通过配置主从复制实现写分离来分摊负载,避免因负载太高而造成无法及时响应请求。
1.3 读写分离类型
- 基于程序代码内部实现
- 在代码中根据select,insert进行路由分类,这类方法也是目前生产环境应用最广泛的,优点是性能好,因为在程序代码中已经将读写的数据源拆分至两个,所以不需要额外的MySQL proxy解析SQL报文,在进行路由至不同数据库节点。缺点是通常该架构较复杂,运维成本相对较高。
- 基于中间代理层实现
- 代理层一般位于客户端和服务器之间,代理服务器接到客户端请求后通过解析SQL文本再将SQL路由至可用的数据库节点中。优点是程序不需要改造可以实现无缝迁移,可移植性较好。缺点是性能相对前者略微逊色一些,并且并不是所有的读操作都能够被路由至从节点中。
二、Atlas读写分离
环境说明:
主机 | IP | 角色 |
---|---|---|
db01 | 10.0.0.51 | mysql主库,atlas |
db02 | 10.0.0.52 | mysql从库 |
db03 | 10.0.0.53 | mysql从库 |
2.1 Atlas简介
- Atlas是360团队弄出来的一套基于MySQL-Proxy基础之上的代理,修改了MySQL-Proxy的一些BUG,并且优化了很多东西。而且安装方便。配置的注释写的蛮详细的,都是中文。英文不好的同学有福了。
2.2 Atlas主要功能
- 主要功能:
- 读写分离
- 从库负载均衡
- IP过滤
- 自动分表
- DBA可平滑上下线DB
- 自动摘除宕机的DB
Atlas相对于官方MySQL-Proxy的优势
- 1.将主流程中所有Lua代码用C重写,Lua仅用于管理接口
- 2.重写网络模型、线程模型
- 3.实现了真正意义上的连接池
- 4.优化了锁机制,性能提高数十倍
2.3 Atlas主要架构
Atlas是一个位于应用程序与MySQL之间中间件。在后端DB看来,Atlas相当于连接它的客户端,在前端应用看来,Atlas相当于一个DB。Atlas作为服务端与应用程序通讯,它实现了MySQL的客户端和服务端协议,同时作为客户端与MySQL通讯。它对应用程序屏蔽了DB的细节,同时为了降低MySQL负担,它还维护了连接池。
2.4 准备主从环境
2.5 Atlas安装
1.下载软件包
[root@localhost packages] wget https://github.com/Qihoo360/Atlas/releases/download/2.2.1/Atlas-2.2.1.el6.x86_64.rpm
2.将软件包上传至服务器
[root@localhost packages] rz
3.使用YUM方式进行安装
[root@localhost packages] rpm -ivh Atlas-sharding_1.0.1-el6.x86_64.rpm
#安装完成后atlas的安装目录为/usr/local/mysql-proxy
2.6 授权Atlas管理账号
#授权atlas管理账号,主从数据库服务器都需要授权,需授权账号地址如下:
mysql> grant all privileges on *.* to atlas@'10.0.0.%' identified by 'atlas';
#制作密码,将生成的加密密码写入以下配置文件内
[root@db01 conf]# /usr/local/mysql-proxy/bin/encrypt atlas
KsWNCR6qyNk=
2.7 修改test配置文件
对应修改配置参数:
[root@db01 mysql-proxy]# vim /usr/local/mysql-proxy/conf/test.cnf
[mysql-proxy]
#管理接口的用户名,指定也行,默认也行
admin-username = admin
#管理接口的密码,指定也行,默认也行
admin-password = admin
#Atlas后端连接的MySQL主库的IP和端口,可设置多项,用逗号分隔
proxy-backend-addresses = 10.0.0.51:3306
#Atlas后端连接的MySQL从库的IP和端口
proxy-read-only-backend-addresses = 10.0.0.52:3306,10.0.0.53:3306
#用户名与其对应的加密过的MySQL密码,需改密码后指定到此
pwds = slave:KyaJUrNF4Pw=
#设置Atlas的运行方式,true为守护进程方式,false时为前台方式,一般开发调试时设为false,线上运行时设为true,true后面不能有空格
daemon = true
#设为true时Atlas会启动两个进程,一个为monitor,一个为worker,monitor在worker意外退出后会自动将其重启
keepalive = true
#工作线程数,对Atlas的性能有很大影响,可根据情况适当设置
event-threads = 8
#日志级别,分为message、warning、critical、error、debug五个级别
log-level = message
#日志存放的路径
log-path = /usr/local/mysql-proxy/log
#SQL日志的开关
sql-log = ON
#Atlas监听的工作接口IP和端口
proxy-address = 0.0.0.0:1234
#Atlas监听的管理接口IP和端口
admin-address = 0.0.0.0:2345
#默认字符集,设置该项后客户端不再需要执行SET NAMES语句
charset = utf8
2.8 服务管理命令
1.服务启动命令
[root@db01 ~]# /usr/local/mysql-proxy/bin/mysql-proxyd test start
2.服务停止命令
[root@db01 ~]# /usr/local/mysql-proxy/bin/mysql-proxyd test stop
3.加密密码生成方式
[root@db01 ~]# /usr/local/mysql-proxy/bin/encrypt atlas
KsWNCR6qyNk=
# atlas为数据库主从授权的密码
2.9检查启动
1.用ps命令检查启动
[root@db01 mysql-proxy]# ps -ef|grep test
root 8892 1 0 16:46 ? 00:00:00 /usr/local/mysql-proxy/bin/mysql-proxy --defaults-file=/usr/local/mysql-proxy/conftest.cnf
root 8893 8892 0 16:46 ? 00:00:06 /usr/local/mysql-proxy/bin/mysql-proxy --defaults-file=/usr/local/mysql-proxy/conftest.cnf
root 20421 1780 0 20:06 pts/0 00:00:00 grep --color=auto test
2.用netstat命令检查启动
[root@db01 mysql-proxy]# netstat -lntp | grep proxy
tcp 0 0 0.0.0.0:2345 0.0.0.0:* LISTEN 8893/mysql-proxy
tcp 0 0 0.0.0.0:1234 0.0.0.0:* LISTEN 8893/mysql-proxy
2.10 Atlas管理界面
1.用altas管理的用户登入 # 配置文件内指定的用户与密码
[root@db01 ~]# mysql -h10.0.0.51 -P2345 -uadmin -padmin
- admin为test配置文件管理账号
- 2345为Atlas监听的管理接口IP和端口
2.查看可用命令帮助
[root@db01 ~]# mysql> select * from help;
+---------------------------------------+---------------------------------------------------------+
| command | description |
+---------------------------------------+---------------------------------------------------------+
| SELECT * FROM help | shows this help |
| SELECT * FROM backends | lists the backends and their state |
| SET OFFLINE $backend_id | offline backend server, $backend_id is backend_ndx's id |
| SET ONLINE $backend_id | online backend server, ... |
| ADD MASTER $backend | example: "add master 127.0.0.1:3306", ... |
| ADD SLAVE $backend | example: "add slave 127.0.0.1:3306", ... |
| ADD GMASTER $group_id $backend | example: "add gmaster 1 127.0.0.1:3306", ... |
| ADD GSLAVE $group_id $backend | example: "add gslave 1 127.0.0.1:3306", ... |
| REMOVE BACKEND $backend_id | example: "remove backend 1", ... |
| REMOVE GBACKEND $group_id $backend_id | example: "remove gbackend 1 1", ... |
| SELECT * FROM clients | lists the clients |
| ADD CLIENT $client | example: "add client 192.168.1.2", ... |
| REMOVE CLIENT $client | example: "remove client 192.168.1.2", ... |
| SELECT * FROM pwds | lists the pwds |
| ADD PWD $pwd | example: "add pwd user:raw_password", ... |
| ADD ENPWD $pwd | example: "add enpwd user:encrypted_password", ... |
| REMOVE PWD $pwd | example: "remove pwd user", ... |
| SAVE CONFIG | save the backends to config file |
| SELECT VERSION | display the version of Atlas |
+---------------------------------------+---------------------------------------------------------+
19 rows in set (0.00 sec)
3.查询后端代理的库
[root@db01 ~]# mysql> select * from backends;
+----------+----------------+-------+------+-------------+
| group_id | address | state | type | backend_ndx |
+----------+----------------+-------+------+-------------+
| -1 | 10.0.0.51:3306 | up | rw | 1 |
| -1 | 10.0.0.52:3306 | up | ro | 2 |
| -1 | 10.0.0.53:3306 | up | ro | 3 |
+----------+----------------+-------+------+-------------+
3 rows in set (0.00 sec)
4.测试平滑摘除某一个库
mysql> remove backend 2;
Empty set (0.00 sec)
# 查看
mysql> select * from backends;
+----------+----------------+-------+------+-------------+
| group_id | address | state | type | backend_ndx |
+----------+----------------+-------+------+-------------+
| -1 | 10.0.0.51:3306 | up | rw | 1 |
| -1 | 10.0.0.53:3306 | up | ro | 2 |
+----------+----------------+-------+------+-------------+
2 rows in set (0.00 sec)
# 提交保存
mysql> save config;
Empty set (0.01 sec)
5.测试平滑添加某一个库
mysql> add slave 10.0.0.52:3306;
# 查看
mysql> select * from backends;
+----------+----------------+-------+------+-------------+
| group_id | address | state | type | backend_ndx |
+----------+----------------+-------+------+-------------+
| -1 | 10.0.0.51:3306 | up | rw | 1 |
| -1 | 10.0.0.53:3306 | up | ro | 2 |
| -1 | 10.0.0.52:3306 | up | ro | 3 |
+----------+----------------+-------+------+-------------+
3 rows in set (0.00 sec)
# 提交保存
mysql> save config;
Empty set (0.01 sec)
2.11 Atlas工作界面
[root@db01 mysql-proxy]# mysql -h 192.168.100.112 -P1234 -uatlas -patlas
mysql> show databases;
mysql> select user,host from mysql.user;
2.12 读写分离测试
#读请求测试
[root@db01 mysql-proxy]# mysql -h 192.168.100.112 -P1234 -uatlas -patlas
mysql> select @@server_id;
#也可在数据库主库或从库查看select查询情况
mysql -uroot -p123
mysql> show global status like '%select%';
#写请求测试
#在数据库主库和从库查看insert情况,将从库同步延时设置为180秒
mysql> stop slave;
mysql> change master to master_delay=180;
mysql> start slave;
mysql> show global status like '%insert%';