自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

盤點(diǎn)分庫分表中件間Mycat中的坑

運(yùn)維 數(shù)據(jù)庫運(yùn)維
公司最近在搞服務(wù)分離,數(shù)據(jù)切分的工作,因?yàn)橛唵魏陀唵雾?xiàng)表的數(shù)據(jù)量實(shí)在過大,而且每天都是以50萬的數(shù)據(jù)量在增長,基于現(xiàn)狀,項(xiàng)目組決定采用分庫的方式來解決當(dāng)前遇到的問題。

 [[400584]]

一、介紹

公司最近在搞服務(wù)分離,數(shù)據(jù)切分的工作,因?yàn)橛唵魏陀唵雾?xiàng)表的數(shù)據(jù)量實(shí)在過大,而且每天都是以50萬的數(shù)據(jù)量在增長,基于現(xiàn)狀,項(xiàng)目組決定采用分庫的方式來解決當(dāng)前遇到的問題。

那具體怎么切分呢?

分庫的策略其實(shí)還比較簡單,主要是要確定分片的字段和策略。

最開始是想通過主鍵ID的奇、偶數(shù)來分兩個(gè)庫,order_1庫主要用于存儲(chǔ)奇數(shù)的ID,order_2庫主要用于存儲(chǔ)偶數(shù)的ID。

但是這種切分,局限性非常大,因?yàn)樽疃嘀荒芊謨蓚€(gè)庫,如果隨著數(shù)據(jù)量的增大,后面就沒很難在分了。

之后又想到了另一個(gè)分片字段:城市ID,因?yàn)橛唵伪砩嫌谐鞘蠭D的屬性,我們可以基于此進(jìn)行分庫,但是全國有幾百個(gè)城市,不可能分幾百個(gè)庫或者表,最后的討論結(jié)果是:

  • 城市ID的生成固定大小,默認(rèn)三位數(shù),100~999
  • 將訂單表分成三個(gè)庫,order_1、order_2、order_3
  • 當(dāng)城市ID 在100~399區(qū)間,就存儲(chǔ)到order_1庫
  • 當(dāng)城市ID 在400~699區(qū)間,就存儲(chǔ)到order_2庫
  • 當(dāng)城市ID 在700~999區(qū)間,就存儲(chǔ)到order_3庫

通過城市ID進(jìn)行分片,如果后期訂單數(shù)據(jù)量進(jìn)一步過大,也可以進(jìn)一步的分庫!

基于Mysql數(shù)據(jù)庫,使用最廣、最成熟的分布式中間件當(dāng)屬于Mycat。

但是,自從采用Mycat中間件進(jìn)行分庫之后,發(fā)現(xiàn)了非常多的坑,下面我們就一起來看看這些坑點(diǎn)!

二、細(xì)數(shù)Mycat中的坑點(diǎn)

2.1、分頁查詢會(huì)出現(xiàn)全表掃描

當(dāng)我們把功能上線之后,測試人員在頁面上從末尾頁不停的往前分頁查詢訂單數(shù)據(jù)的時(shí)候,運(yùn)維平臺(tái)突然報(bào)監(jiān)控到很多慢 SQL 報(bào)警。

以下是運(yùn)維平臺(tái)監(jiān)控到的慢sql語句。

  1. SELECT id FROM order 
  2. WHERE OrderCreateTime BETWEEN '2021-05-01 00:00:00' AND '2021-06-01 00:00:00' 
  3. ORDER BY id DESC 
  4. LIMIT 0, 151400 

于是,運(yùn)維同學(xué)開始找到我們,說我們程序有問題,并在群里開始吐槽我們開發(fā)寫的啥玩意,但是我們開發(fā)堅(jiān)信程序沒有問題,通過查詢?nèi)罩?,我們排查到代碼的查詢語句是長這樣的。

  1. SELECT id FROM order 
  2. WHERE OrderCreateTime BETWEEN '2021-05-01 00:00:00' AND '2021-06-01 00:00:00' 
  3. ORDER BY id DESC 
  4. LIMIT 151300, 100 

與實(shí)際運(yùn)維給的慢sql語句中的LIMIT 0, 151400完全不符合。

包括我們自己也 review 了代碼,把 sql日志也截了圖,找技術(shù)總監(jiān)說理去。

之后,當(dāng)測試人員再次點(diǎn)擊分頁查詢的時(shí)候,運(yùn)維又監(jiān)控到了LIMIT 0, 151400這種怪異的SQL,我們花了好幾個(gè)小時(shí)排查,在本地跑測試,還是沒發(fā)現(xiàn)什么問題,真的感覺到了要懷疑人生了!

當(dāng)多次測試的時(shí)候,這個(gè)問題每次都能復(fù)現(xiàn),讓我想起了一個(gè)問題,是不是 Mycat 分頁的時(shí)候,對(duì)全表掃描了。

后來經(jīng)過查閱資料,才發(fā)現(xiàn)真有這個(gè)坑!

在分庫分表的情況下,宕 limit 的開始位置特別大的時(shí)候,例如大于某表的總行數(shù)時(shí),mycat 將查詢各個(gè)分表的結(jié)果集返,然后在mycat中進(jìn)行合并和排序,再返回結(jié)果。

例如,當(dāng)你原始的 sql 語句是這樣的:

  1. SELECT * FROM table_name WHERE type='xxx' ORDER BY create_time LIMIT 10000,1000 

通過 mycat 執(zhí)行的結(jié)果,會(huì)是這樣的:

  1. SELECT * FROM table_name WHERE type='xxx' ORDER BY create_time LIMIT 0,11000 

結(jié)果集特別大的情況會(huì)導(dǎo)致查詢很慢,嚴(yán)重的情況會(huì)直接導(dǎo)致 mycat OOM!

因此,在分庫分表的情況,不要用 mycat 進(jìn)行大批量的數(shù)據(jù)分頁查詢,通過條件過濾,減小分頁的數(shù)據(jù)量大小!

2.2、子查詢結(jié)果偶爾不完整

當(dāng)通過某些條件,篩選訂單項(xiàng)數(shù)據(jù)時(shí),測試人員反饋某些數(shù)據(jù)偶爾出現(xiàn)不完整。

具體SQL操作如下:

  1. select id,productName 
  2. from orderItem 
  3. where orderId in ( 
  4.  select id from order where userName = '張三' 

預(yù)期的查詢結(jié)果時(shí):

  1. 1,"巧克力" 
  2.  
  3. 2,"可樂" 
  4.  
  5. 3,"果凍" 
  6.  
  7. 4,"蘋果手機(jī)" 

但是實(shí)際查詢的時(shí)候,有時(shí)候的結(jié)果如下:

  1. 1,"巧克力" 
  2. 2,"可樂" 
  3. 4,"蘋果手機(jī)" 

在網(wǎng)上查詢了相關(guān)的問題,在分庫分表的情況下,子查詢出了偶爾查詢不到完整數(shù)據(jù)外,還會(huì)出現(xiàn) mycat 內(nèi)部死鎖,因此盡量在代碼中不要使用子查詢,而是采用主鍵ID或是索引字段進(jìn)行單表查詢,這樣效率會(huì)大大提升!

2.3、跨分片join問題

由于歷史代碼的緣故,訂單服務(wù)里面存在很多各種連表操作,例如:

  1. select a.*,b.accountName,c.address 
  2. from order a 
  3. left join account b on a.accountId = b.id 
  4. left join account_address c on  b.id = c.accountId 
  5. where a.orderId = 11110011 

但是在走 mycat 查詢之后,直接報(bào)錯(cuò)!

原因是:mycat 目前只支持兩張分片表的 Join,如果要支持多張表需要自己改造程序代碼或者改造Mycat的源代碼。

2.4、部分SQL語法不支持

在實(shí)際使用的時(shí)候,發(fā)現(xiàn)還有部分sql語句是不支持的。

復(fù)制插入(不支持)

  1. insert into......select..... 

復(fù)雜更新(不支持)

  1. update a, b set a.remark='備注' where a.id=b.id; 

復(fù)雜刪除(不支持)

  1. delete a from a join b on a.id=b.id; 

還有就是不支持跨庫連表操作!

2.5、不支持存儲(chǔ)過程創(chuàng)建和調(diào)用

有一點(diǎn),需要大家注意的,在走 mycat 中間件的方式與數(shù)據(jù)庫連接的時(shí)候,如果代碼中寫了存儲(chǔ)過程等語句,是 mycat 是不支持調(diào)用的,因此盡量不要使用!

三、小結(jié)

雖然上面介紹了 mycat 有一些坑,但是這些坑,通過一些優(yōu)化手段還是可以避免的。

實(shí)際上,mycat 作為分庫分表的中間件,也有許多的優(yōu)勢,例如下面官網(wǎng)的介紹。

據(jù)了解,mycat 是目前最成熟、使用最廣的中間件,因此大家在使用的時(shí)候,不需要帶有啥顧慮,對(duì)于以上的坑點(diǎn),盡可能的避免。

 

責(zé)任編輯:武曉燕 來源: Java極客技術(shù)
相關(guān)推薦

2024-01-03 08:14:33

GreatSQLMyCat庫名字

2022-05-15 08:13:50

Mysql數(shù)據(jù)庫Mycat

2019-05-13 15:00:14

MySQLMyCat數(shù)據(jù)庫

2021-05-08 18:50:57

分庫分表中間件

2024-06-26 00:34:12

2020-04-10 17:00:33

Mycat分庫分表SpringBoot

2024-09-09 09:08:28

2020-07-30 17:59:34

分庫分表SQL數(shù)據(jù)庫

2024-02-26 08:39:39

分庫分表數(shù)量

2019-11-12 09:54:20

分庫分表數(shù)據(jù)

2024-07-26 00:16:11

2023-03-10 18:20:07

客戶端開源中間件

2022-07-11 08:16:47

NewSQL關(guān)系數(shù)據(jù)庫系統(tǒng)

2021-08-31 20:21:11

VitessMySQL分庫

2023-08-11 08:59:49

分庫分表數(shù)據(jù)數(shù)據(jù)庫

2020-11-18 09:39:02

MySQL數(shù)據(jù)庫SQL

2025-04-01 08:45:00

2020-07-28 09:04:09

NewSQL分庫分表

2021-01-26 05:37:08

分庫分表內(nèi)存

2022-06-15 07:32:24

數(shù)據(jù)庫分庫分表
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)