中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

mysql實現數據切分的方法

發布時間:2020-10-13 14:35:21 來源:億速云 閱讀:153 作者:小新 欄目:MySQL數據庫

這篇文章主要介紹了mysql實現數據切分的方法,具有一定借鑒價值,需要的朋友可以參考下。希望大家閱讀完這篇文章后大有收獲。下面讓小編帶著大家一起了解一下。

mysql實現數據切分的方法:1、使用數據的垂直切分;2、使用數據的水平切分;3、利用MySQL Proxy實現數據切分及整合;4、利用Amoeba實現數據切分;5、利用HiveDB實現數據切分及整合。

mysql實現數據切分的方法:

何謂數據切分

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

數據的切分(Sharding)根據其切分規則的類型,可以分為兩種切分模式。一種是按照不同的表(或者Schema)來切分到不同的數據庫(主機)之上,這種切分可以稱之為數據的垂直(縱向)切分;另外一種則是根據表中數據的邏輯關系,將同一個表中的數據按照某種條件拆分到多臺數據庫(主機)上,這種切分稱之為數據的水平(橫向)切分。

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

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

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

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

數據的垂直切分

我們先來看一下,數據的垂直切分到底是如何切分的。數據的垂直切分,也可以稱為縱向切分。將數據庫想象成由很多個一大塊一大塊的“數據塊”(表)組成,垂直地將這些“數據塊”切開,然后把它們分散到多臺數據庫主機上面。這樣的切分方法就是垂直(縱向)的數據切分。

一個架構設計較好的應用系統,其總體功能肯定是由很多個功能模塊所組成的,而每一個功能模塊所需要的數據對應到數據庫中就是一個或多個表。而在架構設計中,各個功能模塊相互之間的交互點越統一、越少,系統的耦合度就越低,系統各個模塊的維護性及擴展性也就越好。這樣的系統,實現數據的垂直切分也就越容易。

功能模塊越清晰,耦合度越低,數據垂直切分的規則定義也就越容易。完全可以根據功能模塊來進行數據的切分,不同功能模塊的數據存放于不同的數據庫主機中,可以很容易就避免跨數據庫的Join存在,同時系統架構也非常清晰。

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

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

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

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

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

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

  • 用戶模塊表:user,user_profile,user_group,user_photo_album

  • 群組討論表:groups,group_message,group_message_content,top_message

  • 相冊相關表:photo,photo_album,photo_album_relation,photo_comment

  • 事件信息表:event

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

當然不是,再稍微深入分析一下,可以發現,雖然各個模塊所使用的表之間都有關聯,但是關聯關系還算清晰,也比較簡單。

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

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

事件模塊與各個模塊可能都有關聯,但是都只關注其各個模塊中對象的ID信息,同樣比較容易分拆。

所以,第一步可以將數據庫按照功能模塊相關的表進行一次垂直拆分,每個模塊所涉及的表單獨分到一個數據庫中,模塊與模塊之間的表關聯在應用系統端都通過接口來處理。如數據垂直切分示意圖(圖1)所示:

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

垂直切分的優點:

  • 數據庫的拆分簡單明了,拆分規則明確;

  • 應用程序模塊清晰明確,整合容易;

  • 數據維護方便易行,容易定位。

垂直切分的缺點:

  • 部分表關聯無法在數據庫級別完成,要在程序中完成;

  • 對于訪問極其頻繁且數據量超大的表仍然存在性能瓶頸,不一定能滿足要求;

  • 事務處理相對復雜;

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

  • 過度切分可能會帶來系統過于復雜而難以維護。

針對于垂直切分可能遇到數據切分及事務問題,在數據庫層面實在是很難找到一個較好的處理方案。實際應用案例中,數據庫的垂直切分大多是與應用系統的模塊相對應的,同一個模塊的數據源存放于同一個數據庫中,可以解決模塊內部的數據關聯問題。而模塊與模塊之間,則通過應用程序以服務接口的方式來相互提供所需要的數據。雖然這樣做在數據庫的總體操作次數方面確實會有所增加,但是在系統整體擴展性及架構模塊化方面,都是有益的。可能某些操作的單次響應的時間會稍有增加,但是系統的整體性能很可能反而會有一定的提升。而擴展瓶頸問題,就只能依靠下一節將要介紹的數據水平切分架構來解決了。

數據的水平切分

上面一節分析介紹了數據的垂直切分,本節分析數據的水平切分。數據的垂直切分基本上可以簡單地理解為按照表或模塊來切分數據,而水平切分則不同。一般來說,簡單的水平切分主要是將某個訪問極其平凡的表再按照某個字段的某種規則分散到多個表中,每個表包含一部分數據。

簡單來說,可以將數據的水平切分理解為按照數據行的切分,就是將表中的某些行切分到一個數據庫,而另外的某些行又切分到其他的數據庫中。當然,為了能夠比較容易地判定各行數據被切分到哪個數據庫中了,切分總是須要按照某種特定的規則來進行的:如根據某個數字類型字段基于特定數目取模,某個時間類型字段的范圍,或者某個字符類型字段的hash值。如果整個系統中大部分核心表都可以通過某個字段來進行關聯,那這個字段自然是一個進行水平分區的上上之選了,當然,非常特殊無法使用的情況除外。

一般來說,像現在非常火爆的Web 2.0類型網站,基本上大部分數據都能夠通過會員用戶信息關聯上,可能很多核心表都非常適合通過會員ID來進行數據的水平切分。而像論壇社區討論系統,就更容易切分了,可以按照論壇編號來進行水平切分。切分之后基本上不會出現各個庫之間的交互。

如果示例系統的所有數據都是和用戶關聯的,那么就可以根據用戶來進行水平拆分,將不同用戶的數據切分到不同的數據庫中。當然,唯一區別是用戶模塊中的groups表和用戶沒有直接關系,所以groups不能根據用戶來進行水平拆分。對于這種特殊情況下的表,完全可以獨立出來,放在一個獨立的數據庫中。其實這個做法可以說是利用了前面一節所介紹的“數據的垂直切分”方法,將在下一節中更為詳細地介紹這種垂直切分與水平切分同時使用的聯合切分方法。

所以,對于示例數據庫來說,大部分的表都可以根據用戶ID來進行水平切分。不同用戶相關的數據進行切分之后存放在不同的數據庫中。如將所有用戶ID通過被2取模然后分別存放于兩個不同的數據庫中。每個和用戶ID關聯上的表都可以這樣切分。這樣,基本上每個用戶相關的數據,都在同一個數據庫中,即使須要關聯,也非常容易實現。

可以通過水平切分示意圖(圖2)更為直觀地展示水平切分相關信息:

水平切分的優點:

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

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

  • 應用程序端整體架構改動相對較少;

  • 事務處理相對簡單;

  • 只要切分規則能夠定義好,基本上較難遇到擴展性限制。

水平切分的缺點:

  • 切分規則相對復雜,很難抽象出一個能夠滿足整個數據庫的切分規則;

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

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

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

前面兩節內容中,分別了解了“垂直”和“水平”這兩種切分方式的實現和切分之后的架構信息,以及兩種架構各自的優缺點。但是在實際的應用場景中,除了那些負載并不是太大、業務邏輯也相對簡單的系統可以通過上面兩種切分方法之一來解決擴展性問題之外,恐怕其他大部分業務邏輯復雜、系統負載大的系統,都無法通過上面任何一種數據的切分方法來實現較好的擴展性,這就需要將上述兩種切分方法結合使用,不同的場景使用不同的切分方法。

本節將結合垂直切分和水平切分各自的優缺點,進一步完善整體架構,并提高系統的擴展性。

一般來說,數據庫中的所有表很難通過某一個(或少數幾個)字段全部關聯起來,所以僅僅通過數據的水平切分無法解決所有問題。而垂直切分也只能解決部分問題,對于那些負載非常高的系統,即使只是單個表都無法通過單臺數據庫主機來承擔其負載。必須結合“垂直”和“水平”兩種切分方式,充分利用兩者的優點,避開其缺點。

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

此時該如何抉擇?是再次進一步細分模塊,還是尋求其他的解決辦法?如果我們再像最開始那樣繼續細分模塊,進行數據的垂直切分,那可能在不久的將來,又會遇到現在所面臨的同樣問題。而且隨著模塊的不斷細化,應用系統的架構也會越來越復雜,整個系統很可能會出現失控的局面。

這時候就必須要利用數據水平切分的優勢來解決遇到的問題。而且,完全不必在使用數據水平切分時,推倒之前進行數據垂直切分的成果,而是在其基礎上利用水平切分的優勢來避開垂直切分的弊端,解決系統復雜性不斷擴大的問題。而水平拆分的弊端(規則難以統一)也已經被之前的垂直切分解決掉了,讓水平切分可以進行得得心應手。

對于示例數據庫,假設在最開始進行了數據的垂直切分,然而隨著業務的不斷增長,數據庫系統遇到了瓶頸,我們選擇重構數據庫集群的架構。如何重構?考慮到之前已經做好了數據的垂直切分,而且模塊結構清晰明確,而業務增長的勢頭越來越猛,即使現在再次拆分模塊,也堅持不了太久。所以選擇了在垂直切分的基礎上再進行水平切分。

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

組合切分展示了切分后的整個架構:

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

聯合切分的優點:

  • 可以充分利用垂直切分和水平切分各自的優勢而避免各自的缺陷;

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

聯合切分的缺點:

  • 數據庫系統架構比較復雜,維護難度更大;

  • 應用程序架構也更復雜。

  • 數據切分及整合方案

通過前面的章節,已經清楚了通過數據庫的數據切分可以極大地提高系統的擴展性。但是,數據庫中的數據經過垂直和(或)水平切分被存放在不同的數據庫主機之后,應用系統面臨的最大問題就是如何讓這些數據源得到較好的整合,可能這也是很多讀者非常關心的一個問題。本節主要的內容就是分析各種可以幫助我們實現數據切分及數據整合的整體解決方案。

數據的整合很難依靠數據庫本身來達到,雖然MySQL存在Federated存儲引擎,可以解決部分類似的問題,但是在實際應用場景中卻很難較好地運用。那該如何來整合這些分散在各個MySQL主機上的數據源呢?

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

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

通過中間代理層來統一管理所有的數據源,后端數據庫集群對前端應用程序透明。

可能90%以上的人在面對這兩種解決思路時都會傾向于選擇第二種,尤其是系統不斷龐大復雜的時候。確實,這是一個非常正確的選擇,雖然短期內須要付出的成本可能會相對大一些,但對整個系統的擴展性來說,是非常有幫助的。

所以,對于第一種解決思路就不過多分析了,下面重點分析第二種思路中的一些解決方案。

自行開發中間代理層

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

自行開發中間代理層可以最大程度地應對自身應用的特點,最大化定制個性化需求,在面對變化的時候也可以靈活應對。這應該是自行開發代理層最大的優勢了。

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

由于自行開發更多時候考慮的是如何更好地適應自身應用系統,應對自身的業務場景,所以這里也不好分析太多。下面將主要分析當前比較流行的幾種數據源整合解決方案。

利用MySQL Proxy實現數據切分及整合

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

實際上,MySQL Proxy本身并不具有上述所有的功能,而是提供了實現上述功能的基礎。要實現這些功能,還須要我們自行編寫LUA腳本。

MySQL Proxy實際上是在客戶端請求與MySQL Server之間建立了一個連接池。所有客戶端請求都發向MySQL Proxy,然后經由MySQL Proxy進行相應的分析,判斷出是讀操作還是寫操作,分發至對應的MySQL Server上。對于多節點Slave集群,也可以起到負載均衡的效果。如MySQL Proxy基本架構圖(圖4):

通過上面的架構簡圖,可以清晰地看到MySQL Proxy在實際應用中所處的位置,以及能做的基本事情。MySQL Proxy詳細的實施細則在MySQL官方文檔中有非常詳細的介紹和示例,感興趣的讀者朋友可以直接從MySQL官方網站免費下載或者在線閱讀,這里就不贅述。

利用Amoeba實現數據切分

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

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

  • 數據切分后復雜數據源整合;

  • 提供數據切分規則并降低數據切分規則給數據庫帶來的影響;

  • 降低數據庫與客戶端的連接數;

  • 讀寫分離路由。

可以看出,Amoeba所做的事情,正好就是通過數據切分來提升數據庫的擴展性所需要的。

Amoeba并不是一個代理層的Proxy程序,而是一個開發數據庫代理層Proxy程序的框架,目前基于Amoeba所開發的Proxy程序有Amoeba For MySQL和Amoeba For Aladin兩個。

Amoeba For MySQL是專門針對MySQL數據庫的解決方案,前端應用程序請求的協議及后端連接的數據源數據庫都必須是MySQL。對于客戶端的任何應用程序來說,Amoeba For MySQL和一個MySQL數據庫沒有什么區別,任何使用MySQL協議的客戶端請求,都可以被Amoeba For MySQL解析并進行相應的處理。Amoeba For可以告訴我們Amoeba For MySQL的架構信息(出自Amoeba開發者博客):

Amoeba For Aladin則是一個適用更為廣泛、功能更為強大的Proxy程序。它可以同時連接不同數據庫的數據源為前端應用程序提供服務,但是僅僅接受符合MySQL協議的客戶端應用程序請求。也就是說,只要前端應用程序通過MySQL協議連接上來,Amoeba For Aladin會自動分析Query語句,根據Query語句中所請求的數據來自動識別出該Query的數據源是在什么類型數據庫的哪一個物理主機上。Amoeba For Aladdin架構圖(圖6)展示了Amoeba For Aladin的架構細節(出自Amoeba開發者博客)。

乍一看,兩者好像完全一樣嘛。細看才會發現兩者主要的區別僅在于通過MySQL Protocal Adapter處理之后,根據分析結果判斷出數據源數據庫,然后選擇特定的JDBC驅動和相應協議連接后端數據庫。

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

但對于使用MySQL數據庫來說,不論是Amoeba For MySQL還是Amoeba For Aladin都可以很好地使用。當然,考慮到任何一個系統越是復雜,其性能肯定就會有一定的損失,維護成本自然也會更高一些。所以,在僅僅須要使用MySQL數據庫的時候,還是建議使用Amoeba For MySQL。

Amoeba For MySQL的使用非常簡單,所有的配置文件都是標準的XML文件,總共有4個,分別如下:

  • amoeba.xml——主配置文件,配置所有數據源及Amoeba自身的參數;

  • rule.xml——配置所有Query路由規則的信息;

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

  • rullFunctionMap.xml——配置路由規則中需要使用到的特定函數的實現類。

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

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

和前面的MySQL Proxy及Amoeba一樣,HiveDB同樣是一個基于Java針對MySQL數據庫的提供數據切分及整合的開源框架,只是目前的HiveDB僅僅支持數據的水平切分。主要解決大數據量下數據庫的擴展性及數據的高性能訪問問題,同時支持數據的冗余及基本的HA機制。

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

在HiveDB中,通過用戶自定義的各種Partition keys(即制定數據切分規則),將數據分散到多個MySQL Server中。訪問時運行Query請求,則會自動分析過濾條件,并行從多個MySQL Server中讀取數據,并合并結果集返回給客戶端應用程序。

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

HiveDB官方網站上的HiveDB架構示意圖(圖7),描述了HiveDB如何來組織數據的基本信息,雖然不能詳細地表現出架構方面的信息,但是也基本可以展示其在數據切分上獨特的一面了。

其他實現數據切分及整合的解決方案

除了上面介紹的幾個數據切分及整合的整體解決方案之外,還存在很多其他的解決方案、如在MySQL Proxy的基礎上做進一步擴展的HSCALE,通過Rails構建的Spock Proxy,以及基于Pathon的Pyshards,等等。

不管大家選擇使用哪一種解決方案,總體設計思路基本上都不應該有任何變化,即通過數據的垂直和水平切分,增強數據庫的整體服務能力,讓應用系統的整體擴展能力盡量得到提升,擴展方式盡可能便捷。

只要通過中間層Proxy應用程序較好地解決了數據切分和數據源整合問題,那么數據庫的線性擴展能力將像應用程序一樣方便:只要通過添加廉價的PC Server服務器,即可線性增加數據庫集群的整體服務能力,讓數據庫不再輕易成為應用系統的性能瓶頸。

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

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

在實施數據切分方案之前,仍要分析一些可能存在的問題。一般來說,可能遇到的問題主要有以下幾點:

  • 引入分布式事務的問題;

  • 跨節點Join的問題;

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

  • 引入分布式事務的問題

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

在這樣的場景下,如果應用程序仍然按照老的方案,那么勢必須要引入分布式事務來解決。而在MySQL各個版本中,只有從MySQL 5.0開始以后的各個版本才對分布式事務提供支持,而且目前僅有Innodb提供分布式事務支持。不過,即使我們剛好使用了支持分布式事務的MySQL版本,同時也使用Innodb存儲引擎,分布式事務本身對于系統資源的消耗就很大,性能也并不太高,引入分布式事務在異常處理方面會帶來很多比較難控制的問題。

怎么辦?其實可以通過一個變通的方法來解決這種問題,首先須要考慮的是:數據庫是否是唯一一個能夠解決事務的地方?其實并不是這樣的,完全可以結合數據庫及應用程序來共同解決。各個數據庫解決自身的事務,然后通過應用程序來控制多個數據庫上的事務。

也就是說,只要我們愿意,完全可以將一個跨多個數據庫的分布式事務分拆成多個僅處于單個數據庫上的小事務,并通過應用程序來總控各個小事務。當然,這樣做要求應用程序必須要有足夠的健壯性,當然也會給應用程序帶來一些技術難度。

跨節點Join的問題

上面介紹了可能引入分布式事務的問題,現在再看看需要跨節點Join的問題。數據切分之后,也許有些老的Join語句無法繼續使用,因為Join使用的數據源可能被切分到多個MySQL Server中了。

怎么辦?這個問題從MySQL數據庫角度來看,如果非得在數據庫端直接解決的話,恐怕只能通過MySQL一種特殊的存儲引擎Federated處理了。Federated存儲引擎是MySQL解決類似于Oracle的DB Link之類問題的方案。和Oracle DB Link的主要區別在于,Federated會保存一份遠端表結構的定義信息在本地。乍一看,Federated確實是解決跨節點Join非常好的方案。但是我們還應該清楚一點,那就是如果遠端的表結構發生了變更,本地的表定義信息是不會跟著發生變化的。如果在更新遠端表結構的時候并沒有更新本地的Federated表定義信息,Query運行很可能出錯,無法得到正確的結果。

對待這類問題,還是推薦通過應用程序來處理,先在驅動表所在的MySQL Server中取出驅動結果集,然后根據驅動結果集再到被驅動表所在的MySQL Server中取出相應的數據。可能很多讀者朋友會認為這樣做將對性能產生一定的影響,是的,確實會有一定的負面影響,但除此之外,基本上沒有太多其他更好的解決辦法了。而且,由于數據庫通過較好的擴展之后,每臺MySQL Server的負載就可以得到較好的控制,單純針對單條Query來說,其響應時間可能比不切分之前要提高一些,所以性能方面帶來的負面影響也并不是太大。更何況,類似于這種跨節點Join的需求也并不是太多,相對于總體性能而言,可能也只是很小一部分而已。所以為了整體性能,偶爾犧牲一點點,其實是值得的,畢竟系統優化本身就是很多取舍和平衡的過程。

跨節點合并排序分頁問題

一旦進行了數據的水平切分之后,可能就并不只有跨節點Join無法正常運行,有些排序分頁的Query語句的數據源可能也會被切分到多個節點,其直接后果就是這些排序分頁Query無法繼續正常運行。其實這和跨節點Join是一個道理,數據源存在于多個節點上,要通過一個Query來解決,就是一個跨節點Join操作。同樣Federated也可以部分解決,但存在的風險也一樣。但是有一點不同:Join很多時候都有一個驅動與被驅動的關系,所以它涉及的多個表之間的數據讀取一般會存在一個順序關系。但是排序分頁就不同了,排序分頁的數據源基本上可以說是一個表(或者一個結果集),并不存在順序關系,所以從多個數據源取數據的過程是完全可以并行的。這樣,排序分頁數據的取數效率可以比跨庫Join更高,所以帶來的性能損失相對要小,在有些情況下可能比在原來未進行數據切分的數據庫中效率更高了。當然,不論是跨節點Join還是跨節點排序分頁,都會使應用服務器消耗更多的資源,尤其是內存資源,因為在讀取訪問及合并結果集的這個過程須要比不處理合并處理更多的數據。

感謝你能夠認真閱讀完這篇文章,希望小編分享mysql實現數據切分的方法內容對大家有幫助,同時也希望大家多多支持億速云,關注億速云行業資訊頻道,遇到問題就找億速云,詳細的解決方法等著你來學習!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

北辰区| 马山县| 财经| 淅川县| 定安县| 丽水市| 贵港市| 南华县| 从化市| 渭源县| 舞钢市| 连江县| 康乐县| 都匀市| 台州市| 松原市| 石柱| 沾益县| 鄂托克前旗| 阜城县| 那坡县| 武穴市| 甘泉县| 寿阳县| 盘山县| 舒城县| 习水县| 建平县| 临泽县| 贵德县| 丰原市| 花莲县| 景泰县| 泾川县| 北海市| 台前县| 南宫市| 千阳县| 开江县| 潮安县| 凤山市|