操屁眼的视频在线免费看,日本在线综合一区二区,久久在线观看免费视频,欧美日韩精品久久综

新聞資訊

    1.

    2.

    3.

    4.

    一. 數(shù)據(jù)切分

    關(guān)系型數(shù)據(jù)庫(kù)本身比較容易成為系統(tǒng)瓶頸,單機(jī)存儲(chǔ)容量、連接數(shù)、處理能力都有限。當(dāng)單表的數(shù)據(jù)量達(dá)到1000W或100G以后,由于查詢維度較多,即使添加從庫(kù)、優(yōu)化索引,做很多操作時(shí)性能仍下降嚴(yán)重。此時(shí)就要考慮對(duì)其進(jìn)行切分了,切分的目的就在于減少數(shù)據(jù)庫(kù)的負(fù)擔(dān),縮短查詢時(shí)間。

    數(shù)據(jù)庫(kù)分布式核心內(nèi)容無(wú)非就是數(shù)據(jù)切分(),以及切分后對(duì)數(shù)據(jù)的定位、整合。數(shù)據(jù)切分就是將數(shù)據(jù)分散存儲(chǔ)到多個(gè)數(shù)據(jù)庫(kù)中,使得單一數(shù)據(jù)庫(kù)中的數(shù)據(jù)量變小,通過(guò)擴(kuò)充主機(jī)的數(shù)量緩解單一數(shù)據(jù)庫(kù)的性能問(wèn)題,從而達(dá)到提升數(shù)據(jù)庫(kù)操作性能的目的。

    數(shù)據(jù)切分根據(jù)其切分類型,可以分為兩種方式:垂直(縱向)切分和水平(橫向)切分

    1、垂直(縱向)切分

    垂直切分常見有垂直分庫(kù)和垂直分表兩種。

    垂直分庫(kù)就是根據(jù)業(yè)務(wù)耦合性,將關(guān)聯(lián)度低的不同表存儲(chǔ)在不同的數(shù)據(jù)庫(kù)。做法與大系統(tǒng)拆分為多個(gè)小系統(tǒng)類似,按業(yè)務(wù)分類進(jìn)行獨(dú)立劃分。與"微服務(wù)治理"的做法相似,每個(gè)微服務(wù)使用單獨(dú)的一個(gè)數(shù)據(jù)庫(kù)。如圖:

    垂直分表是基于數(shù)據(jù)庫(kù)中的"列"進(jìn)行,某個(gè)表字段較多,可以新建一張擴(kuò)展表,將不經(jīng)常用或字段長(zhǎng)度較大的字段拆分出去到擴(kuò)展表中。

    在字段很多的情況下(例如一個(gè)大表有100多個(gè)字段),通過(guò)"大表拆小表",更便于開發(fā)與維護(hù),也能避免跨頁(yè)問(wèn)題,MySQL底層是通過(guò)數(shù)據(jù)頁(yè)存儲(chǔ)的,一條記錄占用空間過(guò)大會(huì)導(dǎo)致跨頁(yè),造成額外的性能開銷。

    另外數(shù)據(jù)庫(kù)以行為單位將數(shù)據(jù)加載到內(nèi)存中,這樣表中字段長(zhǎng)度較短且訪問(wèn)頻率較高,內(nèi)存能加載更多的數(shù)據(jù),命中率更高,減少了磁盤IO,從而提升了數(shù)據(jù)庫(kù)性能

    垂直切分的優(yōu)點(diǎn):

    缺點(diǎn):

    2、水平(橫向)切分

    當(dāng)一個(gè)應(yīng)用難以再細(xì)粒度的垂直切分,或切分后數(shù)據(jù)量行數(shù)巨大,存在單庫(kù)讀寫、存儲(chǔ)性能瓶頸,這時(shí)候就需要進(jìn)行水平切分了。

    水平切分分為庫(kù)內(nèi)分表和分庫(kù)分表,是根據(jù)表內(nèi)數(shù)據(jù)內(nèi)在的邏輯關(guān)系,將同一個(gè)表按不同的條件分散到多個(gè)數(shù)據(jù)庫(kù)或多個(gè)表中,每個(gè)表中只包含一部分?jǐn)?shù)據(jù),從而使得單個(gè)表的數(shù)據(jù)量變小,達(dá)到分布式的效果。如圖所示:

    庫(kù)內(nèi)分表只解決了單一表數(shù)據(jù)量過(guò)大的問(wèn)題,但沒(méi)有將表分布到不同機(jī)器的庫(kù)上,因此對(duì)于減輕MySQL數(shù)據(jù)庫(kù)的壓力來(lái)說(shuō),幫助不是很大,大家還是競(jìng)爭(zhēng)同一個(gè)物理機(jī)的CPU、內(nèi)存、網(wǎng)絡(luò)IO,最好通過(guò)分庫(kù)分表來(lái)解決。

    水平切分的優(yōu)點(diǎn):

    缺點(diǎn):

    水平切分后同一張表會(huì)出現(xiàn)在多個(gè)數(shù)據(jù)庫(kù)/表中,每個(gè)庫(kù)/表的內(nèi)容不同。幾種典型的數(shù)據(jù)分片規(guī)則為:

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

    修改數(shù)據(jù)庫(kù)最大連接數(shù)_貴陽(yáng)大數(shù)據(jù)數(shù)博會(huì)2018_大數(shù)據(jù) 數(shù)糧

    按照時(shí)間區(qū)間或ID區(qū)間來(lái)切分。例如:按日期將不同月甚至是日的數(shù)據(jù)分散到不同的庫(kù)中;將為1~9999的記錄分到第一個(gè)庫(kù),10000~20000的分到第二個(gè)庫(kù),以此類推。某種意義上,某些系統(tǒng)中使用的"冷熱數(shù)據(jù)分離",將一些使用較少的歷史數(shù)據(jù)遷移到其他庫(kù)中,業(yè)務(wù)功能上只提供熱點(diǎn)數(shù)據(jù)的查詢,也是類似的實(shí)踐。

    這樣的優(yōu)點(diǎn)在于:

    缺點(diǎn):

    2、根據(jù)數(shù)值取模

    一般采用hash取模mod的切分方式,例如:將 表根據(jù) cusno 字段切分到4個(gè)庫(kù)中,余數(shù)為0的放到第一個(gè)庫(kù),余數(shù)為1的放到第二個(gè)庫(kù),以此類推。這樣同一個(gè)用戶的數(shù)據(jù)會(huì)分散到同一個(gè)庫(kù)中,如果查詢條件帶有cusno字段,則可明確定位到相應(yīng)庫(kù)去查詢。

    優(yōu)點(diǎn):

    缺點(diǎn):

    二. 分庫(kù)分表帶來(lái)的問(wèn)題

    分庫(kù)分表能有效的環(huán)節(jié)單機(jī)和單庫(kù)帶來(lái)的性能瓶頸和壓力,突破網(wǎng)絡(luò)IO、硬件資源、連接數(shù)的瓶頸,同時(shí)也帶來(lái)了一些問(wèn)題。下面將描述這些技術(shù)挑戰(zhàn)以及對(duì)應(yīng)的解決思路。

    1、事務(wù)一致性問(wèn)題

    分布式事務(wù)

    當(dāng)更新內(nèi)容同時(shí)分布在不同庫(kù)中,不可避免會(huì)帶來(lái)跨庫(kù)事務(wù)問(wèn)題。跨分片事務(wù)也是分布式事務(wù),沒(méi)有簡(jiǎn)單的方案,一般可使用"XA協(xié)議"和"兩階段提交"處理。

    分布式事務(wù)能最大限度保證了數(shù)據(jù)庫(kù)操作的原子性。但在提交事務(wù)時(shí)需要協(xié)調(diào)多個(gè)節(jié)點(diǎn),推后了提交事務(wù)的時(shí)間點(diǎn),延長(zhǎng)了事務(wù)的執(zhí)行時(shí)間。導(dǎo)致事務(wù)在訪問(wèn)共享資源時(shí)發(fā)生沖突或死鎖的概率增高。隨著數(shù)據(jù)庫(kù)節(jié)點(diǎn)的增多,這種趨勢(shì)會(huì)越來(lái)越嚴(yán)重,從而成為系統(tǒng)在數(shù)據(jù)庫(kù)層面上水平擴(kuò)展的枷鎖。

    最終一致性

    對(duì)于那些性能要求很高,但對(duì)一致性要求不高的系統(tǒng),往往不苛求系統(tǒng)的實(shí)時(shí)一致性,只要在允許的時(shí)間段內(nèi)達(dá)到最終一致性即可,可采用事務(wù)補(bǔ)償?shù)姆绞健Ec事務(wù)在執(zhí)行中發(fā)生錯(cuò)誤后立即回滾的方式不同,事務(wù)補(bǔ)償是一種事后檢查補(bǔ)救的措施,一些常見的實(shí)現(xiàn)方法有:對(duì)數(shù)據(jù)進(jìn)行對(duì)賬檢查,基于日志進(jìn)行對(duì)比,定期同標(biāo)準(zhǔn)數(shù)據(jù)來(lái)源進(jìn)行同步等等。事務(wù)補(bǔ)償還要結(jié)合業(yè)務(wù)系統(tǒng)來(lái)考慮。

    2、跨節(jié)點(diǎn)關(guān)聯(lián)查詢 join 問(wèn)題

    切分之前,系統(tǒng)中很多列表和詳情頁(yè)所需的數(shù)據(jù)可以通過(guò)sql join來(lái)完成。而切分之后,數(shù)據(jù)可能分布在不同的節(jié)點(diǎn)上,此時(shí)join帶來(lái)的問(wèn)題就比較麻煩了,考慮到性能,盡量避免使用join查詢。

    解決這個(gè)問(wèn)題的一些方法:

    1)全局表

    全局表,也可看做是"數(shù)據(jù)字典表",就是系統(tǒng)中所有模塊都可能依賴的一些表,為了避免跨庫(kù)join查詢,可以將這類表在每個(gè)數(shù)據(jù)庫(kù)中都保存一份。這些數(shù)據(jù)通常很少會(huì)進(jìn)行修改,所以也不擔(dān)心一致性的問(wèn)題。

    2)字段冗余

    一種典型的反范式設(shè)計(jì),利用空間換時(shí)間,為了性能而避免join查詢。例如:訂單表保存時(shí)候,也將冗余保存一份,這樣查詢訂單詳情時(shí)就不需要再去查詢"買家user表"了。

    但這種方法適用場(chǎng)景也有限修改數(shù)據(jù)庫(kù)最大連接數(shù),比較適用于依賴字段比較少的情況。而冗余字段的數(shù)據(jù)一致性也較難保證,就像上面訂單表的例子,買家修改了后,是否需要在歷史訂單中同步更新呢?這也要結(jié)合實(shí)際業(yè)務(wù)場(chǎng)景進(jìn)行考慮。

    修改數(shù)據(jù)庫(kù)最大連接數(shù)_貴陽(yáng)大數(shù)據(jù)數(shù)博會(huì)2018_大數(shù)據(jù) 數(shù)糧

    3)數(shù)據(jù)組裝

    在系統(tǒng)層面,分兩次查詢,第一次查詢的結(jié)果集中找出關(guān)聯(lián)數(shù)據(jù)id,然后根據(jù)id發(fā)起第二次請(qǐng)求得到關(guān)聯(lián)數(shù)據(jù)。最后將獲得到的數(shù)據(jù)進(jìn)行字段拼裝。

    4)ER分片

    關(guān)系型數(shù)據(jù)庫(kù)中,如果可以先確定表之間的關(guān)聯(lián)關(guān)系,并將那些存在關(guān)聯(lián)關(guān)系的表記錄存放在同一個(gè)分片上,那么就能較好的避免跨分片join問(wèn)題。在1:1或1:n的情況下,通常按照主表的ID主鍵切分。如下圖所示:

    這樣一來(lái),Data Node1上面的order訂單表與訂單詳情表就可以通過(guò)進(jìn)行局部的關(guān)聯(lián)查詢了,Data Node2上也一樣。

    3、跨節(jié)點(diǎn)分頁(yè)、排序、函數(shù)問(wèn)題

    跨節(jié)點(diǎn)多庫(kù)進(jìn)行查詢時(shí),會(huì)出現(xiàn)limit分頁(yè)、order by排序等問(wèn)題。分頁(yè)需要按照指定字段進(jìn)行排序,當(dāng)排序字段就是分片字段時(shí),通過(guò)分片規(guī)則就比較容易定位到指定的分片;當(dāng)排序字段非分片字段時(shí),就變得比較復(fù)雜了。

    需要先在不同的分片節(jié)點(diǎn)中將數(shù)據(jù)進(jìn)行排序并返回,然后將不同分片返回的結(jié)果集進(jìn)行匯總和再次排序,最終返回給用戶。如圖所示:

    上圖中只是取第一頁(yè)的數(shù)據(jù),對(duì)性能影響還不是很大。但是如果取得頁(yè)數(shù)很大,情況則變得復(fù)雜很多,因?yàn)楦鞣制?jié)點(diǎn)中的數(shù)據(jù)可能是隨機(jī)的,為了排序的準(zhǔn)確性,需要將所有節(jié)點(diǎn)的前N頁(yè)數(shù)據(jù)都排序好做合并,最后再進(jìn)行整體的排序,這樣的操作時(shí)很耗費(fèi)CPU和內(nèi)存資源的,所以頁(yè)數(shù)越大,系統(tǒng)的性能也會(huì)越差。

    在使用Max、Min、Sum、Count之類的函數(shù)進(jìn)行計(jì)算的時(shí)候,也需要先在每個(gè)分片上執(zhí)行相應(yīng)的函數(shù),然后將各個(gè)分片的結(jié)果集進(jìn)行匯總和再次計(jì)算,最終將結(jié)果返回。如圖所示:

    4、全局主鍵避重問(wèn)題

    在分庫(kù)分表環(huán)境中,由于表中數(shù)據(jù)同時(shí)存在不同數(shù)據(jù)庫(kù)中,主鍵值平時(shí)使用的自增長(zhǎng)將無(wú)用武之地,某個(gè)分區(qū)數(shù)據(jù)庫(kù)自生成的ID無(wú)法保證全局唯一。因此需要單獨(dú)設(shè)計(jì)全局主鍵,以避免跨庫(kù)主鍵重復(fù)問(wèn)題。有一些常見的主鍵生成策略:

    1)UUID

    UUID標(biāo)準(zhǔn)形式包含32個(gè)16進(jìn)制數(shù)字,分為5段,形式為8-4-4-4-12的36個(gè)字符,例如:-e29b-41d4-a716-

    UUID是主鍵是最簡(jiǎn)單的方案,本地生成,性能高,沒(méi)有網(wǎng)絡(luò)耗時(shí)。但缺點(diǎn)也很明顯,由于UUID非常長(zhǎng),會(huì)占用大量的存儲(chǔ)空間;另外,作為主鍵建立索引和基于索引進(jìn)行查詢時(shí)都會(huì)存在性能問(wèn)題,在下,UUID的無(wú)序性會(huì)引起數(shù)據(jù)位置頻繁變動(dòng),導(dǎo)致分頁(yè)。

    2)結(jié)合數(shù)據(jù)庫(kù)維護(hù)主鍵ID表

    在數(shù)據(jù)庫(kù)中建立 表:

    CREATE?TABLE?`sequence`?(??
    ??`id`?bigint(20)?unsigned?NOT?NULL?auto_increment,??
    ??`stub`?char(1)?NOT?NULL?default?'',??
    ??PRIMARY?KEY??(`id`),??
    ??UNIQUE?KEY?`stub`?(`stub`)??
    )?ENGINE=MyISAM;

    stub字段設(shè)置為唯一索引,同一stub值在表中只有一條記錄,可以同時(shí)為多張表生成全局ID。表的內(nèi)容,如下所示:

    +-------------------+------+??
    |?id????????????????|?stub?|??
    +-------------------+------+??
    |?72157623227190423?|????a?|??
    +-------------------+------+??

    使用 存儲(chǔ)引擎而不是 ,以獲取更高的性能。使用的是表級(jí)別的鎖,對(duì)表的讀寫是串行的,所以不用擔(dān)心在并發(fā)時(shí)兩次讀取同一個(gè)ID值。

    當(dāng)需要全局唯一的64位ID時(shí),執(zhí)行:

    貴陽(yáng)大數(shù)據(jù)數(shù)博會(huì)2018_大數(shù)據(jù) 數(shù)糧_修改數(shù)據(jù)庫(kù)最大連接數(shù)

    REPLACE?INTO?sequence?(stub)?VALUES?('a');??
    SELECT?LAST_INSERT_ID();??

    這兩條語(yǔ)句是級(jí)別的, () 必須與 into 在同一數(shù)據(jù)庫(kù)連接下才能得到剛剛插入的新ID。

    使用 into代替 into好處是避免了表行數(shù)過(guò)大,不需要另外定期清理。

    此方案較為簡(jiǎn)單,但缺點(diǎn)也明顯:存在單點(diǎn)問(wèn)題,強(qiáng)依賴DB,當(dāng)DB異常時(shí),整個(gè)系統(tǒng)都不可用。配置主從可以增加可用性,但當(dāng)主庫(kù)掛了,主從切換時(shí),數(shù)據(jù)一致性在特殊情況下難以保證。另外性能瓶頸限制在單臺(tái)MySQL的讀寫性能。

    團(tuán)隊(duì)使用的一種主鍵生成策略,與上面的表方案類似,但更好的解決了單點(diǎn)和性能瓶頸的問(wèn)題。

    這一方案的整體思想是:建立2個(gè)以上的全局ID生成的服務(wù)器,每個(gè)服務(wù)器上只部署一個(gè)數(shù)據(jù)庫(kù),每個(gè)庫(kù)有一張表用于記錄當(dāng)前全局ID。表中ID增長(zhǎng)的步長(zhǎng)是庫(kù)的數(shù)量,起始值依次錯(cuò)開,這樣能將ID的生成散列到各個(gè)數(shù)據(jù)庫(kù)上。如下圖所示:

    由兩個(gè)數(shù)據(jù)庫(kù)服務(wù)器生成ID,設(shè)置不同的值。第一臺(tái)的起始值為1,每次步長(zhǎng)增長(zhǎng)2,另一臺(tái)的起始值為2,每次步長(zhǎng)增長(zhǎng)也是2。結(jié)果第一臺(tái)生成的ID都是奇數(shù)(1, 3, 5, 7 …),第二臺(tái)生成的ID都是偶數(shù)(2, 4, 6, 8 …)。

    這種方案將生成ID的壓力均勻分布在兩臺(tái)機(jī)器上。同時(shí)提供了系統(tǒng)容錯(cuò),第一臺(tái)出現(xiàn)了錯(cuò)誤,可以自動(dòng)切換到第二臺(tái)機(jī)器上獲取ID。但有以下幾個(gè)缺點(diǎn):系統(tǒng)添加機(jī)器,水平擴(kuò)展時(shí)較復(fù)雜;每次獲取ID都要讀寫一次DB,DB的壓力還是很大,只能靠堆機(jī)器來(lái)提升性能。

    可以基于的方案繼續(xù)優(yōu)化,使用批量的方式降低數(shù)據(jù)庫(kù)的寫壓力,每次獲取一段區(qū)間的ID號(hào)段,用完之后再去數(shù)據(jù)庫(kù)獲取,可以大大減輕數(shù)據(jù)庫(kù)的壓力。如下圖所示:

    還是使用兩臺(tái)DB保證可用性,數(shù)據(jù)庫(kù)中只存儲(chǔ)當(dāng)前的最大ID。ID生成服務(wù)每次批量拉取6個(gè)ID,先將修改為5,當(dāng)應(yīng)用訪問(wèn)ID生成服務(wù)時(shí),就不需要訪問(wèn)數(shù)據(jù)庫(kù),從號(hào)段緩存中依次派發(fā)0~5的ID。當(dāng)這些ID發(fā)完后,再將修改為11,下次就能派發(fā)6~11的ID。于是,數(shù)據(jù)庫(kù)的壓力降低為原來(lái)的1/6。

    3)分布式自增ID算法

    的算法解決了分布式系統(tǒng)生成全局ID的需求,生成64位的Long型數(shù)字,組成部分:

    這樣的好處是:毫秒數(shù)在高位,生成的ID整體上按時(shí)間趨勢(shì)遞增;不依賴第三方系統(tǒng),穩(wěn)定性和效率較高,理論上QPS約為409.6w/s(1000*2^12),并且整個(gè)分布式系統(tǒng)內(nèi)不會(huì)產(chǎn)生ID碰撞;可根據(jù)自身業(yè)務(wù)靈活分配bit位。

    不足就在于:強(qiáng)依賴機(jī)器時(shí)鐘,如果時(shí)鐘回?fù)埽瑒t可能導(dǎo)致生成ID重復(fù)。

    綜上

    結(jié)合數(shù)據(jù)庫(kù)和的唯一ID方案,可以參考業(yè)界較為成熟的解法:

    并考慮到了高可用、容災(zāi)、分布式下時(shí)鐘等問(wèn)題。

    5、數(shù)據(jù)遷移、擴(kuò)容問(wèn)題

    當(dāng)業(yè)務(wù)高速發(fā)展,面臨性能和存儲(chǔ)的瓶頸時(shí),才會(huì)考慮分片設(shè)計(jì),此時(shí)就不可避免的需要考慮歷史數(shù)據(jù)遷移的問(wèn)題。一般做法是先讀出歷史數(shù)據(jù),然后按指定的分片規(guī)則再將數(shù)據(jù)寫入到各個(gè)分片節(jié)點(diǎn)中。

    此外還需要根據(jù)當(dāng)前的數(shù)據(jù)量和QPS,以及業(yè)務(wù)發(fā)展的速度,進(jìn)行容量規(guī)劃,推算出大概需要多少分片(一般建議單個(gè)分片上的單表數(shù)據(jù)量不超過(guò)1000W)

    如果采用數(shù)值范圍分片,只需要添加節(jié)點(diǎn)就可以進(jìn)行擴(kuò)容了,不需要對(duì)分片數(shù)據(jù)遷移。如果采用的是數(shù)值取模分片,則考慮后期的擴(kuò)容問(wèn)題就相對(duì)比較麻煩。

    三. 什么時(shí)候考慮切分

    修改數(shù)據(jù)庫(kù)最大連接數(shù)_貴陽(yáng)大數(shù)據(jù)數(shù)博會(huì)2018_大數(shù)據(jù) 數(shù)糧

    下面講述一下什么時(shí)候需要考慮做數(shù)據(jù)切分。

    1、能不切分盡量不要切分

    并不是所有表都需要進(jìn)行切分,主要還是看數(shù)據(jù)的增長(zhǎng)速度。切分后會(huì)在某種程度上提升業(yè)務(wù)的復(fù)雜度,數(shù)據(jù)庫(kù)除了承載數(shù)據(jù)的存儲(chǔ)和查詢外,協(xié)助業(yè)務(wù)更好的實(shí)現(xiàn)需求也是其重要工作之一。

    不到萬(wàn)不得已不用輕易使用分庫(kù)分表這個(gè)大招,避免"過(guò)度設(shè)計(jì)"和"過(guò)早優(yōu)化"。分庫(kù)分表之前,不要為分而分,先盡力去做力所能及的事情,例如:升級(jí)硬件、升級(jí)網(wǎng)絡(luò)、讀寫分離、索引優(yōu)化等等。當(dāng)數(shù)據(jù)量達(dá)到單表的瓶頸時(shí)候,再考慮分庫(kù)分表。

    2、數(shù)據(jù)量過(guò)大,正常運(yùn)維影響業(yè)務(wù)訪問(wèn)

    這里說(shuō)的運(yùn)維,指:

    1)對(duì)數(shù)據(jù)庫(kù)備份,如果單表太大,備份時(shí)需要大量的磁盤IO和網(wǎng)絡(luò)IO。例如1T的數(shù)據(jù),網(wǎng)絡(luò)傳輸占50MB時(shí)候,需要20000秒才能傳輸完畢,整個(gè)過(guò)程的風(fēng)險(xiǎn)都是比較高的

    2)對(duì)一個(gè)很大的表進(jìn)行DDL修改時(shí),MySQL會(huì)鎖住全表,這個(gè)時(shí)間會(huì)很長(zhǎng),這段時(shí)間業(yè)務(wù)不能訪問(wèn)此表,影響很大。如果使用pt---,使用過(guò)程中會(huì)創(chuàng)建觸發(fā)器和影子表,也需要很長(zhǎng)的時(shí)間。在此操作過(guò)程中,都算為風(fēng)險(xiǎn)時(shí)間。將數(shù)據(jù)表拆分,總量減少,有助于降低這個(gè)風(fēng)險(xiǎn)。

    3)大表會(huì)經(jīng)常訪問(wèn)與更新,就更有可能出現(xiàn)鎖等待。將數(shù)據(jù)切分,用空間換時(shí)間,變相降低訪問(wèn)壓力

    3、隨著業(yè)務(wù)發(fā)展,需要對(duì)某些字段垂直拆分

    舉個(gè)例子,假如項(xiàng)目一開始設(shè)計(jì)的用戶表如下:

    id???????????????????bigint?????????????#用戶的ID
    name?????????????????varchar????????????#用戶的名字
    last_login_time??????datetime???????????#最近登錄時(shí)間
    personal_info????????text???????????????#私人信息
    .....???????????????????????????????????#其他信息字段

    在項(xiàng)目初始階段,這種設(shè)計(jì)是滿足簡(jiǎn)單的業(yè)務(wù)需求的,也方便快速迭代開發(fā)。而當(dāng)業(yè)務(wù)快速發(fā)展時(shí),用戶量從10w激增到10億,用戶非常的活躍,每次登錄會(huì)更新 字段,使得 user 表被不斷,壓力很大。

    而其他字段:id, name, 是不變的或很少更新的,此時(shí)在業(yè)務(wù)角度,就要將 拆分出去,新建一個(gè) 表。

    屬性是更新和查詢頻率較低的,并且text字段占據(jù)了太多的空間。這時(shí)候,就要對(duì)此垂直拆分出 表了。

    4、數(shù)據(jù)量快速增長(zhǎng)

    隨著業(yè)務(wù)的快速發(fā)展,單表中的數(shù)據(jù)量會(huì)持續(xù)增長(zhǎng),當(dāng)性能接近瓶頸時(shí),就需要考慮水平切分,做分庫(kù)分表了。此時(shí)一定要選擇合適的切分規(guī)則,提前預(yù)估好數(shù)據(jù)容量

    5、安全性和可用性

    雞蛋不要放在一個(gè)籃子里。在業(yè)務(wù)層面上垂直切分,將不相關(guān)的業(yè)務(wù)的數(shù)據(jù)庫(kù)分隔,因?yàn)槊總€(gè)業(yè)務(wù)的數(shù)據(jù)量、訪問(wèn)量都不同,不能因?yàn)橐粋€(gè)業(yè)務(wù)把數(shù)據(jù)庫(kù)搞掛而牽連到其他業(yè)務(wù)。利用水平切分,當(dāng)一個(gè)數(shù)據(jù)庫(kù)出現(xiàn)問(wèn)題時(shí),不會(huì)影響到100%的用戶,每個(gè)庫(kù)只承擔(dān)業(yè)務(wù)的一部分?jǐn)?shù)據(jù),這樣整體的可用性就能提高。

    四. 案例分析1、用戶中心業(yè)務(wù)場(chǎng)景

    用戶中心是一個(gè)非常常見的業(yè)務(wù),主要提供用戶注冊(cè)、登錄、查詢/修改等功能,其核心表為:

    User(uid,?login_name,?passwd,?sex,?age,?nickname)

    uid為用戶ID,??主鍵
    login_name,?passwd,?sex,?age,?nickname,??用戶屬性

    任何脫離業(yè)務(wù)的架構(gòu)設(shè)計(jì)都是耍流氓,在進(jìn)行分庫(kù)分表前,需要對(duì)業(yè)務(wù)場(chǎng)景需求進(jìn)行梳理:

    用戶側(cè):前臺(tái)訪問(wèn),訪問(wèn)量較大,需要保證高可用和高一致性。主要有兩類需求:

    運(yùn)營(yíng)側(cè):后臺(tái)訪問(wèn),支持運(yùn)營(yíng)需求,按照年齡、性別、登陸時(shí)間、注冊(cè)時(shí)間等進(jìn)行分頁(yè)的查詢。是內(nèi)部系統(tǒng),訪問(wèn)量較低,對(duì)可用性、一致性的要求不高。

    修改數(shù)據(jù)庫(kù)最大連接數(shù)_貴陽(yáng)大數(shù)據(jù)數(shù)博會(huì)2018_大數(shù)據(jù) 數(shù)糧

    2、水平切分方法

    當(dāng)數(shù)據(jù)量越來(lái)越大時(shí),需要對(duì)數(shù)據(jù)庫(kù)進(jìn)行水平切分,上文描述的切分方法有"根據(jù)數(shù)值范圍"和"根據(jù)數(shù)值取模"。

    "根據(jù)數(shù)值范圍":以主鍵uid為劃分依據(jù),按uid的范圍將數(shù)據(jù)水平切分到多個(gè)數(shù)據(jù)庫(kù)上。例如:user-db1存儲(chǔ)uid范圍為0~1000w的數(shù)據(jù),user-db2存儲(chǔ)uid范圍為1000w~數(shù)據(jù)。

    優(yōu)點(diǎn)是:擴(kuò)容簡(jiǎn)單,如果容量不夠,只要增加新db即可。

    不足是:請(qǐng)求量不均勻,一般新注冊(cè)的用戶活躍度會(huì)比較高,所以新的user-db2會(huì)比user-db1負(fù)載高,導(dǎo)致服務(wù)器利用率不平衡

    "根據(jù)數(shù)值取模":也是以主鍵uid為劃分依據(jù),按uid取模的值將數(shù)據(jù)水平切分到多個(gè)數(shù)據(jù)庫(kù)上。例如:user-db1存儲(chǔ)uid取模得1的數(shù)據(jù),user-db2存儲(chǔ)uid取模得0的uid數(shù)據(jù)。

    優(yōu)點(diǎn)是:數(shù)據(jù)量和請(qǐng)求量分布均均勻

    不足是:擴(kuò)容麻煩,當(dāng)容量不夠時(shí),新增加db,需要。需要考慮對(duì)數(shù)據(jù)進(jìn)行平滑的遷移。

    3、非uid的查詢方法

    水平切分后,對(duì)于按uid查詢的需求能很好的滿足,可以直接路由到具體數(shù)據(jù)庫(kù)。而按非uid的查詢,例如,就不知道具體該訪問(wèn)哪個(gè)庫(kù)了,此時(shí)需要遍歷所有庫(kù),性能會(huì)降低很多。

    對(duì)于用戶側(cè),可以采用"建立非uid屬性到uid的映射關(guān)系"的方案;對(duì)于運(yùn)營(yíng)側(cè),可以采用"前臺(tái)與后臺(tái)分離"的方案。

    3.1、建立非uid屬性到uid的映射關(guān)系

    1)映射關(guān)系

    例如:不能直接定位到數(shù)據(jù)庫(kù),可以建立→uid的映射關(guān)系,用索引表或緩存來(lái)存儲(chǔ)。當(dāng)訪問(wèn)時(shí),先通過(guò)映射表查詢出對(duì)應(yīng)的uid,再通過(guò)uid定位到具體的庫(kù)。

    映射表只有兩列,可以承載很多數(shù)據(jù),當(dāng)數(shù)據(jù)量過(guò)大時(shí),也可以對(duì)映射表再做水平切分。這類kv格式的索引結(jié)構(gòu),可以很好的使用cache來(lái)優(yōu)化查詢性能,而且映射關(guān)系不會(huì)頻繁變更,緩存命中率會(huì)很高。

    2)基因法

    分庫(kù)基因:假如通過(guò)uid分庫(kù),分為8個(gè)庫(kù),采用uid%8的方式進(jìn)行路由,此時(shí)是由uid的最后3bit來(lái)決定這行User數(shù)據(jù)具體落到哪個(gè)庫(kù)上,那么這3bit可以看為分庫(kù)基因。

    上面的映射關(guān)系的方法需要額外存儲(chǔ)映射表,按非uid字段查詢時(shí),還需要多一次數(shù)據(jù)庫(kù)或cache的訪問(wèn)。如果想要消除多余的存儲(chǔ)和查詢,可以通過(guò)f函數(shù)取的基因作為uid的分庫(kù)基因。生成uid時(shí),參考上文所述的分布式唯一ID生成方案,再加上最后3位bit值=f()。

    當(dāng)查詢時(shí),只需計(jì)算f()%8的值,就可以定位到具體的庫(kù)。不過(guò)這樣需要提前做好容量規(guī)劃,預(yù)估未來(lái)幾年的數(shù)據(jù)量需要分多少庫(kù),要預(yù)留一定bit的分庫(kù)基因。

    3.2、前臺(tái)與后臺(tái)分離

    對(duì)于用戶側(cè),主要需求是以單行查詢?yōu)橹鳎枰?phone/email到uid的映射關(guān)系,可以解決這些字段的查詢問(wèn)題。

    而對(duì)于運(yùn)營(yíng)側(cè),很多批量分頁(yè)且條件多樣的查詢,這類查詢計(jì)算量大,返回?cái)?shù)據(jù)量大,對(duì)數(shù)據(jù)庫(kù)的性能消耗較高。此時(shí)修改數(shù)據(jù)庫(kù)最大連接數(shù),如果和用戶側(cè)公用同一批服務(wù)或數(shù)據(jù)庫(kù),可能因?yàn)楹笈_(tái)的少量請(qǐng)求,占用大量數(shù)據(jù)庫(kù)資源,而導(dǎo)致用戶側(cè)訪問(wèn)性能降低或超時(shí)。

    這類業(yè)務(wù)最好采用"前臺(tái)與后臺(tái)分離"的方案,運(yùn)營(yíng)側(cè)后臺(tái)業(yè)務(wù)抽取獨(dú)立的和db,解決和前臺(tái)業(yè)務(wù)系統(tǒng)的耦合。由于運(yùn)營(yíng)側(cè)對(duì)可用性、一致性的要求不高,可以不訪問(wèn)實(shí)時(shí)庫(kù),而是通過(guò)異步同步數(shù)據(jù)到運(yùn)營(yíng)庫(kù)進(jìn)行訪問(wèn)。在數(shù)據(jù)量很大的情況下,還可以使用ES搜索引擎或Hive來(lái)滿足后臺(tái)復(fù)雜的查詢方式。

    五. 支持分庫(kù)分表中間件

    站在巨人的肩膀上能省力很多,目前分庫(kù)分表已經(jīng)有一些較為成熟的開源解決方案:

    六. 參考

網(wǎng)站首頁(yè)   |    關(guān)于我們   |    公司新聞   |    產(chǎn)品方案   |    用戶案例   |    售后服務(wù)   |    合作伙伴   |    人才招聘   |   

友情鏈接: 餐飲加盟

地址:北京市海淀區(qū)    電話:010-     郵箱:@126.com

備案號(hào):冀ICP備2024067069號(hào)-3 北京科技有限公司版權(quán)所有