於是我回到座位,開始實驗用 PostgreSQL 原生工具讓兩台 db 做對拷。首先需要設定防火牆,讓 slave db 可以直接連到 target RDS 的 5432,使用者帳號也需要先在 RDS 中設定好,接下來連入 slave db EC2,在 console 下這個命令
PGPASSWORD=<馬賽克> pg_dump -C -h localhost -U <username> -d <db_name> | psql -h <target_rds>.rds.amazonaws.com -U <user_name> <db_name>
console 會問我們一次 target RDS 的密碼,輸入後,就會看到 db 立馬快速做 dump。
另外用 psql 連線到 target RDS,的確有資料在進來,表也都建好了!
「太棒了!感覺有希望!接下來只要測量要跑的時間,下次 cutover 心裡就有底了!」我心想。
果不其然,因為資料量實在太大,原生工具也是花了整整 7 個小時才備份完成。
雖然原生工具掛保證,但為了避免漏資料的問題再度發生,我把實驗的 RDS 做備份後,把他的 image 和 api server 的 image 傳輸到 Oregon,打算在那邊還原出接近 prod 的環境,先測過一遍看看有沒有什麼問題,增加屆時 cutover 的信心。
但困難在於,原本 api server 環境就亂七八糟,光是要起起來,就耗費了我將近一個多小時的時間。不過這是值得的,只要這邊成功,幾乎預告著未來我們也會成功轉移。
經過我和 C 的測試後,發現沒有問題!原生工具甚至把 data team 在 db 裡建立的 function 和 view 等都搬過去,這些是 DMS 都沒辦法搬移的。
「看來沒有啥重大問題,如何?這禮拜六晚上再搞一次?」我詢問著 C 的意見。「恩,看來也只能這樣,先讓 BD 們再被罵一週吧!」C 苦笑著。
只要 db 不趕快 migrate 過去,不穩定和效能瓶頸就會一直存在,使用者不斷抱怨,BD 不斷回來問我們,我們不斷地重啟….的地獄循環。雖然很想立刻處理,但轉移的風險還是存在,外加至少需要七到八小時,要是真的衰小出問題,隔天使用者一早上班要使用就會出現更大的抱怨。
我們也只能咬牙再撐一週。
終於來到週六,一樣晚上十點在線上和 C 打招呼。
「準備好了嗎?」我敲入鍵盤。
「來吧!GO!」
這次直接延用之前寫好的 script 來做防火牆等切換,同時我也準備好,假設失敗的話,能夠自動還原的 script。
萬事俱備,只欠下指令。
啟動防火牆切斷連線後,我照著實驗時的手法,但這次改連入 master db EC2,下了一樣的指令
PGPASSWORD=<馬賽克> pg_dump -C -h localhost -U <username> -d <db_name> | psql -h <target_rds>.rds.amazonaws.com -U <user_name> <db_name>
再次輸入密碼,db 立刻開始執行複製的工作。
「這次可以好好睡一覺了,七小時後見吧!」我信心滿滿的傳訊給 C。
「希望這次可以成功。」C 回覆。
這次肯定可以成功的!我非常有自信地想。然後倒頭就睡。
七小後,手機鬧鐘大作,我爬起來先看了結果。
沒有錯誤訊息。
沒有訊息就是好消息,看起來複製成功,我立刻下之前寫好確認 row 總數的 script,先檢查看看有沒有缺少。
python dms_check_count.py
經過一段時間,沒有任何紅字,看來是完整搬移過去了。
「開始測試吧!」
我和 C 迫不及待的開始分頭測功能,check list 上的項目陸續的被勾選完成。
就這樣,終於最後一個也被勾起,所有我們能想到的功能測試都是正常的。
「那,我開放防火牆了哦!」我略作遲疑的傳訊給 C。
雖然信心度很高,但是在完成前還是會猶豫一下,心想有沒有哪個部分是我們漏掉的。
「恩,能測的我們也都測了。」C 意指盡了人事,接下來只能聽天命。
依據我不科學的經驗,如果事情一次就成功,基本上有很大的機率會立刻發生錯誤失敗。但如果經過曲折離奇的路才成功,基本上真的成功的機會就很大。於是,我依照著心中自圓其說的經驗,下了開放防火牆的指令。
python set_online_sg.py
並且啟動了幾項簡單的監測系統(這真是不好意思,此系統以前連監測都沒有,情急之下我們才在轉移前幾週搭了幾項監測)。
一切正常。
「我們就再觀察看看吧!」我留言。
週一,這系統已經挺過了 24 小時,RDS 的 cpu 都在極低的範圍內跳動,throughtput 距離機型上限也還很遠,看來我們高估了用量開太大台。如果這幾天都這麼低,就可以打算縮小。RDS 就是這樣方便又安全,比之前用 EC2 自己搭建的黑盒子 db 來得令人安心。
到了星期四,我把 RDS 縮小一個等級,但這裡遇到一個坑,縮放 RDS 時其實會對 instance 做重新開機,twistd 那邊並沒有設計在 db connection 斷掉後自動重新連接,只會不斷報錯然後掛在那邊,所以必須再去手動一一重啟。
「不斷的掃雷!」我苦笑著。
經過一個禮拜,抱怨顯著減少,可以說幾乎沒有了。
但我依然擔憂,因為最前面的機器還在使用 c3 系列的 EC2,而且 ubuntu 的版本依然卡在 12,這都是八年前的老系統了!
「必須趕快再想辦法處理這件事!不然我們開大了後面的 db,總有一天,前面老舊的機型就會變成新的瓶頸!」我在會議上說。
所以我提出,我們應該開始把原來的 twistd 包成 container 並開新的 EC2 來跑,讓 process 不再依賴於 os,並且用 ELB 擋在最前面,逐步分流給新建立好的機器,直到我們確定沒有問題,可以拔掉舊的 EC2 為止。
但 K 反對,他認為系統會卡主要是因為第一頁的 sql 太複雜,他已經和 Y 在做 index,讓 query 能夠變快,再加上我們已經轉移到 RDS,效能勢必足夠。
但我認為,這邏輯怪怪的,我擔心的是前面系統和機型老舊。既然後面的 db 都已經更換高效能的機型,為何前面還要沿用舊的架構?而且就算真的加了 index 變快好了,如果前面 api server 的吞吐量小於後面 db 的吞吐量,只要有一天前面塞滿了,後面有再多厲害的 index 也是無用武之地。我們既然都知道系統有這些問題,應該要防範未然,持續的做整頓才對,而不是走一步看一步,挖東牆補西牆。
「那我必須先做風險告知,前面的 EC2 無論是機型或是系統都相當老舊,你可以當作他還在跑 windows XP 這種古董級的電腦。雖然現在調了 db 沒了抱怨,但我不知道他能夠撐多久,哪一天再爆一次都不奇怪!」我慎重地說明。
後來 K 就問我說如果要搞 ELB 並做 container 化,需要多少時間。
「我其實已經在做準備,以目前實驗的狀況,最多再兩週!」我回覆。
原來 K 在意的是時間,他以為還需要一個月,這樣就會延誤到後面專案的進度。
但這也是我不能理解的地方,專案必然重要,但系統高度不穩定,不先趕快集中人力調教他,反而在計較調教的時間會影響後續專案,這不是本末導致嗎?
不過,我並沒有說出這些,因為我的目標很簡單,就是把系統趕快搞好,至於他人的想法,就不是一夕可以改變的。
於是,RDS 轉移的任務就告一段落,開啟了 container 化原來的系統以及掛上 ELB 的新挑戰!
延伸閱讀:
拯救脆弱系統 – migrate to RDS by DMS #3
AWS Data Migration Service 攻略
封面圖片備註:成功複製了 db,創造了世界上另一個 db 雙胞胎