偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

運(yùn)維的苦,誰(shuí)懂?一次“心驚肉跳”的遷庫(kù)經(jīng)歷?。ㄓ胁实埃?/h1> 原創(chuàng)

運(yùn)維 系統(tǒng)運(yùn)維
IT 運(yùn)維工程師一直是個(gè)“苦逼”的職業(yè),“鋤禾日當(dāng)午,不如運(yùn)維苦,對(duì)著破電腦,一調(diào)一下午”是對(duì)運(yùn)維工作的一個(gè)形象的描述。下面看看本文作者一次驚心肉跳的數(shù)據(jù)庫(kù)遷移經(jīng)歷。

【51CTO.com原創(chuàng)稿件】IT 運(yùn)維工程師一直是個(gè)“苦逼”的職業(yè),“鋤禾日當(dāng)午,不如運(yùn)維苦,對(duì)著破電腦,一調(diào)一下午”是對(duì)運(yùn)維工作的一個(gè)形象的描述。下面看看本文作者一次驚心肉跳的數(shù)據(jù)庫(kù)遷移經(jīng)歷。

事件起源

整個(gè)事件的起源還要從我最近入職了一家區(qū)塊鏈金融公司說(shuō)起,公司業(yè)務(wù)發(fā)展比較迅猛,突破百萬(wàn)用戶(hù)也是近在眼前。

整個(gè)系統(tǒng)都在阿里云上運(yùn)行,每天都能看到用戶(hù)的不斷增長(zhǎng),即興奮又擔(dān)憂(yōu),為什么這么說(shuō)呢?

由于我過(guò)來(lái)的時(shí)候,公司業(yè)務(wù)就已經(jīng)上線(xiàn)了,系統(tǒng)接過(guò)來(lái)之后,快速了解了所有的應(yīng)用服務(wù)都是在 Docker Swarm 跑起來(lái)的,也包括 MySQL 數(shù)據(jù)庫(kù)。

按照這種用戶(hù)量發(fā)展下去,MySQL 在容器中運(yùn)行用不了多久肯定會(huì)撐不住,以至于我就有了遷庫(kù)的想法。

我開(kāi)始隱隱的擔(dān)憂(yōu)起來(lái),畢竟不想每天提心吊膽的做運(yùn)維。所以立即重新規(guī)劃了新的方案和大家一起探討。

最終總監(jiān)和相關(guān)技術(shù)負(fù)責(zé)人都敲定用 RDS 做為數(shù)據(jù)庫(kù)新的方案,周星馳的功夫中也說(shuō)到:“天下武功,唯快不破”,于是就開(kāi)始干起來(lái)。

遷移計(jì)劃

原架構(gòu)圖

如上圖所示,分析一下原來(lái)的架構(gòu)圖:

  • 從入口層(CDN)→到安全層(WAF)→***到達(dá)應(yīng)用層 (ECS集群)。
  • Docker Swarm 打通了 ECS 集群中的每臺(tái)服務(wù)器,在每臺(tái) ECS 宿主機(jī)安裝 Docker engine 并部署了公司需要的應(yīng)用服務(wù)和數(shù)據(jù)庫(kù)(Nginx、PHP、Redis、MySQL等)。
  • MySQL 容器通過(guò)本文件掛載到容器中實(shí)現(xiàn)數(shù)據(jù)持久化。
  • 業(yè)務(wù)項(xiàng)目以 PHP 為主,PHP 也是運(yùn)行在容器中,通過(guò) PHP 指定的配置文件連接到 MySQL 容器中。

隨便展示一下其中一個(gè)庫(kù)的 docker-compose yaml 文件:

  1. version: "3" 
  2. services: 
  3.   ussbao: 
  4.     # replace username/repo:tag with your name and image details 
  5.     image: 隱藏此鏡像信息 
  6.     deploy: 
  7.       replicas: 1 
  8.       restart_policy: 
  9.         condition: on-failure 
  10.     environment: 
  11.       MYSQL_ROOT_PASSWORD: 隱藏此信息 
  12.     volumes: 
  13.       - "/data//mysql/db1/:/var/lib/mysql/" 
  14.       - "/etc/localtime:/etc/localtime" 
  15.       - "/etc/timezone:/etc/timezone" 
  16. networks: 
  17.   default
  18.     external: 
  19.       name: 隱藏此信息 

從上面的信息可以看出來(lái),每個(gè)庫(kù)只運(yùn)行了一個(gè) MySQL 容器,并沒(méi)有主從或讀寫(xiě)分離的方案。

而且也沒(méi)有對(duì)數(shù)據(jù)庫(kù)做任何優(yōu)化,數(shù)據(jù)庫(kù)這樣跑下去讓筆者很擔(dān)憂(yōu),正常來(lái)說(shuō),都會(huì)把數(shù)據(jù)庫(kù)獨(dú)立部署運(yùn)行。

調(diào)整后架構(gòu)圖

從上圖可以看出來(lái),筆者只是把 MySQL 獨(dú)立出來(lái)了,開(kāi)通 RDS 實(shí)例來(lái)跑數(shù)據(jù)庫(kù),當(dāng)然還開(kāi)通了其他的一些服務(wù)(比如 OSS、云 Redis 等),這些不是本文的重點(diǎn),就沒(méi)有畫(huà)出來(lái)。

Nginx 和 PHP 服務(wù)還是在 Docker Swarm 中運(yùn)行。本文只是對(duì)遷移后出了問(wèn)題的庫(kù)進(jìn)行分享,下面來(lái)看看遷移的方案吧。

遷移流程方案

遷移流程的方案:開(kāi)通 RDS 實(shí)例→備份 SQL→導(dǎo)入到 RDS→修改數(shù)據(jù)庫(kù)配置文件→測(cè)試驗(yàn)證。

遷移步驟如下:

  • 根據(jù)業(yè)務(wù)量規(guī)劃開(kāi)通 RDS 實(shí)例,創(chuàng)建數(shù)據(jù)庫(kù)和用戶(hù)
  • 提前做好 RDS 白名單,添加允許訪(fǎng)問(wèn) RDS 的 IP 地址
  • mysqldump 備份 Docker 中的 MySQL
  • 把備份好的 .sql 文件導(dǎo)入到 RDS 中
  • 修改 PHP 項(xiàng)目的數(shù)據(jù)庫(kù)配置文件
  • 清空 PHP 項(xiàng)目的緩存文件或目錄
  • 測(cè)試驗(yàn)證
  • RDS 定時(shí)備份

具體遷移細(xì)節(jié)就不展示了,我是在夜深人靜的時(shí)候進(jìn)行遷移操作的,確定大半夜沒(méi)人訪(fǎng)問(wèn)我們的 App 和網(wǎng)站了才開(kāi)干的。

我們的業(yè)務(wù)情況有點(diǎn)像股市,我們是晚上 12 點(diǎn)不許操作和交易,第 2 天早上 9 點(diǎn)開(kāi)盤(pán),9 點(diǎn)鐘是并發(fā)的高峰期,就像朝陽(yáng)大悅城上午開(kāi)門(mén)一樣,大批的顧客同時(shí)并發(fā)過(guò)來(lái)了。

所以那天晚上在 12 點(diǎn) 15 分準(zhǔn)時(shí)開(kāi)干,按計(jì)劃和提前準(zhǔn)備的配置、命令、腳本進(jìn)行操作的。

把 Docker 中運(yùn)行的 MySQL 遷移到 RDS 上非常順利,好幾個(gè)庫(kù)的遷移不到半個(gè)小時(shí)就結(jié)束了,并且把網(wǎng)站和 App 的流程都跑了一遍,也都是妥妥的。

最終把提前準(zhǔn)備好的備份腳本放在 crontab 中定時(shí)執(zhí)行,可以看下腳本內(nèi)容:

  1. #!/bin/bash 
  2. #數(shù)據(jù)庫(kù)IP 
  3. dbserver='*******' 
  4. #數(shù)據(jù)庫(kù)用戶(hù)名 
  5. dbuser='ganbing' 
  6. #數(shù)據(jù)庫(kù)密碼 
  7. dbpasswd='************' 
  8. #備份數(shù)據(jù)庫(kù),多個(gè)庫(kù)用空格隔開(kāi) 
  9. dbname='db1 db2 db3' 
  10. #備份時(shí)間 
  11. backtime=`date +%Y%m%d%H%M` 
  12. out_time=`date +%Y%m%d%H%M%S` 
  13. #備份輸出路徑 
  14. backpath='/data/backup/mysql/' 
  15. logpath=''/data/backup/logs/' 
  16.  
  17. echo "################## ${backtime} #############################"  
  18. echo "開(kāi)始備份"  
  19. #日志記錄頭部 
  20. echo "" >> ${logpath}/${dbname}_back.log 
  21. echo "-------------------------------------------------" >> ${logpath}/${dbname}_back.log 
  22. echo "備份時(shí)間為${backtime},備份數(shù)據(jù)庫(kù) ${dbname} 開(kāi)始" >> ${logpath}/${dbname}_back.log 
  23.  
  24. #正式備份數(shù)據(jù)庫(kù) 
  25. for DB in $dbname; do 
  26.   source=`/usr/bin/mysqldump  -h ${dbserver} -u ${dbuser} -p${dbpasswd} ${DB} > ${backpath}/${DB}-${out_time}.sql` 2>> ${backpath}/mysqlback.log; 
  27.   #備份成功以下操作 
  28.   if [ "$?" == 0 ];then 
  29.     cd $backpath 
  30.     #為節(jié)約硬盤(pán)空間,將數(shù)據(jù)庫(kù)壓縮 
  31.     tar zcf ${DB}-${backtime}.tar.gz ${DB}-${backtime}.sql > /dev/null 
  32.     #刪除原始文件,只留壓縮后文件 
  33.     rm -f ${DB}-${backtime}.sql 
  34.     #刪除15天前備份,也就是只保存15天內(nèi)的備份 
  35.     find $backpath -name "*.tar.gz" -type f -mtime +15 -exec rm -rf {} \; > /dev/null 2>&1 
  36.     echo "數(shù)據(jù)庫(kù) ${dbname} 備份成功!!" >> ${logpath}/${dbname}_back.log 
  37.   else 
  38.   #備份失敗則進(jìn)行以下操作 
  39.   echo "數(shù)據(jù)庫(kù) ${dbname} 備份失敗!!" >> ${logpath}/${dbname}_back.log 
  40.   fi 
  41. done 
  42.  
  43. echo "完成備份" 
  44. echo "################## ${backtime} #############################" 

到了 1 點(diǎn)鐘,確定沒(méi)問(wèn)題后發(fā)通知到群里,發(fā)微信給領(lǐng)導(dǎo)表示已遷移完成,進(jìn)行很順利,然后筆者打車(chē)回家,睡覺(jué)。

雪崩來(lái)臨

其實(shí)這一晚筆者睡得也不踏實(shí),到了 8 點(diǎn)半就醒了,因?yàn)槲覀?9 點(diǎn)鐘開(kāi)盤(pán),會(huì)有大量的客戶(hù)涌進(jìn),每天開(kāi)始產(chǎn)生新的交易(買(mǎi)入和賣(mài)出),給大家看下截圖:

果不其然,9 點(diǎn)過(guò)后,我打開(kāi) App,一切正常,點(diǎn)擊切換幾個(gè)界面后,發(fā)現(xiàn)其中一個(gè)功能的請(qǐng)求超時(shí)了,一直在轉(zhuǎn),然后緊接著其他功能也超時(shí)了。

完了,出問(wèn)題了。趕緊開(kāi)電腦查問(wèn)題,過(guò)了一會(huì)兒群里就開(kāi)始沸騰了(反映好多客戶(hù)打開(kāi) App 都顯示請(qǐng)求超時(shí)了),我的電話(huà)也***時(shí)間響了,技術(shù)總監(jiān)打來(lái)的,問(wèn)我怎么回事,我說(shuō)正在開(kāi)電腦排查。

緊急處理

排查問(wèn)題

電腦打開(kāi)后,首先想到的就是 RDS 數(shù)據(jù)庫(kù)出了問(wèn)題,登錄阿里云,進(jìn)入 RDS 中的 DMS 數(shù)據(jù)管理控制臺(tái),一進(jìn)去就傻眼了 “CPU 爆了”,這么多連接數(shù),如下圖:

進(jìn)入會(huì)話(huà)去看看,發(fā)現(xiàn)會(huì)話(huà)“炸鍋了”,發(fā)現(xiàn)幾百頁(yè)的 select 都擠在 ub_user_calculate 這個(gè)表中,這個(gè)表數(shù)據(jù)量相對(duì)大一些,目前有 200 多萬(wàn)條數(shù)據(jù),如下圖:

我的自然反應(yīng)就是去查看此表的結(jié)構(gòu),但發(fā)現(xiàn)此表沒(méi)有索引,我被驚訝到了,竟然沒(méi)有索引,這...... 

然后筆者返回源數(shù)據(jù)庫(kù)查看這張表,也發(fā)現(xiàn)沒(méi)有索引,由此可以確定我導(dǎo)過(guò)來(lái)的這張表就是沒(méi)有創(chuàng)建索引,如下圖:

當(dāng)數(shù)據(jù)庫(kù)中出現(xiàn)訪(fǎng)問(wèn)表的 SQL 沒(méi)創(chuàng)建索引,會(huì)導(dǎo)致全表掃描,如果表的數(shù)據(jù)量很大,掃描大量的數(shù)據(jù),執(zhí)行效率過(guò)慢,占用數(shù)據(jù)庫(kù)連接,連接數(shù)堆積很快達(dá)到數(shù)據(jù)庫(kù)的***連接數(shù)設(shè)置,新的應(yīng)用請(qǐng)求將會(huì)被拒絕導(dǎo)致故障發(fā)生。

解決問(wèn)題

我趕緊把此事反映給開(kāi)發(fā)負(fù)責(zé)人,表明問(wèn)題根源找到了,會(huì)話(huà)鎖死了,是由其中的一張表沒(méi)有索引而導(dǎo)致的,問(wèn)詢(xún)需要給哪幾個(gè)字段加索引。

然后接著操作增加索引:

點(diǎn)擊保存后,發(fā)現(xiàn)創(chuàng)建索引的 SQL 一直卡死著,如下圖所示:

突然想起來(lái)還有一堆會(huì)話(huà)在那里,先 Kill 掉所有會(huì)話(huà)吧,不然索引肯定創(chuàng)建不了,然后又發(fā)現(xiàn)會(huì)話(huà)根本殺不完,如下圖:

怎么辦呢?會(huì)話(huà)殺不完...沒(méi)辦法,先把訪(fǎng)問(wèn)入口切斷吧,反正現(xiàn)在用戶(hù)訪(fǎng)問(wèn)也超時(shí),就毅然決定先把域名停了,訪(fǎng)問(wèn)入口給切斷了,然后在增加索引。索引加上了,發(fā)現(xiàn) CPU 還下不去,如下圖:

為了快速讓 CPU 降下去,重啟這個(gè)實(shí)例吧:

實(shí)例重啟完后,CPU 下去了,會(huì)話(huà)也下去了:

開(kāi)啟入口層的域名訪(fǎng)問(wèn)吧,再次觀(guān)察現(xiàn)在的會(huì)話(huà)和 CPU 等況,如下圖:

這就對(duì)了,會(huì)話(huà)也正常了,通知領(lǐng)導(dǎo)業(yè)務(wù)恢復(fù)。

再來(lái)看一下服務(wù)器 CPU 的情況(遷移 MySQL 后的情況),明顯逐漸好轉(zhuǎn)。

索引使用策略及優(yōu)化

創(chuàng)建索引注意事項(xiàng):

  • 在經(jīng)常查詢(xún)而不經(jīng)常增刪改操作的字段加索引。
  • order by 與 group by 后應(yīng)直接使用字段,而且字段應(yīng)該是索引字段。
  • 一個(gè)表上的索引不應(yīng)該超過(guò) 6 個(gè)。
  • 索引字段的長(zhǎng)度固定,且長(zhǎng)度較短。
  • 索引字段重復(fù)不能過(guò)多,如果某個(gè)字段為主鍵,那么這個(gè)字段不用設(shè)為索引。
  • 在過(guò)濾性高的字段上加索引。

使用索引注意事項(xiàng):

  • 使用 like 關(guān)鍵字時(shí),前置 % 會(huì)導(dǎo)致索引失效。
  • 使用 null 值會(huì)被自動(dòng)從索引中排除,索引一般不會(huì)建立在有空值的列上。
  • 使用 or 關(guān)鍵字時(shí),or 左右字段如果存在一個(gè)沒(méi)有索引,有索引字段也會(huì)失效。
  • 使用 != 操作符時(shí),將放棄使用索引。因?yàn)榉秶淮_定,使用索引效率不高,會(huì)被引擎自動(dòng)改為全表掃描。
  • 不要在索引字段進(jìn)行運(yùn)算。
  • 在使用復(fù)合索引時(shí),最左前綴原則,查詢(xún)時(shí)必須使用索引的***個(gè)字段,否則索引失效;并且應(yīng)盡量讓字段順序與索引順序一致。
  • 避免隱式轉(zhuǎn)換,定義的數(shù)據(jù)類(lèi)型與傳入的數(shù)據(jù)類(lèi)型保持一致。

參考鏈接:https://help.aliyun.com/document_detail/52274.html?spm=a2c4g.11174283.6.812.ZGPyBQ

總結(jié)

此次故障雖然是表沒(méi)有索引造成的,但是我是有責(zé)任的,沒(méi)有挨個(gè)表檢查一下表的結(jié)構(gòu)。

通過(guò)此次故障也可以看出來(lái)開(kāi)發(fā)在設(shè)計(jì)表的時(shí)候真的要非常的重視,注意細(xì)節(jié)。

還有就是之前在容器中運(yùn)行的 MySQL 也時(shí)不時(shí)的出現(xiàn) CPU 瓶頸(比如 CPU 使用率偶爾會(huì)達(dá)到 80% 以上),我應(yīng)該提前發(fā)現(xiàn)這些問(wèn)題,徹底排查找出問(wèn)題所在原因再進(jìn)行遷庫(kù)的操作。

福利來(lái)啦

掃描下方二維碼。關(guān)注51CTO技術(shù)棧公眾號(hào),歡迎在技術(shù)棧微信公眾號(hào)留言探討,您運(yùn)維工作中最驚心動(dòng)魄的“救火故事”,小編將選出留言最精彩的 10 名網(wǎng)友,送出《Docker從入門(mén)到實(shí)戰(zhàn)》圖書(shū)一本~活動(dòng)截止時(shí)間 5 月 4 日 12 時(shí)整,特別鳴謝機(jī)械工業(yè)出版社為本次活動(dòng)提供的圖書(shū)贊助。

內(nèi)容簡(jiǎn)介

深度剖析 Docker 的核心概念、實(shí)現(xiàn)原理、應(yīng)用技巧和生態(tài)系統(tǒng);全面涵蓋 Docker 四大管理工具、三大組件、集群編排;介紹上百個(gè)實(shí)戰(zhàn)案例,提升動(dòng)手能力;以 Docker 當(dāng)前的流行版本為例講解 Swarm 集群管理。

[[227597]]

 

甘兵,高級(jí)運(yùn)維工程師,6 年運(yùn)維工作經(jīng)驗(yàn)。曾就職于國(guó)家互聯(lián)網(wǎng)應(yīng)急中心、天音控股等企業(yè)。擁有豐富系統(tǒng)運(yùn)維經(jīng)驗(yàn),大型網(wǎng)絡(luò)架構(gòu)設(shè)計(jì)經(jīng)驗(yàn)。熱衷于開(kāi)源技術(shù)的研究,關(guān)注的技術(shù)方向 Docker、DevOps 等。

【51CTO原創(chuàng)稿件,合作站點(diǎn)轉(zhuǎn)載請(qǐng)注明原文作者和出處為51CTO.com】

責(zé)任編輯:武曉燕 來(lái)源: 51CTO技術(shù)棧
相關(guān)推薦

2015-04-24 10:57:41

2014-05-22 13:28:41

2016-08-30 11:01:12

災(zāi)備

2014-09-18 01:07:26

2021-01-22 05:35:19

Lvm模塊Multipath

2012-08-28 09:21:59

Ajax查錯(cuò)經(jīng)歷Web

2023-03-29 09:36:32

2025-03-17 10:01:07

2021-12-06 19:29:17

LRU內(nèi)存算法

2017-08-07 10:53:57

程序員客戶(hù)項(xiàng)目

2011-04-13 09:21:30

死鎖SQL Server

2013-04-01 10:27:37

程序員失業(yè)

2016-12-06 09:34:33

線(xiàn)程框架經(jīng)歷

2013-01-17 10:31:13

JavaScriptWeb開(kāi)發(fā)firebug

2021-04-13 18:17:48

Hbase集群配置

2018-12-06 16:25:39

數(shù)據(jù)庫(kù)服務(wù)器線(xiàn)程池

2019-04-04 15:00:40

SQL索引數(shù)據(jù)庫(kù)

2015-07-02 11:41:04

宕機(jī)云服務(wù)

2012-07-12 14:35:31

面試經(jīng)歷

2024-04-10 08:48:31

MySQLSQL語(yǔ)句
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)