1. 程式人生 > >一個迅速發展創業公司的 RDS 重塑之路

一個迅速發展創業公司的 RDS 重塑之路

RDS

RDS 是關係型資料庫服務。有贊為什麼重新打造 RDS 東西?這要從四個角度去分析:背景、問題、發展、實現。

有贊四個發展階段的問題

首先,背景來說的話有贊是一家創業公司,它從 0 到 50 人團隊的時候,業務相對而言還是比較單一的。這個時候的業務發展沒有那麼快。而到了 50-200 人階段的時候,業務線非常的多,比如說微小店、微商城,再比如說分銷的業務,這些業務線起來之後,流量是慢慢的緩增到 200-300 人階段的時候,大量工程師在快速的湧入公司,並且設計量這個時候也在增長。到 300 人的時候不僅僅是流量的緩增,而且這個時候流量也滿滿地增長,這個是比較重要的。

這樣四個階段的背景下面產生什麼樣的問題呢?

在 0-50 人的時候,人員相對比較能 Hold 住 MySQL。

50-200 人階段對資料庫壓力是比較大的,所以產生了讀寫分離的需求,因為單機 MySQL 壓力是蠻高的。

而到 200-300 人不僅僅是流量的增加,而且是資料量的增加。對單一的垂直業務線而言本身資料量在 MySQL 是 Hold 不住的。

等到 300 人 + 的時候全部業務線全面開花,包括業務人員,開發人員很多 DDL 產生,流程會變得很重,這都是很典型的創業公司的問題。

技術棧的發展

針對這些問題我們跟網際網路公司差不多是一樣的,首先它的發展而言對 MySQL 而言是單接使用率,然後到很典型使用應用程式,主動的去讀或者是寫 Master。

技術棧的發展

到第三階段讀寫分離,這裡有一個背景是說我們的業務是基於 PSP 原始線。所以當流量上來的時候,在 MySQL 中間一層加像 360 的一個開源元件 Altas。後面一個階段,引入阿里巴巴的一個開源的帶 Sharding 功能的方案 Cobar。

介紹一下這兩個元件的區別和方案的對比。

360 開源元件 Altas 滿足了讀寫分離的需求,但是在電商領域或者更嚴格要求 ACID 的金融領域來說的話事務性要求很高的,這點是短板;不過它做了更好的運維上面的上線、下線 MySQL 的控制。而阿里巴巴的開源元件 Cobar 是簡單的對 MySQL 做一些 Sharding。這兩個架構本身而言對有贊來說的話是經歷了比較長的一個時間,直到我後來加入之後,我把這些問題梳理了一下,這些問題主要會產生線上的故障非常多,即便是引入了 360 或者阿里巴巴的架構實現來說的話還是有很多的問題。所以我們進行了改造,變成了 RDS-Proxy。

重塑,剖析 RDS-Proxy

本身 RDS 不是一開始就有的。這個是 Proxy 的一個雛形,為了去掉 RDS 和 kober,我們在 kober 上進行了改造,所以 Proxy 是一箇中間基層,所以上下協議都是通過 MySQL 協議來訪問的。

剖析 RDS-Proxy

在 Proxy 上我們增加了很多的功能,比如讀寫分離,還增加了 MySQL 的權重,原先是沒有的。而 ConnPool 也做了大量改造,主要是增強了它的連線數的複用性。原來 Kober 和那個的連線池用的是 IP+Pool 再加 MySQL 資料庫的 Sgam。而我們改造後是共同承載非常多的 Sharding。這個 BIO 和 NIO 是比較大的改造,本身這個是非常重要的一點,無論是哪個方案,對於 MySQL 而言,它的 IO 是同步的協議在 IO 上很消耗效能。所以我們加前端的連線和後端的連線改成 NIO。這樣的話就可以釋放出 Proxy 上大量的記憶體。這個改造後我們就大量的提升了線上的效能,包括 Plos 的效能。

Plos 的效能

除了效能的改造之外我們還做了一些類似 FastFailed 的機制,對於 RDS-Proxy 改造後我們形成了這樣的功能,就是前面所說的幾點,ShardingFuction 增強,很重要的一點是 BIO 改造成了 NIO,無論是前置的連線和後置的連線都進行了改造,而 FastFailed 是增加了壟斷的機制。通過這些改造後大家會不會有疑問,說增加了這麼多功能它的效能會下降,其實不然。實際上我們通過改造程式碼量增加了,但是效能是提高了非常多的。首先我們在這樣的測試場景下面,我們的背景使在 E5-2630 24CPU 上,千兆網絡卡打滿了,Proxy 本身會氣動 8×24 執行緒。而實際測的資料如螢幕上顯示的,較以前的效能來說有 30% 的提高,140K QPS。

做了這麼多效能對於穩定性有什麼樣的效果呢?我們由原來一個季度裡會有 1-3 次的故障,而且是全站故障,改造後變成了 0 個。我們現在目前改造之後是沒有全站故障的,因為 MySQL 的訪問,Proxy 的訪問所導致的。

說了這麼多,我們做了哪些功能?我舉個簡單的例子講一下如何實現的,下面可能會比較燒腦,因為有一些程式碼,不太適合在開場或者熱身的階段,所以舉個比較簡單的事情。讀寫分離,原來是沒有讀寫分析的,所以對靜態類,這塊是新加的功能,我先講一下總體的功能。MySQL Data Note 裡會使用到 Channl,每個 Channl 是去執行 SQL 語句的。本身 MySQL 會使用到 Sleef,每個請求用一個連線,或者多個請求複用一個連線。原來沒有 Sleef 要求,我進行了改造,並且進行了檢測是否可用。對於前置的連線來說的話進行判斷是否進行讀寫分離。而對於讀寫分離我們是不願意讓業務上層去做太多改造所以用了 MySQL Fent,然後再做路由,去拿到後端的路由之後,然後決定是選擇 Master 還是最底下的哪個 Sleef。最終這樣的改造之後夠可以滿足到讀寫分離功能。

即便是做了這麼多效能跟穩定性改造之後,其實還是有很多的問題。尤其是在 300 人的團隊以上,這個時候團隊裡的技能是參差不齊的,尤其是有多的業務線,有很多的研發,有很多的流量,而這些引發出每一天做 DDL 的變更會很多。而在 DDL 的變更,像在一個叢集數量大的時候,每個分片都要做對接,引發的故障也會多一些。並且研發人員多跟 DBA 交流和互動時間效率也會變得很低。並且業務開發人員他的 SQL 技能是跟不上,比如說覆蓋索引,組合索引,MySQL 緊密索引,都沒有什麼概念,在技能沒有跟上的情況下面,對於生產系統是一個非常大的挑戰。並且 MySQL 本身也會有 Feel,Master 要掛掉,在這個時候會頻繁發生 MySQL HA。而對 MySQLHA 是災難性事情,資料是很難保持一致。所以在退化資料的時候,在退化的過程中資料的一致性是非常難以保證。所以在這樣的問題下面,我們單純的 RDS 功能增加有如下的,對 Proxy 的改造,增加了 DDL 支援工作流,讓每個研發人員能夠在同一個平臺提交 DDL,並且幫助 DBA 節省他熬夜的工作時間,能夠提升他自己的工作效率,這個是比較重要的。第三,對 MySQLHA 的一些改造。

 MySQLHA

講 RDS 結構之前先一下 RDS 模組。它的模組如圖。

RDS

Console 是作為總管理端和操作入口。Proxy 是從一開始就有,這是使用者訪問的代理層。而 HA Master 是作為 HA 檢測和切換操作。Canal Manager 是作為資料驅動的事件通知系統,Tablet 是部署我在每個 MySQL 主機上面的代理,是一個 Local Agent,Tablet 現在能夠承載於啟動 MySQL 指令,能夠對 MySQL 進行白名單的過濾,而 MySQL 本身是我們網際網路重度依賴的一個開源的軟體資料庫的。在每個單機上會部署多個數據組。M 就是 Master1 的使令,Tablet 是跟 RDS 互動,當然 MySQL HA 要做的時候,檢測中 MySQL Master 掛了,要啟動其中的一個 F1 或者 0,是通過 Master 檢測和控制的。本身 HA-Master 跟 Console 可以放同一個程序裡,但是迭代是比較快,所以為了穩定性拆開,後續會考慮合併。然後把 MySQL 上面的 Realy 儘量蒐集到且回放給 log。通過這樣鏈路的調整之後,我們現在夠去掉了原先 VIP 那個 RDS 的方案。右下角這端相對而言是互聯網裡比較常用的事件驅動源的架構對孵化的程序中,這個可以忽略。

效果展示

系統架構

這個是當時梳理的系統架構,系統裡的概念,主要針對運維的需求和線上開發人員,還有 DBA 的一些需求和 MySQL 自己本身的一些概念所做的一些梳理。所以對 RDS 做了這些 Proxy 改造和 DDL 的工作流之後,我們對 RDS 有一個相對比較大的提升。整個控制檯可以看到所有的都在這個控制檯,可以看到單純的流量是多少等等。這裡截了兩張圖,沒有太多的演示,因為這個產品介面本身也在不斷的改,主要是這兩個功能是比較重要的。

寫在最後

最重要的一點,我覺得在 300-1000 人或者在未來更多人的團隊裡,工作流是非常重要的,而且在使用 MySQL 過程中,它的本身就很複雜,無論它的合理實現或者不合理實現都會引發概念上或者實現上的一些區別,所以我們對 DDL 進行工作流的支援,這樣的話就可以提高整個業務線上面開發效率,能夠縮短業務上線時間。我認為這個是比較重要的工作效率的提高。雖然說很多的所謂想做高併發軟體設計不適合做這個,但是這個是很重要的事。關於 RDS 前面講了我們所做的,可能沒那麼多高大上的事情,但是實際上是我們已經做的事,和關於 RDS 未來我們還會繼續往以下的系統模組再繼續加深。RDS-Console,做更好的測試,RDS Proxy 做更好的效能和流量的劃分。HA Master 會引入 Roft 協議做診斷,而不是像前面所看到的圖裡面,它是中間是居前判斷。而 CanalManager 會併入,不是通過 Canal 量,而是通過整套系統輸出的。而 Tablet 會做更多的試用和運維的動作,而 MySQL 沒有太多的改造,只會做更新迭代。

 提問:請問 DDL 具體怎麼提高工作效率的?

林足雄:我不知道多少人經歷過 0-300 人團隊或者 300 人團隊。DDL 本身開發給 DBA 提交 DDL 的時候,它是通過口對口,或者文字檔案或者是後來稍微改進一點的,比如工作流,在這裡提交一個工單,然後 DBA 每天去過那些工單。過完工單之後,DBA 把具體的 DDL 在 MySQL 上通過命令函 CL 顯示執行 DDL。而 DDL 本身當時來說是沒有問題的。

我前面提到了,業務線非常多的時候,在七八個語句的時候效率蠻高的,當又有分片的時候來說,每條具體的語句就要形成 1014 個執行任務,DDL 的時間就會很大量的佔用 DBA 的時間。還包括 DDL 對於每一個 Sharding 上是否成功 DBA 也關心。而是否成功這個動作本身還是需要同步等待的。比如說一百句資料庫的話它就得等,或者過一段時間再檢查。而改造變成把這些工作流全放在管理系統裡。管理系統裡通過開發人員在管理系統裡提交工單,然後給具體的執行 MySQL,把執行的後果和進度提交到 Console 系統上,上報到 Console 系統可以通過介面展示,並且連動手機的報警和簡訊,或者我們有贊內部的 APP 系統蒐集就可以。這樣會減少 DBA 凌晨執行任務的時間。因為大量的 DBL 是在凌晨跑的。比如說十句以下的 DDL 下去,DBA 在凌晨不需要值班,以前是需要的。所以 DBA 的生命還是蠻寶貴的。

作者介紹

林足雄,有贊架構師,2010-2013 金山軟體,開發經理 + 架構師;2013-2015 蘑菇街,架構師;2015- 至今 有贊,中介軟體 TL+ 架構師。

文章來自微信公眾號:高效開發運維