回覆列表
  • 1 # 架構思維

    分庫分表是比較靠後的最佳化手段,因為成本比較高。

    遇到資料庫瓶頸:

    - 首先考慮sql最佳化,這是最簡單的方法。對現有系統基本沒有影響。

    - 其次就是考慮資料庫的讀寫分離,這也是相對簡單的方法。在資料庫層面進行配置,系統層面只需要調整一下獲取資料庫連線的邏輯。讀資料時即可以獲取主庫連線,也可以獲取從庫連線。寫資料時只獲取主庫連線。

    - 再考慮增加快取層。將資料快取到快取中,當再次訪問時不再從資料庫獲取。一般快取層對系統是透明的,基本對系統本身沒有影響。但是引入快取,也引入了相應的需要考慮的問題,比如雪崩,命中率,分散式快取等

    - 還有一種非技術手段,就是改需求。引起效能問題的原因是否是需求不合理?或者需求太複雜?是否可以簡化需求?此方法對系統的影響也相對較小。

    - 最後才考慮分庫分表。優先分庫,因為相對分表更簡單。將對應的表移動到新庫,調整系統獲取資料庫連線的邏輯。這裡需要考慮要移動哪些表,在提高效能的前提下,首先儘量避免分散式事務。

    - 最最後,考慮分表。分表的主要原因是單表資料量太大。分表又分縱切和橫切。縱切就是按列切,比如使用者表,常用資訊為基本資訊表,其它資訊為詳情表。橫切就是按行切,比如一億資料量的表切分為十張一千萬的表。這裡就涉及資料該存放到哪張表,或從哪張表裡取。分表後又可以分庫,來進一步最佳化。

    - 如果涉及到分散式事務,又要考慮如何保證分散式事務。理論方面2pc,3pc,paxos,cap,base。對應的中介軟體的使用。

    對系統的設計和最佳化不是人云亦云,需要根據實際的場景來進行處理。

  • 2 # 淺析架構

    1.最佳化SQL加索引

    2.業務是否可以垂直拆分,業務拆分了可以分庫

    3.業務單邊資料量還是大,是否可以把一些欄位獨立出去,表垂直拆分。水平拆分表可以按時間,或者id的has值進行拆分

    4.分庫分表必然帶來很多問題,比如關聯查詢,聚合等操作,可以嘗試下NewSQL,業務不再關心分庫分表操作了。國內開源實現有TiDB,可以瞭解下,NewSQL應該是未來的趨勢。

  • 3 # JAVA前線

    1 阿里開發手冊的建議

    關於分庫分表,阿里開發手冊有這樣的建議:單錶行數超過500萬行或者單表容量超過2G,才推薦進行分庫分表。如果預計三年後的資料量根本達不到這個級別,請不要在建立表時就分庫分表。

    2 分庫分表實踐

    分庫分表是比較複雜的工作,有以下要點需要考慮:遷移資料的準確性,系統是停機還是不停機,上線後資料驗證,分表後資料統計,分庫後分布式事務,出現異常回滾方案等等。所以決定分庫分表前,一定要考慮周全。

    3 我的建議

    先從語句效能考慮,找出慢SQL,看看索引是否使用得當,先最佳化語句,成本最小。

    再考慮增加快取,將熱點資料快取起來,本地快取效能最好,分散式快取也可以。

    最後思考分庫分表,優先考慮分表,再考慮分庫。建議最好由有經驗的同事主導。

  • 4 # 一席話君

    不到萬不得已,不要分庫分表。

    資料庫遇到瓶頸,應該首先考慮最佳化。sql伺服器硬體最佳化,sql語句最佳化,索引最佳化,讀寫分離,快取層。

    如果都不行,那就只能考慮分庫分表了,可以利用mycat,DBProxy等中介軟體。

    一旦分庫分表,就會引出分散式事物,應該儘量避免。關聯查詢,聚合統計等操作等地方也有坑,一定要注意!

    個人建議:一般到了分庫分表的地步,都是因為資料量到了一定級別,單臺伺服器無法承受。一般都是某幾張表或者某個庫資料量過大。與其費力分庫分表,倒不如考慮一些新興的資料庫,例如HBase或者TiDB等newSQL甚至ES。如果這些大表,不涉及複雜,需要考慮事物的業務,完全可以頂上。

    本人專注網際網路前沿動態,大資料,資料採集,資料處理,資料治理,望交流!

  • 5 # 會點程式碼的大叔

    大部分的軟體架構、元件或解決方案,都是在解決一些問題的同時,會帶來另外的問題。

    資料庫的分庫分表,又可以分為垂直拆分和水平拆分(可能大家常說的分庫分表主要指的是後者):

    垂直拆分:這是一種比較常見的資料庫設計方法,就是把一個欄位比較多的大表,拆分成多個小表,特別是在現在分散式、微服務的架構下,可以把各個小表按照業務模型,劃分到不同的資料庫中,這樣就可以利用多臺資料庫伺服器的效能;但當被拆分出來小表的資料量不斷增長,到了一個極限的時候,還是需要考慮水平拆分。

    水平拆分:將表中的資料,按照一定的規則分佈到不同的資料庫中,比如對主鍵進行Hash和取模操作後,按照結果把資料路由到對應的資料庫上;水平分庫分表,可以降低每張表的資料量,這也是現在大部分公司所使用的方法。

    資料庫擴容問題

    上文中說到,水平拆分常用的手段是對主鍵進行Hash和取模操作後,按照結果把資料路由到對應的資料庫上;但如果被拆分的子表,資料量也達到極限值以後,就要面對資料庫擴容的問題,比如開始規劃分成8個庫,現在要擴到16個庫;

    路由規則發生變化:hash(id)%8 變成了 hash(id)%16,那麼歷史資料也就要面臨遷移的問題;這種情況,要麼做資料遷移,要麼增加分表演算法的複雜性,讓演算法可以相容增加分表前後的資料路由。

    複雜查詢、關聯查詢、order by、group by等的問題

    在單庫時代,複雜的關聯查詢是很容易實現的,但是資料庫被拆分後,資料被儲存在了不同的資料庫伺服器上,那麼誇庫的join就成了很大的問題。通常解決方案有:

    如果是垂直拆分,那麼可以考慮做一定程度的欄位冗餘,避免跨表關聯;或者可以做資料同步,把需要的表同步到同一個庫中,進行表關聯;

    程式碼層面組裝,也就是把兩邊的資料都拿出來,然後在程式碼裡面關聯組裝;或者先獲取主表資料,再把其餘欄位補齊;但是從實際情況來看,這個方案在大多數場景下,實現起來都比較困難;

    現在一個比較主流的做法,是引入ES或ES+HBase或solr+HBase,把部分欄位的全量資料儲存在同一個地方。

    ID問題

    在水平拆分的場景下,一單一張表被拆分成多張表部署在多個數據庫中,那麼就不能使用資料庫自身的主鍵生成機制了;這時候就需要由我們自己來考慮主鍵生成策略:

    主鍵生成中心:可以利用資料庫、Redis、MongoDB、zookeeper等元件實現,需要生產主鍵的時候,呼叫主鍵生成中心的介面;缺點也很明顯,增加了網路開銷,並且主鍵生成中心如果發生問題,後果會很嚴重。

    UUID:本地生成,不需要第三方元件,生成比較簡單,效能好;不過缺點也不少,長度長,不利於儲存,並且沒有排序,是個字串,不利於查詢。

    一些唯一性ID的生成演算法:比如Snowflake、UidGenerator、Leaf等等。

    事務問題

    單庫的時候,解決事務問題很簡單,但是現在要保證跨庫的事務問題,需要額外的成本;

    這種場景下(效能要求高,一致性要求不是那麼的高),大部分公司會放棄事務的【實時】一致性,只要在一定的時間內,事務【最終】一致即可。

  • 中秋節和大豐收的關聯?
  • 秦並巴蜀的歷史意義?