乾貨!大數據量下,58同城mysql實踐

  WOT(World Of Tech)2015,互聯網運維與開發者大會將在北京舉行,會上58同城將分享《大數據量下,58同城mysql實戰》的主題,乾貨分享搶先看。

  1)基本概念

  2)常見問題及解決思路

  3)拆庫實戰

  4)拆庫後業務實戰

  5)總結

  一、基本概念

  大數據量下,搞mysql,以下概念需要先達成一致

  1)單庫,不多說了,就是一個庫

  2)分片(sharding),水平拆分,用於解決擴展性問題,按天拆分表

  3)複製(replication)與分組(group),用於解決可用性問題

  4)分片+分組,這是大數據量下,架構的實際情況

  二、大數據量下,mysql常見問題及解決思路

  1)常見問題

  如何保證可用性?

  各色各異的讀寫比,怎麼辦?

  如何做無縫倒庫,加字段,擴容?

  數據量大,怎麼解決?

  2)解決思路

  2.1)可用性解決思路:複製

  讀庫可用性

  從庫複製多個,例如:1主2從

  從庫掛了讀主庫,例如:1主1從

  寫庫可用性

  雙主模式

  “雙主”當“主從”用

  2.2)讀寫比解決思路-針對特性做設計

  讀多些少場景:提升讀性能,3種常見方案:

  a)新建索引提高讀性能,什麼小技巧?

  b)讀寫分離,增加從庫擴展讀性能

  c)增加緩存來擴展讀性能

  a)b)c)方案存在什麼問題?

  如何解決這些問題?

  讀寫相近場景:不要使用緩存,考慮水平切分

  寫多讀少場景:不要使用緩存,考慮水平切分

  2.3)無縫倒庫[擴容,增加字段,數據遷移]

  追日誌方案

  a)記錄寫日誌

  b)倒庫

  c)倒庫完畢

  d)追日誌

  e)追日誌完畢+數據校驗

  f)切庫

  雙寫方案

  a)服務雙寫

  b)倒庫

  c)倒庫完畢+數據校驗

  d)切庫

  2.4)數據量大解決思路:拆庫

  三、數據庫拆庫實戰

  四類場景覆蓋99%拆庫業務

  a)“單key”場景,用戶庫如何拆分: user(uid, XXOO)

  b)“1對多”場景,帖子庫如何拆分: tiezi(tid, uid, XXOO)

  c)“多對多”場景,好友庫如何拆分: friend(uid, friend_uid, XXOO)

  d)“多key”場景,訂單庫如何拆分:order(oid, buyer_id, seller_id, XXOO)

  1)用戶庫如何拆分

  用戶庫,10億數據量

  user(uid, uname, passwd, age, sex, create_time);

  業務需求如下

  a)1%登錄請求 => where uname=XXX and passwd=XXX

  b)99%查詢請求 => where uid=XXX

  結論:“單key”場景使用“單key”拆庫

  2)帖子庫如何拆分

  帖子庫,15億數據量

  tiezi(tid, uid, title, content, time);

  業務需求如下

  a)查詢帖子詳情(90%請求)

  SELECT * FROM tiezi WHERE tid=$tid

  b)查詢用戶所有發帖(10%請求)

  SELECT * FROM tiezi WHERE uid=$uid

  結論:“1對多”場景使用“1”分庫,例如帖子庫1個uid對應多個tid,則使用uid分庫,tid生成時加入分庫標記

  3)好友庫如何拆分

  好友庫,1億數據量

  friend(uid, friend_uid, nick, memo, XXOO);

  業務需求如下

  a)查詢我的好友(50%請求) => 用於界面展示

  SELECT friend_uid FROM friend WHERE uid=$my_uid

  b)查詢加我爲好友的用戶(50%請求) => 用戶反向通知

  SELECT uid FROM friend WHERE friend_uid=$my_uid

  結論:“多對多”場景,使用數據冗餘方案,多份數據使用多種分庫手段

  4)訂單庫如何拆分

  訂單庫,10億數據量

  order(oid, buyer_id, seller_id, order_info, XXOO);

  業務需求如下

  a)查詢訂單信息(80%請求)

  SELECT * FROM order WHERE oid=$oid

  b)查詢我買的東東(19%請求)

  SELECT * FROM order WHERE buyer_id=$my_uid

  c)查詢我賣出的東東(1%請求)

  SELECT * FROM order WHERE seller_id=$my_uid

  結論:“多key”場景一般有兩種方案

  a)方案一,使用2和3綜合的方案

  b)方案二,1%的請求採用多庫查詢

  四、分庫後業務實戰

  分庫後出現的問題:單庫時mysql的SQL功能不再支持了

  1)海量數據下,mysql的SQL怎麼玩

  不會這麼玩

  a)各種聯合查詢

  b)子查詢

  c)觸發器

  d)用戶自定義函數

  e)“事務”都用的很少

  原因:對數據庫性能影響極大

  2)分庫後,IN查詢怎麼玩

  用戶庫如何進行uid的IN查詢

  user(uid, uname, passwd, age, sex, photo, create_time, ...);

  Partition key:uid

  查詢需求:IN查詢:WHERE uid IN(1,2,3,4,5,6)

  解決方案:服務做MR

  方案一:直接分發

  方案二:拼裝成不同SQL,定位不同的庫

  3)分庫後,非Partition key的查詢怎麼玩

  方案一:業務方不關心數據來自哪個庫,可以只定位一個庫

 

 

 

  例如:有頭像的用戶

  方案二:結果集只有一條數據,業務層做分發,只有一條記錄返回就返回

   例如:用戶登錄時,使用userName和passwd的查詢

  4)分庫後,誇庫分頁怎麼玩?

  問題的提出與抽象:ORDER BY xxx OFFSET xxx LIMIT xxx

  a)按時間排序

  b)每頁100條記錄

  c)取第100頁的記錄

  單機方案

  ORDER BY time OFFSET 10000 LIMIT 100

  分庫後的難題:如何確認全局偏移量

  分庫後傳統解決方案,查詢改寫+內存排序

  a)ORDER BY time OFFSET 0 LIMIT 10000+100

  b)對20200條記錄進行排序

  c)返回第10000至10100條記錄

  優化方案一:增加輔助id,以減少查詢量

  a)技術上,引入特殊id,作爲查詢條件(或者帶入上一頁的排序條件)

  b)業務上,儘量禁止跨頁查詢

  單庫情況

   a)第一頁,直接查

  b)得到第一頁的max(id)=123(一般是最後一條記錄)

  c)第二頁,帶上id>123查詢:WHERE id>123 LIMIT 100

  多庫情況

 

  a)將WHERE id>xxx LIMIT 100分發

  b)將300條結果排序

  c)返回前100條

  優點:避免了全局排序,只對小量記錄進行排序

  優化方案二:模糊查詢

  a)業務上:禁止查詢XX頁之後的數據

  b)業務上:允許模糊返回 => 第100頁數據的精確性真這麼重要麼?

  優化方案三:終極方案,查詢改寫與兩段查詢

  方案一和方案二在業務上都有所折衷,前者不允許跨頁查詢,後者數據精度有損失,解決誇庫分頁問題的終極方案是,將order by + offset + limit進行查詢改寫,分兩段查詢。

  五、總結

  《概念》

   單庫、分片、複製、分組

  《常見問題及解決思路》

   1)可用性,解決思路是冗餘(複製)

   2)讀寫比

   2.1)讀多些少:用從庫,緩存,索引來提高讀性能

   2.2)業務層控制強制讀主來解決從庫不一致問題

   2.3)雙淘汰來解決緩存不一致問題

   2.4)讀寫相近,寫多讀少:不要使用緩存,該怎麼整怎麼整

   3)無縫導

    3.1)寫日誌追數據

   3.2)雙寫

   4)數據量大,解決思路是分片(拆庫)

 

   《四大類拆庫思路》

   1)用戶庫,“單key”場景使用“單key”拆庫

   2)帖子庫,“1對多”場景使用“1”分庫,例如帖子庫1個uid對應多個tid,則使用uid分庫,tid生成時加入分庫標記

   3)好友庫,“多對多”場景,使用數據冗餘方案,多份數據使用多種分庫手段

   4)訂單庫,“多key”場景一般有兩種方案

    4.1)方案一,使用2和3綜合的方案

   4.2)方案二,1%的請求採用多庫查詢

   《拆庫後業務實戰》

   1)不這麼玩:聯合查詢、子查詢、觸發器、用戶自定義函數、誇庫事務

   2)IN查詢怎麼玩

   2.1)分發MR

   2.2)拼裝成不同SQL語句

   3)非partition key查詢怎麼玩

    3.1)定位一個庫

   3.2)分發MR

   4)誇庫分頁怎麼玩

   4.1)修改sql語句,服務內排序

   4.2)引入特殊id,減少返回數量

   4.3)業務優化,禁止跨頁查詢,允許模糊查詢

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章