分层架构设计(转)
1. 互聯(lián)網(wǎng)分層架構(gòu)的本質(zhì):
? ? 1).互聯(lián)網(wǎng)分層架構(gòu)的本質(zhì),是數(shù)據(jù)的移動(dòng)
? ? 2).互聯(lián)網(wǎng)分層架構(gòu)中,數(shù)據(jù)的傳輸格式(協(xié)議)與數(shù)據(jù)在各層次的形態(tài)很重要
? ? 3).互聯(lián)網(wǎng)分層架構(gòu)演進(jìn)的核心原則與方法:封裝與復(fù)用
? ? ? ? a.讓上游更高效的獲取與處理數(shù)據(jù),復(fù)用
? ? ? ? b.讓下游能屏蔽數(shù)據(jù)的獲取細(xì)節(jié),封裝
2. 互聯(lián)網(wǎng)分層架構(gòu)是一個(gè)很有意思的問(wèn)題,服務(wù)化的引入,并不是越早越好:
? ? 1).請(qǐng)求處理時(shí)間可能會(huì)增加
? ? 2).運(yùn)維可能會(huì)更加復(fù)雜
? ? 3).定位問(wèn)題可能會(huì)更加麻煩
3. 當(dāng)業(yè)務(wù)越來(lái)越復(fù)雜,垂直拆分的系統(tǒng)越來(lái)越多,基礎(chǔ)數(shù)據(jù)服務(wù)越來(lái)越多,底層數(shù)據(jù)獲取復(fù)雜性成為通用痛點(diǎn)的時(shí)候,就應(yīng)該抽象出通用業(yè)務(wù)服務(wù),簡(jiǎn)化數(shù)據(jù)獲取過(guò)程,提高數(shù)據(jù)獲取效率,向上游屏蔽底層的復(fù)雜性。
? ? 這樣的好處是:
? ? 復(fù)雜的從基礎(chǔ)服務(wù)獲取數(shù)據(jù)代碼,只有在通用業(yè)務(wù)service處寫(xiě)了一次,沒(méi)有代碼拷貝
? ? 底層基礎(chǔ)數(shù)據(jù)service接口發(fā)生變化,只有通用業(yè)務(wù)service一處需要升級(jí)修改
? ? 如果有bug,不管是底層基礎(chǔ)數(shù)據(jù)service的bug,還是通用業(yè)務(wù)service的bug,都只有一處需要升級(jí)修改
? ? 業(yè)務(wù)web-server獲取數(shù)據(jù)更便捷,獲取所有數(shù)據(jù),只需一個(gè)RPC接口調(diào)用
4. 為啥要前后端分離
? ? 1).一點(diǎn)點(diǎn)展現(xiàn)的改動(dòng),需要Java工程師們重新編譯,打包,上線,重啟tomcat,效率極低
? ? 2).原先Java工程師負(fù)責(zé)所有MVC的研發(fā)工作,現(xiàn)在分為Java和FE兩塊,需要等前端和后端都完成研發(fā),才能一起調(diào)試整體效果,不僅增加了溝通成本,任何一塊出問(wèn)題,都可能導(dǎo)致項(xiàng)目延期
? ? ? ? 當(dāng)業(yè)務(wù)越來(lái)越復(fù)雜,端上的產(chǎn)品越來(lái)越多,展現(xiàn)層的變化越來(lái)越快越來(lái)越多,站點(diǎn)層存在大量代碼拷貝,數(shù)據(jù)獲取復(fù)雜性成為通用痛點(diǎn)的時(shí)候,就應(yīng)該進(jìn)行前后端分離分層抽象,簡(jiǎn)化數(shù)據(jù)獲取過(guò)程,提高數(shù)據(jù)獲取效率,向上游屏蔽底層的復(fù)雜性。
? ? ? ? 這樣的好處是:
? ? ? ? 復(fù)雜的業(yè)務(wù)邏輯與數(shù)據(jù)生成,只有在站點(diǎn)數(shù)據(jù)層處寫(xiě)了一次,沒(méi)有代碼拷貝
? ? ? ? 底層service接口發(fā)生變化,只有站點(diǎn)數(shù)據(jù)層一處需要升級(jí)修改
? ? ? ? 底層service如果有bug,只有站點(diǎn)數(shù)據(jù)層一處需要升級(jí)修改
? ? ? ? 站點(diǎn)展現(xiàn)層可以根據(jù)產(chǎn)品的不同形態(tài),傳入不同的參數(shù),調(diào)用不同的站點(diǎn)數(shù)據(jù)層接口
? ? ? ? 除此之外:
? ? ? ? 產(chǎn)品追求絢麗的效果,并對(duì)設(shè)備兼容性要求高,不再困擾Java工程師,由更專業(yè)的FE對(duì)接
? ? ? ? 一點(diǎn)點(diǎn)展現(xiàn)的改動(dòng),不再需要Java工程師們重新編譯,打包,上線,重啟tomcat
? ? ? ?約定好json接口后,Java和FE分開(kāi)開(kāi)發(fā),FE可以用mock的接口自測(cè),不再等待一起聯(lián)調(diào)
5. 分庫(kù)需求
? ? 高并發(fā)大流量的互聯(lián)網(wǎng)架構(gòu),一般通過(guò)服務(wù)層來(lái)訪問(wèn)數(shù)據(jù)庫(kù),隨著數(shù)據(jù)量的增大,數(shù)據(jù)庫(kù)需要進(jìn)行水平切分,分庫(kù)后將數(shù)據(jù)分布到不同的數(shù)據(jù)庫(kù)實(shí)例(甚至物理機(jī)器)上,以達(dá)到降低數(shù)據(jù)量,增加實(shí)例數(shù)的擴(kuò)容目的。
? ? 一旦涉及分庫(kù),逃不開(kāi)“分庫(kù)依據(jù)”patition key的概念,使用哪一個(gè)字段來(lái)水平切分?jǐn)?shù)據(jù)庫(kù)呢:大部分的業(yè)務(wù)場(chǎng)景,會(huì)使用業(yè)務(wù)主鍵id。
? ? 確定了分庫(kù)依據(jù)patition key后,接下來(lái)要確定的是分庫(kù)算法:大部分的業(yè)務(wù)場(chǎng)景,會(huì)使用業(yè)務(wù)主鍵id取模的算法來(lái)分庫(kù),這樣即能夠保證每個(gè)庫(kù)的數(shù)據(jù)分布是均勻的,又能夠保證每個(gè)庫(kù)的請(qǐng)求分布是均勻的,
? ? ?實(shí)在是簡(jiǎn)單實(shí)現(xiàn)負(fù)載均衡的好方法,此法在互聯(lián)網(wǎng)架構(gòu)中應(yīng)頗多。
6. 究竟為什么要引入數(shù)據(jù)庫(kù)中間件
? ? ?1). partition key上的單行查詢
? ? ? ? ? 典型場(chǎng)景:通過(guò)uid查詢user
? ? ? ? ? 場(chǎng)景特點(diǎn):通過(guò)patition key查詢;每次只返回一行記錄
? ? ? ? ? 解決方案:base-service層通過(guò)patition key來(lái)進(jìn)行庫(kù)路由
? ? ? 2).非patition key上的單行查詢
? ? ? ? ? 典型場(chǎng)景:通過(guò)login_name查詢user
? ? ? ? ? 場(chǎng)景特點(diǎn):通過(guò)非patition key查詢;每次只返回一行記錄
? ? ? ? ? 解決方案1:base-service層訪問(wèn)所有庫(kù)
? ? ? ? ? 解決方案2:base-service先查mapping庫(kù),再通過(guò)patition key路由
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? a.新建mapping庫(kù),記錄login_name到uid的映射關(guān)系
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? b.當(dāng)有非 patition key的查詢時(shí),先通過(guò)login_name查詢uid
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? c.再通過(guò)patition key進(jìn)行路由,最終返回一條記錄
? ? ? ? ? 解決方案3:基因法?
? ? ? 3).patition key上的批量查詢:
? ? ? ? ? ?典型場(chǎng)景:用戶列表uid上的IN查詢
? ? ? ? ? ?場(chǎng)景特點(diǎn):通過(guò)patition key查詢;每次返回多行記錄
? ? ? ? ? ?解決方案1:base-service層訪問(wèn)所有庫(kù),結(jié)果集到base-service合并
? ? ? ? ? ?解決方案2:base-service分析路由規(guī)則,按需訪問(wèn)
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?a.base-service根據(jù)路由規(guī)則分析,判斷出有些數(shù)據(jù)落在庫(kù)1,有些數(shù)據(jù)落在庫(kù)2
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?b.base-service按需訪問(wèn)相關(guān)庫(kù),而不是訪問(wèn)全庫(kù)
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?c.base-service合并結(jié)果集,返回列表數(shù)據(jù)
? ? ? 4).非patition key上的跨庫(kù)分頁(yè)需求
? ? ? ? ? 關(guān)于分庫(kù)后,跨庫(kù)分頁(yè)的查詢需求,詳見(jiàn)《業(yè)界難題,跨庫(kù)分頁(yè)的四種方案》。
? ? ? 5).本文寫(xiě)到這里,上述一、二、三、四、五其實(shí)都不是重點(diǎn),base-service層通過(guò)各種各樣的奇技淫巧,能夠解決db水平切分后的數(shù)據(jù)訪問(wèn)問(wèn)題,只不過(guò):
? ? ? ? ? ?base-service層的復(fù)雜度提高了; 數(shù)據(jù)的獲取效率降低了
? ? ? ? ? ?底層的復(fù)雜性會(huì)擴(kuò)散到各個(gè)base-service,所有的base-service都要關(guān)注:
? ? ? ? ? ?patition key路由;非patition key查詢,先mapping,再路由;先全庫(kù),再合并;先分析,再按需路由;跨庫(kù)分頁(yè)處理…
? ? ? ? ? ?這個(gè)架構(gòu)圖是不是看上去很別扭?如何讓數(shù)據(jù)的獲取更加高效快捷呢?
? ? ? ? ? ?數(shù)據(jù)庫(kù)中間件的引入,勢(shì)在必行。
? ? ? ? ? ?這是“基于服務(wù)端”的數(shù)據(jù)庫(kù)中間件架構(gòu)圖:
? ? ? ? ? ? base-service層,就像訪問(wèn)db一樣,訪問(wèn)db-proxy,高效獲取數(shù)據(jù)
? ? ? ? ? ? 所有底層的復(fù)雜性,都屏蔽在db-proxy這一層
? ? ? ? ? ? 這是“基于客戶端”的數(shù)據(jù)庫(kù)中間件架構(gòu)圖:
? ? ? ? ? ? base-service層,通過(guò)db-proxy.jar,高效獲取數(shù)據(jù)
? ? ? ? ? ? 所有底層的復(fù)雜性,都屏蔽在db-proxy.jar這一層
? ? ? ? ? ? 結(jié)論:
? ? ? ? ? ?當(dāng)數(shù)據(jù)庫(kù)水平切分,base-service層獲取db數(shù)據(jù)過(guò)于復(fù)雜,成為通用痛點(diǎn)的時(shí)候,就應(yīng)該抽象出數(shù)據(jù)庫(kù)中間件,簡(jiǎn)化數(shù)據(jù)獲取過(guò)程,提高數(shù)據(jù)獲取效率,向上游屏蔽底層的復(fù)雜性。
?
轉(zhuǎn)載于:https://www.cnblogs.com/Jtianlin/p/8902925.html
總結(jié)