实战
核心原则
分而治之
背景说明
随着业务量的上涨,既是好事也是坏事.好事是业务开始发育,毕竟我们做了很多拉新,培育市场的工作.坏事就是对于系统接口响应时间的挑战.必须要解决随着数据量起来带来计算耗时问题.基于目前的架构,我们必须要让数据库集群搭建来分摊计算任务.同时,业务架构也要做好分离和调整。我们的后台业务架构是微服务架构,所以并不需要做垂直切分,天然分库.所以,只需要对业务代码做好读写分离工作即可
实战操作
数据库集群搭建
演示环境说明
该环境只是为了向大家说明数据库集群搭建流程,所以采用docker容器部署.生产环境基本上不会这样干.同时,每家的数据库部署都不一样,如果是云数据库就舒服很多了,如果是本地部署居多的话,建议是老盘迁移新盘来做比较好.具体问题具体分析具体处理吧
部署步骤说明
- docker拉取mysql镜像
docker pull mysql:5.7
- mysql数据卷创建
cd /data
#### 创建主数据库
mkdir mysql-master
cd mysql-master
mkdir data
mkdir logs
mkdir conf
#### 创建从数据库
mkdir mysql-slave
mkdir data
mkdir logs
mkdir conf
- mysql配置文件创建
vim my.cnf
my.cnf配置明细,从数据库一定要关了log-bin,因为从只要同步,没有写入的资格
[mysql]
#mysql以socket方式运行时的sock文件路径
socket=/var/lib/mysql/mysqld.sock
[mysqld]
#lower_case_table_names=0,表示区分大小写,创建的库表会原样大小写保存在磁盘上
#lower_case_table_names=1,表示不区分大小写,创建库表时MySQL会将所有的库表名转换成小写字母保存在磁盘上
#,且SQL语句中涉及到库表无论写成大写或者小写,都会被转化成小写进行查询和写入
lower_case_table_names=1
#mysql运行的端口
port=3306
#mysql5.7以后的不兼容问题处理
sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
#打开log-bin日志
log-bin=mysql-bin
#存放数据的路径
datadir=/var/lib/mysql
#mysql以socket方式运行时的sock文件路径
socket=/var/lib/mysql/mysqld.sock
#是否支持符号连接,即数据库或表能够存储在my.cnf
#中指定datadir以外的分区或目录,为0不开启
symbolic-links=0
#mysql服务器分配的ID,在启用主从和集群的时候必须指定,并且不能重复
server-id = 1
#要给从机同步的库
#binlog-do-db=hl
#不给从机同步的库(这里不同步mysql、information_schema、performance_schema、sys库)
#binlog-ignore-db=mysql
#binlog-ignore-db=information_schema
#binlog-ignore-db=performance_schema
#binlog-ignore-db=sys
#mysql允许最大连接数
max_connections=2000
#默认字符集
character-set-server=utf8
#默认存储引擎
default-storage-engine=INNODB
#mysql最大接受的数据包大小
max_allowed_packet=16M
#日志自动过时清理天数
expire_logs_days = 90
# 事务等待获取资源等待的最长时间,超过这个时间还未分配到资源则会返回应用失败;参数的时间单位是秒
innodb_lock_wait_timeout=120
#设置时区
default-time_zone='+8:00'
[mysqld_safe]
#进程ID文件
pid-file=/data/var/mysql/mysqld.pid
#错误日志纪录位置
log-error=/var/log/mysqld.log
- 启动mysql集群服务
docker run -p 3301:3306 --name mysql-master -e MYSQL_ROOT_PASSWORD=123456 -v /etc/localtime:/etc/localtime -v /data/mysql-master/conf/my.cnf:/etc/mysql/mysql.conf.d/mysqld.cnf -d mysql:5.7
docker run -p 3302:3306 --name mysql-slave -e MYSQL_ROOT_PASSWORD=123456 -v /etc/localtime:/etc/localtime -v /data/mysql-slave01/conf/my.cnf:/etc/mysql/mysql.conf.d/mysqld.cnf -d mysql:5.7
docker run -p 3303:3306 --name mysql-slave2 -e MYSQL_ROOT_PASSWORD=123456 -v /etc/localtime:/etc/localtime -v /data/mysql-slave02/conf/my.cnf:/etc/mysql/mysql.conf.d/mysqld.cnf -d mysql:5.7
5. 主数据库创建用户用于同步
## 进入容器内部
docker exec -it 4512
## 进入mysql命令行
mysql -uroot -proot
## 创建用户
CREATE USER 'slave'@'%' IDENTIFIED BY 'root';
GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'slave'@'%';
FLUSH PRIVILEGES;
- 主数据库数据节点同步 这一步对于主从来说就是最关键的,cv的时候一定要检查有没有空格这种小问题哦
SHOW MASTER STATUS;
- 从数据库同步
## 进入容器内部
docker exec -it 962x
## 连接mysql
mysql -uroot -proot
## 进行同步
CHANGE MASTER TO master_host = '172.17.0.39',master_user = 'slave',master_password = 'root',master_port = 3306,master_log_file = 'mysql-bin.000003',master_log_pos=9720,master_connect_retry = 30;
## 启动从功能
START SLAVE
## 查看当前状态,主要是看master_log_file的数据节点
SHOW SLAVE STATUS\G;
-
同步情况
-
搭建过程问题总结
主从库同步异常
CHANGE MASTER TO MASTER_LOG_FILE='log-bin.000013',MASTER_LOG_POS=154;
业务服务群架构调整
业务服务群的调整,核心是分库,这一步能让系统稳定性有保障,而不会一嘎全部都嘎.最简单的思考出发点,将核心订单业务如果独立成库,那么我们其他服务是不是就不会被这个巨大计算量拖累. 同时这一步分库做完,也有利于我们后期的扩容,如果分表打下基础,同时也可以混合技术来处理,可以参考单表爆炸文章
案例
业务代码改造和这个案例大差不差的,格外注意的一点是我们必须要管控好事务,格外提出来的点是业务选择的事务级别,是本地事务还是分布式事务(XA,TCC...)
落地总结
读写分离感受
采用读写分离是因为目前业务在70%的写入场景都是选择异步写入的方式,一定程度上减轻写库的压力.同时,在系统负载情况以及慢sql,埋点分析来看,读的压力大部分都是处于大页读取居多.增加了3个从库之后,确实我们页面响应速度都是翻倍
ShardingSphere感受
ShardingSphere-jdbc是符合当前业务形态的,接入简易一个下午就完成接入.分布式事务的情况下,也是无缝对接,挺爽的.
参考内容
求文推荐
觉得文章对你有帮助,记得点赞收藏关注,一键三连