分庫又分表,吞吐要爆表
本文轉載自微信公眾號「有關SQL」,作者Lenis 。轉載本文請聯系有關SQL公眾號。
“你們最大的表,有多少數據量?”
圈子里幾個常玩的伙伴,聚在一起吃火鍋,或者喝咖啡,通常都會問些特技術范兒的問題。上面這個,就是常問的問題之一。
其實,倒也不是真對數據量感興趣,而是量大了之后,碰到什么特別有意思的事情,以及,用了什么特別的方法解決。
上億了之后,怎么解決;上 TB 級別的存儲量,又怎么解決。
就這樣的問題,如果是在星巴克,大家伙兒都能吹到下半夜去。我記得,最帶勁的劉哥,一言不合,就打開黑乎乎的 shell, 給我們演示。
像這樣的大表場景,如果分庫分表,就是最終殺器。剛開始,幾個外企和民企的朋友,還經常吵嘴。一波人說分庫分表,另一波說 sharding, partitioning, 吵來吵去,都是一個意思。
Partition 不是數據庫中常說的表分區,實際上它和分庫分表一個意思。而 Sharding (分片)則是 MongoDB, ElasticSearch 等這類 NoSQL 數據庫針對分庫分表的專有術語。
那么,分庫分表究竟該怎么用呢,涉及到的原理都有哪些呢?說實話,這個話題太大,在本文中,并不能全部一一說到,我只挑自己理解的來說。
讀和寫,數據庫之本
這看起來是句廢話。數據庫可不就用來存儲,和返回數據的嘛!是的,同學你可以把搬磚放下,還不到砸我的時候。
讀和寫是基本,就和人要吃飯運動一樣,是最基本生理活動。人吃飯吃多了,或者運動過多了,那問題就大了。一旦讀和寫,都開始多起來了,同樣也會帶來一系列的問題。
讀自己的數據,讓別人無數據可讀
這,并不是玩笑話。但它有個前提,數據庫的連接數,是有限的。一旦超額,就再也無法新建連接。此時,只有先連上的用戶,才能讀取數據。之后的請求,只能排隊等待,或者干脆收到 timeout(超時) 警告。
說到這,順便再提下,前兩天我在談到 Replication(復制時), 提到農村里看電影的例子。
80年代的農村,經常有戲班子來放露天電影。所謂“露天”,就是臨時在村頭,搭個舞臺,吊塊幕布,把電影投射上去,支個功放,村民就開始看電影了。
畫個草圖,大概就是這樣子:
這露天電影有個難受的地方,前排的人,耳朵炸聾,后排的人,啥都聽不見。觀影體驗賊差,所以整場下來,只有小孩和真正的影迷,能堅持到最后。其他人中途都跑了。
所以戲班子想了個法兒,在村頭村尾各搭個舞臺。這樣容納的人就多了。有些村實在口人太大,那就村東村西,再放兩個舞臺。這樣村子里所有人,都可以照顧到了。而實現這個目的,就只需復刻 3 份膠卷。
這就是數據庫復制原理所在。把數據復刻多份的時候,就可以供更多人讀取。
所謂“做人留一線,日后好相見”。看個電影而已,沒必要傷害鄉里鄉親的感情。大家為了搶一個好位置,最后結局只能是誰都看得不爽。所以這里看不了,我就去別的場地看。
復制技術出來之后,讀數據就不搶占一個庫了。這臺服務器讀請求,在排隊,那就去另一臺服務器。假設網絡里,服務器夠多,那么總有一臺能讀到數據。
SQL Server 可以支持 8 臺服務器同時服務讀,而 MySQL 通過中間件,則可以支持更多,比如 MySQL Proxy, MySQL Cat, MySQL DAL等等。
寫入時代大爆炸
之前欣賞電影,只能在電影院,生產這些電影,往往都是大團隊。那時,看電影,純屬于消費時代。
但4G, 5G來了之后,消費時代悄然變化了。小團隊,甚至個人,開始制作電影。小眾視頻,勝在長尾效應。比如 Youtube, B 站,這個時代,人人兼可創作。
如此之多的視頻,僅靠電影制片廠,是完全來不及生產了。網民集體的創作狂熱,必須由民間力量,B站,愛奇藝,騰訊視頻等等,來 Hold 住。
就像,你的數據庫,在經歷了 7, 8年的發展后,受眾越來越多,大家寫入的熱情也越來越高漲。此時,數據庫,也將面臨跟視頻網站一樣的困擾,究竟該如何支撐主這些 “洪流”?
經歷了大爆炸后,視頻平臺痛下決心,把視頻服務器分散,開到全國去。在全國各個重要的大城市,組建視頻中心,讓周圍的視頻創作者,把視頻傳到這些服務器上。
這就是分庫分表的模式。
雖然華東南西北中,是相互獨立的,但它們的視頻始終都以邏輯整體存在。一個VLOG作者,在北京上傳了個視頻,如果坐飛機到了廣州,他就訪問不到在北京上傳的那個視頻,那怎么也說不過去。
所以,所有這些視頻,都是維護在一張邏輯表中。根據這些視頻的上傳者GIS地址,傳到最近的服務器上。這就是分庫分表常用的,按 Key 值分區策略。雖然這樣的策略,會有一系列問題,但暫且這么理解。
分庫分表好處非常明顯,一來可以容納更多數據量,二來訪問更快捷。
怎么實現分庫分表呢?
有人說,可以用客戶端代碼來控制訪問數據庫;也有人說,我就愛寫中間件,讓服務器自動支持分庫分表,并且沒有語言限制,也很極客;還有人說,用云原生,程序員負責實現邏輯,運維這檔子事交給供應商。
當然,統統都可以。但是本文還是著重講講中間件。畢竟,供應商費銀子,客戶端費腦子,只有中間件,可以一勞永逸。
分享 2 種方法:
Percona XtraDB Cluster方案
Percona XtraDB Cluster簡稱PXC。Percona Xtradb Cluster的實現是在原mysql代碼上通過Galera包將不同的mysql實例連接起來,實現了multi-master的集群架構。
上圖中有三個實例,組成了一個集群,而這三個節點與普通的主從架構不同,它們都可以作為主節點,三個節點是對等的,這種一般稱為multi-master架構,當有客戶端要寫入或者讀取數據時,隨便連接哪個實例都是一樣的,讀到的數據是相同的,寫入某一個節點之后,集群自己會將新數據同步到其它節點上面,這種架構不共享任何數據,是一種高冗余架構。
作者:羅阿紅 出處:http://www.cnblogs.com/luoahong/
MySQL DAL (Data Access Layer )
當年手機之家高春輝領導開發的產品。它解決了單臺計算機容量有限的難題。真正實現了分庫分表的優勢。
DAL 有三大組件,Java Netty 框架,ZooKeep 控態,SQL 處理模塊( 通過分解 SQL 生成語法樹,依據 SQL 路由表,生成對應的執行路徑)
由于 MySQL DAL 是閉源產品,相關的實現沒有源碼可看。但我看到這篇論文有提及部分原理:
嗯,上次有微信群水友問,數據庫開發與數據庫開發有什么區別。大概在這里,可以說的明白了。
一類人,是做CRUD應用系統的開發,比如做個報表,寫個ETL;另一類數據庫開發,是實現數據庫的某項功能,比如分庫分表組件。