Mysql读写分离——主从数据库+Atlas

mysql集群
最近在参加项目开发微信小程序后台,由于用户数量巨大,且后台程序并不是很完美,所以对用户的体验很是不友好(简单说就是很卡)。赶巧最近正在翻阅《大型网站系统与Java中间件实践》。
所以,先是使用Docker swarm构建了负载均衡集群,然后使用Atlas做了数据库的读写分离,尽可能对用户进行分流,降低对单机服务器的负载,提高访问体验。本片随笔仅对数据库的读写分离部分进行介绍。

目标:实现mysql数据库集群,一个主节点负责写入数据,多个从节点负责读取数据

实验环境
服务器:

阿里云服务器:centos7(10.0.0.1)
腾讯云服务器:ubuntu:16.04(10.0.0.2)
京东云服务器:ubuntu:16.04 (10.0.0.3)
mysql:5.7

docker:18.03

实现方案
mysql 主从数据库 + Atlas读写分离

步骤:
进入Master服务器进行配置
使用Docker,在服务器上创建MySQL服务
docker run -p 3306:3306 --name mysql3306 -v /opt/mysql/data/data3306:/var/lib/mysql -v /opt/mysql/logs/logs3306:/logs -e MYSQL_ROOT_PASSWORD=hello -d mysql:5.7
进Master服务器的MySQL数据库中,创建用户"niwoo"设置密码为"hello"
mysql -h 127.0.0.1 -uroot -phello

mysql> grant all on . to ninwoo@'127.0.0.1' identified by "hello";
Query OK, 0 rows affected, 1 warning (0.00 sec)
修改niwoo的访问权限
mysql> use mysql
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> update user set host = '%' where user = 'ninwoo';
Query OK, 0 rows affected (0.00 sec)
Rows matched: 0 Changed: 0 Warnings: 0
确认是否修改成功
mysql> update user set host = '%' where user = 'ninwoo';
Query OK, 1 row affected (0.02 sec)
Rows matched: 1 Changed: 1 Warnings: 0

mysql> select user, host from user;
+---------------+-----------+
| user | host |
+---------------+-----------+
| ninwoo | % |
| root | % |
| mysql.session | localhost |
| mysql.sys | localhost |
| root | localhost |
+---------------+-----------+
5 rows in set (0.00 sec)
更新数据库,是配置生效
mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)
Master,Slave1的MySQL数据库上创建CampusHire数据库

进入Slave1执行相同1,2,3,4操作
配置主从数据库连接
进入Master服务器进行配置

进入mysql容器内部,修改配置文件
docker exec -it mysql3306 bash
默认没有vim,无法修改文件

更新软件源

apt update

安装vim

apt install vim
修改mysql配置文件
vim /etc/mysql/mysql.conf.d/mysqld.cnf
添加如下配置

主从复制配置

innodb_flush_log_at_trx_commit=1
sync_binlog=1

需要备份的数据库

binlog-do-db=test

不需要备份的数据库

binlog-ignore-db=mysql

启动二进制文件

log-bin=mysql-bin

服务器ID

server-id=1
退出容器,重启docker应用
docker restart mysql3306
进入数据库,配置主从复制的权限
mysql -h 127.0.0.1 -uroot -phello
mysql> grant replication slave on . to 'ninwoo'@'127.0.0.1' identified by 'hello';
Query OK, 0 rows affected, 1 warning (0.01 sec)
锁定数据库
mysql> flush tables with read lock;
Query OK, 0 rows affected (0.00 sec)
查看主数据库信息,记住下面的“File”与“Position”的信息
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000001 | 439 | CampusHire | mysql | |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
进入slave服务器,进入mysql容器内部

更新软件源

apt update

安装vim

apt install vim
修改从数据库的配置文件
vim /etc/mysql/mysql.conf.d/mysqld.cnf
添加server-id=2

重启Slave数据库
docker restart mysql3306
进入数据库,输入刚刚记录下来的File和Position
MySQL [(none)]> change master to master_host='10.0.0.1',
->
-> master_user='ninwoo',
-> master_password='hello',
-> master_port=3306,
-> master_log_file='mysql-bin.000001',
-> master_log_pos=439,
-> master_connect_retry=10;
启动Slave进程
mysql> start slave;
Query OK, 0 rows affected (0.00 sec)
查看复制状态
mysql> show slave status \G;
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 139.199.194.49
Master_User: ninwoo
Master_Port: 3306
Connect_Retry: 10
Master_Log_File: mysql-bin.000001
Read_Master_Log_Pos: 439
Relay_Log_File: 2a8a4abdcf68-relay-bin.000002
Relay_Log_Pos: 320
Relay_Master_Log_File: mysql-bin.000001
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 439
Relay_Log_Space: 534
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 0
Last_SQL_Error:
Replicate_Ignore_Server_Ids:
Master_Server_Id: 1
Master_UUID: 4a0187fa-b0a5-11e8-a7e7-0242ac110003
Master_Info_File: /var/lib/mysql/master.info
SQL_Delay: 0
SQL_Remaining_Delay: NULL
Slave_SQL_Running_State: Slave has read all relay log; waiting for more up dates
Master_Retry_Count: 86400
Master_Bind:
Last_IO_Error_Timestamp:
Last_SQL_Error_Timestamp:
Master_SSL_Crl:
Master_SSL_Crlpath:
Retrieved_Gtid_Set:
Executed_Gtid_Set:
Auto_Position: 0
Replicate_Rewrite_DB:
Channel_Name:
Master_TLS_Version:
1 row in set (0.00 sec)
到这里主从数据的配置就已经完成,在向主库写入数据的同时,将在从库进行自动的备份。但在实际测试中遇到了配置完成之后无法向主数据库写入的问题,初步
判断是由于主库加锁而未解锁的问题,所以这里采用比较暴力的方法,重启主数据库容器。

master节点

docker restart mysql3306
配置Atlas
Atlas是有360团队优化mysqlproxy而衍生出的版本,性能更好更稳定。

Atlas有两个版本,这里我选择普通版本,即不分表。

在阿里云主机(centos7)上进行一下安装步骤:

下载安装
[root@localhost ~]# cd /home/
[root@localhost home]# wget https://github.com/Qihoo360/Atlas/releases/download/2.2.1/Atlas-2.2.1.el6.x86_64.rpm
安装
[root@localhost home]# rpm -ivh Atlas-2.2.1.el6.x86_64.rpm
安装目录位于/usr/local/mysql-proxy/

使用安装目录下的bin/encrypt程序加密数据库密码
[root@localhost bin]# ./encrypt hello
配置Atlas
[root@localhost conf]# cd /usr/local/mysql-proxy/conf/
[root@localhost conf]# vim test.cnf
修改以下配置:

管理接口的用户名

admin-username = user

管理接口的密码

admin-password = pwd

...

Atlas后端连接的MySQL主库的IP和端口,可设置多项,用逗号分隔

proxy-backend-addresses = 10.0.0.1:3306

Atlas后端连接的MySQL从库的IP和端口,@后面的数字代表权重,用来作负载均衡,若省略则默认为1,可设置多项,用逗号分隔

proxy-read-only-backend-addresses = 10.0.0.2:3306@1

...

用户名与其对应的加密过的MySQL密码,密码使用PREFIX/bin目录下的加密程序encrypt加密,下行的user1和user2为示例,将其替换为你的MySQL的用户名和加密密码!

pwds = buck:RePBqJ+5gI4=

...

Atlas监听的工作接口IP和端口

proxy-address = 0.0.0.0:1234

Atlas监听的管理接口IP和端口

admin-address = 0.0.0.0:2345
读者需要根据自己的实际情况修改以上配置

启动Atlas
[root@localhost bin]# /etc/init.d/mysqld status
OK: MySQL-Proxy of test is started
使用mysql命令连接数据库
其中2345端口是管理端口,用户可以在该管理数据库中修改数据库代理服务器的相关配置

[root@localhost bin]# mysql -h127.0.0.1 -P2345 -uuser -ppwd
其中1234端口是数据库代理服务器的端口,用户可以直接访问该端口进行数据库的访问和更新

[root@localhost bin]# mysql -h127.0.0.1 -P1234 -ubuck -phello
使用软件连接Atlas数据库代理服务器
这里发现,之前使用的mysql workbench无法正常使用,更换Navicat可以正常使用。

使用jdbc连接数据库
使用方法与普通数据库一样。

后记
到这里,配置就已经全部完成。有心的读者或者已经发现,还有一台服务器未使用,这台服务器将在以后接入到现有的mysql数据库集群当中,充当新的slave节点。该实验将在以后补上。

理论上说,我所做的这些或许会对负载过大的问题有所解决。但最近并未出现太高的访问现象,所以短期也没有看到效果。具体效果,将在实际场景中验证后补充上,敬请期待。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,519评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,842评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,544评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,742评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,646评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,027评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,513评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,169评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,324评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,268评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,299评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,996评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,591评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,667评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,911评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,288评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,871评论 2 341

推荐阅读更多精彩内容