分區方法:
1、range
2、hash
3、路由規則規定哪個庫
可用性–> 複製一份數據(數據一致性)
雙主問題,同時寫庫,數據會不一致,同一ID會同時寫入
注:只允許一個寫入
可用性 一致性
讀寫走主?
id中午化
緩存與數據庫數據不一致
雙淘汰
無縫導庫
什麼情況會導庫?
1). 實踐: 分庫,擴容,庫遷移與拆分
2). 實踐: 數據庫遷移, mongo => mysql
3). 實踐: 數據庫增加字段 => 能 alter table麼? (不能在線增加)
解決方案:
- 停服務 => 業務能接受的話,強烈建議
- 無縫方案
實踐: 追日誌倒庫
目標
- 1個庫分成4個庫
- 多個庫部署到多臺物理機上
解決方案
如果回滾?
實踐: 雙寫倒庫
目標
- 數據由 mongo 遷移到mysql(增加字段同樣適用)
- 不停止對外服務
數據量大?
拆庫,四類典型場景
如何拆?拆庫依據是什麼?
(單key) 用戶庫如何拆分: user(uid, XXOO)
(1對多) 帖子庫如何拆分: tiezi(tid, uid, XXOO)
(多對多) 好友庫如何拆分: friend(uid, friend_uid, XXOO)
(多key) 訂單庫如何拆分: order(oid, buyer_id, seller_id, order_info, XXOO)
帖子庫,以帖子ID作爲拆分依據
好友表拆分,是做兩份數據,成功一次做個日誌,每天定時掃描,來保證數據一致性
訂單表,百分之八十根據oid查詢,百分之二十根據買家ID來查詢,百分之一根據賣家ID查詢
冗餘數據,即多做一份數據,進行處理
分庫後業務實戰即拆完庫之後會有什麼問題?
海量數據下Mysql怎麼玩
互聯網公司少量數據下,以下不會使用:
1、各種連接
2、子查詢
3、觸發器
4、用戶自定義函數
5、…
6、"事務"都用的很少(跨庫事務)
爲什麼?
以上業務是邏輯層的,就放在邏輯層來解決,數據庫只做數據的增刪查改
實戰-IN查詢怎麼做?
查詢需求:IN查詢:where uid IN(1,2,3,4,5,6)
解決方案:服務做MR
(1) 直接分發 (分配給所有的庫都查)
(2) 拼裝成不同SQL 分析ID,查出在哪個庫,就查哪個庫
不是主鍵的查詢,如頭像查詢 條件是:用戶帳號
解決方案:只定位一個庫,隨機時
跨庫分頁查詢怎麼做?
需求:order by xxx OFFSET xxx LIMIT xxx
(1) 按時間排序
(2) 每頁100條記錄
(3) 取第100頁的記錄
單機方案
order by time OFFSET 10000 LIMIT 100
分庫後如何實現?
分庫後難點:如何全局排序?
傳統做法:SQL改寫 + 自己排序取數據
(1) 每個庫 order by time OFFSET 0 LIMIT 10100
(2) 對所有庫 取的數據進行排序
(3) 返回第 10000 至 10100條的數據
方案一:
(1) 技術上,引入特殊ID,作爲查詢條件(或者帶入上一頁的排序條件)
(2) 業務上,儘量禁止跨頁查詢
單機情況
(1) 第一頁,直接查
(2) 得到第一頁的max(id)=123 (一般是最後一條記錄)
(3) 第二頁,帶上 id > 123 查詢:where id>123 LIMIT 100
這樣每次只要查100條,那分庫情況呢?
分庫情況 (假如3個庫)
(1) 將where id > xxx LIMIT 100 分發
(2) 將300條結果排序
(3) 返回前100條
方案二:
(1) 業務上:禁止查詢xx頁之後的數據
(2) 業務上:允許模糊返回 => 第100頁數據的精確性真這麼重要麼?
總結
(1) 分片
(2) 複製
(3) 分組
(4) 路由規則
分佈式,軟件架構帶來的問題
可用性 ==> 複製,一致性
讀寫筆 ==> 增加從庫,緩存,索引,