美团java研发岗二面:java静态方法存储在哪个区
思維導(dǎo)圖
前言
在很多時候,我們都可以在各種框架應(yīng)用中看到ZooKeeper的身影,比如Kafka中間件,Dubbo框架,Hadoop等等。為什么到處都看到ZooKeeper?
一、
前些年,互聯(lián)網(wǎng)行業(yè)里對架構(gòu)師這個崗位的標(biāo)準(zhǔn)還不是很清晰。所以,很多架構(gòu)師的工作往往就是一些技術(shù)被公司認(rèn)可的資深工程師負(fù)責(zé)。
彼時,正巧我也是這類人員之一,故也得到了一個從零開始架設(shè)一套廣告投放平臺的機(jī)會。
我很喜歡鉆研技術(shù),對這種機(jī)會自然很看重。
那時候,架構(gòu)并無如今這么復(fù)雜,一開始就是前面搞幾個 Web 應(yīng)用,后面共享個數(shù)據(jù)庫。大致像這樣:
當(dāng)然,上面的架構(gòu)其實做了很多簡化,省略了很多細(xì)節(jié)。比如,為了提高性能做的緩存,為了提高吞吐做的負(fù)載均衡統(tǒng)統(tǒng)沒有在上圖給出。因為這些和本章話題無關(guān),暫時咱們就忽略這些東西,只看核心部分。
這套架構(gòu)初期運(yùn)行還是沒什么問題的,再加上一些緩存機(jī)制,初期一些性能問題都通過調(diào)整緩存提升緩存的碰撞率應(yīng)付了過去。
可是,隨著廣告投放量的增大,廣告的訪問量也在暴漲。這些暴漲的訪問量引發(fā)了性能問題。當(dāng)時,由于前端有負(fù)載均衡,應(yīng)用層倒是沒出現(xiàn)什么問題……
問題出在后面的數(shù)據(jù)庫上
二、
這套架構(gòu)數(shù)據(jù)庫用的是 MySQL,本身也只有一臺主庫在對外服務(wù),另外一臺備庫采用了 MySQL 自己的全同步機(jī)制做實時備份。
當(dāng)廣告訪問量暴漲的時候,因為業(yè)務(wù)需要,很多數(shù)據(jù)需要在數(shù)據(jù)庫中做實時插入,這就導(dǎo)致了大量的磁盤 IO 產(chǎn)生。這些大量的磁盤 IO 造成了數(shù)據(jù)庫本身性能的急劇下降。
悲催的是,整套廣告平臺的所有功能又都是共享一個數(shù)據(jù)庫的,所以隨著數(shù)據(jù)庫本身的性能下降,平臺的所有功能都受到了影響。
由于問題主要在于大量廣告流量的寫入,所以,靠讀寫分離的方案去緩解問題這條路就走不通了。
只好先升級硬件了。在經(jīng)過了幾輪硬件升級和數(shù)據(jù)庫調(diào)優(yōu)之后,單數(shù)據(jù)庫再也無法支撐不斷上漲的流量了。沒辦法,要考慮搞數(shù)據(jù)庫切分了。
那時候,我個人是很恐懼?jǐn)?shù)據(jù)庫切分的。
原因不僅僅在于需要在應(yīng)用層多寫很多復(fù)雜的邏輯,其根本原因是當(dāng)時流行的 2PC(兩階段提交)方案,這個方案本身能保證在數(shù)據(jù)庫切分的情況下,原來的事務(wù)依然保留著自身的 ACID 性質(zhì)。即:
但也正因為這 4 個特性,2PC 才讓我顧慮重重。
顧慮1:首先,數(shù)據(jù)庫拆分了,那么根據(jù)事務(wù)的原子性,事務(wù)自身必須是一體的,那么事務(wù)涉及到的不同的數(shù)據(jù)庫就必須都訪問一遍,而這本身就意味著很高的通信成本。
再加上,為了保持一致性,事務(wù)失敗后,還必須恢復(fù)各個數(shù)據(jù)庫原來的狀態(tài),這就必須讓已經(jīng)成功執(zhí)行過本地事務(wù)的數(shù)據(jù)庫全部回滾。
而稍微懂點數(shù)據(jù)庫的人都知道,這個成本有多大。
更可怕的是,本身事務(wù)的隔離性還可能加上鎖。一旦一個熱點數(shù)據(jù)區(qū)域被大量訪問,最差情況就可能出現(xiàn)串行訪問。而這對此套平臺,包括我自己都將是個悲劇。
顧慮2:數(shù)據(jù)庫的拆分會造成整個平臺的可用性下降。
假設(shè)我現(xiàn)在有一臺數(shù)據(jù)庫,它的可用性是 99.9%。如果因為分庫,數(shù)據(jù)庫從一臺變成兩臺,那么平臺的可用性就會變成:
平臺的可用性 = 99.9% * 99.9% = 99.8%
從 99.9% 變成了 99.8%,這意味著可用性下降了 0.1%,每個月的不可用時間會增加 43 分鐘之多。
一邊是硬件升級已經(jīng)到頂,單機(jī)數(shù)據(jù)庫也優(yōu)化到了極限,再不做數(shù)據(jù)庫拆分,平臺可能隨時癱瘓。一邊是沒有好的策略,可能拆分?jǐn)?shù)據(jù)庫后,每個月都有宕機(jī)的風(fēng)險,同時性能也可能會出現(xiàn)劇烈的下降。
我被逼入了死角。
三、
這種痛苦的糾結(jié)折磨了我大概一周,直到我看到了 CAP 定理。當(dāng) CAP 定理說分布式系統(tǒng)在分區(qū)容錯的時候,只能一致性和可用性二選一時,我高興的蹦了起來。
原來,可用性和一致性是不能兼得的。
為何我會那么高興?因為逼我入死角的可不僅是技術(shù)上的問題了,我還承受著來自于業(yè)務(wù)方和領(lǐng)導(dǎo)的壓力。每天一上班,我就需要面對業(yè)務(wù)各方的抱怨,以及領(lǐng)導(dǎo)一輪又一輪的催促。
有了 CAP 定理的支持,我知道我最終是要面臨選擇的。既然在這個世界上做分布式架構(gòu)的所有人都要面臨選擇,那我又怎么可能獨善其身呢?
在對單機(jī)數(shù)據(jù)庫引發(fā)的各種問題做了一次徹底的各種歸因以后,我下了決心:
一定要搞定拆分?jǐn)?shù)據(jù)庫并給出良好方案。
只是,2PC 這個攔路虎,它成為了我的大敵。通過 CAP 定理,我非常肯定,只要我選了 2PC 方案,可用性就一定會出現(xiàn)嚴(yán)重的問題,這個方案也肯定不可能拿出來丟人現(xiàn)眼的。
我唯一的方向就是去犧牲一些一致性,往可用性方向走。可是,怎么走呢?
也許是老天眷顧,也許是大家都承受著和我一樣夜不能寐的壓力,很快,BASE 理論在國內(nèi)傳開了。
BASE 理論讓我知道了,這個世上能排到前幾名的技術(shù)大公司也一樣會出問題,也一樣會對這些問題進(jìn)行妥協(xié)。而且 BASE 理論的思想讓我的思路一下子就打開了,苦思而不得的問題開始有了頭緒。
我要開始著手制定技術(shù)方案了。
四、
BASE 思想中的 BA(Basically Available)基本可用,是鼓勵通過預(yù)先的架構(gòu)設(shè)計或者前期規(guī)劃,盡量在分布式的系統(tǒng)中,把以前可能影響全平臺的嚴(yán)重問題,變成只會影響平臺中的一部分?jǐn)?shù)據(jù)或者功能的非嚴(yán)重問題。
有了這個思想之后,我就對廣告平臺中的很多重要的數(shù)據(jù)表進(jìn)行了拆分,并將這些表的數(shù)據(jù)分散到了不同的數(shù)據(jù)庫中。
比如,有個廣告流量詳情表,每當(dāng)用戶點擊廣告或者廣告展示出來的時候,為了保證不丟失,這些數(shù)據(jù)都是實時插入到這個表里的。
我對這張表是怎么切分的呢?
當(dāng)有人點擊廣告了,他的點擊記錄會被傳到我的應(yīng)用層,然后我會在應(yīng)用層根據(jù)廣告 ID 做哈希,再根據(jù)哈希結(jié)果的不同,分別存到不同的數(shù)據(jù)庫中去。
假如這三個數(shù)據(jù)庫中的一個出現(xiàn)了問題,則只會有三分之一的數(shù)據(jù)受到影響。這就實現(xiàn)了 BASE 理論中的 BA——基本可用了。基本可用其實也真的就是表達(dá)的這么一回事:
通過一些架構(gòu)設(shè)計,即使平臺中某部分組件出現(xiàn)了問題,也不會導(dǎo)致整個平臺不可用。
好了,既然采取了數(shù)據(jù)庫拆分的策略,又根據(jù) BASE 理論中的 BA 思想拆分了一些重要的表,那么,到了現(xiàn)在,可能也無從后悔,只能繼續(xù)沿著 BASE 這條路,一條路走到黑了。
五、
接下來,需要著手解決性能問題了。2PC 方案……算了……它瘋狂的一致性性格會要了我的狗命的。
那么極端點,我們不搞事務(wù)可不可以呢?
還用前面說的那套廣告平臺舉例。
當(dāng)時,從業(yè)務(wù)上,要求廣告的訪問數(shù)據(jù)都要保證及時入庫不能丟,因為丟了就可能造成計費(fèi)的損失,而這些損失全是錢。所以,每當(dāng)用戶點擊廣告或者廣告展示出來的時候,為了保證不丟失,這些數(shù)據(jù)都是實時入庫的。
又根據(jù)業(yè)務(wù)需求,當(dāng)廣告流量入庫時,還需要往廣告預(yù)算表和媒體流水表里同時根據(jù)這筆流量進(jìn)行記賬,以供后續(xù)財務(wù)計算。
如果完全不考慮事務(wù),則拆分庫后,操作可能會是這個樣子。
這三個操作可能會并行發(fā)往不同的數(shù)據(jù)庫執(zhí)行。由于三個操作之間沒有事務(wù)的約束,所以,一個操作出問題了,另外的操作并不會受到影響。
而這卻也引發(fā)了另外一個問題,數(shù)據(jù)狀態(tài)不一致。
如果在上面的業(yè)務(wù)中,插入廣告流量表的操作失敗了,但其余兩張表插入成功了,業(yè)務(wù)就會面臨一個很尷尬的情況:他們算出的財務(wù)報表沒有依據(jù)。財務(wù)流水中找不到產(chǎn)生了這筆流水的依據(jù)。
而這種不一致的狀態(tài)由于已經(jīng)被持久化到了數(shù)據(jù)庫中,就會導(dǎo)致這種不一致的狀態(tài)永久存在了數(shù)據(jù)庫中。這業(yè)務(wù)能接受嗎?但凡有點職業(yè)精神的程序員能接受嗎?
給大家分享下我的復(fù)習(xí)的面試資料
這些面試全部出自大廠面試真題和面試合集當(dāng)中,小編已經(jīng)為大家整理完畢(PDF版)
資料獲取方式:戳這里前往我的騰訊文檔免費(fèi)下載
- 第一部分:Java基礎(chǔ)-中級-高級
- 第二部分:開源框架(SSM:Spring+SpringMVC+MyBatis)
- 第三部分:性能調(diào)優(yōu)(JVM+MySQL+Tomcat)
- 第四部分:分布式(限流:ZK+Nginx;緩存:Redis+MongoDB+Memcached;通訊:MQ+kafka)
- 第五部分:微服務(wù)(SpringBoot+SpringCloud+Dubbo)
- 第六部分:其他:并發(fā)編程+設(shè)計模式+數(shù)據(jù)結(jié)構(gòu)與算法+網(wǎng)絡(luò)
進(jìn)階學(xué)習(xí)筆記pdf
都已整理好,需免費(fèi)下載點擊這里即可
- Java架構(gòu)進(jìn)階之架構(gòu)筑基篇(Java基礎(chǔ)+并發(fā)編程+JVM+MySQL+Tomcat+網(wǎng)絡(luò)+數(shù)據(jù)結(jié)構(gòu)與算法)
- Java架構(gòu)進(jìn)階之開源框架篇(設(shè)計模式+Spring+SpringMVC+MyBatis)
- Java架構(gòu)進(jìn)階之分布式架構(gòu)篇 (限流(ZK/Nginx)+緩存(Redis/MongoDB/Memcached)+通訊(MQ/kafka))
- Java架構(gòu)進(jìn)階之微服務(wù)架構(gòu)篇(RPC+SpringBoot+SpringCloud+Dubbo+K8s)
647883)]
[外鏈圖片轉(zhuǎn)存中…(img-YgbLqlyf-1622454647884)]
- Java架構(gòu)進(jìn)階之微服務(wù)架構(gòu)篇(RPC+SpringBoot+SpringCloud+Dubbo+K8s)
[外鏈圖片轉(zhuǎn)存中…(img-zhclYh1U-1622454647885)]
[外鏈圖片轉(zhuǎn)存中…(img-P3ZBq2h0-1622454647886)]
總結(jié)
以上是生活随笔為你收集整理的美团java研发岗二面:java静态方法存储在哪个区的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 成都欢乐谷要带身份证么
- 下一篇: 阿里P8亲自讲解!javawhile循环