第?部分:?致性Hash算法
第?部分:集群時(shí)鐘同步問題
第三部分:分布式ID解決?案
數(shù)據(jù)表A(ID)疙咸,A的數(shù)據(jù)量很?的情況下,我們會(huì)進(jìn)?分表操作尝艘,A(ID)表拆分成了A1表 (ID)+A2表(ID)气忠,需要?種在分布式集群架構(gòu)中能夠產(chǎn)?全局唯?ID的?案
第四部分:分布式調(diào)度問題(定時(shí)任務(wù)的分布式)
第五部分:Session共享(?致性)問題
瀏覽器—>Nginx—>Tomcat1(Session中記錄?戶信息)
—>Tomcat2
—>Tomcat3
一、?致性Hash算法
Hash算法旬昭,?如說在安全加密領(lǐng)域MD5、SHA等加密算法菌湃,在數(shù)據(jù)存儲(chǔ)和查找??有Hash表等, 以上都應(yīng)?到了Hash算法稳懒。
為什么需要使?Hash?
Hash算法較多的應(yīng)?在數(shù)據(jù)存儲(chǔ)和查找領(lǐng)域,最經(jīng)典的就是Hash表慢味,它的查詢效率?常之?场梆,其中的哈希算法如果設(shè)計(jì)的?較ok的話,那么Hash表的數(shù)據(jù)查詢時(shí)間復(fù)雜度可以接近于O(1)纯路,示例需求:提供?組數(shù)據(jù) 1,5,7,6,3,4,8或油,對(duì)這組數(shù)據(jù)進(jìn)?存儲(chǔ),然后隨便給定?個(gè)數(shù)n驰唬,請(qǐng)你判斷n是否存在于剛才的數(shù)據(jù)集中顶岸?
list:List[1,5,7,6,3,4,8]
// 通過循環(huán)判斷來實(shí)現(xiàn)
for(int element: list) {
if(element == n) {
如果相等,說明n存在于數(shù)據(jù)集中
}
}
以上這種?法叫做順序查找法 :這種?式我們是通過循環(huán)來完成叫编,?較原始辖佣,效率也不?
?分查找:排序之后折半查找,相對(duì)于順序查找法會(huì)提??些效率搓逾,但是效率也并不是特別好我能否不循環(huán)卷谈!不?分!?是通過?次查詢就把數(shù)據(jù)n從數(shù)據(jù)集中查詢出來霞篡?世蔗??可以朗兵!
定義?個(gè)數(shù)組污淋,數(shù)組?度?于等于數(shù)據(jù)集?度,此處?度為9余掖,數(shù)據(jù)1就存儲(chǔ)在下標(biāo)為1的位置寸爆,3就存儲(chǔ)在下標(biāo)為3的元素位置,盐欺,赁豆,依次類推。這個(gè)時(shí)候找田,我想看下5存在與否歌憨,只需要判斷l(xiāng)ist.get(5) array[5] 是否為空,如果為空墩衙,代表5不存在于數(shù)據(jù)集务嫡,如果不為空代表5在數(shù)據(jù)集當(dāng)中甲抖,通過?次查找就達(dá)到了?的,時(shí)間復(fù)雜度為O(1)心铃。
這種?式叫做“直接尋址法”:直接把數(shù)據(jù)和數(shù)組的下標(biāo)綁定到?起准谚,查找的時(shí)候,直接array[n]就取出了數(shù)據(jù)
優(yōu)點(diǎn):速度快去扣,?次查找得到結(jié)果
缺點(diǎn):
1)浪費(fèi)空間柱衔,?如 1,5,7,6,3,4,8,12306 ,最?值12306 愉棱,按照上述?式需要定義?個(gè)?如?度為12307的數(shù)組唆铐,但是只存儲(chǔ)零星的?個(gè)數(shù)據(jù),其他位置空間都浪費(fèi)著
2)數(shù)據(jù)如:1,5,7,6,3,4,8,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2最?值12奔滑,?如開辟13個(gè)空間艾岂,存儲(chǔ)不了這么多內(nèi)容
現(xiàn)在,換?種設(shè)計(jì)朋其,如果數(shù)據(jù)是3王浴,5,7梅猿,12306氓辣,?共4個(gè)數(shù)據(jù),我們開辟任意個(gè)空間袱蚓,?如5個(gè)钞啸,那么具體數(shù)據(jù)存儲(chǔ)到哪個(gè)位置呢,我們可以對(duì)數(shù)據(jù)進(jìn)?求模(對(duì)空間位置數(shù)5)癞松,根據(jù)求模余數(shù)確定存儲(chǔ)位置的下標(biāo)爽撒,?如3%5=3,就可以把3這個(gè)數(shù)據(jù)放到下標(biāo)為3的位置上响蓉,12306%5=1,就把12306這個(gè)數(shù)據(jù)存儲(chǔ)到下標(biāo)為1的位置上
上?對(duì)數(shù)據(jù)求模 (數(shù)據(jù)%空間位置數(shù)) 他就是?個(gè)hash算法哨毁,只不過這是?種?較普通?簡單的hash算法枫甲,這種構(gòu)造Hash算法的?式叫做除留余數(shù)法
如果數(shù)據(jù)是1,6扼褪,7想幻,8,把這4個(gè)數(shù)據(jù)存儲(chǔ)到上?的數(shù)組中
在此基礎(chǔ)上采?開放尋址法(了解)
開放尋址法:1放進(jìn)去了话浇,6再來的時(shí)候脏毯,向前或者向后找空閑位置存放,不好的地?幔崖,如果數(shù)組?度定義好了?如10食店,?度不能擴(kuò)展渣淤,來了11個(gè)數(shù)據(jù),不管Hash沖突不沖突吉嫩,肯定存不下這么多數(shù)據(jù)
拉鏈法:數(shù)據(jù)?度定義好了价认,怎么存儲(chǔ)更多內(nèi)容呢,算好Hash值自娩,在數(shù)組元素存儲(chǔ)位置放了?個(gè)鏈表
如果Hash算法設(shè)計(jì)的?較好的話用踩,那么查詢效率會(huì)更接近于O(1),如果Hash算法設(shè)計(jì)的?較low忙迁,那么查詢效率就會(huì)很低了
所以脐彩,Hash表的查詢效率?不?取決于Hash算法,hash算法能夠讓數(shù)據(jù)平均分布姊扔,既能夠節(jié)省空間?能提?查詢效率惠奸。Hash算法的研究是很深的??學(xué)問,?較復(fù)雜旱眯,?久以來晨川,Hash表內(nèi)部的Hash算法也?直在更新,很多數(shù)學(xué)家也在研究删豺。
除留余數(shù)法 3%5
線性構(gòu)造Hash算法
直接尋址法也是?種構(gòu)造Hash的?式共虑,只不過更簡單,表達(dá)式:H(key)=key
?如H(key)=a*key + b(a,b是常量)
hashcode其實(shí)也是通過?個(gè)Hash算法得來的
1. Hash算法應(yīng)?場景
Hash算法在分布式集群架構(gòu)中的應(yīng)?場景:Hash算法在很多分布式集群產(chǎn)品中都有應(yīng)?呀页,?如分布式集群架構(gòu)Redis妈拌、Hadoop、ElasticSearch蓬蝶,Mysql分庫分表尘分,Nginx負(fù)載均衡等
主要的應(yīng)?場景歸納起來兩個(gè)
1).請(qǐng)求的負(fù)載均衡(?如nginx的ip_hash策略)
Nginx的IP_hash策略可以在客戶端ip不變的情況下,將其發(fā)出的請(qǐng)求始終路由到同?個(gè)?標(biāo)服務(wù)上丸氛,實(shí)現(xiàn)會(huì)話粘滯培愁,避免處理session共享問題。如果沒有IP_hash策略缓窜,那么如何實(shí)現(xiàn)會(huì)話粘滯定续?
可以維護(hù)?張映射表,存儲(chǔ)客戶端IP或者sessionid與具體?標(biāo)服務(wù)器的映射關(guān)系:<ip,tomcat1>
缺點(diǎn)
1)那么禾锤,在客戶端很多的情況下私股,映射表?常?,浪費(fèi)內(nèi)存空間
2)客戶端上下線恩掷,?標(biāo)服務(wù)器上下線倡鲸,都會(huì)導(dǎo)致重新維護(hù)映射表,映射表維護(hù)成本很?
如果使?哈希算法黄娘,事情就簡單很多峭状,我們可以對(duì)ip地址或者sessionid進(jìn)?計(jì)算哈希值克滴,哈希值與服務(wù)器數(shù)量進(jìn)?取模運(yùn)算,得到的值就是當(dāng)前請(qǐng)求應(yīng)該被路由到的服務(wù)器編號(hào)宁炫,如此偿曙,同?個(gè)客戶端ip發(fā)送過來的請(qǐng)求就可以路由到同?個(gè)?標(biāo)服務(wù)器,實(shí)現(xiàn)會(huì)話粘滯羔巢。
2).分布式存儲(chǔ)
以分布式內(nèi)存數(shù)據(jù)庫Redis為例,集群中有redis1望忆,redis2,redis3 三臺(tái)Redis服務(wù)器
那么,在進(jìn)?數(shù)據(jù)存儲(chǔ)時(shí),<key1,value1>數(shù)據(jù)存儲(chǔ)到哪個(gè)服務(wù)器當(dāng)中呢竿秆?針對(duì)key進(jìn)?hash處hash(key1)%3=index, 使?余數(shù)index鎖定存儲(chǔ)的具體服務(wù)器節(jié)點(diǎn)
2.普通Hash算法存在的問題
普通Hash算法存在?個(gè)問題启摄,以ip_hash為例,假定下載?戶ip固定沒有發(fā)?改變幽钢,現(xiàn)在tomcat3出現(xiàn)了問題歉备,down機(jī)了,服務(wù)器數(shù)量由3個(gè)變?yōu)榱?個(gè)匪燕,之前所有的求模都需要重新計(jì)算蕾羊。
如果在真實(shí)?產(chǎn)情況下,后臺(tái)服務(wù)器很多臺(tái)帽驯,客戶端也有很多龟再,那么影響是很?的,縮容和擴(kuò)容都會(huì)存在這樣的問題尼变,?量?戶的請(qǐng)求會(huì)被路由到其他的?標(biāo)服務(wù)器處理利凑,?戶在原來服務(wù)器中的會(huì)話都會(huì)丟失。
3.?致性Hash算法
?致性哈希算法思路如下:
?先有?條直線嫌术,直線開頭和結(jié)尾分別定為為1和2的32次?減1哀澈,這相當(dāng)于?個(gè)地址,對(duì)于這樣?條線度气,彎過來構(gòu)成?個(gè)圓環(huán)形成閉環(huán)割按,這樣的?個(gè)圓環(huán)稱為hash環(huán)。我們把服務(wù)器的ip或者主機(jī)名求hash值然后對(duì)應(yīng)到hash環(huán)上磷籍,那么針對(duì)客戶端?戶哲虾,也根據(jù)它的ip進(jìn)?hash求值,對(duì)應(yīng)到環(huán)上某個(gè)位置择示,然后如何確定?個(gè)客戶端路由到哪個(gè)服務(wù)器處理呢?按照順時(shí)針?向找最近的服務(wù)器節(jié)點(diǎn)
假如將服務(wù)器3下線晒旅,服務(wù)器3下線后栅盲,原來路由到3的客戶端重新路由到服務(wù)器4,對(duì)于其他客戶端沒有影響只是這??部分受影響(請(qǐng)求的遷移達(dá)到了最?废恋,這樣的算法對(duì)分布式集群來說?常合適的谈秫,避免了?量請(qǐng)求遷移 )
增加服務(wù)器5之后扒寄,原來路由到3的部分客戶端路由到新增服務(wù)器5上,對(duì)于其他客戶端沒有影響只是這??部分受影響(請(qǐng)求的遷移達(dá)到了最?拟烫,這樣的算法對(duì)分布式集群來說?常合適的该编,避免了?量請(qǐng)求遷移 )
1)如前所述,每?臺(tái)服務(wù)器負(fù)責(zé)?段硕淑,?致性哈希算法對(duì)于節(jié)點(diǎn)的增減都只需重定位環(huán)空間中的??部分?jǐn)?shù)據(jù)课竣,具有較好的容錯(cuò)性和可擴(kuò)展性。但是置媳,?致性哈希算法在服務(wù)節(jié)點(diǎn)太少時(shí)于樟,容易因?yàn)楣?jié)點(diǎn)分部不均勻?造成數(shù)據(jù)傾斜問題。例如系統(tǒng)中只有兩臺(tái)服務(wù)器拇囊,其環(huán)分布如下迂曲,節(jié)點(diǎn)2只能負(fù)責(zé)?常?的?段,?量的客戶端請(qǐng)求落在了節(jié)點(diǎn)1上寥袭,這就是數(shù)據(jù)(請(qǐng)求)傾斜問題
2)為了解決這種數(shù)據(jù)傾斜問題路捧,?致性哈希算法引?了虛擬節(jié)點(diǎn)機(jī)制,即對(duì)每?個(gè)服務(wù)節(jié)點(diǎn)計(jì)算多個(gè)哈希传黄,每個(gè)計(jì)算結(jié)果位置都放置?個(gè)此服務(wù)節(jié)點(diǎn)杰扫,稱為虛擬節(jié)點(diǎn)。
具體做法可以在服務(wù)器ip或主機(jī)名的后?增加編號(hào)來實(shí)現(xiàn)尝江。?如涉波,可以為每臺(tái)服務(wù)器計(jì)算三個(gè)虛擬節(jié)點(diǎn),于是可以分別計(jì)算 “節(jié)點(diǎn)1的ip#1”炭序、“節(jié)點(diǎn)1的ip#2”啤覆、“節(jié)點(diǎn)1的ip#3”、“節(jié)點(diǎn)2的ip#1”惭聂、“節(jié)點(diǎn)2的ip#2”窗声、“節(jié)點(diǎn)2的ip#3”的哈希值,于是形成六個(gè)虛擬節(jié)點(diǎn)辜纲,當(dāng)客戶端被路由到虛擬節(jié)點(diǎn)的時(shí)候其實(shí)是被路由到該虛擬節(jié)點(diǎn)所對(duì)應(yīng)的真實(shí)節(jié)點(diǎn)
4.?寫實(shí)現(xiàn)?致性Hash算法
普通Hash算法實(shí)現(xiàn)
?致性Hash算法實(shí)現(xiàn)(不含虛擬節(jié)點(diǎn))
?致性Hash算法實(shí)現(xiàn)(含虛擬節(jié)點(diǎn))
5. Nginx 配置?致性Hash負(fù)載均衡策略
ngx_http_upstream_consistent_hash 模塊是?個(gè)負(fù)載均衡器笨觅,使??個(gè)內(nèi)部?致性hash算法來選擇合適的后端節(jié)點(diǎn)。
該模塊可以根據(jù)配置參數(shù)采取不同的?式將請(qǐng)求均勻映射到后端機(jī)器耕腾,1.consistent_hash $remote_addr:可以根據(jù)客戶端ip映射2.consistent_hash $request_uri:根據(jù)客戶端請(qǐng)求的uri映射3.consistent_hash $args:根據(jù)客戶端攜帶的參數(shù)進(jìn)?映
ngx_http_upstream_consistent_hash 模塊是?個(gè)第三?模塊见剩,需要我們下載安裝后使?
1)github下載nginx?致性hash負(fù)載均衡模塊 https://github.com/replay/ngx_http_consistent_hash
2)將下載的壓縮包上傳到nginx服務(wù)器,并解壓
3)我們已經(jīng)編譯安裝過nginx扫俺,此時(shí)進(jìn)?當(dāng)時(shí)nginx的源碼?錄苍苞,執(zhí)?如下命令
./confifigure —add-module=/root/ngx_http_consistent_hash-master
make
make install
4)Nginx就可以使?啦,在nginx.conf?件中配置
二、集群時(shí)鐘同步問題
第 1 節(jié) 時(shí)鐘不同步導(dǎo)致的問題
時(shí)鐘此處指服務(wù)器時(shí)間羹呵,如果集群中各個(gè)服務(wù)器時(shí)鐘不?致勢必導(dǎo)致?系列問題骂际,試想 “集群是各個(gè)服務(wù)器?起團(tuán)隊(duì)化作戰(zhàn),?家?作都不在?個(gè)點(diǎn)上冈欢,豈不亂了套歉铝!”
舉?個(gè)例?,電商?站業(yè)務(wù)中,新增?條訂單,那么勢必會(huì)在訂單表中增加了?條記錄器躏,該條記錄中應(yīng)該會(huì)有“下單時(shí)間”這樣的字段种冬,往往我們會(huì)在程序中獲取當(dāng)前系統(tǒng)時(shí)間插?到數(shù)據(jù)庫或者直接從數(shù)據(jù)庫服務(wù)器獲取時(shí)間。那我們的訂單?系統(tǒng)是集群化部署,或者我們的數(shù)據(jù)庫也是分庫分表的集群化部署,然?他們的系統(tǒng)時(shí)鐘缺不?致,?如有?臺(tái)服務(wù)器的時(shí)間是昨天呀非,那么這個(gè)時(shí)候下單時(shí)間就成了昨天,那我們的數(shù)據(jù)將會(huì)混亂镜盯!如下
2.集群時(shí)鐘同步配置
集群時(shí)鐘同步思路:
1.分布式集群中各個(gè)服務(wù)器節(jié)點(diǎn)都可以連接互聯(lián)?
操作?式:
#使? ntpdate ?絡(luò)時(shí)間同步命令
ntpdate -u ntp.api.bz #從?個(gè)時(shí)間服務(wù)器同步時(shí)間
如果服務(wù)器沒安裝ntp就用yum安裝一下yum install ntp
windows有計(jì)劃任務(wù);Linux也有定時(shí)任務(wù)岸裙,crond,可以使?linux的定時(shí)任務(wù)速缆,每隔10分鐘執(zhí)??次ntpdate命令
2.分布式集群中某?個(gè)服務(wù)器節(jié)點(diǎn)可以訪問互聯(lián)?或者所有節(jié)點(diǎn)都不能夠訪問互聯(lián)?
思路:????
操作?式:1)選取集群中的?個(gè)服務(wù)器節(jié)點(diǎn)A(172.17.0.17)作為時(shí)間服務(wù)器(整個(gè)集群時(shí)間從這臺(tái)服務(wù)器同步降允,如果這臺(tái)服務(wù)器能夠訪問互聯(lián)?,可以讓這臺(tái)服務(wù)器和?絡(luò)時(shí)間保持同步艺糜,如果不能就?動(dòng)設(shè)置?個(gè)時(shí)間)
?先設(shè)置好A的時(shí)間
把A配置為時(shí)間服務(wù)器(修改/etc/ntp.conf?件)
1剧董、如果有 restrict default ignore,注釋掉它
2破停、添加如下??內(nèi)容
restrict 172.17.0.0 mask 255.255.255.0 nomodify notrap # 放開局
域?同步功能,172.17.0.0是你的局域??段
server 127.127.1.0 # local clock
fudge 127.127.1.0 stratum 10
3翅楼、重啟?效并配置ntpd服務(wù)開機(jī)?啟動(dòng)
service ntpd restart
chkconfig ntpd on
集群中其他節(jié)點(diǎn)就可以從A服務(wù)器同步時(shí)間了
ntpdate 172.17.0.17
三、分布式ID解決?案
1.為什么需要分布式ID(分布式集群環(huán)境下的全局唯?ID)
2.分布式ID生成方案之UUID
UUID 是指Universally Unique Identififier真慢,翻譯為中?是通?唯?識(shí)別碼毅臊,產(chǎn)?重復(fù) UUID 并造成錯(cuò)誤的情況?常低,是故?可不必考慮此問題黑界。Java中得到?個(gè)UUID管嬉,可以使?java.util包提供的?法
3.分布式ID生成方案之獨(dú)?數(shù)據(jù)庫的?增ID
?如A表分表為A1表和A2表,那么肯定不能讓A1表和A2表的ID?增朗鸠,那么ID怎么獲取呢蚯撩?我們可以單獨(dú)的創(chuàng)建?個(gè)Mysql數(shù)據(jù)庫,在這個(gè)數(shù)據(jù)庫中創(chuàng)建?張表烛占,這張表的ID設(shè)置為?增求厕,其他地?需要全局唯?ID的時(shí)候,就模擬向這個(gè)Mysql數(shù)據(jù)庫的這張表中模擬插??條記錄,此時(shí)ID會(huì)?增呀癣,然后我們可以通過Mysql的select last_insert_id() 獲取到剛剛這張表中?增?成的ID.
?如,我們創(chuàng)建了?個(gè)數(shù)據(jù)庫實(shí)例global_id_generator弦赖,在其中創(chuàng)建了?個(gè)數(shù)據(jù)表项栏,表結(jié)構(gòu)如下:
-- ----------------------------
-- Table structure for DISTRIBUTE_ID
-- ----------------------------
DROP TABLE IF EXISTS `DISTRIBUTE_ID`;
CREATE TABLE `DISTRIBUTE_ID` (
`id` bigint(32) NOT NULL AUTO_INCREMENT COMMENT '主鍵',
`createtime` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
當(dāng)分布式集群環(huán)境中哪個(gè)應(yīng)?需要獲取?個(gè)全局唯?的分布式ID的時(shí)候,就可以使?代碼連接這個(gè)數(shù)據(jù)庫實(shí)例蹬竖,執(zhí)?如下sql語句即可沼沈。
insert into DISTRIBUTE_ID(createtime) values(NOW());
select LAST_INSERT_ID();
注意:
1)這?的createtime字段?實(shí)際意義币厕,是為了隨便插??條數(shù)據(jù)以?于能夠?增id列另。
2)使?獨(dú)?的Mysql實(shí)例?成分布式id,雖然可?旦装,但是性能和可靠性都不夠好页衙,因?yàn)槟阈枰a連接到數(shù)據(jù)庫才能獲取到id,性能?法保障阴绢,另外mysql數(shù)據(jù)庫實(shí)例掛掉了店乐,那么就?法獲取分布式id了。
3)有?些開發(fā)者?針對(duì)上述的情況將?于?成分布式id的mysql數(shù)據(jù)庫設(shè)計(jì)成了?個(gè)集群架構(gòu)呻袭,那么其實(shí)這種?式現(xiàn)在基本不?眨八,因?yàn)檫^于麻煩了。
3.分布式ID生成方案之SnowFlake 雪花算法(可以?左电,推薦)
雪花算法是Twitter推出的?個(gè)?于?成分布式ID的策略廉侧。
雪花算法是?個(gè)算法,基于這個(gè)算法可以?成ID篓足,?成的ID是?個(gè)long型段誊,那么在Java中?個(gè)long型是8個(gè)字節(jié),算下來是64bit纷纫,如下是使?雪花算法?成的?個(gè)ID的?進(jìn)制形式示意:
另外枕扫,?切互聯(lián)?公司也基于上述的?案封裝了?些分布式ID?成器,?如滴滴的tinyid(基于數(shù)據(jù)庫實(shí)現(xiàn))辱魁、百度的uidgenerator(基于SnowFlake)和美團(tuán)的leaf(基于數(shù)據(jù)庫和SnowFlake)等烟瞧。
代碼實(shí)現(xiàn):
4.分布式ID生成方案之借助Redis的Incr命令獲取全局唯?ID(推薦)
Redis Incr 命令將 key 中儲(chǔ)存的數(shù)字值增?。如果 key 不存在染簇,那么 key 的值會(huì)先被初始化為 0参滴,然后再執(zhí)? INCR 操作。
<key,value>
<id,>
.incr(id) 1 2 3 4
在src?錄下執(zhí)? ./redis-server ../redis.conf 啟動(dòng)redis服務(wù)
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>
Java代碼(此處我們就是連接單節(jié)點(diǎn)锻弓,也不使?連接池)
四砾赔、分布式調(diào)度問題
調(diào)度—>定時(shí)任務(wù),分布式調(diào)度—>在分布式集群環(huán)境下定時(shí)任務(wù)這件事
Elastic-job(當(dāng)當(dāng)?開源的分布式調(diào)度框架)
1.定時(shí)任務(wù)的場景? ??
2.什么是分布式調(diào)度
什么是分布式任務(wù)調(diào)度?有兩層含義
1)運(yùn)?在分布式集群環(huán)境下的調(diào)度任務(wù)(同?個(gè)定時(shí)任務(wù)程序部署多份暴心,只應(yīng)該有?個(gè)定時(shí)任務(wù)在執(zhí)?)
2)分布式調(diào)度—>定時(shí)任務(wù)的分布式—>定時(shí)任務(wù)的拆分(即為把?個(gè)?的作業(yè)任務(wù)拆分為多個(gè)?的作業(yè)任務(wù)妓盲,同時(shí)執(zhí)?)
3.定時(shí)任務(wù)與消息隊(duì)列的區(qū)別
4.定時(shí)任務(wù)的實(shí)現(xiàn)?式
定時(shí)任務(wù)的實(shí)現(xiàn)?式有多種。早期沒有定時(shí)任務(wù)框架的時(shí)候专普,我們會(huì)使?JDK中的Timer機(jī)制和多線程機(jī)制(Runnable+線程休眠)來實(shí)現(xiàn)定時(shí)或者間隔?段時(shí)間執(zhí)?某?段程序悯衬;后來有了定時(shí)任務(wù)框架,?如?名鼎鼎的Quartz任務(wù)調(diào)度框架檀夹,使?時(shí)間表達(dá)式(包括:秒筋粗、分、時(shí)炸渡、?娜亿、周、年)配置某?個(gè)任務(wù)什么時(shí)間去執(zhí)?:
任務(wù)調(diào)度框架Quartz回顧示意
引?jar
<!--任務(wù)調(diào)度框架quartz-->
<!-- https://mvnrepository.com/artifact/org.quartz-scheduler/quartz --
>
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.3.2</version>
</dependency
以上蚌堵,是回顧?下任務(wù)調(diào)度框架Quartz的?致?法买决,那么在分布式架構(gòu)環(huán)境中使?Quartz已經(jīng)不能更好的滿?我們需求,我們可以使?專業(yè)的分布式調(diào)度框架辰斋,這?我們推薦使?Elastic-job策州。
5.分布式調(diào)度框架Elastic-Job
①Elastic-Job介紹:Elastic-Job是當(dāng)當(dāng)?開源的?個(gè)分布式調(diào)度解決?案,基于Quartz?次開發(fā)的宫仗,由兩個(gè)相互獨(dú)?的?項(xiàng)?Elastic-Job-Lite和Elastic-Job-Cloud組成够挂。我們要學(xué)習(xí)的是 Elastic-Job-Lite,它定位為輕量級(jí)?中?化解決?案藕夫,使?Jar包的形式提供分布式任務(wù)的協(xié)調(diào)服務(wù)孽糖,?Elastic-Job-Cloud?項(xiàng)?需要結(jié)合Mesos以及Docker在云環(huán)境下使?。
Elastic-Job的github地址:https://github.com/elasticjob
②Elastic-Job-Lite應(yīng)?
jar包(API) + 安裝zk軟件
Elastic-Job依賴于Zookeeper進(jìn)?分布式協(xié)調(diào)毅贮,所以需要安裝Zookeeper軟件(3.4.6版本以上)办悟,關(guān)于Zookeeper,此處我們不做詳解滩褥,在階段三會(huì)有深度學(xué)習(xí)病蛉,我們此處需要明?Zookeeper的本質(zhì)功能:存儲(chǔ)+通知。
安裝Zookeeper(此處單例配置)
1)我們使?3.4.10版本瑰煎,在linux平臺(tái)解壓下載的zookeeper-3.4.10.tar.gz
2)進(jìn)?conf?錄铺然,cp zoo_sample.cfg zoo.cfg
3) 進(jìn)?bin?錄酒甸,啟動(dòng)zk服務(wù)
啟動(dòng) ./zkServer.sh start
停? ./zkServer.sh stop
查看狀態(tài) ./zkServer.sh status
引?Jar包
<!-- https://mvnrepository.com/artifact/com.dangdang/elastic-job-lite-core
-->
<dependency>
<groupId>com.dangdang</groupId>
<artifactId>elastic-job-lite-core</artifactId>
<version>2.1.5</version>
</dependency>
③魄健、Elastic-Job-Lite輕量級(jí)去中?化的特點(diǎn)
④、任務(wù)分?
?個(gè)?的?常耗時(shí)的作業(yè)Job插勤,?如:?次要處理?億的數(shù)據(jù)沽瘦,那這?億的數(shù)據(jù)存儲(chǔ)在數(shù)據(jù)庫中革骨,如果??個(gè)作業(yè)節(jié)點(diǎn)處理?億數(shù)據(jù)要很久,在互聯(lián)?領(lǐng)域是不太能接受的析恋,互聯(lián)?領(lǐng)域更希望機(jī)器的增加去橫向擴(kuò)展處理能?良哲。所以,ElasticJob可以把作業(yè)分為多個(gè)的task(每?個(gè)task就是?個(gè)任務(wù)分?)绿满,每?個(gè)task交給具體的?個(gè)機(jī)器實(shí)例去處理(?個(gè)機(jī)器實(shí)例是可以處理多個(gè)task的)臂外,但是具體每個(gè)task執(zhí)?什么邏輯由我們??來指定。
Strategy策略定義這些分?項(xiàng)怎么去分配到各個(gè)機(jī)器上去喇颁,默認(rèn)是平均去分,可以定制嚎货,?如某?個(gè)機(jī)器負(fù)載 ?較?或者預(yù)配置?較?橘霎,那么就可以寫策略。分?和作業(yè)本身是通過?個(gè)注冊(cè)中?協(xié)調(diào)的殖属,因?yàn)樵诜植际江h(huán)境下姐叁,狀態(tài)數(shù)據(jù)肯定集中到?點(diǎn),才可以在分布式中溝通洗显。
5.彈性擴(kuò)容
新增加?個(gè)運(yùn)?實(shí)例app3外潜,它會(huì)?動(dòng)注冊(cè)到注冊(cè)中?,注冊(cè)中?發(fā)現(xiàn)新的服務(wù)上線挠唆,注冊(cè)中?會(huì)通知ElasticJob 進(jìn)?重新分?处窥,那么總得分?項(xiàng)有多少,那么就可以搞多少個(gè)實(shí)例機(jī)器玄组,?如完全可以分1000?
最多就可以有多少app實(shí)例滔驾,,俄讹,哆致,機(jī)器能成的主,完全可以分1000?
那么就可以搞1000臺(tái)機(jī)器?起執(zhí)?作業(yè)
注意:1)分?項(xiàng)也是?個(gè)JOB配置患膛,修改配置摊阀,重新分?,在下?次定時(shí)運(yùn)?之前會(huì)重新調(diào)?分?算法踪蹬,那么這個(gè)分?算法的結(jié)果就是:哪臺(tái)機(jī)器運(yùn)?哪?個(gè)??胞此,這個(gè)結(jié)果存儲(chǔ)到zk中的,主節(jié)點(diǎn)會(huì)把分?給分好放到注冊(cè)中?去延曙,然后執(zhí)?節(jié)點(diǎn)從注冊(cè)中?獲取信息(執(zhí)?節(jié)點(diǎn)在定時(shí)任務(wù)開啟的時(shí)候獲取相應(yīng)的分?)豌鹤。
2)如果所有的節(jié)點(diǎn)掛掉值剩下?個(gè)節(jié)點(diǎn),所有分?都會(huì)指向剩下的?個(gè)節(jié)點(diǎn)枝缔,這也是ElasticJob的?可?布疙。
五蚊惯、Session共享問題
Session共享及Session保持或者叫做Session?致性
第 1 節(jié) Session問題原因分析
出現(xiàn)這個(gè)問題的原因,從根本上來說是因?yàn)镠ttp協(xié)議是?狀態(tài)的協(xié)議灵临〗匦停客戶端和服務(wù)端在某次會(huì)話中產(chǎn)?的數(shù)據(jù)不會(huì)被保留下來,所以第?次請(qǐng)求服務(wù)端?法認(rèn)識(shí)到你曾經(jīng)來過儒溉, Http為什么要設(shè)計(jì)為?狀態(tài)協(xié)議宦焦?早期都是靜態(tài)???所謂有?狀態(tài),后來有動(dòng)態(tài)的內(nèi)容更豐富顿涣,就需要有狀態(tài)波闹,出現(xiàn)了兩種?于保持Http狀態(tài)的技術(shù),那就是Cookie和Session涛碑。?出現(xiàn)上述不停讓登錄的問題精堕,分析如下圖:
第 2 節(jié) 解決Session?致性的?案
優(yōu)點(diǎn):
能適應(yīng)各種負(fù)載均衡策略
服務(wù)器重啟或者宕機(jī)不會(huì)造成Session丟失
擴(kuò)展能?強(qiáng)
適合?集群數(shù)量使?
缺點(diǎn):
對(duì)應(yīng)?有?侵,引?了和Redis的交互代碼