日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

long 雪花算法_海量数据分库分表方案(一)算法方案

發(fā)布時間:2024/10/8 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 long 雪花算法_海量数据分库分表方案(一)算法方案 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
本文主要描述分庫分表的算法方案、按什么規(guī)則劃分。循序漸進(jìn)比較目前出現(xiàn)的幾種規(guī)則方式,最后第五種增量遷移方案是我設(shè)想和推薦的方式。后續(xù)章再講述技術(shù)選型和分庫分表后帶來的問題。。

背景

隨著業(yè)務(wù)量遞增,數(shù)據(jù)量遞增,一個表將會存下大量數(shù)據(jù),在一個表有一千萬行數(shù)據(jù)時,通過sql優(yōu)化、提升機(jī)器性能還能承受。為了未來長遠(yuǎn)角度應(yīng)在一定程度時進(jìn)行分庫分表,如出現(xiàn)數(shù)據(jù)庫性能瓶頸、增加字段時需要耗時比較長的時間的情況下。解決獨(dú)立節(jié)點(diǎn)承受所有數(shù)據(jù)的壓力,分布多個節(jié)點(diǎn),提供容錯性,不必一個掛整個系統(tǒng)不能訪問。

目的

本文講述的分庫分表的方案,是基于水平分割的情況下,選擇不同的規(guī)則,比較規(guī)則的優(yōu)缺點(diǎn)。 一般網(wǎng)上就前三種,正常一點(diǎn)的會說第四種,但不是很完美,前面幾種遷移數(shù)據(jù)都會很大影響,推薦我認(rèn)為比較好的方案五。

  • 方案一:對Key取模,除數(shù)逐步遞增
  • 方案二:按時間劃分
  • 方案三:按數(shù)值范圍
  • 方案四:一致性Hash理念——平均分布方案(大眾點(diǎn)評用這種,200G并且一步到位)
  • 方案五:一致性Hash理念——按迭代增加節(jié)點(diǎn)(為了方便增量遷移)
  • 方案六:一致性Hash理念——按范圍分庫(迭代遷移)

Version:1.0 StartHTML:000000208 EndHTML:000021485 StartFragment:000004002 EndFragment:000021399 StartSelection:000004002 EndSelection:000021395 SourceURL:https://my.oschina.net/u/4200053/blog/4255903 window.__STATIC_DOMAIN = "https://static.oschina.net";

方案選擇


方案一:對Key取模,除數(shù)逐步遞增


公式:key mod x (x為自然數(shù))
Key可以為主鍵,也可以為訂單號,也可以為用戶id,這個需要根據(jù)場景決定,哪個作為查詢條件概率多用哪個。優(yōu)點(diǎn):

  • 按需增加庫、表,逐步增加
  • 分布均勻,每一片差異不多

缺點(diǎn):

  • 很多時候會先從2開始分兩個庫逐級遞增,然后分3個、4個、5個。如在mod 3 變 mod 5的情況下,取模后的大部分的數(shù)據(jù)的取模結(jié)果會變化,如key=3時,mod 3=0,突然改變?yōu)閙od 5=3,則將會從第0表遷移到第3表,將會造成很多數(shù)據(jù)多重復(fù)移動位置。
  • 會重復(fù)遷移數(shù)據(jù),當(dāng)分2個時,有數(shù)據(jù)A在第0號表,分3個時數(shù)據(jù)A去了第1號表、到分4個時數(shù)據(jù)A會回到第0號表

方案二:按時間劃分
可以按日、按月、按季度。
tb_20190101 tb_20190102 tb_20190103 ……
這個算法要求在訂單號、userId上添加年月日或者時間戳,或者查詢接口帶上年月日,才能定位在哪個分片。優(yōu)點(diǎn):

  • 數(shù)據(jù)按時間連續(xù)
  • 看數(shù)據(jù)增長比較直觀

缺點(diǎn):

  • 因?yàn)榭紤]到歷史數(shù)據(jù)一開始沒分庫分表后續(xù)進(jìn)行分庫分表時,歷史數(shù)據(jù)的訂單號不一定有時間戳,歷史數(shù)據(jù)可能為自增或者自定義算法得出的分布式主鍵,導(dǎo)致查詢時必須要上游系統(tǒng)傳訂單號、創(chuàng)建時間兩個字段。
  • 若上游系統(tǒng)沒有傳時間,或者上游系統(tǒng)的創(chuàng)建時間與當(dāng)前系統(tǒng)對應(yīng)訂單的創(chuàng)建時間不在同一天的情況下,則當(dāng)前數(shù)據(jù)庫表的數(shù)據(jù)記錄需要有時間字段。因?yàn)樯嫌蜗到y(tǒng)只傳訂單號,這個時候需要獲取創(chuàng)建時間,當(dāng)前系統(tǒng)就必須要有一個主表維護(hù)訂單號和創(chuàng)建時間的關(guān)系,并且每次查詢時都需要先查當(dāng)前系統(tǒng)主表,再查具體表,這樣就會消耗性能。
  • 分布不一定均勻:每月增長數(shù)據(jù)不一樣,可能會有些月份多有些月份少

推薦使用場景:日志記錄


方案三:按數(shù)值范圍


表0 [0,10000000) 表1 [10000000,20000000) 表2 [20000000,30000000) 表3 [30000000,40000000) ……優(yōu)點(diǎn):

  • 分布均勻

缺點(diǎn):

  • 因?yàn)槲粗畲笾?#xff0c;所以無法用時間戳作為key,這個方法不能用表的自增主鍵,因?yàn)槊總€表都自增數(shù)量不是統(tǒng)一維護(hù)。所以需要有一個發(fā)號器或發(fā)號系統(tǒng)做統(tǒng)一維護(hù)key自增的地方。

說后續(xù)推薦的方案中先簡單說說一致性hash
先說一下一致性hash,有些文章說一致性Hash是一種算法,我認(rèn)為它并不是具體的計算公式,而是一個設(shè)定的思路。
1.先假定一個環(huán)形Hash空間,環(huán)上有固定最大值和最小值,頭尾相連,形成一個閉環(huán),如int,long的最大值和最小值。 很多文章會假定2^32個位置,最大值為2^32-1最小值為0,即0~(2^32)-1的數(shù)字空間,他們只是按照常用的hash算法舉例,真實(shí)分庫分表的情況下不是用這個數(shù)字,所以我才會認(rèn)為一致性hash算法其實(shí)是一個理念,并不是真正的計算公式。 如下圖

2. 設(shè)計一個公式函數(shù) value = hash(key),這個公式將會有最大值和最小值,如 key mod 64 = value; 這個公式最大為64,最小為0。然后把數(shù)據(jù)都落在環(huán)上。

3. 設(shè)定節(jié)點(diǎn)node。設(shè)定節(jié)點(diǎn)的方式如對ip進(jìn)行hash,或者自定義固定值(后續(xù)方案是使用固定值)。然后node逆時針走,直到前一個節(jié)點(diǎn)為止,途經(jīng)value=hash(key)的所有數(shù)據(jù)的都?xì)w這個節(jié)點(diǎn)管。 如 hash(node1)=10,則hash(key)=0~10的數(shù)據(jù)都?xì)wnode1管。


概括
這里不詳細(xì)說明這個理論,它主要表達(dá)的意思是固定好最大值,就不再修改最大值到最小值范圍,后續(xù)只修改節(jié)點(diǎn)node的位置和增加node來達(dá)到減少每個node要管的數(shù)據(jù),以達(dá)到減少壓力。
備注: * 不推薦對ip進(jìn)行hash,因?yàn)榭赡軙?dǎo)致hash(ip)得出的結(jié)果很大,例如得出60,若這個節(jié)點(diǎn)的前面沒有節(jié)點(diǎn),則60號位置的這個節(jié)點(diǎn)需要管大部分的數(shù)據(jù)了。 * 最好生成key的方式用雪花算法snowFlake來做,至少要是不重復(fù)的數(shù)字,也不要用自增的形式。 * 推薦閱讀銅板街的方案 訂單號末尾添加user%64


方案四:一致性Hash理念——平均分布方案
利用一致性hash理論,分庫選擇hash(key)的公式基準(zhǔn)為 value= key mod 64,分表公式value= key / 64 mod 64,key為訂單號或者userId等這類經(jīng)常查詢的主要字段。(后續(xù)會對這個公式有變化) 我們假定上述公式,則可以分64個庫,每個庫64個表,假設(shè)一個表1千萬行記錄。則最大64 * 64 * 1000萬數(shù)據(jù),我相信不會有這一天的到來,所以我們以這個作為最大值比較合理,甚至選擇32 * 32都可以。
因?yàn)榍捌谟貌簧线@么多個表,一開始建立這么多表每個表都insert數(shù)據(jù),會造成浪費(fèi)機(jī)器,所以在我們已知最大值的情況下,我們從小的數(shù)字開始使用,所以我們將對上述計算得出的value進(jìn)行分組。
分組公式:64 = 每組多少個count * group需要分組的個數(shù) 數(shù)據(jù)所在環(huán)的位置(也就是在哪個庫中):value = key mode 64 / count * count
以下舉例為16組,也就是16個庫,group=16 這個時候庫的公式為value = key mode 64 / 4 * 4,除以4后,會截取小數(shù)位得出一個整數(shù),然后 * 4倍,就是數(shù)據(jù)所在位置。
// 按4個為一組,分兩個表 count = 4: Integer dbValue = userId % 64 / count * count ;


hash(key)在0~3之間在第0號庫 hash(key)在4~7之間在第4號庫 hash(key)在8~11之間在第8號庫 ……
備注:其實(shí)一開始可以64個為一組就是一個庫,后續(xù)變化32個為一組就是兩個庫,從一個庫到兩個庫,再到4個庫,逐步遞進(jìn)。
從分1庫開始擴(kuò)容的迭代:


下圖中舉例分16組后,變?yōu)榉值?2組,需要每個庫都拿出一半的數(shù)據(jù)遷移到新數(shù)據(jù),擴(kuò)容直到分64個組。


可以看到當(dāng)需要進(jìn)行擴(kuò)容一倍時需要遷移一半的數(shù)據(jù)量,以2^n遞增,所以進(jìn)行影響范圍會比較大。優(yōu)點(diǎn):

  • 如果直接拆分32組,那么就比較一勞永逸
  • 如果數(shù)據(jù)量比較大,未做過分表可以用一勞永逸方式。
  • 分布均勻
  • 遷移數(shù)據(jù)時不需要像方案一那樣大部分的數(shù)據(jù)都需要進(jìn)行遷移并有重復(fù)遷移,只需要遷移一半

缺點(diǎn):

  • 可以擴(kuò)展,但是影響范圍大。
  • 遷移的數(shù)據(jù)量比較大,雖然不像方案一那樣大部分?jǐn)?shù)據(jù)遷移,當(dāng)前方案每個表或庫都需要一半數(shù)據(jù)的遷移。
  • 若要一勞永逸,則需要整體停機(jī)來遷移數(shù)據(jù)

方案五:一致性Hash理念——按迭代增加節(jié)點(diǎn)
(我認(rèn)為比較好的方案)
一致性hash方案結(jié)合比較范圍方案,也就是方案三和方案四的結(jié)合。
解析方案四問題所在
方案四是設(shè)定最大范圍64,按2^n指數(shù)形式從1增加庫或者表數(shù)量,這樣帶來的是每次拆分進(jìn)行遷移時會影響當(dāng)總體數(shù)據(jù)量的1/2的數(shù)據(jù),影響范圍比較大,所以要么就直接拆分到32組、64組一勞永逸,要么每次1/2遷移。
方案四對應(yīng)遷移方案:

  • 第一種是停機(jī)遷移數(shù)據(jù),成功后,再重新啟動服務(wù)器。影響范圍為所有用戶,時間長。
  • 第二種是把數(shù)據(jù)源切到從庫,讓用戶只讀,主庫遷移數(shù)據(jù),成功后再切到主庫,雖然用戶能適用,影響業(yè)務(wù)增量
  • 第三種是設(shè)定數(shù)據(jù)源根據(jù)規(guī)則讓一半的用戶能只讀,另一半的用戶能讀能寫,因?yàn)榉桨杆倪w移都是影響一般的數(shù)據(jù)的,所以最多能做到這個方式。
  • 方案五詳解
    現(xiàn)在我想方法時,保持一致性hash理念,1個1個節(jié)點(diǎn)來增加,而不是方案四的每次增加2^n-n個節(jié)點(diǎn)。但是代碼上就需要進(jìn)行對新節(jié)點(diǎn)內(nèi)的數(shù)據(jù)hash值判斷。
    我們基于已經(jīng)發(fā)生過1次迭代分了兩個庫的情況來做后續(xù)迭代演示,首先看看已經(jīng)拆分兩個庫的情況:
    數(shù)據(jù)落在第64號庫名為db64和第32號庫名為db32


    迭代二: 區(qū)別與方案四直接增加兩個節(jié)點(diǎn),我們只增加一個節(jié)點(diǎn),這樣遷移數(shù)據(jù)時由原本影響1/2的用戶,將會只影響1/4的用戶。

    在代碼中,我們先把分組從32個一組改為16個一組,再給代碼特殊處理 0~16的去到新的節(jié)點(diǎn) 16~32走回原來的32號節(jié)點(diǎn) 32~63走回原來64號節(jié)點(diǎn) 所以下面就要對節(jié)點(diǎn)特殊if else
    // 按32改為16個為一組,分兩變?yōu)?個庫 count = 16; Integer dbValue = userId % 64 / count * count ; if(dbValue<16){ // 上一個迭代這些數(shù)據(jù)落在db32中,現(xiàn)在走新增節(jié)點(diǎn)名為db16號的那個庫 dbValue = 16; return dbValue; } else { // 按原來規(guī)則走 return dbValue; }


    迭代三:

    這樣就可以分迭代完成方案四種的一輪的遷移
    遷移前可以先上線,增加一段開關(guān)代碼,請求接口特殊處理hash值小于16的訂單號或者用戶號,這樣就只會影響1/4的人
    // 在請求接口中增加邏輯 public void doSomeService(Integer userId){ if(遷移是否完成的開關(guān)){ // 如果未完成 Integer dbValue = userId % 64 / count * count ; if(dbValue<16){ //這部分用戶暫時不能走下面的邏輯 return ; } } return dbValue; } }
    // 在分片時按32個為一組,分兩個庫 count = 16; Integer dbValue = userId % 64 / count * count ; if(dbValue<16){ // 上一個迭代這些數(shù)據(jù)落在db32中,有一半需要走新增節(jié)點(diǎn)名為db16號的那個庫 if(遷移是否完成的開關(guān)){ // 如果已經(jīng)完成,就去db16的庫 dbValue = 16; } return dbValue; } else { // 按原來規(guī)則走 return dbValue; }
    如此類推,下一輪總共8個節(jié)點(diǎn)時,每次遷移只需要遷移1/8。其實(shí)也可以在第一個迭代時,不選擇dbValue小于16號的來做。直接8個分一組,只選擇dbValue<8的來做,這樣第一個迭代的影響范圍也會比較案例中小。上述案例用16只是比較好演示優(yōu)點(diǎn):

    • 易于擴(kuò)展
    • 數(shù)據(jù)逐漸增大過程中,慢慢增加節(jié)點(diǎn)
    • 影響用戶數(shù)量少
    • 按迭代進(jìn)行,減少風(fēng)險
    • 遷移時間短,如敏捷迭代思想

    缺點(diǎn):

    • 一段時間下不均勻

    方案六:一致性Hash理念——按范圍分庫(迭代遷移)
    如同上述方案五是方案四+方案一,可以達(dá)到逐步遷移數(shù)據(jù),還有一種方案。就是方案四+方案三,只是不用取模后分組。
    userId % 64 / count * count
    因?yàn)樯鲜龉?#xff0c;得出結(jié)果中,不一定每一片數(shù)據(jù)都是平均分布的。其實(shí)我們可以取模后,按范圍劃分分片,如下公式。
    第一片 0<userId % 64<15 第二片 16<userId % 64<31 第三片 32<userId % 64<47 第四片 48<userId % 64<63
    當(dāng)然范圍可以自定義,看取模后落入哪個值的數(shù)量比較多,就切某一片數(shù)據(jù)就好了,具體就不畫圖了,跟方案四類似。
    因?yàn)檫w移數(shù)據(jù)的原因,方案四中,如果數(shù)據(jù)量大,達(dá)到1000萬行記錄,每次遷移都需要遷移很多的數(shù)據(jù),所以很多公司會盡早分庫分表。
    但是在業(yè)務(wù)優(yōu)先情況下,一直迭代業(yè)務(wù),數(shù)據(jù)一進(jìn)達(dá)到很多的情況下16分支一也是很多的數(shù)據(jù)時,我們就可以用一致性Hash理念--按范圍分庫

    總結(jié)

    以上是生活随笔為你收集整理的long 雪花算法_海量数据分库分表方案(一)算法方案的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 日本少妇全体裸体洗澡 | 女人被灌满精子 | 538国产视频 | xxav在线 | 一区二区三区视频在线观看免费 | 日韩欧美一区二 | 久久无码人妻丰满熟妇区毛片 | 国产伦精品一区二区三区妓女下载 | 中文字幕自拍偷拍 | 加勒比精品在线 | 久久羞羞 | 成人精品一区日本无码网 | 超碰66 | 人妻在线一区 | 播放美国生活大片 | 波多野结衣视频在线观看 | 欧美一级xxx| 亚洲无毛视频 | 怡红院av亚洲一区二区三区h | 久久人妻精品白浆国产 | 精品久久久久久亚洲 | 国产视频a| 国产调教打屁股xxxx网站 | 欧美午夜剧场 | 欧美午夜精品一区二区蜜桃 | 成人午夜精品福利 | 手机福利在线 | 2020狠狠干| 丝袜制服中文字幕 | av一起看香蕉 | 色综合久久久久无码专区 | 欧美乱妇日本无乱码特黄大片 | 色婷婷av一区二区三区软件 | 国产一区在线不卡 | 91麻豆映画传媒 | 91亚洲国产成人精品性色 | 夜夜爽夜夜叫夜夜高潮漏水 | 精品无码久久久久久久久成人 | 91精品中文字幕 | 中文字幕av播放 | 韩国伦理片在线观看 | a黄视频 | 毛片国产精品 | 国产成人精品a视频 | 四虎亚洲精品 | 国产一区二区小视频 | 亚洲4区 | 在哪里可以看毛片 | 中国黄色一级视频 | 黄色污小说 | 欧美日韩国产区 | 色网av | 国产精品扒开腿做爽爽 | 妺妺窝人体色www婷婷 | 91丨九色 | 国产原创视频 | 一区二区三区在线免费观看视频 | 在线观看日韩欧美 | 青青草综合视频 | 国产主播99 | 中文字幕av亚洲精品一部二部 | 最新中文字幕视频 | 久久精品二区 | 亚洲free性xxxx护士白浆 | www.youjizz.com在线观看 | 亚洲精品自拍偷拍 | 波多野结衣先锋影音 | 午夜一区二区三区免费观看 | 久久高清精品 | 国产视频在线观看一区二区 | 精品免费视频一区二区 | 中文字幕一区二区三区四区不卡 | 五月天婷婷在线视频 | 欧美日韩一区二区三区在线 | 成年人看的黄色片 | 视频网站在线观看18 | 日韩a视频 | 欧美亚洲伦理 | 亚洲精品日韩欧美 | 国产欧美二区 | 欧美xxxxx自由摘花 | 日韩不卡一区二区三区 | 黄色的视频网站 | 久热这里只有 | av片国产| 亚洲精品色图 | 日本美女久久 | 99国产精品久久久久99打野战 | 大学生一级片 | 日韩久久久久 | www.夜夜爽 | 精品久久久久久一区二区里番 | 色哟哟网站入口 | 国产性在线 | 广州毛片 | 日韩女优在线播放 | 91超碰在线播放 | 观看av在线| 国产a视频免费观看 |