面試的時候,極可能會被問到海量數據的處理問題:面試
1.訂單數據愈來愈多(億級),查詢愈來愈慢,如何處理?spring
2.分庫分表會帶來哪些反作用?可能的解決方式有哪些?數據庫
目前常用的關係型數據庫如MySQL、SQL Server等,都是以「行」爲單位進行存儲,爲了快速檢索,也都採用了B樹或其餘索引技術。後端
從原理上來說,表中的數據越多,索引樹的範圍越大,磁盤讀取也越多,性能也就越低。安全
從實踐角度來看,通常以百萬到千萬做爲一個表的存儲量級,超出該範圍以後,性能就會降低,須要採用其餘技術手段解決。性能優化
首先想到的就是可否將讀和寫分離,主數據庫用於寫入,讀數據庫(多個)用於對外提供查詢,經過數據複製的方式將主數據庫的數據同步到讀庫。該架構提高了數據庫的讀寫能力,但對於主數據庫的寫入能力依然無法擴展。微信
其次,依據數據庫分區的思路,能夠將不一樣的數據分散到不一樣的庫中,每一個庫存儲的數據都不一樣,這樣就能夠將單一庫的壓力分散到多個庫中,從而提高整個數據庫的服務能力,這就是所說的分庫分表技術。架構
若按照「字段(列)」分區,每一個庫/表存儲不一樣的的字段,即schema不一樣,就是「垂直拆分」;框架
若按「數據記錄(行)」分區,每一個庫/表的schema一致,但存儲的數據不一樣,就是「水平拆分」。異步
垂直拆分
水平拆分
這樣作的好處就是解決了數據存儲容量的問題,但也帶來了諸多弊端。這裏以「水平拆分」爲例來分析。
1.如何能作到數據的平均拆分,防止某一庫壓力過大?
系統開發者要結合業務特色來肯定分庫分表鍵,好比以userID爲分庫分表鍵,採用hash取模的方式將數據散列到不一樣的庫中。
但並非全部場景都適合用userID做爲分庫分表鍵的,若存在「大賣家」,則該userID可能有不少條記錄,若簡單的按照上述方法進行拆分,則可能打爆其中一個數據庫。
通常來講,會將一段時間之前的數據歸檔(好比某個userID三個月以前的數據),存放到相似HBase這種非關係型數據庫中,以此來解決上述問題。
2.分庫分表以後就要求每一個查詢的where子句中必須攜帶分庫分表鍵,但並不是每一個查詢都能攜帶分庫分表鍵的。
好比訂單庫按照訂單號hash取模以後存儲,此時分庫分表鍵爲訂單號,那麼想查詢某位買家全部的訂單,查詢時就沒有了分庫分表鍵,就會出現「全表掃描」的狀況。
通常在實踐中解決這種問題的方法是創建「異構索引表」,即採用異步機制將原表內的每次一建立或更新,都換一個維度保存一份完整的數據表或索引表,拿空間換時間。
在上面說到,訂單庫按照訂單號hash取模以後存儲,同時也按照userID維度進行hash取模,再存儲一份數據,那麼想要獲取某一userID的所有訂單時,就將userID做爲分庫分表鍵傳進去便可,避免了全表掃描。
上面這些是在海量數據處理過程當中出現問題的解決思路,工程師的硬實力不只體如今解決問題的思路上,更在於細節問題的打磨,所以還需在細節上進行更深的學習和探討。若是你對這些感興趣,那麼如下免費福利就很適合你:
福利1
《網易雲課堂Java進階免費直播課》
適聽人羣:Java初、中級開發工程師
▼
1. 4月8日 20:00
深刻淺出線程安全 ~ 從原子性到手寫實現JAVA鎖
2. 4月9日 20:00
Shiro企業級安全框架應用&原理源碼解讀
3. 4月10日 20:00
美團技術團隊-分佈式事務實踐
4. 4月11日 20:00
搜索引擎核心理論思想
5. 4月12日 20:00
網易嚴選後端性能優化實錄
6. 4月13日 20:00
spring事務管理原理源碼解讀
7. 4月14日 20:00
網易組件式封裝 - 基於Spring Boot實現本身的Starter
(全部直播可回看)
福利2
Java開發進階資料包
包含「Java開發參考書籍」「Java開發學習圖譜」「大數據容器數據庫架構技術文檔」等
掃描下方二維碼
便可免費參與Java直播進階課程
並領取Java開發進階資料包
全方位擴充你的知識體系
微信號:weizhuanye51
免費課程,名額有限,先到先得~~