伺機房搬遷的機會,打算作一次業務整合。現有的架構是在2010年規劃並運營起來的,隨着時間的推移,項目也愈來愈多。打開nginx配置文件,有四十多行include包含存在,每個包含就是一個項目(有些是web,有些是app)。一整個機櫃,老舊的設備,負載均衡高可用架構。爲保證業務一致性和下降成本,業務數據(開發的應用程序及用戶上傳數據)共享一套NFS;各業務共享同一套物理數據庫(一臺物理服務器mysql建立多個庫)。隨着業務和訪問量的增加,這種隱患愈來愈使人擔心,主要表如今如下幾個方面:mysql
◆安全問題linux
數十個站點共享目錄,以nfs方式共享給各物理服務器,這幾十個項目,只要任何一個有安全漏洞存在,有心人都能進來隨心所欲,讓站點所有淪陷。時不時的,被人注入惡意代碼,針對性的進行清除,但沒多久又被注入篡改。你們內心都有數,存在漏洞的地方,不必定是被篡改的那個。但站點太多,又沒有隔離,根本沒法用安全工具掃描(一個站點進行掃描,平均花費一天)。android
[root@web57 ~]# more /usr/local/nginx/conf/nginx.confnginx user www www;程序員 worker_processes 6;web
worker_rlimit_nofile 51200;ajax
events {sql use epoll;數據庫 #use kqueue; #FreeBSD systemapi worker_connections 51200; }
http { include mime.types; default_type application/octet-stream; #charset gb2312; server_names_hash_bucket_size 256; client_header_buffer_size 256k; large_client_header_buffers 4 256k; client_max_body_size 500m; …………………………………………省略若干………………………………… include vhosts/faxian.quanzhen.com.conf; include vhosts/www.quanzhen.com.conf; include vhosts/news.quanzhen.com.conf; include vhosts/s.quanzhen.com.conf; include vhosts/down.quanzhen.com.conf; include vhosts/static.quanzhen.com.conf; include vhosts/image.quanzhen.com.conf; include vhosts/3g.quanzhen.com.conf; include vhosts/mini.quanzhen.com.conf; include vhosts/xml.quanzhen.com.conf; include vhosts/mayiapi.quanzhen.com.conf; include vhosts/www.android77.com.conf; include vhosts/fahongbao.android77.com.conf; include vhosts/update.android77.com.conf; include vhosts/dev.quanzhen.com.conf; include vhosts/qr.110.cc.conf; include vhosts/110.cc.conf; include vhosts/eggserver.quanzhen.com.conf; include vhosts/apkegg.quanzhen.com.conf; include vhosts/eggserver.yidong7.cn.conf; include vhosts/www.yidong7.cn.conf; include vhosts/down.yidong7.cn.conf; include vhosts/wan.quanzhen.com.conf; include vhosts/open.quanzhen.com.conf; include vhosts/bakdown.yidong7.cn.conf ; include vhosts/hanhua.quanzhen.com.conf; include vhosts/mpk.quanzhen.com.conf; include vhosts/android.quanzhen.com.conf; include vhosts/pay.quanzhen.com.conf; include vhosts/cmstop.quanzhen.cn.conf; include vhosts/news.quanzhen.cn.conf; include vhosts/pingce.quanzhen.cn.conf; include vhosts/gonglue.quanzhen.cn.conf; include vhosts/hao.quanzhen.cn.conf; include vhosts/all.quanzhen.cn.conf; include vhosts/s.quanzhen.cn.conf; include vhosts/apkz.quanzhen.com.conf; include vhosts/ajax.quanzhen.com.conf; include vhosts/union.quanzhen.com.conf; include vhosts/mai.quanzhen.com.conf; include vhosts/blog.quanzhen.com.conf; include vhosts/guazi.quanzhen.com.conf; include vhosts/lockscreen.yidong7.cn.conf; include vhosts/dsp.pujia8.com.conf; include vhosts/3svx4haii9.quanzhen.com.conf; include vhosts/u.quanzhen.com.conf; include vhosts/bianji.quanzhen.com.conf; include vhosts/default.conf; } |
◆性能問題
主要集中在數據庫上邊,只要有一個庫出現問題,引發鎖表或者其它競爭,所有相關業務都會掛起,煩不勝煩啊。想進行拆分,決策人認爲,原本就滿機櫃了,若是再新家機器,得另租機櫃,考慮到成本等其它問題,只求不出事便可。
整合的計劃是,遷移部分業務到公有云上,騰出服務器後,對現有的設備進行擴充配置(拼內存、硬盤等,古舊的機器直接下架)。留下配置高的,進行虛擬化,既能減小設備數量(託管費下降),又有利於平常維護。
前邊說了這麼多,彷佛與技術關係不大,但對於一些有遺留問題的項目,仍是具備參考意義。接下來,咱們就進入正題,看看咱們要遷移的項目情況。要往雲上遷移的數據包括網站數據及數據庫數據,網站數據比較好辦,rsync同步到對應的目錄,而數據庫相對而言,要麻煩很多。兩個數據庫,一個容量38G,另外一個29G,不算太大,但公用的ibdata1文件卻有123G,最初是嘗試把這兩個庫,直接導入到阿里雲的RDS,在進行數次操做失敗後,諮詢客服獲得的答覆是RDS暫時不支持分表的數據庫。爲節省成本,購買一個配置高一點的雲主機(cpu 8core,內存32G,1T高效雲盤),部署上mysql5.6,供兩個數據庫使用。
第一次嘗試
預估了一下,200G的數據,貪心一把,看一次性能不能遷移完。提早幾天,把雲上的環境所有準備穩當(能出來測試頁),運營部門把通知發下去,而後某天夜裏0:30分,一些人在辦公室,一些人在家裏,眯着眼,莊重地在鍵盤敲入「screen」這幾個字符。在qq羣裏獲得一致許可,能夠進行數據庫導出操做之後,小弟當心翼翼地發來一條指令:
[root@db-209 ~]# innobackupex --user=root --passwor='i%=KGb76' \ --defaults-file=/etc/my.cnf \ --databases=「quanzhen_mobile7lockscreen quanzhen_equipment」 /data/bakmysql/ InnoDB Backup Utility v1.5.1-xtrabackup; Copyright 2003, 2009 Innobase Oy and Percona Ireland Ltd 2009-2012. All Rights Reserved.
This software is published under the GNU GENERAL PUBLIC LICENSE Version 2, June 1991.
180618 00:30:31 innobackupex: Starting mysql with options: --defaults-file='/etc/my.cnf' --password=xxxxxxxx --user='root' --unbuffered -- 180618 00:30:31 innobackupex: Connected to database with mysql child process (pid=20090) 180618 00:30:37 innobackupex: Connection to database server closed IMPORTANT: Please check that the backup run completes successfully. At the end of a successful backup run innobackupex prints "completed OK!".
innobackupex: Using mysql Ver 14.12 Distrib 5.0.95, for redhat-linux-gnu (x86_64) using readline 5.1 innobackupex: Using mysql server version Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
innobackupex: Created backup directory /data/bakmysql/2018-06-18_00-30-37 180618 00:30:37 innobackupex: Starting mysql with options: --defaults-file='/etc/my.cnf' --password=xxxxxxxx --user='root' --unbuffered -- 180618 00:30:37 innobackupex: Connected to database with mysql child process (pid=20123) 180618 00:30:39 innobackupex: Connection to database server closed
180618 00:30:39 innobackupex: Starting ibbackup with command: xtrabackup_55 --defaults-file="/etc/my.cnf" --defaults-group="mysqld" --backup --suspend-at-end --target-dir=/data/bakmysql/2018-06-18_00-30-37 --tmpdir=/tmp innobackupex: Waiting for ibbackup (pid=20132) to suspend innobackupex: Suspend file '/data/bakmysql/2018-06-18_00-30-37/xtrabackup_suspended'
xtrabackup_55 version 2.0.7 for Percona Server 5.5.16 Linux (x86_64) (revision id: 552) xtrabackup: uses posix_fadvise(). xtrabackup: cd to /data/mysql_db xtrabackup: Target instance is assumed as followings. xtrabackup: innodb_data_home_dir = ./ xtrabackup: innodb_data_file_path = ibdata1:10M:autoextend xtrabackup: innodb_log_group_home_dir = ./ xtrabackup: innodb_log_files_in_group = 2 xtrabackup: innodb_log_file_size = 5242880 >> log scanned up to (601191481892) [01] Copying ./ibdata1 to /data/bakmysql/2018-06-18_00-30-37/ibdata1 >> log scanned up to (601191481892) >> log scanned up to (601191481892) >> log scanned up to (601191481892) >> log scanned up to (601191481892) >> log scanned up to (601191481892) >> log scanned up to (601191481892) >> log scanned up to (601191481892) …………………………………省略…………………………………………… |
樂觀估計,上午7點前,能完成整個遷移,幾我的商量輪流監看進展程度,等進行完一步後叫醒休息的人,以便進行下一步。結果,到凌晨六點多,才執行完這個innobackupex,還差好幾步呢,每一步都一樣耗時,只能宣告遷移暫時失敗,選個黃道吉日,分兩次進行遷移。
第二次分拆遷移
萬年曆排除近期諸事不宜的日子,再搖卦選利用用神的地支,選定日誌,約上相關人等,繼續進行遷移。有了上一次的教訓,在遷移前又對要遷移的庫作了清理,刪掉了一些無用的數據,省出來好幾個G的空間。在源數據庫,執行指令:
[root@db-209 ~]#innobackupex --user=root --passwor='i%=KGb76' \ --defaults-file=/etc/my.cnf --databases=「quanzhen_equipment」 /data/bakmysql/ |
我交到好之後,就躺下睡覺,到凌晨三點電話響了,告知第一步完成。
[root@db-209 ~]#innobackupex --apply-log /data/bakmysql/2018-06-18_00-30-37 |
日誌應用卻是執行的很快,回車即完。而後進行tar 打包和複製文件到目標服務器,因爲租賃的出口帶寬過小(總帶寬30M,如今讀者知道爲何要夜間訪問低谷進行遷移了吧?),複製文件到目標服務花了一些時間。
目標服務器,僅僅須要安裝好mysql軟件,建立好目錄/data/mysql_db,不須要執行數據庫初始化操做,由於innobackupex導入時,要求數據目錄必須爲空。阿里雲的配置,遠比源服務器配置高,解壓文件很快就完成。
檢查一下mysql選項文件/etc/my.cnf,注意是選項文件。設定「—datadir=/data/mysql_db」,就可執行導入操做,指令以下:
[root@msyql mysql_db]# innobackupex --defaults-file=/etc/my.cnf \ --copy-back /data/db_bk/2018-06-18_00-30-37 |
源數據導出時,沒有把庫mysql一併導出,這倒不是什麼要緊的事情,反正只有一個帳戶須要建立。接下來,初始化數據庫並建立應用賬號,具體操作以下:
[root@msyql mysql_db]#cd /usr/local/mysql/ [root@msyql ~]#scripts/mysql_install_db --user=mysql --datadir=/data/mysql_db [root@msyql ~]#mysql mysql>grant all on quanzhen_equipment.* to …… |
還要記得給mysql空密碼消除掉。
源庫與目標庫,比對一下表的數量,以及隨機抽取一些大表,對記錄數進行比較。確認數據完整之後,一幫去調試應用,後續工做不表,沒我什麼事。
第三次分拆遷移
有了上一次的成功經驗,此次信心滿滿了,不過擔憂仍是有的,就是那個目標庫導入時,要求數據目錄爲空。小弟在未開始時,就來徵求個人意見,我擔憂可能會有障礙,就對他說,你只要把源站數據導出準備好,放到目標數據庫,餘下的我親自搞定。
本身的選擇有兩個,一個是使用選項「--force-non-empty-directories」,若是不行,就再弄一個mysql實例,啓用3307端口,雙實例運行。先嚐試第一個選項,看能不能進行下去,具體指令爲:
[root@msyql db_bk]# pwd /data/db_bk [root@msyql db_bk]#innobackupex --defaults-file=/etc/my.cnf --copy-back \ --force-non-empty-directories 2018-06-22_00-24-52 180623 23:31:57 innobackupex: Starting the copy-back operation
IMPORTANT: Please check that the copy-back run completes successfully. At the end of a successful copy-back run innobackupex prints "completed OK!".
innobackupex version 2.4.11 based on MySQL server 5.7.19 Linux (x86_64) (revision id: b4e0db5) innobackupex: Can't create/write to file '/data/mysql_db/ib_logfile0' (Errcode: 17 - File exists) [01] error: cannot open the destination stream for ib_logfile0 [01] Error: copy_file() failed. |
悲催了,有同名文件存在,不行!直接終止運行。好吧,我把文件「ib_logfile0、ib_logfile1」挪走,再執行,仍是不行,提示文件「ibdata1」存在,這但是個你們夥。雖然擔憂新導入的ibdata1可能不包含現有數據庫相關信息,但忍不住想試一把。可能有讀者會問,這樣搞可能把數據庫原有的數據破壞掉了,其實我想到這一層來,老早我就把整個庫作了備份,買了保險的。
正全神貫注盯着屏幕查看輸出,但願進展順利,忽然,qq羣有消息傳來,問進展如何,啥時能完成。一看時間,六點了,北方大地已經一片光明。時間來不及了,停掉進程,試試直接複製文件,不使用innobuckupex。心中沒底,就去仔細比較了數據庫目錄與導出數據目錄中的三個文件「ibdata一、ib_logfile0、ib_logfile1」,發現其大小徹底相同。無論了,把現有數據庫裏的這幾個文件搬走,從導出目錄cp來着三個文件。複製完,執行mysqld_safe啓動服務,失敗,提示ib_logfile0無寫入權限;這好辦,一條chown指令而已。再執行啓動mysql服務,正常。
那麼數據對不對呢?我不能肯定,萬一不對,就再配一個mysql,導入數據,以雙實例啓動,後邊再想法整合;阿里雲購買的服務器,相互通訊是內網,不會在傳輸上浪費太多時間。
既然服務正常,就對一下數據吧,萬一運氣爆棚(前幾天夜裏夢到本身能飛,抓住一隻巨型天鵝,我美美地摟着天鵝的脖子…),數據完整可用呢!我本身悄悄對比了一陣,沒差別呢,又到qq羣呼叫其它人,說導入有障礙,數次不成功,後邊採起了一些不肯定的手段,mysql服務是起來了,請你們覈實一下數據,看是否完整可用。幾個程序員一陣忙碌,獲得答覆,數據是完整可用的。到此,個人工做完成了。
有人可能要鄙視我一番,爲何不先測試?不制定完善的流程?這個問題問得好!我數次建議決策人,準備點資源,說白了就是準備1臺空閒服務器,再內網演練,就算白天也能能進行(複製數據走內網,不在用戶訪問的帶寬),可是,沒有資源給我啊,但事情又不得不作。雖然累點,折騰一番,翻過來想,咱玩懸的也得到經驗,否則也沒有這個文章問世,大家以爲覺呢?
道長有話說
最近受邀在51CTO博客專欄出版《負載均衡高手煉成記》,依託本身十餘年的IT運維經驗,以實際工做經驗爲基礎,介紹不一樣場景下,負載均衡的實現方式,以及負載均衡的平常維護。
本專欄適合於一直徘徊在運維初級未找到入佳境之門的運維工程師,也適合對負載均衡有興趣瞭解和學習的技術愛好者。跟着田道長學完這個系列課程,不只學知識,更是漲薪、升職、進心儀公司的一大捷徑!
負載均衡高手煉成記