今年以來,網(wǎng)絡(luò)上時(shí)不時(shí)的就會傳出“某某公司又裁員了,技術(shù)團(tuán)隊(duì)也被裁了”,其中不乏我們熟悉的一些大廠。 在這之后,市場上的“技術(shù)勞動力”又多了起來,而且這些“勞動力”中有相當(dāng)一部分是有大型工程經(jīng)驗(yàn)的,比如海量數(shù)據(jù)處理、高并發(fā)處理等經(jīng)驗(yàn)。 對于求職者來說,競爭更加激烈了,在這個(gè)時(shí)刻,硬實(shí)力更顯得尤為重要。 面試的時(shí)候,很可能會被問到海量數(shù)據(jù)的處理問題: 訂單數(shù)據(jù)越來越多(億級),查詢越來越慢,如何處理? 分庫分表會帶來哪些副作用?可能的解決方式有哪些? 目前經(jīng)常使用的關(guān)系型數(shù)據(jù)庫如MySQL、SQL Server等,都是以“行”為單位進(jìn)行存儲,為了快速檢索,也都采用了B樹或其他索引技術(shù)。 從原理上來講,表中的數(shù)據(jù)越多,索引樹的范圍越大,磁盤讀取也越多,性能也就越低。 從實(shí)踐角度來看,一般以百萬到千萬作為一個(gè)表的存儲量級,超出該范圍之后,性能就會下降,需要采用其他技術(shù)手段解決。 首先想到的就是能否將讀和寫分離,主數(shù)據(jù)庫用于寫入,讀數(shù)據(jù)庫(多個(gè))用于對外提供查詢,通過數(shù)據(jù)復(fù)制的方式將主數(shù)據(jù)庫的數(shù)據(jù)同步到讀庫。該架構(gòu)提升了數(shù)據(jù)庫的讀寫能力,但對于主數(shù)據(jù)庫的寫入能力依然沒法擴(kuò)展。 其次,依據(jù)數(shù)據(jù)庫分區(qū)的思路,可以將不同的數(shù)據(jù)分散到不同的庫中,每個(gè)庫存儲的數(shù)據(jù)都不同,這樣就可以將單一庫的壓力分散到多個(gè)庫中,從而提升整個(gè)數(shù)據(jù)庫的服務(wù)能力,這就是所說的分庫分表技術(shù)。 若按照“字段(列)”分區(qū),每個(gè)庫/表存儲不同的的字段,即schema不同,就是“垂直拆分”; 若按“數(shù)據(jù)記錄(行)”分區(qū),每個(gè)庫/表的schema一致,但存儲的數(shù)據(jù)不同,就是“水平拆分”。 垂直拆分 水平拆分 這樣做的好處就是解決了數(shù)據(jù)存儲容量的問題,但也帶來了諸多弊端。這里以“水平拆分”為例來分析。 1.如何能做到數(shù)據(jù)的平均拆分,防止某一庫壓力過大? 系統(tǒng)開發(fā)者要結(jié)合業(yè)務(wù)特點(diǎn)來確定分庫分表鍵,比如以userID為分庫分表鍵,采用hash取模的方式將數(shù)據(jù)散列到不同的庫中。 但并不是所有場景都適合用userID作為分庫分表鍵的,若存在“大賣家”,則該userID可能有很多條記錄,若簡單的按照上述方法進(jìn)行拆分,則可能打爆其中一個(gè)數(shù)據(jù)庫。 一般來說,會將一段時(shí)間以前的數(shù)據(jù)歸檔(比如某個(gè)userID三個(gè)月之前的數(shù)據(jù)),存放到類似HBase這種非關(guān)系型數(shù)據(jù)庫中,以此來解決上述問題。 2.分庫分表之后就要求每個(gè)查詢的where子句中必須攜帶分庫分表鍵,但并非每個(gè)查詢都能攜帶分庫分表鍵的。 比如訂單庫按照訂單號hash取模之后存儲,此時(shí)分庫分表鍵為訂單號,那么想查詢某位買家所有的訂單,查詢時(shí)就沒有了分庫分表鍵,就會出現(xiàn)“全表掃描”的情況。 一般在實(shí)踐中解決這種問題的方法是建立“異構(gòu)索引表”,即采用異步機(jī)制將原表內(nèi)的每次一創(chuàng)建或更新,都換一個(gè)維度保存一份完整的數(shù)據(jù)表或索引表,拿空間換時(shí)間。 在上面說到,訂單庫按照訂單號hash取模之后存儲,同時(shí)也按照userID維度進(jìn)行hash取模,再存儲一份數(shù)據(jù),那么想要獲取某一userID的全部訂單時(shí),就將userID作為分庫分表鍵傳進(jìn)去即可,避免了全表掃描。 上面這些是在海量數(shù)據(jù)處理過程中出現(xiàn)問題的解決思路,工程師的硬實(shí)力不僅體現(xiàn)在解決問題的思路上,更在于細(xì)節(jié)問題的打磨,因此還需在細(xì)節(jié)上進(jìn)行更深的學(xué)習(xí)和探討。如果你對這些感興趣,那么以下福利就很適合你: 福利1 《網(wǎng)易云課堂Java進(jìn)階免費(fèi)直播課》 適聽人群:Java初、中級開發(fā)工程師 ▼ 1. 4月8日 20:00 深入淺出線程安全 ~ 從原子性到手寫實(shí)現(xiàn)JAVA鎖 2. 4月9日 20:00 Shiro企業(yè)級安全框架應(yīng)用&原理源碼解讀 3. 4月10日 20:00 美團(tuán)技術(shù)團(tuán)隊(duì)-分布式事務(wù)實(shí)踐 4. 4月11日 20:00 搜索引擎核心理論思想 5. 4月12日 20:00 網(wǎng)易嚴(yán)選后端性能優(yōu)化實(shí)錄 6. 4月13日 20:00 spring事務(wù)管理原理源碼解讀 7. 4月14日 20:00 網(wǎng)易組件式封裝 - 基于Spring Boot實(shí)現(xiàn)自己的Starter 福利2 Java開發(fā)進(jìn)階資料包 包含「Java開發(fā)參考書籍」「Java開發(fā)學(xué)習(xí)圖譜」「大數(shù)據(jù)容器數(shù)據(jù)庫架構(gòu)技術(shù)文檔」等 |
|