Xpisme's Blog

数据库水平拆分-分享记录

有幸参加沈剑的有关数据库水平拆分的技术分享,
把分享的一些点记录了下来。

业务决定架构
磁盘很容易成为架构的瓶颈,往磁盘上写数据有两类
一类:日志,只是新增数据,没有大的性能影响
另一类:数据库写磁盘

一:基本概念

  • 分片 sharding
    业务场景:数据量大
    单库分为两个或多个库,例如user表有1亿条记录,分成两个5千万的表
  • 复制 replication
    业务场景:数据备份,读多写少
    主从复制,一主两从等等
  • 分组 group
    一主两从或一主多从 为一组
  • 路由规则 route rule
    常见的路由方法
    • 范围:range
      0~1千万 1库
      1~2千万 2库
      2~3千万 3库

      规则简单,拿id取模就可以找到对应的库中查询
      易扩容,新增数据,按照范围,直接可扩容
      数据访问不平均,1库访问较多,2库访问明显较少
    • 哈希:hash
      规则简单,对id哈希得到数,然后去对应的库中查询
      数据访问理论上平均
      不易扩容
    • 路由服务:router-config-server
      调用者无需关心如何拆分数据库,不需要将选库的逻辑放在代码中
      多了一次调用

二:如何进行水平拆分?拆分依据是什么?

  • 四类典型场景
    几乎涵盖互联网90%业务场景
    • (单key)用户库如何拆分:user(uid, XXOO)
    • (1对多)帖子库如何拆分:tiezi(tid, uid, XXOO)
    • (多对多)好友库如何拆分:friend(uid, friend_uid, XXOO)
    • (多key)订单库如何拆分:order(oid, buyer_id, seller_id, XXOO)

三:用户库拆分?

  • 用户库,10亿数据量
    user(uid, uname, passwd, age, sex, create_time);
  • 业务需求如下
    (1)1%登录请求=> where uname=XXX and passwd=XXX
    (2)99%查询请求=> where uid=XXX
  • 问题?那uname的查询怎么办?
  • 解决方案
    • 建立uname与uid的对应关系
    • uname与uid uname的长度一般是固定的,采用树形结构进行存储

四:帖子库拆分?

  • 帖子库,15亿数据量
    tiezi(tid, uid, title, content, time);
  • 业务需求如下
    (1)查询帖子详情(90%请求)
    SELECT FROM tiezi WHERE tid=$tid
    (2)查询用户所有发帖(10%请求)
    SELECT
    FROM tiezi WHERE uid=$uid
  • 如何拆分?
    根据tid来分,90%的问题能解决。
    10%的问题,最粗暴的方法,循环每个库来一遍

五:好友库拆分?

  • 好友库,1亿数据量
    friend(uid, friend_uid, nick, memo, XXOO);
  • 业务需求如下
    (1)查询我的好友(50%请求)=> 用亍界面展示
    SELECT friend_uidFROM friend WHERE uid=$my_uid
    (2)查询加我为好友的用户(50%请求)=> 用户反向通知
    SELECT uidFROM friend WHERE friend_uid=$my_uid
  • 方案
    维护uid与friend_id的关系 friend_id与uid的关系

六:订单库如何拆分?

  • 订单库,10亿数据量
    order(oid, buyer_id, seller_id, order_info, XXOO);
  • 业务需求如下
    (1)查询订单信息(80%请求)
    SELECT FROM order WHERE oid=$oid
    (2)查询我买的东东(19%请求)
    SELECT
    FROM order WHERE buyer_id=$my_uid
    (3)查询我卖出的东东(1%请求)
    SELECT *FROM order WHERE seller_id=$my_uid
  • 方案
    • 方案1
      需求一和需求二 用帖子库的处理方法处理
      需求三和需求二 用好友库的处理反复处理
    • 方案2
      需求一和需求二 用帖子库的处理方法处理
      需求三仅仅是1% 但是增加了架构的复杂度 没有必要

TIPS

  • 1主3从,其中1从用于后台的查询。
    原因是后台与前台请求没有分开,如果后台的请求对数据库进行order by操作,
    整个CPU都满了,那么会影响前台的请求。
  • 主库写的多,可以不给主库设置索引,只给从库设置索引
xpisme wechat
微信号