容器中的mysql搬迁RDS,会话却“爆了”51CTO博客 - 凯时娱乐

容器中的mysql搬迁RDS,会话却“爆了”51CTO博客

2019年03月06日10时03分35秒 | 作者: 灵寒 | 标签: 搬迁,索引,容器 | 浏览: 894

1事情来源

 整个事情的来源还要从笔者最近入职了一家区块链金融公司来说起(为了保密性,不方便泄漏公司姓名),公司事务开展比较迅猛,打破百万用户也是近在眼前。整个体系都在阿里云上运转,每天都能看到用户的不断添加,即振奋又忧虑,为什么这么说呢?

 由于笔者过来的时分这儿事务就现已上线了,体系接过来之后,快速了解了一切的运用效劳都是在docker swarm跑起来的,也包含mysql数据库,以至于笔者就有了迁库的主意,依照这种用户量开展下去,mysql在容器中运转用不了多久必定会撑不住。

 笔者就开端隐约的忧虑起来,究竟不想每天胆战心惊的做运维。所以立马从头规划了新的计划和咱们一同讨论,终究总监和相关技能负责人都敲定用RDS做为数据库新的计划,周星驰的功夫中也说道过:“全国武功,唯快不破”。就立马开端启航干起来。

2搬迁计划 2.1原架构图

剖析架构图

1、从进口层(CDN)-> 到安全层(WAF) -> 终究抵达运用层 (ECS集群);
2、Docker Swarm打通了ECS集群中的每台效劳器,在每台ECS宿主机装置Docker engine并布置了公司需求的运用效劳和数据库(nginx、php、redis、mysql等);
3、mysql容器经过宿主机的本地(目录)挂载到容器中完结数据耐久化;
4、事务项目以php为主,php也是运转在容器中,经过php指定的装备文件衔接到mysql容器中。

其间一个库的 docker-compose yaml文件

笔者就随意展现一下其间一个库的yaml文件,比较简单:

version: "3"
services:
  ussbao:
  # replace username/repo:tag with your name and image details
  image: 躲藏此镜像信息
  deploy:
  replicas: 1
  restart_policy:
  condition: on-failure
  environment:
  MYSQL_ROOT_PASSWORD: 躲藏此信息
  volumes:
  - "/data//mysql/db1/:/var/lib/mysql/"
  - "/etc/localtime:/etc/localtime"
  - "/etc/timezone:/etc/timezone"
networks:
  default:
  external:
  name: 躲藏此信息

从上面的信息能够看出来,每个库只运转了一个mysql容器,并没有主从或读写别离的计划。而且也没有对数据库进行做任何优化,数据库这样跑下去让笔者很忧虑,正常来说,都会把数据库独立布置运转。

2.2调整后架构图


 从上图能够看出来,笔者仅仅把mysql独立出来了,注册RDS实例来跑数据库,当然还注册了其它的一些效劳(比方oss、云redis等),这些不是本文的要点,就没有画出来。nginx和php效劳仍是在docker swarm中运转。本文仅仅对搬迁后出了问题的库进行共享,下面来看看搬迁的计划吧。

2.3 搬迁流程计划

注册RDS实例 -> 备份sql > 导入到RDS -> 修正数据库装备文件 ->测验验证

1、依据事务量规划注册RDS实例,创立数据库和用户;
2、提早做好RDS白名单,添加答应拜访RDS的IP地址;
3、mysqldump 备份docker 中的mysql;
4、把备份好的.sql文件导入到RDS中;
5、修正php项目的数据库装备文件;
6、清空php项目的缓存文件或目录;
7、测验验证;
8、RDS守时备份;

 详细搬迁细节就不展现了,笔者是在夜深人静的时分进行搬迁操作的,断定大深夜没人拜访咱们的APP和网站了才开干的。

 咱们的事务状况还有点像股市,咱们是晚上12点不许操作和买卖,第2天早上9点开盘,9点钟是并发的高峰期,就像向阳大悦城上午开门相同,大批的顾客一起并发过来了。

 所以那天晚上在12点15分按时开干,按计划和提早准备的装备、指令、脚本进行操作的。把docker 中运转的mysql搬迁到RDS上十分顺畅,好几个库搬迁不到半个小时就完毕了,而且把网站和APP的流程都跑了一遍,也都是妥妥的,终究把提早准备好备份脚本放在crontab中守时履行,能够来看下脚本内容:

#!/bin/bash
#数据库IP
dbserver=*******
#数据库用户名
dbuser=ganbing
#数据库暗码
dbpasswd=************
#备份数据库,多个库用空格离隔
dbname=db1 db2 db3
#备份时刻
backtime=`date +%Y%m%d%H%M`
out_time=`date +%Y%m%d%H%M%S`
#备份输出途径
backpath=/data/backup/mysql/
logpath=/data/backup/logs/

echo " ${backtime} #" 
echo "开端备份" 
#日志记载头部
echo "" >> ${logpath}/${dbname}_back.log
echo "-" >> ${logpath}/${dbname}_back.log
echo "备份时刻为${backtime},备份数据库 ${dbname} 开端" >> ${logpath}/${dbname}_back.log

#正式备份数据库
for DB in $dbname; do
  source=`/usr/bin/mysqldump  -h ${dbserver} -u ${dbuser} -p${dbpasswd} ${DB} > ${backpath}/${DB}-${out_time}.sql` 2>> ${backpath}/mysqlback.log;
  #备份成功以下操作
  if [ "$?"  0 ];then
  cd $backpath
  #为节省硬盘空间,将数据库紧缩
  tar zcf ${DB}-${backtime}.tar.gz ${DB}-${backtime}.sql > /dev/null
  #删去原始文件,只留紧缩后文件
  rm -f ${DB}-${backtime}.sql
  #删去15天前备份,也就是只保存15天内的备份
  find $backpath -name "*.tar.gz" -type f -mtime +15 -exec rm -rf {} \; > /dev/null 2>&1
  echo "数据库 ${dbname} 备份成功!!" >> ${logpath}/${dbname}_back.log
  else
  #备份失利则进行以下操作
  echo "数据库 ${dbname} 备份失利!!" >> ${logpath}/${dbname}_back.log
  fi
done

echo "完结备份"
echo " ${backtime} #"

到了1点钟,断定没问题后发告诉到群里,发微信给领导标明已搬迁完结,进行很顺畅,然后笔者打车回家,睡觉。

3雪崩降临

其实这一晚笔者睡得也不结壮,到了8点半就醒了,由于咱们9点钟开盘,会有很多的客户涌进,每天开端发作新的买卖(买入和卖出),给咱们看下截图:

果不其然,9点往后,笔者翻开APP,一切正常,点击切换几个界面后,发现其间一个功用的恳求超时了,一向在转,然后紧接着其它功用也超时了。完了,出问题了。赶忙开笔记本查问题,过了一瞬间群里就开端欢腾了(反映很多客户翻开APP都显现恳求超时了),我的电话也立马响了,技能总监打来的,问我怎么回事,我说正在开笔记本排查。

这个时分,我要阐明一下:运维人员此刻需求镇定而且安静的处理问题,公司领导千万别催得太急防止打乱处理人的思路。咱们总监临场处理才能做得真是十分到位,立刻跟我说不必忧虑上面压力,有他扛着,叫我只管排查和解决问题。

4紧迫处理 4.1 排查问题

笔记本翻开后,首要想到的就是RDS数据库出了问题,登录阿里云,进入RDS中的DMS数据管理控制台,一进去就傻眼了 “CPU爆了”,这么多衔接数,如下图:

进入会话去看看,发现会话“炸锅了”,发现几百页的select都挤在ub_user_calculate这个表中,这个表是数据量相对大一些,这张表现在有200多万条数据:
![]

天然反响就是去检查此表的结构,发现此表没有索引,被惊奇到了,居然没有索引,这...... 然后笔者回来源数据库检查这张表,也发现没有索引,由此能够断定我导过来的这张表就是没有创立索引,如下图:

剖析:当数据库中呈现拜访表的SQL没创立索引导致全表扫描,假如表的数据量很大扫描很多的数据,履行功率过慢,占用数据库衔接,衔接数堆积很快到达数据库的最大衔接数设置,新的运用恳求将会被回绝导致毛病发作。

4.2 解决问题

赶忙把此事反响给开发负责人,标明问题本源找到了,会话锁死了,由其间的一张表没有索引而导致的,问问询需求给哪几个字段加索引。然后接着操作添加索引:

点击保存后,发现创立索引的sql一向卡死着,,如下图所示:


俄然想起来还有一堆会话在那里,先kill 掉一切会话吧,不然索引必定创立不了,然后又发现会话底子杀不完,如下图:

怎么办呢?会话杀不完...

没办法,先把拜访进口堵截吧,横竖现在用户拜访也超时,就决然肯定先把域名停了,拜访进口给堵截了,然后在添加索引,索引加上了。

进口也断了,索引也加上了,发现CPU还下去,如下图:

为了快速让CPU降下去,重启这个实例吧:

实例重启完后,CPU下去了,会话也下去了:

敞开进口层的域名拜访吧,在次调查现在的会话和CPU等况,如下图:

这就对了,会话也正常了,告诉领导事务康复。。。

笔者后期补的一张图:在来看一下效劳器CPU状况(搬迁MYSQL后的状况),显着逐步好转。

5索引运用战略及优化 创立索引
  • 在常常查询而不常常增修改操作的字段加索引。
  • order by与group by后应直接运用字段,而且字段应该是索引字段。
  • 一个表上的索引不应该超越6个。
  • 索引字段的长度固定,且长度较短。
  • 索引字段重复不能过多,假如某个字段为主键,那么这个字段不必设为索引。
  • 在过滤性高的字段上加索引。
运用索引留意事项
  • 运用like关键字时,前置%会导致索引失效。
  • 运用null值会被主动从索引中扫除,索引一般不会建立在有空值的列上。
  • 运用or关键字时,or左右字段假如存在一个没有索引,有索引字段也会失效。
  • 运用!=操作符时,将抛弃运用索引。由于规模不断定,运用索引功率不高,会被引擎主动改为全表扫描。
  • 不要在索引字段进行运算。
  • 在运用复合索引时,最左前缀准则,查询时有必要运用索引的第一个字段,不然索引失效;而且应尽量让字段次序与索引次序共同。
  • 防止隐式转化,界说的数据类型与传入的数据类型保持共同。

参阅:https://help.aliyun.com/document_detail/52274.html?spm=a2c4g.11174283.6.812.ZGPyBQ

6总结

1、此次毛病虽然是表没有索引形成的,可是笔者是有职责的,没有挨个表检查一下表的结构;
2、经过此次毛病也能够看出来开发在规划表的真的要十分的注重,留意细节;
3、还有就是之前在容器中运转的mysql也时不时的呈现CPU瓶颈(比方CPU运用率偶然会到达80%以上),笔者应该就要提早发现这些问题,完全排查找出问题所在原因在进行迁库的操作。

本章内容到此完毕,喜欢我的文章,请点击最上方右角处的《重视》!!!

版权声明
本文来源于网络,版权归原作者所有,其内容与观点不代表凯时娱乐立场。转载文章仅为传播更有价值的信息,如采编人员采编有误或者版权原因,请与我们联系,我们核实后立即修改或删除。

猜您喜欢的文章