国产精品高清一区二区三区不卡-国产精品一区二区三区免费视频-日韩免费高清一级毛片-亚洲欧美一区二区三区国产精品-日韩欧美一区二区三区不卡视频-亚欧免费视频一区二区三区-亚洲欧美日韩一区成人-欧美日韩视频综合一区无弹窗-精品日韩在线视频一区二区三区-国内精品视频一区二区三区

你好,歡迎進(jìn)入江蘇優(yōu)軟數(shù)字科技有限公司官網(wǎng)!

誠信、勤奮、創(chuàng)新、卓越

友好定價(jià)、專業(yè)客服支持、正版軟件一站式服務(wù)提供

13262879759

工作日:9:00-22:00

千萬級(jí)并發(fā)架構(gòu)下,關(guān)系型數(shù)據(jù)庫應(yīng)該如何優(yōu)化?

發(fā)布時(shí)間:2023-11-12

瀏覽次數(shù):0

大家好,我是頂級(jí)建筑師。

一、概述

順應(yīng)趨勢,大數(shù)據(jù)的高并發(fā)需要不斷的系統(tǒng)升級(jí),分庫分表就是其中之一。

2、為什么要分庫分表?

場景:隨著互聯(lián)網(wǎng)技術(shù)的蓬勃發(fā)展,大數(shù)據(jù)、高并發(fā)是很多企業(yè)遇到的情況。 例如,隨著公司業(yè)務(wù)的發(fā)展,系統(tǒng)用戶數(shù)量迅速增加。 系統(tǒng)每天會(huì)新增10萬條數(shù)據(jù),一個(gè)月會(huì)新增300萬條數(shù)據(jù)。 單表數(shù)據(jù)量已達(dá)到數(shù)百萬,高峰期請(qǐng)求數(shù)達(dá)到1000次。 處理的辦法是我們?cè)诰€部署幾臺(tái)機(jī)器,使用nginx做負(fù)載均衡,數(shù)據(jù)庫支持足夠。 然而,數(shù)據(jù)量不斷增長,下一步我們?cè)撛趺崔k?

當(dāng)每天有幾千萬的活躍用戶,單表每天新增數(shù)據(jù)多達(dá)50萬條時(shí),一張表的總數(shù)據(jù)量就達(dá)到了20~3000萬。 數(shù)據(jù)庫磁盤容量不斷被消耗,并發(fā)峰值達(dá)到驚人的5000。 ~! 此時(shí),單一數(shù)據(jù)庫已經(jīng)無法抵抗。

3、分表3.1、分表計(jì)劃

當(dāng)單表達(dá)到千萬級(jí)時(shí),單表數(shù)據(jù)量過大,會(huì)極大影響SQL執(zhí)行的性能。 稍后,你的 SQL 可能會(huì)運(yùn)行得很慢。 一般來說,當(dāng)單表達(dá)到幾百萬的時(shí)候,性能會(huì)比較差,就會(huì)出現(xiàn)分表的情況。

對(duì)數(shù)值取模

使用Id取模的方法來劃分表格。 例如表示例中,表根據(jù)cusno字段分為4個(gè)庫。 余數(shù)為0的放入第一庫,余數(shù)為1的放入第二庫,余數(shù)為2的放入第三庫。 ,余數(shù)為3的放入第三庫。 這樣,同一個(gè)用戶的數(shù)據(jù)就會(huì)分散到不同的表中。 如果查詢條件包含cusno字段,則可以明確定位對(duì)應(yīng)的表進(jìn)行查詢。

示例描述:

// 首先創(chuàng)建三個(gè)表,然后我創(chuàng)建一個(gè)uuid表,用于提供自增id。

create?table?**customer0**(

????id?int?unsigned?primary?key?,

????name?varchar(32)?not?null?default?'',

????pwd?varchar(32)?not?null?default?''

)engine=myisam?charset?utf8;

create?table?**customer1**(

????id?int?unsigned?primary?key?,

????name?varchar(32)?not?null?default?'',

????pwd?varchar(32)?not?null?default?''

)engine=myisam?charset?utf8;

create?table?**customer2**(

????id?int?unsigned?primary?key?,

????name?varchar(32)?not?null?default?'',

????pwd?varchar(32)?not?null?default?''

)engine=myisam?charset?utf8;

create?table?**customer3**(

????id?int?unsigned?primary?key?,

????name?varchar(32)?not?null?default?'',

????pwd?varchar(32)?not?null?default?''

)engine=myisam?charset?utf8;

create?table?**uuid**(

????id?int?unsigned?primary?key?auto_increment

)engine=myisam?charset?utf8;

**利用以上創(chuàng)建的表進(jìn)行業(yè)務(wù)處理**

@Service

public?class?CustomerService?{

????@Autowired

?????private?JdbcTemplate?jdbcTemplate;

????/**

?????*?注冊(cè)的代碼

?????*?@param?name

?????*?@param?pwd

?????*?@return

?????*/


????public?String?regiter(String?name,String?pwd){

????????//1.生成cusno?,-??先獲取到?自定增長ID

????????String?insertUUidSql?=?"insert?into?uuid?values(null)";//插入空數(shù)據(jù),這里的id是自動(dòng)增長的

????????jdbcTemplate.update(insertUUidSql);//執(zhí)行

??????????//查詢到最近的添加的主鍵id

????????Long?cusno?=?jdbcTemplate.queryForObject("select?last_insert_id()",?Long.class);

????????//2.存放具體的那張表中?-?也就是判斷存儲(chǔ)表名稱

????????String?tableName?=?"customer"?+?cusno?%?3;

????????//3.插入到具體的表中去-?注冊(cè)數(shù)據(jù)

????????String?insertUserSql?=?"INSERT?INTO?"?+?tableName?+?"?VALUES?('"?+?cusno?+?"','"?+?name?+?"','"?+?pwd?+?"');";

????????System.out.println("insertUserSql:"?+?insertUserSql);

????????jdbcTemplate.update(insertUserSql);

????????return?"success";

????}

???/**

?????*?通過cusno查詢name

?????*?@param?userid

?????*?@return

?????*/


????public?String?get(Long?cusno)?{

????????//具體哪張表

????????String?tableName?=?"customer"?+?cusno?%?3;

????????String?sql?=?"select?name?from?"?+?tableName?+?"?where?id="+cusno;

????????System.out.println("SQL:"?+?sql);

????????return?jdbcTemplate.queryForObject(sql,?String.class);//執(zhí)行查詢出name

????}

}

優(yōu)缺點(diǎn)總結(jié)

優(yōu)勢:

將一張數(shù)據(jù)表的數(shù)據(jù)劃分為多張表后,數(shù)據(jù)會(huì)比較均勻,這樣會(huì)減少高并發(fā)訪問對(duì)數(shù)據(jù)庫造成的壓力。

缺點(diǎn):

如果后期擴(kuò)容,則需要遷移舊數(shù)據(jù)并重新計(jì)算。

跨表查詢的復(fù)雜度增加。 例如上例中,如果經(jīng)常使用的查詢條件中不包含cusno,則不會(huì)定位到數(shù)據(jù)庫。 因此,需要同時(shí)向四個(gè)庫發(fā)起查詢,然后合并內(nèi)存中的數(shù)據(jù),取最小集合返回給應(yīng)用程序。 相反,圖書館成了一個(gè)累贅。

根據(jù)數(shù)值范圍

為了解決后期集群擴(kuò)容時(shí)遷移舊數(shù)據(jù)的問題,可以使用按日期或ID進(jìn)行表分區(qū)。 例如:將不同月份甚至幾天的數(shù)據(jù)按日期分布到不同的表中; 將 從 1 到 9999 的記錄分配給第一個(gè)表,將 10000 到 20000 的記錄分配給第二個(gè)表,依此類推。 從某種意義上說,一些系統(tǒng)中采用的“冷熱數(shù)據(jù)分離”,將一些較少使用的歷史數(shù)據(jù)遷移到其他庫,只在業(yè)務(wù)功能中提供熱數(shù)據(jù)查詢,也是類似的做法。

的優(yōu)點(diǎn)和缺點(diǎn)

優(yōu)勢:

單臺(tái)尺寸可控

橫向擴(kuò)展自然很容易。 如果后續(xù)想要擴(kuò)展整個(gè)分片集群,只需要添加節(jié)點(diǎn)即可,不需要遷移其他分片的數(shù)據(jù)。

使用分片字段進(jìn)行范圍搜索時(shí),連續(xù)分片可以快速定位分片進(jìn)行快速查詢,有效避免跨分片查詢問題。

缺點(diǎn):

熱數(shù)據(jù)成為性能瓶頸。 連續(xù)分片可能存在數(shù)據(jù)熱點(diǎn),例如按時(shí)間字段分片。 有些分片存儲(chǔ)的是最近一段時(shí)間的數(shù)據(jù),可能被頻繁讀寫,而有些分片存儲(chǔ)的是很少被查詢的歷史數(shù)據(jù)。

4. 分庫

即一個(gè)數(shù)據(jù)庫一般最多可以支持2000個(gè)并發(fā)。 隨著查詢量的增加,單個(gè)數(shù)據(jù)庫服務(wù)器已經(jīng)無法支持。 此外,為了獲得健康的單數(shù)據(jù)庫并發(fā)值,最好保持在每秒 1000 個(gè)左右。 不要太大,否則會(huì)引起問題。 導(dǎo)致單個(gè)DB的存儲(chǔ)空間不足。 然后就可以將一個(gè)庫的數(shù)據(jù)拆分成多個(gè)庫,訪問時(shí)訪問一個(gè)庫。

垂直分割

垂直拆分就是對(duì)數(shù)據(jù)庫的列進(jìn)行處理,列與對(duì)應(yīng)的業(yè)務(wù)相關(guān)。 這意味著相關(guān)性較低的不同表根據(jù)業(yè)務(wù)耦合存儲(chǔ)在不同的數(shù)據(jù)庫中。 另外,搜索公眾號(hào)Linux,了解如何在后臺(tái)回復(fù)“git books”,即可獲得驚喜大禮包。

考慮到微服務(wù),該方法類似于將一個(gè)大系統(tǒng)拆分為多個(gè)小系統(tǒng)。 它們按照業(yè)務(wù)分類獨(dú)立劃分,每個(gè)微服務(wù)使用獨(dú)立的數(shù)據(jù)庫。 例如,最初有一個(gè)包含用戶表的數(shù)據(jù)庫。 隨著公司業(yè)務(wù)的發(fā)展,技術(shù)團(tuán)隊(duì)成員也隨之?dāng)U大,分為不同的技術(shù)組,不同的組負(fù)責(zé)不同的業(yè)務(wù)模塊。比如A團(tuán)隊(duì)負(fù)責(zé)用戶模塊,B團(tuán)隊(duì)負(fù)責(zé)產(chǎn)品模塊,分為庫和庫。

需要解決的問題:跨庫事務(wù)、jion查詢等。

水平分割

按照規(guī)則,一般是水平分庫在垂直分庫之后。 例如,每天處理的訂單量是海量的,可以按照一定的規(guī)則和級(jí)別進(jìn)行劃分。 例如,表太大,無法存儲(chǔ)在單個(gè)數(shù)據(jù)庫中,或者訪問性能受到壓力。 將一個(gè)表拆分為多個(gè)表,每個(gè)表存儲(chǔ)部分記錄并保存在不同的數(shù)據(jù)庫中。 水平拆分需要對(duì)系統(tǒng)進(jìn)行重大改變。 。

1)縱向擴(kuò)展,升級(jí)數(shù)據(jù)庫所在物理機(jī),提高內(nèi)存/存儲(chǔ)/IO性能。 但這種升級(jí)成本高昂,且只能滿足短期需求。

2)橫向擴(kuò)展,將訂單庫拆分為多個(gè)庫,分發(fā)到多臺(tái)機(jī)器上存儲(chǔ)和訪問。 這種方式支持橫向擴(kuò)展,可以滿足長期需求。

訂單數(shù)據(jù)庫主要包括訂單主表/訂單明細(xì)表(記錄產(chǎn)品詳細(xì)信息)/訂單擴(kuò)展表。 水平分庫將這三個(gè)表的記錄劃分到多個(gè)數(shù)據(jù)庫中。 訂單橫向分庫效果如下圖:

intellij idea 數(shù)據(jù)庫關(guān)系圖_關(guān)系庫的標(biāo)準(zhǔn)語言_數(shù)據(jù)庫中關(guān)系圖怎么出來

數(shù)據(jù)庫分片策略:類似于水平分表

分庫維度確定后,如何將記錄劃分到各個(gè)數(shù)據(jù)庫中? 一般有兩種方式:

根據(jù)取值范圍,例如將用戶ID為1-9999的記錄分配給第一庫,將用戶ID為10000-20000的記錄分配給第二庫,以此類推。

根據(jù)取模值intellij idea 數(shù)據(jù)庫關(guān)系圖,例如用戶ID mod n,余數(shù)為0的記錄放入第一個(gè)庫,余數(shù)為1的記錄放入第二個(gè)庫,以此類推。

需要解決的問題:數(shù)據(jù)路由、組裝。

讀寫分離

對(duì)于時(shí)間不敏感的數(shù)據(jù),可以通過讀寫分離的方式緩解數(shù)據(jù)庫壓力。

需要解決的問題:區(qū)分允許一定時(shí)間延遲的業(yè)務(wù)、數(shù)據(jù)同步問題。

垂直分庫-->水平分庫-->讀寫分離

五、分裂后面臨的新問題的解決辦法

常用解決方案:站在巨人的肩膀上可以省很多力氣。 目前,已經(jīng)有一些相對(duì)成熟的分庫分表開源解決方案。 擴(kuò)展:

使用第三方數(shù)據(jù)庫中間件(Atlas、Mycat、TDDL、DRDS),業(yè)務(wù)系統(tǒng)需要配合數(shù)據(jù)存儲(chǔ)的升級(jí)。 綜合考慮后,其實(shí)建議考慮-jdbc和Mycatintellij idea 數(shù)據(jù)庫關(guān)系圖,這兩個(gè)都可以考慮使用。

-jdbc 這一層方案的優(yōu)點(diǎn)是不需要部署,運(yùn)維成本低,不需要代理層二次轉(zhuǎn)發(fā)請(qǐng)求,性能較高。 不過如果有升級(jí)什么的,每個(gè)系統(tǒng)都需要重新升級(jí)版本才發(fā)布。 每個(gè)系統(tǒng)都需要-jdbc依賴;

Mycat的代理層方案的缺點(diǎn)是需要自己部署和運(yùn)維一套中間件,運(yùn)維成本較高。 但好處是對(duì)每個(gè)項(xiàng)目都是透明的。 如果遇到升級(jí)之類的,通過自己的中間件來處理即可。 。

一般來說,兩種方案都可以使用,但我個(gè)人建議中小型公司選擇-jdbc。 該層解決方案重量輕,維護(hù)成本低。 不需要額外的人力,中小型公司的系統(tǒng)復(fù)雜度會(huì)更低。 ,項(xiàng)目不多; 不過中大型公司最好選擇Mycat之類的代理層解決方案,因?yàn)榇蠊究赡芟到y(tǒng)和項(xiàng)目很多,團(tuán)隊(duì)很大,人員充足,所以最好有專門的人來研究和維護(hù)他們。 mycat,然后大量的項(xiàng)目就可以直接透明的使用了。

隨附的:

負(fù)載均衡:車輛超載,多車運(yùn)輸物料。 有一個(gè)總調(diào)度中心分配每輛車的重量和拉動(dòng)的貨物量。 系統(tǒng)中,總調(diào)度中心可以是nginx。 通過配置多臺(tái)服務(wù)器的IP地址,進(jìn)行權(quán)重分配,并采用輪詢算法實(shí)現(xiàn)處理大并發(fā)的策略。

主鍵生成策略:

intellij idea 數(shù)據(jù)庫關(guān)系圖_數(shù)據(jù)庫中關(guān)系圖怎么出來_關(guān)系庫的標(biāo)準(zhǔn)語言

歡迎大家互相討論、碰撞、發(fā)表意見。 如果有什么問題也可以和我交流。

最后,我們整理了一份BAT各大公司的真實(shí)面試題清單,供讀者參考。 如果您需要,可以掃描二維碼并回復(fù)“面試問題”即可獲取。

公眾號(hào)后臺(tái)回復(fù)結(jié)構(gòu)或結(jié)構(gòu)整齊有驚喜大禮包!

頂尖建筑師交流群

《頂尖建筑師》專門為讀者和建筑師建立了交流群。 可以添加小編微信進(jìn)群。 歡迎有想法、愿意分享的朋友一起交流學(xué)習(xí)。

掃一掃添加好友邀請(qǐng)您加入建筑師群。 添加我時(shí)請(qǐng)注明【姓名+公司+職位】

如有侵權(quán)請(qǐng)聯(lián)系刪除!

13262879759

微信二維碼