<form id="hz9zz"></form>
  • <form id="hz9zz"></form>

      <nobr id="hz9zz"></nobr>

      <form id="hz9zz"></form>

    1. 明輝手游網中心:是一個免費提供流行視頻軟件教程、在線學習分享的學習平臺!

      mysql數據庫分庫分表技術難點處理策略

      [摘要]mysql數據庫分庫分表方案,一旦數據庫過于龐大,尤其是當寫入過于頻繁,非常難由一臺主機支撐的時候,我們還是會面臨到擴展瓶頸。這時候,我們就必須許找其它技術手段來解決這個瓶頸,那就是我們這一章所要介...
      mysql數據庫分庫分表方案,一旦數據庫過于龐大,尤其是當寫入過于頻繁,非常難由一臺主機支撐的時候,我們還是會面臨到擴展瓶頸。這時候,我們就必須許找其它技術手段來解決這個瓶頸,那就是我們這一章所要介紹惡的數據切分技術。


      mysql數據庫切分

      前言

      通過MySQLReplication功能所實現的擴展總是會受到數據庫大小的限制。一旦數據庫過于龐大,尤其是當寫入過于頻繁,非常難由一臺主機支撐的時候,我們還是會面臨到擴展瓶頸。這時候,我們就必須許找其它技術手段來解決這個瓶頸,那就是我們這一章所要介紹惡的數據切分技術。

      何謂數據切分

      可能非常多讀者朋友在網上或者雜志上面都已經多次見到關于數據切分的相關文章了,僅僅只是在有些文章中稱之為數據的Sharding。事實上無論是稱之為數據的Sharding還是數據的切分,其概念都是一樣的。

      簡單來說,就是指通過某種特定的條件,將我們存放在同一個數據庫中的數據分散存放到多個數據庫(主機)上面,以達到分散單臺設備負載的效果。數據的切分同一時候還能夠提高系統的總體可用性,由于單臺設備Crash之后。僅僅有總體數據的某部分不可用,而不是全部的數據。

      數據的切分(Sharding)依據其切分規則的類型。能夠分為兩種切分模式。

      一種是依照不同的表(或者Schema)來切分到不同的數據庫(主機)之上,這樣的切能夠稱之為數據的垂直(縱向)切分。另外一種則是依據表中的數據的邏輯關系,將同一個表中的數據依照某種條件拆分到多臺數據庫(主機)上面。這樣的切分稱之為數據的水平(橫向)切分。

      垂直切分的最大特點就是規則簡單,實施也更為方便,尤其適合各業務之間的耦合度非常低。相互影響非常小,業務邏輯非常清晰的系統。在這樣的系統中,能夠非常easy做到將不同業務模塊所使用的表分拆到不同的數據庫中。依據不同的表來進行拆分。對應用程序的影響也更小,拆分規則也會比較簡單清晰。

      水平切分于垂直切分相比。相對來說略微復雜一些。由于要將同一個表中的不同數據拆分到不同的數據庫中,對于應用程序來說,拆分規則本身就較依據表名來拆分更為復雜,后期的數據維護也會更為復雜一些。

      當我們某個(或者某些)表的數據量和訪問量特別的大,通過垂直切分將其放在獨立的設備上后仍然無法滿足性能要求,這時候我們就必須將垂直切分和水平切分相結合。先垂直切分,然后再水平切分。才干解決這樣的超大型表的性能問題。

      以下我們就針對垂直、水平以及組合切分這三種數據切分方式的架構實現及切分后數據的整合進行對應的分析。

      數據的垂直切分

      我們先來看一下,數據的垂直切分究竟是怎樣一個切分法的。數據的垂直切分。也能夠稱之為縱向切分。將數據庫想象成為由非常多個一大塊一大塊的“數據塊”(表)組成。我們垂直的將這些“數據塊”切開,然后將他們分散到多臺數據庫主機上面。這樣的切分方法就是一個垂直(縱向)的數據切分。

      一個架構設計較好的應用系統。其總體功能肯定是由非常多個功能模塊所組成的。而每一個功能模塊所須要的數據對應到數據庫中就是一個或者多個表。

      而在架構設計中,各個功能模塊相互之間的交互點越統一越少,系統的耦合度就越低,系統各個模塊的維護性以及擴展性也就越好。這樣的系統。實現數據的垂直切分也就越easy。

      當我們的功能模塊越清晰,耦合度越低,數據垂直切分的規則定義也就越easy。全然能夠依據功能模塊來進行數據的切分,不同功能模塊的數據存放于不同的數據庫主機中,能夠非常easy就避免掉跨數據庫的Join存在。同一時候系統架構也非常的清晰。

      當然。非常難有系統能夠做到全部功能模塊所使用的表全然獨立,全然不須要訪問對方的表或者須要兩個模塊的表進行Join操作。這樣的情況下,我們就必須依據實際的應用場景進行評估權衡。決定是遷就應用程序將須要Join的表的相關某快都存放在同一個數據庫中,還是讓應用程序做很多其它的事情,也就是程序全然通過模塊接口取得不同數據庫中的數據,然后在程序中完畢Join操作。

      一般來說。假設是一個負載相對不是非常大的系統,并且表關聯又非常的頻繁。那可能數據庫讓步。將幾個相關模塊合并在一起降低應用程序的工作的方案能夠降低較多的工作量。是一個可行的方案。

      當然。通過數據庫的讓步,讓多個模塊集中共用數據源,實際上也是簡單介紹的默許了各模塊架構耦合度增大的發展,可能會讓以后的架構越來越惡化。尤其是當發展到一定階段之后,發現數據庫實在無法承擔這些表所帶來的壓力。不得不面臨再次切分的時候。所帶來的架構改造成本可能會遠遠大于最初的時候。

      所以。在數據庫進行垂直切分的時候,怎樣切分,切分到什么樣的程度,是一個比較考驗人的難題。僅僅能在實際的應用場景中通過平衡各方面的成本和收益。才干分析出一個真正適合自己的拆分方案。

      比方在本書所使用演示樣例系統的example數據庫,我們簡單的分析一下。然后再設計一個簡單的切分規則,進行一次垂直垂直拆分。

      系統功能能夠基本分為四個功能模塊:用戶,群組消息,相冊以及事件。分別對應為例如以下這些表:

      1. 用戶模塊表:user,user_profile,user_group,user_photo_album

      2. 群組討論表:groups,group_message,group_message_content,top_message

      3. 相冊相關表:photo,photo_album,photo_album_relation,photo_comment

      4. 事件信息表:event

      初略一看,沒有哪一個模塊能夠脫離其它模塊獨立存在,模塊與模塊之間都存在著關系。莫非無法切分?

      當然不是,我們再略微深入分析一下,能夠發現,盡管各個模塊所使用的表之間都有關聯,可是關聯關系還算比較清晰,也比較簡單。

      ◆ 群組討論模塊和用戶模塊之間主要存在通過用戶或者是群組關系來進行關聯。一般關聯的時候都會是通過用戶的id或者nick_name以及group的id來進行關聯。通過模塊之間的接口實現不會帶來太多麻煩。

      ◆ 相冊模塊僅僅與用戶模塊存在通過用戶的關聯。這兩個模塊之間的關聯基本就有通過用戶id關聯的內容。簡單清晰,接口明白;

      ◆ 事件模塊與各個模塊可能都有關聯,可是都僅僅關注其各個模塊中對象的ID信息,相同能夠做到非常easy分拆。

      所以。我們第一步能夠將數據庫依照功能模塊相關的表進行一次垂直拆分。每一個模塊所涉及的表單獨到一個數據庫中,模塊與模塊之間的表關聯都在應用系統端通過藉口來處理。例如以下圖所看到的:

      20150228194849_11.png

      通過這樣的垂直切分之后。之前僅僅能通過一個數據庫來提供的服務。就被分拆成四個數據庫來提供服務,服務能力自然是添加幾倍了。

      垂直切分的長處

      ◆ 數據庫的拆分簡單明了,拆分規則明白;

      ◆ 應用程序模塊清晰明白,整合easy。

      ◆ 數據維護方便易行,easy定位。

      垂直切分的缺點

      ◆ 部分表關聯無法在數據庫級別完畢。須要在程序中完畢。

      ◆ 對于訪問極其頻繁且數據量超大的表仍然存在性能平靜,不一定能滿足要求。

      ◆ 事務處理相對更為復雜;

      ◆ 切分達到一定程度之后,擴展性會遇到限制;

      ◆ 過讀切分可能會帶來系統過渡復雜而難以維護。

      針對于垂直切分可能遇到數據切分及事務問題,在數據庫層面實在是非常難找到一個較好的處理方案。實際應用案例中,數據庫的垂直切分大多是與應用系統的模塊相對應,同一個模塊的數據源存放于同一個數據庫中,能夠解決模塊內部的數據關聯問題。而模塊與模塊之間,則通過應用程序以服務接口方式來相互提供所須要的數據。

      盡管這樣做在數據庫的總體操作次數方面確實會有所添加,可是在系統總體擴展性以及架構模塊化方面,都是故意的?赡茉谀承┎僮鞯膯未雾憫獣r間會稍有添加?墒窍到y的總體性能非?赡芊炊鴷幸欢ǖ奶嵘。而擴展瓶頸問題。就僅僅能依靠下一節將要介紹的數據水平切分架構來攻克了。

      數據的水平切分

      上面一節分析介紹了數據的垂直切分,這一節再分析一下數據的水平切分。數據的垂直切分基本上能夠簡單的理解為依照表依照模塊來切分數據,而水平切分就不再是依照表或者是功能模塊來切分了。一般來說,簡單的水平切分主要是將某個訪問極其平庸的表再依照某個字段的某種規則來分散到多個表之中。每一個表中包括一部分數據。

      簡單來說。我們能夠將數據的水平切分理解為是依照數據行的切分。就是將表中的某些行切分到一個數據庫,而另外的某些行又切分到其它的數據庫中。當然,為了能夠比較easy的判定各行數據被切分到哪個數據庫中了,切分總是都須要依照某種特定的規則來進行的。

      如依據某個數字類型字段基于特定數目取模,某個時間類型字段的范圍;蛘呤悄硞字符類型字段的hash值。假設整個系統中大部分核心表都能夠通過某個字段來進行關聯。那這個字段自然是一個進行水平分區的上上之選了,當然,非常特殊無法使用就僅僅能另選其它了。

      一般來說,像如今互聯網非;鸨腤eb2.0類型的站點;旧洗蟛糠謹祿寄軌蛲ㄟ^會員用戶信息關聯上,可能非常多核心表都非常適合通過會員ID來進行數據的水平切分。

      而像論壇社區討論系統。就更easy切分了,非常easy依照論壇編號來進行數據的水平切分。

      切分之后基本上不會出現各個庫之間的交互。

      如我們的演示樣例系統。全部數據都是和用戶關聯的。那么我們就能夠依據用戶來進行水平拆分,將不同用戶的數據切分到不同的數據庫中。當然,唯一有點差別的是用戶模塊中的groups表和用戶沒有直接關系。所以groups不能依據用戶來進行水平拆分。對于這樣的特殊情況下的表,我們全然能夠獨立出來。單獨放在一個獨立的數據庫中。

      事實上這個做法能夠說是利用了前面一節所介紹的“數據的垂直切分”方法。我將在下一節中更為具體的介紹這樣的垂直切分與水平切分同一時候使用的聯合切分方法。

      所以,對于我們的演示樣例數據庫來說,大部分的表都能夠依據用戶ID來進行水平的切分。不同用戶相關的數據進行切分之后存放在不同的數據庫中。如將全部用戶ID通過2取模然后分別存放于兩個不同的數據庫中。

      每一個和用戶ID關聯上的表都能夠這樣切分。這樣,基本上每一個用戶相關的數據。都在同一個數據庫中,即使是須要關聯,也能夠非常簡單的關聯上。

      我們能夠通過下圖來更為直觀的展示水平切分相關信息:水平切分的長處

      mysql數據庫分庫分表技術難點解決策略

      ◆ 表關聯基本能夠在數據庫端全部完畢;

      ◆ 不會存在某些超大型數據量和高負載的表遇到瓶頸的問題;

      ◆ 應用程序端總體架構修改相對較少;

      ◆ 事務處理相對簡單;

      ◆ 僅僅要切分規則能夠定義好;旧陷^難遇到擴展性限制;

      水平切分的缺點

      ◆ 切分規則相對更為復雜,非常難抽象出一個能夠滿足整個數據庫的切分規則;

      ◆ 后期數據的維護難度有所添加,人為手工定位數據更困難;

      ◆ 應用系統各模塊耦合度較高,可能會對后面數據的遷移拆分造成一定的困難。

      垂直與水平切分的聯合使用

      上面兩節內容中。我們分別,了解了“垂直”和“水平”這兩種切分方式的實現以及切分之后的架構信息。同一時候也分析了兩種架構各自的優缺點。可是在實際的應用場景中,除了那些負載并非太大。業務邏輯也相對較簡單的系統能夠通過上面兩種切分方法之中的一個來解決擴展性問題之外?峙缕渌蟛糠謽I務邏輯略微復雜一點,系統負載大一些的系統,都無法通過上面不論什么一種數據的切分方法來實現較好的擴展性。而須要將上述兩種切分方法結合使用,不同的場景使用不同的切分方法。

      在這一節中。我將結合垂直切分和水平切分各自的優缺點,進一步完好我們的總體架構,讓系統的擴展性進一步提高。

      一般來說。我們數據庫中的全部表非常難通過某一個(或少數幾個)字段全部關聯起來,所以非常難簡單的僅僅通過數據的水平切分來解決全部問題。而垂直切分也僅僅能解決部分問題,對于那些負載非常高的系統,即使僅僅僅僅是單個表都無法通過單臺數據庫主機來承擔其負載。

      我們必須結合“垂直”和“水平”兩種切分方式同一時候使用,充分利用兩者的長處,避開其缺點。

      每一個應用系統的負載都是一步一步增長上來的,在開始遇到性能瓶頸的時候,大多數架構師和DBA都會選擇先進行數據的垂直拆分,由于這樣的成本最先。最符合這個時期所追求的最大投入產出比。然而。隨著業務的不斷擴張。系統負載的持續增長,在系統穩定一段時期之后,經過了垂直拆分之后的數據庫集群可能又再一次不堪重負,遇到了性能瓶頸。

      這時候我們該怎樣抉擇?是再次進一步細分模塊呢,還是尋求其它的辦法來解決?假設我們再一次像最開始那樣繼續細分模塊,進行數據的垂直切分,那我們可能在不久的將來,又會遇到如今所面對的相同的問題。并且隨著模塊的不斷的細化,應用系統的架構也會越來越復雜,整個系統非?赡軙霈F失控的局面。

      這時候我們就必須要通過數據的水平切分的優勢,來解決這里所遇到的問題。并且,我們全然不必要在使用數據水平切分的時候,推倒之前進行數據垂直切分的成果,而是在其基礎上利用水平切分的優勢來避開垂直切分的弊端。解決系統復雜性不斷擴大的問題。

      而水平拆分的弊端(規則難以統一)也已經被之前的垂直切分解決掉了。讓水平拆分能夠進行的得心應手。

      對于我們的演示樣例數據庫。假設在最開始。我們進行了數據的垂直切分,然而隨著業務的不斷增長,數據庫系統遇到了瓶頸,我們選擇重構數據庫集群的架構。怎樣重構?考慮到之前已經做好了數據的垂直切分,并且模塊結構清晰明白。

      而業務增長的勢頭越來越猛。即使如今進一步再次拆分模塊,也堅持不了太久。

      我們選擇了在垂直切分的基礎上再進行水平拆分。

      在經歷過垂直拆分后的各個數據庫集群中的每一個都僅僅有一個功能模塊。而每一個功能模塊中的全部表基本上都會與某個字段進行關聯。如用戶模塊全部都能夠通過用戶ID進行切分,群組討論模塊則都通過群組ID來切分。相冊模塊則依據相冊ID來進切分。最后的事件通知信息表考慮到數據的時限性(僅僅僅僅會訪問近期某個事件段的信息),則考慮按時間來切分。

      下圖展示了切分后的整個架構:

      mysql數據庫分庫分表技術難點解決策略

      實際上,在非常多大型的應用系統中,垂直切分和水平切這兩種數據的切分方法基本上都是并存的。并且經常在不斷的交替進行,以不斷的添加系統的擴展能力。我們在應對不同的應用場景的時候,也須要充分考慮到這兩種切分方法各自的局限,以及各自的優勢。在不同的時期(負載壓力)使用不同的結合方式。

      聯合切分的長處

      ◆ 能夠充分利用垂直切分和水平切分各自的優勢而避免各自的缺陷;

      ◆ 讓系統擴展性得到最大化提升。

      聯合切分的缺點

      ◆ 數據庫系統架構比較復雜。維護難度更大。

      ◆ 應用程序架構也相對更復雜;

      數據切分及整合方案

      通過前面的章節。我們已經非常清晰了通過數據庫的數據切分能夠極大的提高系統的擴展性?墒牵瑪祿䦷熘械臄祿诮涍^垂直和(或)水平切分被存放在不同的數據庫主機之后,應用系統面臨的最大問題就是怎樣來讓這些數據源得到較好的整合?赡苓@也是非常多讀者朋友非常關心的一個問題。這一節我們主要針對的內容就是分析能夠使用的各種能夠幫助我們實現數據切分以及數據整合的總體解決方式。

      數據的整合非常難依靠數據庫本身來達到這個效果,盡管MySQL存在Federated存儲引擎,能夠解決部分相似的問題。可是在實際應用場景中卻非常難較好的運用。那我們該怎樣來整合這些分散在各個MySQL主機上面的數據源呢?

      總的來說,存在兩種解決思路:

      1. 在每一個應用程序模塊中配置管理自己須要的一個(或者多個)數據源。直接訪問各個數據庫,在模塊內完畢數據的整合;

      2. 通過中間代理層來統一管理全部的數據源。后端數據庫集群對前端應用程序透明;

      可能90%以上的人在面對上面這兩種解決思路的時候都會傾向于選擇另外一種,尤其是系統不斷變得龐大復雜的時候。

      確實。這是一個非常正確的選擇,盡管短期內須要付出的成本可能會相對更大一些,可是對整個系統的擴展性來說,是非常有幫助的。

      所以,對于第一種解決思路我這里就不準備過多的分析,以下我重點分析一下在另外一種解決思路中的一些解決方式。

      ★ 自行開發中間代理層

      在決定選擇通過數據庫的中間代理層來解決數據源整合的架構方向之后,有不少公司(或者企業)選擇了通過自行開發符合自身應用特定場景的代理層應用程序。

      通過自行開發中間代理層能夠最大程度的應對自身應用的特定。最大化的定制非常多個性化需求,在面對變化的時候也能夠靈活的應對。這應該說是自行開發代理層最大的優勢了。

      當然,選擇自行開發,享受讓個性化定制最大化的樂趣的同一時候,自然也須要投入很多其它的成本來進行前期研發以及后期的持續升級改進工作。并且本身的技術門檻可能也比簡單的Web應用要更高一些。所以,在決定選擇自行開發之前,還是須要進行比較全面的評估為好。

      由于自行開發很多其它時候考慮的是怎樣更好的適應自身應用系統,應對自身的業務場景,所以這里也不好分析太多。后面我們主要分析一下當前比較流行的幾種數據源整合解決方式。

      ★利用MySQLProxy實現數據切分及整合

      MySQLProxy是MySQL官方提供的一個數據庫代理層產品,和MySQLServer一樣,相同是一個基于GPL開源協議的開源產品。可用來監視、分析或者傳輸他們之間的通訊信息。他的靈活性同意你最大限度的使用它,眼下具備的功能主要有連接路由,Query分析,Query過濾和修改,負載均衡。以及主要的HA機制等。

      實際上,MySQLProxy本身并不具有上述全部的這些功能。而是提供了實現上述功能的基礎。

      要實現這些功能,還須要通過我們自行編寫LUA腳本來實現。

      MySQLProxy實際上是在client請求與MySQLServer之間建立了一個連接池。全部client請求都是發向MySQLProxy,然后經由MySQLProxy進行對應的分析。推斷出是讀操作還是寫操作,分發至對應的MySQLServer上。對于多節點Slave集群,也能夠起做到負載均衡的效果。以下是MySQLProxy的基本架構圖:

      mysql數據庫分庫分表技術難點解決策略

      通過上面的架構簡圖。我們能夠非常清晰的看出MySQLProxy在實際應用中所處的位置,以及能做的基本事情。

      關于MySQLProxy更為具體的實施細則在MySQL官方文檔中有非常具體的介紹和演示樣例。感興趣的讀者朋友能夠直接從MySQL官方站點免費下載或者在線閱讀,我這里就不累述浪費紙張了。

      ★利用Amoeba實現數據切分及整合

      Amoeba是一個基于Java開發的,專注于解決分布式數據庫數據源整合Proxy程序的開源框架,基于GPL3開源協議。眼下,Amoeba已經具有Query路由,Query過濾,讀寫分離,負載均衡以及HA機制等相關內容。

      Amoeba 主要解決的以下幾個問題:

      1. 數據切分后復雜數據源整合;

      2. 提供數據切分規則并降低數據切分規則給數據庫帶來的影響。

      3. 降低數據庫與client的連接數。

      4. 讀寫分離路由;

      我們能夠看出,Amoeba所做的事情,正好就是我們通過數據切分來提升數據庫的擴展性所須要的。

      Amoeba并非一個代理層的Proxy程序,而是一個開發數據庫代理層Proxy程序的開發框架,眼下基于Amoeba所開發的Proxy程序有AmoebaForMySQL和AmoebaForAladin兩個。

      AmoebaForMySQL主要是專門針對MySQL數據庫的解決方式,前端應用程序請求的協議以及后端連接的數據源數據庫都必須是MySQL。對于client的不論什么應用程序來說,AmoebaForMySQL和一個MySQL數據庫沒有什么差別。不論什么使用MySQL協議的client請求,都能夠被AmoebaForMySQL解析并進行對應的處理。下如能夠告訴我們AmoebaForMySQL的架構信息(出自Amoeba開發人員博客):

      mysql數據庫分庫分表技術難點解決策略

      AmoebaForAladin則是一個適用更為廣泛。功能更為強大的Proxy程序。

      他能夠同一時候連接不同數據庫的數據源為前端應用程序提供服務,可是僅僅接受符合MySQL協議的client應用程序請求。也就是說,僅僅要前端應用程序通過MySQL協議連接上來之后,AmoebaForAladin會自己主動分析Query語句,依據Query語句中所請求的數據來自己主動識別出該所Query的數據源是在什么類型數據庫的哪一個物理主機上面。下圖展示了AmoebaForAladin的架構細節(出自Amoeba開發人員博客):

      mysql數據庫分庫分表技術難點解決策略

      咋一看,兩者好像全然一樣嘛。細看之后,才會發現兩者主要的差別僅在于通過MySQLProtocalAdapter處理之后。依據分析結果推斷出數據源數據庫。然后選擇特定的JDBC驅動和對應協議連接后端數據庫。

      事實上通過上面兩個架構圖大家可能也已經發現了Amoeba的特點了,他僅僅僅僅是一個開發框架。我們除了選擇他已經提供的ForMySQL和ForAladin這兩款產品之外。還能夠基于自身的需求進行對應的二次開發。得到更適應我們自己應用特點的Proxy程序。

      當對于使用MySQL數據庫來說。不論是AmoebaForMySQL還是AmoebaForAladin都能夠非常好的使用。當然,考慮到不論什么一個系統越是復雜,其性能肯定就會有一定的損失,維護成本自然也會相對更高一些。所以,對于僅僅須要使用MySQL數據庫的時候,我還是建議使用AmoebaForMySQL。

      AmoebaForMySQL的使用非常簡單,全部的配置文件都是標準的XML文件,總共同擁有四個配置文件。分別為:

      ◆ amoeba.xml:主配置文件,配置全部數據源以及Amoeba自身的參數設置。

      ◆ rule.xml:配置全部Query路由規則的信息。

      ◆ functionMap.xml:配置用于解析Query中的函數所對應的Java實現類;

      ◆ rullFunctionMap.xml:配置路由規則中須要使用到的特定函數的實現類;

      假設您的規則不是太復雜,基本上僅須要使用到上面四個配置文件里的前面兩個就可完畢全部工作。Proxy程序經常使用的功能如讀寫分離。負載均衡等配置都在amoeba.xml中進行。此外。Amoeba已經支持了實現數據的垂直切分和水平切分的自己主動路由。路由規則能夠在rule.xml進行設置。

      眼下Amoeba少有欠缺的主要就是其在線管理功能以及對事務的支持了,以前在與相關開發人員的溝通過程中提出過相關的建議,希望能夠提供一個能夠進行在線維護管理的命令行管理工具,方便在線維護使用,得到的反饋是管理專門的管理模塊已經納入開發日程了。另外在事務支持方面臨時還是Amoeba無法做到的,即使client應用在提交給Amoeba的請求是包括事務信息的,Amoeba也會忽略事務相關信息。當然,在經過不斷完好之后,我相信事務支持肯定是Amoeba重點考慮添加的feature。

      關于Amoeba更為具體的用法讀者朋友能夠通過Amoeba開發人員博客(http://amoeba.sf.net)上面提供的使用手冊獲取,這里就不再細述了。

      ★利用HiveDB實現數據切分及整合

      和前面的MySQLProxy以及Amoeba一樣,HiveDB相同是一個基于Java針對MySQL數據庫的提供數據切分及整合的開源框架,僅僅是眼下的HiveDB僅僅支持數據的水平切分。

      主要解決大數據量下數據庫的擴展性及數據的高性能訪問問題,同一時候支持數據的冗余及主要的HA機制。

      HiveDB的實現機制與MySQLProxy和Amoeba有一定的差異,他并非借助MySQL的Replication功能來實現數據的冗余,而是自行實現了數據冗余機制,而其底層主要是基于HibernateShards來實現的數據切分工作。

      在HiveDB中,通過用戶自己定義的各種Partitionkeys(事實上就是制定數據切分規則),將數據分散到多個MySQLServer中。在訪問的時候。在執行Query請求的時候。會自己主動分析過濾條件,并行從多個MySQLServer中讀取數據,并合并結果集返回給client應用程序。

      單純從功能方面來講,HiveDB可能并不如MySQLProxy和Amoeba那樣強大,可是其數據切分的思路與前面二者并無本質差異。此外,HiveDB并不僅僅僅僅是一個開源愛好者所共享的內容,而是存在商業公司支持的開源項目。

      以下是HiveDB官方站點上面一章圖片,描寫敘述了HiveDB怎樣來組織數據的基本信息,盡管不能具體的表現出太多架構方面的信息,可是也基本能夠展示出其在數據切分方面獨特的一面了。

      mysql數據庫分庫分表技術難點解決策略

      ★ mycat 數據整合:具體http://www.songwie.com/articlelist/11

      ★ 其它實現數據切分及整合的解決方式

      除了上面介紹的幾個數據切分及整合的總體解決方式之外,還存在非常多其它相同提供了數據切分與整合的解決方式。如基于MySQLProxy的基礎上做了進一步擴展的HSCALE,通過Rails構建的SpockProxy。以及基于Pathon的Pyshards等等。

      無論大家選擇使用哪一種解決方式,總體設計思路基本上都不應該會有不論什么變化。那就是通過數據的垂直和水平切分,增強數據庫的總體服務能力,讓應用系統的總體擴展能力盡可能的提升。擴展方式盡可能的便捷。

      僅僅要我們通過中間層Proxy應用程序較好的攻克了數據切分和數據源整合問題。那么數據庫的線性擴展能力將非常easy做到像我們的應用程序一樣方便。僅僅須要通過加入便宜的PCServerserver,就可以線性添加數據庫集群的總體服務能力,讓數據庫不再輕易成為應用系統的性能瓶頸。

      數據切分與整合可能存在的問題

      這里。大家應該對數據切分與整合的實施有了一定的認識了。也許非常多讀者朋友都已經依據各種解決方式各自特性的優劣基本選定了適合于自己應用場景的方案,后面的工作主要就是實施準備了。

      在實施數據切分方案之前,有些可能存在的問題我們還是須要做一些分析的。

      一般來說,我們可能遇到的問題主要會有以下幾點:

      ◆ 引入分布式事務的問題。

      ◆ 跨節點Join的問題;

      ◆ 跨節點合并排序分頁問題。

      1. 引入分布式事務的問題

      一旦數據進行切分被分別存放在多個MySQLServer中之后,無論我們的切分規則設計的多么的完美(實際上并不存在完美的切分規則),都可能造成之前的某些事務所涉及到的數據已經不在同一個MySQLServer中了。

      在這樣的場景下,假設我們的應用程序仍然依照老的解決方式。那么勢必須要引入分布式事務來解決。而在MySQL各個版本號中,僅僅有從MySQL5.0開始以后的各個版本號才開始對分布式事務提供支持,并且眼下僅有Innodb提供分布式事務支持。不僅如此。即使我們剛好使用了支持分布式事務的MySQL版本號。同一時候也是使用的Innodb存儲引擎,分布式事務本身對于系統資源的消耗就是非常大的,性能本身也并非太高。并且引入分布式事務本身在異常處理方面就會帶來較多比較難控制的因素。

      怎么辦?事實上我們能夠能夠通過一個變通的方法來解決這樣的問題。首先須要考慮的一件事情就是:是否數據庫是唯一一個能夠解決事務的地方呢?事實上并非這樣的,我們全然能夠結合數據庫以及應用程序兩者來共同解決。各個數據庫解決自己身上的事務。然后通過應用程序來控制多個數據庫上面的事務。

      也就是說。僅僅要我們愿意。全然能夠將一個跨多個數據庫的分布式事務分拆成多個僅處于單個數據庫上面的小事務。并通過應用程序來總控各個小事務。

      當然,這樣作的要求就是我們的俄應用程序必須要有足夠的健壯性。當然也會給應用程序帶來一些技術難度。

      2.跨節點Join的問題

      上面介紹了可能引入分布式事務的問題,如今我們再看看須要跨節點Join的問題。

      數據切分之后?赡軙斐捎行├系腏oin語句無法繼續使用。由于Join使用的數據源可能被切分到多個MySQLServer中了。

      怎么辦?這個問題從MySQL數據庫角度來看,假設非得在數據庫端來直接解決的話,恐怕僅僅能通過MySQL一種特殊的存儲引擎Federated來攻克了。Federated存儲引擎是MySQL解決相似于Oracle的DBLink之類問題的解決方式。

      和OracleDBLink的主要差別在于Federated會保存一份遠端表結構的定義信息在本地。咋一看,Federated確實是解決跨節點Join非常好的解決方式?墒俏覀冞應該清晰一點,那就似乎假設遠端的表結構發生了變更,本地的表定義信息是不會跟著發生對應變化的。假設在更新遠端表結構的時候并沒有更新本地的Federated表定義信息。就非?赡茉斐蒕uery執行出錯,無法得到正確的結果。

      對待這類問題,我還是推薦通過應用程序來進行處理,先在驅動表所在的MySQLServer中取出對應的驅動結果集。然后依據驅動結果集再到被驅動表所在的MySQLServer中取出對應的數據?赡芊浅6嘧x者朋友會覺得這樣做對性能會產生一定的影響,是的,確實是會對性能有一定的負面影響,可是除了此法,基本上沒有太多其它更好的解決的方法了。

      并且,由于數據庫通過較好的擴展之后,每臺MySQLServer的負載就能夠得到較好的控制。單純針對單條Query來說,其響應時間可能比不切分之前要提高一些,所以性能方面所帶來的負面影響也并非太大。更何況。相似于這樣的須要跨節點Join的需求也并非太多。相對于總體性能而言,可能也僅僅是非常小一部分而已。所以為了總體性能的考慮,偶爾犧牲那么一點點。事實上是值得的。畢竟系統優化本身就是存在非常多取舍和平衡的過程。

      3. 跨節點合并排序分頁問題

      一旦進行了數據的水平切分之后,可能就并不僅僅僅僅有跨節點Join無法正常執行,有些排序分頁的Query語句的數據源可能也會被切分到多個節點。這樣造成的直接后果就是這些排序分頁Query無法繼續正常執行。事實上這和跨節點Join是一個道理。數據源存在于多個節點上,要通過一個Query來解決,就和跨節點Join是一樣的操作。相同Federated也能夠部分解決。當然存在的風險也一樣。

      還是相同的問題,怎么辦?我相同仍然繼續建議通過應用程序來解決。

      怎樣解決?解決的思路大體上和跨節點Join的解決相似,可是有一點和跨節點Join不太一樣。Join非常多時候都有一個驅動與被驅動的關系。所以Join本身涉及到的多個表之間的數據讀取一般都會存在一個順序關系?墒桥判蚍猪摼筒惶粯恿,排序分頁的數據源基本上能夠說是一個表(或者一個結果集)。本身并不存在一個順序關系,所以在從多個數據源取數據的過程是全然能夠并行的。

      這樣。排序分頁數據的取數效率我們能夠做的比跨庫Join更高。所以帶來的性能損失相對的要更小,在有些情況下可能比在原來未進行數據切分的數據庫中效率更高了。

      當然,不論是跨節點Join還是跨節點排序分頁。都會使我們的應用server消耗很多其它的資源,尤其是內存資源,由于我們在讀取訪問以及合并結果集的這個過程須要比原來處理很多其它的數據。

      分析到這里,可能非常多讀者朋友會發現,上面全部的這些問題,我給出的建議基本上都是通過應用程序來解決。大家可能心里開始犯嘀咕了。是不是由于我是DBA,所以就非常多事情都扔給應用架構師和開發人員了?

      事實上全然不是這樣,首先應用程序由于其特殊性。能夠非常easy做到非常好的擴展性,可是數據庫就不一樣。必須借助非常多其它的方式才干做到擴展。并且在這個擴展過程中,非常難避免帶來有些原來在集中式數據庫中能夠解決但被切分開成一個數據庫集群之后就成為一個難題的情況。

      要想讓系統總體得到最大限度的擴展,我們僅僅能讓應用程序做很多其它的事情。來解決數據庫集群無法較好解決的問題。

      小結

      通過數據切分技術將一個大的MySQLServer切分成多個小的MySQLServer,既攻克了寫入性能瓶頸問題,同一時候也再一次提升了整個數據庫集群的擴展性。不論是通過垂直切分,還是水平切分。都能夠讓系統遇到瓶頸的可能性更小。尤其是當我們使用垂直和水平相結合的切分方法之后,理論上將不會再遇到擴展瓶頸了。

      相關推薦:

      Mysql數據庫分庫和分表方式(常用)_MySQL

      mysql主從數據庫,分庫分表等筆記_MySQL

      老男孩mysql視頻:MySQL數據庫多實例啟動問題排錯方法及實戰排錯

      以上就是mysql數據庫分庫分表技術難點解決策略的詳細內容,更多請關注php中文網其它相關文章!


      學習教程快速掌握從入門到精通的SQL知識。




      日韩精品一区二区三区高清