談談MySQL水平擴展

jopen 9年前發布 | 33K 次閱讀 MySQL

原文  http://www.gpfeng.com/?p=657

寫在前面

14年中換了一份工作,出國游蕩了一陣子,目前工作離數據庫內核遠了點,離業務近了些,業務層面碰到的‘高深’技術問題也少了,旅行后發現人也懶了不少,導致博客都長草了

2015開始了,先表態一下目標: 我2015年的目標就是搞定2014年那些原定于2013年完成的安排,不為別的,只為兌現我2012年時要完成的2011年年度計劃的諾言

談談MySQL水平擴展

問題背景

工作中遇到數據庫數據增長過快,單表一年之后預計到達35M行數據,可以預見MySQL性能將下降厲害,并且隨著業務的規模化,擔心單表將很難抗 住并發壓力,出現故障后恢復時間變長對業務影響也會變大,因此需要考慮數據水平擴展,目前項目采用Golang開發,一個Google開發的以簡潔的語 法,內建高并發模型,支持垃圾回收為主要特點的編譯型語言,性能比Java好,開發效率比C/C++高,其目標是替代C/C++

分庫分表

這四個字在阿里聽得最多,其實這也是被問題和壓力推動的,畢竟要支撐起那么大的業務,等著Oracle這樣的公司提供解決方案是不靠譜的,還不如 卷起袖子自己干,接著就陸續搞出并開源了Cobar,TDDL(不給出鏈接了,太容易搜到)這些數據庫中間件,Cobar應該在TDDL之前,這個東西采 用proxy方式,性能肯定不如以后續jdbc層面實現的TDDL,畢竟少了一次網絡轉發,現在TDDL在阿里核心系統上大量使用,不過外部用戶想用起來 這個沒有那么容易,首先語言限制在了Java,另外還需要阿里配置管理服務Diamond的支持

要想水平擴展,就需要分庫分表的支持,分庫分表這四個字說起來很容易,按照id取模將數據打散分攤壓力,但是干完這些之后需要解決由此帶來的問題,這些很難:

            1. 事務支持,擴庫/擴表后事務就成分布式的了,問題難度顯然上升了一個級別
        </p>
        <p>
            2. 查詢結果合并,這個看起來不難,但是把order by/limit/查詢中不帶分表字段等加上,要解決的問題還也不少
        </p>
        <p>
            3. join,這個更難
        </p>
        <p>
            4. 分庫?分表?還是分庫分表?這個需要考慮并做一個決定
        </p>
        <p>
            5. 分完后能否合并?分容易,和很難
        </p>
        <p>
            6.。。。
        </p>
    </div>
    <h3>
        開源解決方案
    </h3>
    <p>
        數據庫分庫分表開源產品有很多,下圖中列出了6個,它們已經在線上承載了較大壓力,主要分為2類:代理及非代理,非代理方式是以library方 式提供,library負責SQL解析,路由計算等,位于driver層,實現難度較大,一般僅支持少數幾種語言;代理方式相當于一個多了一次轉發,應用 程序連接的是代理服務器,由代理服務器負責路由計算并發送SQL到目的DB,多一次網絡,因此在性能上代理方式比非代理方式性能稍低
    </p>
    <p>
        <img src="https://simg.open-open.com/show/e83d8948cdd34496734f7f78866a7d63.jpg" alt="談談MySQL水平擴展" height="442" width="700" /> 
    </p>
    <p>
        這些解決方案中MySQL Fabric/TDDL兩個為非代理方式,直接提供語言層面的支持,優點是性能會很好,劣勢是支持的語言很受限制,TDDL支持支Java,MySQL Faric支持Java/PHP/Python,想實現其他語言支持,相當于再次實現一次,不過目前Java/PHP/Python非常流行,能夠覆蓋的 用戶很多了,TDDL對于外部用戶來說,先用起來沒有那么容易,和阿里平臺緊密綁定,如果有時間配置Diamond的話,可以好好研究,這里不進行深入探 討
    </p>
    <p>
        另外四個全部都是Proxy方式,以部分性能換來靈活性,這個就是仁者見仁智者見智的決定了,值得一提的是BAT中B也實現了一個 <a href="/misc/goto?guid=4958860561244840629">Heisenberg</a> 的中間件,從部分代碼、配置以及文件結構來看,這個是從Cobar來的,應該優化了部分特性,不進行贅述,有興趣可以自己研究
    </p>
    <div>
        <p>
            MySQL Fabric
        </p>
        <p>
            這個是MySQL官方水平擴展方案,號稱管理目標為:farm of mysqld,其實我比較看好這個東西,原因是個人喜歡簡潔的東西,總感覺Proxy方式多了一層轉發帶來了麻煩,除了性能外還有復雜性,運維起來也多了 不少事情,畢竟這個進程down掉后可用性會受到影響,簡單才是美,希望MySQL Fabric能夠提供更多語言支持
        </p>
    </div>
    <div>
        <p>
            Cobar
        </p>
        <p>
            Cobar是阿里的中間件,以Proxy方式提供服務,在阿里內部大量使用,目前已經開源在 <a href="/misc/goto?guid=4958860561333047516">github</a> 了,贊開源精神,據說在很多外部公司有一些成功使用的案例,配置比較容易,不需要依賴其他東西,有Java環境就OK,小試了一把,事務支持比較麻煩,需 要通過set autocommit=0來實現,如果想要完美支持的話,還是需要修改JDBC或對應語言的MySQL library,分庫示意圖(Cobar中d.t分到兩個庫中:d1.t,d2.t):
        </p>
    </div>
    <p>
        <img src="https://simg.open-open.com/show/913d18f4eed05022debc6137df48d4a1.jpg" alt="談談MySQL水平擴展" height="347" width="597" /> 
    </p>
    <p>
        Cobar支持分布式分表,但是不支持單庫分多表,前段(對接APP)和后端(對接MySQL)都實現了MySQL客戶端協議,比較友好,對于擴 表結果集的合并也支持,寫其內部的SQL parse工程師功底應該比較深,顯示起事務會報錯,應該是“BEGIN”或者“Start transaction”不包含分表信息的緣故,但是這個可以通過defer到后面一個包含分表信息的SQL過來一起發到目標庫中執行或者通過分布式事 務,比如2PC來支持,執行效果:
    </p>
    <p>
        <img src="https://simg.open-open.com/show/b23a2accb39ba5e1a06132313a3f1251.jpg" alt="談談MySQL水平擴展" height="659" width="523" /> 
    </p>
    <div>
        <p>
            Atlas
        </p>
        <p>
            雖然個人對數字公司沒啥好感,但是這個 <a href="/misc/goto?guid=4958860561420845098">Atlas</a> 還是非常有特點的,它是基于MySQL-Proxy上二次開發的,主要支持兩個特性:分表和讀寫分離,但是分表的話只支持單庫多表,即事實上是不支持分布 式分表的,所有分表都在同一個庫中,小試了一把,下面是分庫示意圖(四個分表t_0,t_1,t_2,t_3在同一個庫中):
        </p>
    </div>
    <p>
        <img src="https://simg.open-open.com/show/7376e818989ae80c72d62b2b319e35c1.jpg" alt="談談MySQL水平擴展" height="424" width="700" /> 
    </p>
    <p>
        Atlas擴展性限制在單實例最大性能,但是好處是:事務支持的很好,因為不存在跨庫事務,有些事情反而變得簡單,讀寫分離這個東西其實沒有水平 擴展那么難,畢竟MySQL的備庫很好搭,不得不吐槽一下,通過atlas看到的不是一張完整的表,而是各個分表,只能通過分表的字段定位和操作數據,否 則會報錯,與Cobar對比后,Atlas這個產品其實簡潔也粗糙很多,但是的確有它特有的應用場景:
    </p>
    <p>
        <img src="https://simg.open-open.com/show/42d5b3e12ebeacea5b1a877385d1155b.jpg" alt="談談MySQL水平擴展" height="736" width="551" /> 
    </p>
    <p>
        另外,Atlas配置稍微簡單一些,但是分表算法支持上相對于Cobar顯得并不完善
    </p>
    <div>
        <p>
            Vitess
        </p>
        <p>
            <a href="/misc/goto?guid=4958860561509202607">Vitess是</a> 油Tube開源的數據庫擴展及高可用方案,已經用于生產環境,功能強大,但是構架復雜,部署及運維成本較高,構架圖:
        </p>
    </div>
    <p>
        <img src="https://simg.open-open.com/show/46517d8ad491858f9d11621d31fabd1a.jpg" alt="談談MySQL水平擴展" height="456" width="700" /> 
    </p>
    <p>
        Vitess在app與database之間存在vtgate及vttablet兩個server,vttablet實現了MySQL連接池及 row cache,與MySQL實例是一對一關系,可以當成是MySQL前端,一般與MySQL部署在一起,所有落到MySQL的query都需要經過 vttablet,vtgate是一個proxy,負責路由計算以及app及vttablet之間的數據轉發,分表規則及配置數據存放在topology 中(zookeeper實現),因此每個query執行需要走的路徑較長,雖然vttablet實現的連接池和row cache可以加速query執行速度,但是zookeeper訪問,app與vtgage、vtgate與vttablet之間兩次數據轉發都要走網 絡,如果網絡不夠穩定可以預見性能損失較大
    </p>
    <p>
        通過與vitess開發者確認,vtgate會緩存topology的分表規則數據,因此相對于其他proxy方案,只是多了一層vttablet的轉發代價,但是考慮到row cache的加速,最后性能應該相差不大
    </p>
    <p>
        另外,這個項目是采用Golang語言的,這對于Golang項目優勢非常明顯,采用本文中Vitess之外的方案, <a href="/misc/goto?guid=4958860561599179979">go-sql-driver</a> 無法支持事務,詳見 <a href="/misc/goto?guid=4958860561689591374">google-group vitess</a> 討論
    </p>
    <h3>
        總結
    </h3>
    <p>
        本文源于項目實際需求,對國內外開源的MySQL水平擴展方案做了一個簡單總結,可以看到國內互聯網公司這這方面做得很不錯,再次為他們的開源精神點贊
    </p>
</div>

</div>

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!