From 8a81763d0328df82713e776ffe7c7a8cc4bb5e3b Mon Sep 17 00:00:00 2001
From: yanglbme <szuyanglb@outlook.com>
Date: Fri, 30 Nov 2018 17:01:19 +0800
Subject: [PATCH] docs(database): add database-shard.md
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

如何分库分表?有哪些分库分表中间件?如何垂直拆分?水平拆分?
---
 README.md                               |   2 +-
 docs/high-concurrency/database-shard.md | 105 ++++++++++++++++++++++++
 img/database-split-horizon.png          | Bin 0 -> 10791 bytes
 img/database-split-vertically.png       | Bin 0 -> 7590 bytes
 4 files changed, 106 insertions(+), 1 deletion(-)
 create mode 100644 docs/high-concurrency/database-shard.md
 create mode 100644 img/database-split-horizon.png
 create mode 100644 img/database-split-vertically.png

diff --git a/README.md b/README.md
index a0545e6..b24cea1 100644
--- a/README.md
+++ b/README.md
@@ -67,7 +67,7 @@
 - [生产环境中的 Redis 是怎么部署的?](/docs/high-concurrency/redis-production-environment.md)
 
 ### 分库分表
-- 为什么要分库分表(设计高并发系统的时候,数据库层面该如何设计)?用过哪些分库分表中间件?不同的分库分表中间件都有什么优点和缺点?你们具体是如何对数据库如何进行垂直拆分或水平拆分的?
+- [为什么要分库分表(设计高并发系统的时候,数据库层面该如何设计)?用过哪些分库分表中间件?不同的分库分表中间件都有什么优点和缺点?你们具体是如何对数据库如何进行垂直拆分或水平拆分的?](/docs/high-concurrency/database-shard.md)
 - 现在有一个未分库分表的系统,未来要分库分表,如何设计才可以让系统从未分库分表动态切换到分库分表上?
 - 如何设计可以动态扩容缩容的分库分表方案?
 - 分库分表之后,id 主键如何处理?
diff --git a/docs/high-concurrency/database-shard.md b/docs/high-concurrency/database-shard.md
new file mode 100644
index 0000000..d3412a6
--- /dev/null
+++ b/docs/high-concurrency/database-shard.md
@@ -0,0 +1,105 @@
+## 面试题
+为什么要分库分表(设计高并发系统的时候,数据库层面该如何设计)?用过哪些分库分表中间件?不同的分库分表中间件都有什么优点和缺点?你们具体是如何对数据库如何进行垂直拆分或水平拆分的?
+
+## 面试官心理分析
+其实这块肯定是扯到**高并发**了,因为分库分表一定是为了**支撑高并发、数据量大**两个问题的。而且现在说实话,尤其是互联网类的公司面试,基本上都会来这么一下,分库分表如此普遍的技术问题,不问实在是不行,而如果你不知道那也实在是说不过去!
+
+## 面试题剖析
+### 为什么要分库分表?(设计高并发系统的时候,数据库层面该如何设计?)
+说白了,分库分表是两回事儿,大家可别搞混了,可能是光分库不分表,也可能是光分表不分库,都有可能。
+
+我先给大家抛出来一个场景。
+
+假如我们现在是一个小创业公司(或者是一个 BAT 公司刚兴起的一个新部门),现在注册用户就 20 万,每天活跃用户就 1 万,每天单表数据量就 1000,然后高峰期每秒钟并发请求最多就 10。天,就这种系统,随便找一个有几年工作经验的,然后带几个刚培训出来的,随便干干都可以。
+
+结果没想到我们运气居然这么好,碰上个 CEO 带着我们走上了康庄大道,业务发展迅猛,过了几个月,注册用户数达到了 2000 万!每天活跃用户数 100 万!每天单表数据量 10 万条!高峰期每秒最大请求达到 1000!同时公司还顺带着融资了两轮,进账了几个亿人民币啊!公司估值达到了惊人的几亿美金!这是小独角兽的节奏!
+
+好吧,没事,现在大家感觉压力已经有点大了,为啥呢?因为每天多 10 万条数据,一个月就多 300 万条数据,现在咱们单表已经几百万数据了,马上就破千万了。但是勉强还能撑着。高峰期请求现在是 1000,咱们线上部署了几台机器,负载均衡搞了一下,数据库撑 1000QPS 也还凑合。但是大家现在开始感觉有点担心了,接下来咋整呢......
+
+再接下来几个月,我的天,CEO 太牛逼了,公司用户数已经达到 1 亿,公司继续融资几十亿人民币啊!公司估值达到了惊人的几十亿美金,成为了国内今年最牛逼的明星创业公司!天,我们太幸运了。
+
+但是我们同时也是不幸的,因为此时每天活跃用户数上千万,每天单表新增数据多达 50 万,目前一个表总数据量都已经达到了两三千万了!扛不住啊!数据库磁盘容量不断消耗掉!高峰期并发达到惊人的 `5000~8000`!别开玩笑了,哥。我跟你保证,你的系统支撑不到现在,已经挂掉了!
+
+好吧,所以你看到这里差不多就理解分库分表是怎么回事儿了,实际上这是跟着你的公司业务发展走的,你公司业务发展越好,用户就越多,数据量越大,请求量越大,那你单个数据库一定扛不住。
+
+#### 分表
+
+比如你单表都几千万数据了,你确定你能扛住么?绝对不行,**单表数据量太大**,会极大影响你的 sql **执行的性能**,到了后面你的 sql 可能就跑的很慢了。一般来说,就以我的经验来看,单表到几百万的时候,性能就会相对差一些了,你就得分表了。
+
+分表是啥意思?就是把一个表的数据放到多个表中,然后查询的时候你就查一个表。比如按照用户 id 来分表,将一个用户的数据就放在一个表中。然后操作的时候你对一个用户就操作那个表就好了。这样可以控制每个表的数据量在可控的范围内,比如每个表就固定在 200 万以内。
+
+#### 分库
+
+分库是啥意思?就是你一个库一般我们经验而言,最多支撑到并发 2000,一定要扩容了,而且一个健康的单库并发值你最好保持在每秒 1000 左右,不要太大。那么你可以将一个库的数据拆分到多个库中,访问的时候就访问一个库好了。
+
+这就是所谓的**分库分表**,为啥要分库分表?你明白了吧。
+
+
+| # | 分库分表前 | 分库分表后 |
+|---|---|---|
+| 并发支撑情况 | MySQL 单机部署,扛不住高并发 | MySQL从单机到多机,能承受的并发增加了多倍 |
+| 磁盘使用情况 | MySQL 单机磁盘容量几乎撑满 | 拆分为多个库,数据库服务器磁盘使用率大大降低 |
+| SQL 执行性能 | 单表数据量太大,SQL 越跑越慢 | 单表数据量减少,SQL 执行效率明显提升 |
+
+### 用过哪些分库分表中间件?不同的分库分表中间件都有什么优点和缺点?
+这个其实就是看看你了解哪些分库分表的中间件,各个中间件的优缺点是啥?然后你用过哪些分库分表的中间件。
+
+比较常见的包括:
+
+- cobar
+- TDDL
+- atlas
+- sharding-jdbc
+- mycat
+
+#### cobar
+阿里 b2b 团队开发和开源的,属于 proxy 层方案。早些年还可以用,但是最近几年都没更新了,基本没啥人用,差不多算是被抛弃的状态吧。而且不支持读写分离、存储过程、跨库 join 和分页等操作。
+
+#### TDDL
+淘宝团队开发的,属于 client 层方案。支持基本的 crud 语法和读写分离,但不支持 join、多表查询等语法。目前使用的也不多,因为还依赖淘宝的 diamond 配置管理系统。
+
+#### atlas
+360 开源的,属于 proxy 层方案,以前是有一些公司在用的,但是确实有一个很大的问题就是社区最新的维护都在 5 年前了。所以,现在用的公司基本也很少了。
+
+#### sharding-jdbc
+当当开源的,属于 client 层方案。确实之前用的还比较多一些,因为 SQL 语法支持也比较多,没有太多限制,而且目前推出到了 2.0 版本,支持分库分表、读写分离、分布式 id 生成、柔性事务(最大努力送达型事务、TCC 事务)。而且确实之前使用的公司会比较多一些(这个在官网有登记使用的公司,可以看到从 2017 年一直到现在,是有不少公司在用的),目前社区也还一直在开发和维护,还算是比较活跃,个人认为算是一个现在也**可以选择的方案**。
+
+#### mycat
+基于 cobar 改造的,属于 proxy 层方案,支持的功能非常完善,而且目前应该是非常火的而且不断流行的数据库中间件,社区很活跃,也有一些公司开始在用了。但是确实相比于 sharding jdbc 来说,年轻一些,经历的锤炼少一些。
+
+#### 总结
+综上,现在其实建议考量的,就是 sharding-jdbc 和 mycat,这两个都可以去考虑使用。
+
+sharding-jdbc 这种 client 层方案的**优点在于不用部署,运维成本低,不需要代理层的二次转发请求,性能很高**,但是如果遇到升级啥的需要各个系统都重新升级版本再发布,各个系统都需要**耦合** sharding-jdbc 的依赖;
+
+mycat 这种 proxy 层方案的**缺点在于需要部署**,自己运维一套中间件,运维成本高,但是**好处在于对于各个项目是透明的**,如果遇到升级之类的都是自己中间件那里搞就行了。
+
+通常来说,这两个方案其实都可以选用,但是我个人建议中小型公司选用 sharding-jdbc,client 层方案轻便,而且维护成本低,不需要额外增派人手,而且中小型公司系统复杂度会低一些,项目也没那么多;但是中大型公司最好还是选用 mycat 这类 proxy 层方案,因为可能大公司系统和项目非常多,团队很大,人员充足,那么最好是专门弄个人来研究和维护 mycat,然后大量项目直接透明使用即可。
+
+### 你们具体是如何对数据库如何进行垂直拆分或水平拆分的?
+
+**水平拆分**的意思,就是把一个表的数据给弄到多个库的多个表里去,但是每个库的表结构都一样,只不过每个库表放的数据是不同的,所有库表的数据加起来就是全部数据。水平拆分的意义,就是将数据均匀放更多的库里,然后用多个库来抗更高的并发,还有就是用多个库的存储容量来进行扩容。
+
+![database-split-horizon](/img/database-split-horizon.png)
+
+**垂直拆分**的意思,就是**把一个有很多字段的表给拆分成多个表**,**或者是多个库上去**。每个库表的结构都不一样,每个库表都包含部分字段。一般来说,会**将较少的访问频率很高的字段放到一个表里去**,然后**将较多的访问频率很低的字段放到另外一个表里去**。因为数据库是有缓存的,你访问频率高的行字段越少,就可以在缓存里缓存更多的行,性能就越好。这个一般在表层面做的较多一些。
+
+![database-split-vertically](/img/database-split-vertically.png)
+
+这个其实挺常见的,不一定我说,大家很多同学可能自己都做过,把一个大表拆开,订单表、订单支付表、订单商品表。
+
+还有**表层面的拆分**,就是分表,将一个表变成 N 个表,就是**让每个表的数据量控制在一定范围内**,保证 SQL 的性能。否则单表数据量越大,SQL 性能就越差。一般是 200 万行左右,不要太多,但是也得看具体你怎么操作,也可能是 500 万,或者是 100 万。你的SQL越复杂,就最好让单表行数越少。
+
+好了,无论分库还是分表,上面说的那些数据库中间件都是可以支持的。就是基本上那些中间件可以做到你分库分表之后,**中间件可以根据你指定的某个字段值**,比如说 userid,**自动路由到对应的库上去,然后再自动路由到对应的表里去**。
+
+你就得考虑一下,你的项目里该如何分库分表?一般来说,垂直拆分,你可以在表层面来做,对一些字段特别多的表做一下拆分;水平拆分,你可以说是并发承载不了,或者是数据量太大,容量承载不了,你给拆了,按什么字段来拆,你自己想好;分表,你考虑一下,你如果哪怕是拆到每个库里去,并发和容量都ok了,但是每个库的表还是太大了,那么你就分表,将这个表分开,保证每个表的数据量并不是很大。
+
+
+而且这儿还有两种**分库分表的方式**:
+
+- 一种是按照 range 来分,就是每个库一段连续的数据,这个一般是按比如**时间范围**来的,但是这种一般较少用,因为很容易产生热点问题,大量的流量都打在最新的数据上了。
+- 或者是按照某个字段hash一下均匀分散,这个较为常用。
+
+range 来分,好处在于说,扩容的时候很简单,因为你只要预备好,给每个月都准备一个库就可以了,到了一个新的月份的时候,自然而然,就会写新的库了;缺点,但是大部分的请求,都是访问最新的数据。实际生产用 range,要看场景。
+
+hash 分发,好处在于说,可以平均分配每个库的数据量和请求压力;坏处在于说扩容起来比较麻烦,会有一个数据迁移的过程,之前的数据需要重新计算 hash 值重新分配到不同的库或表。
\ No newline at end of file
diff --git a/img/database-split-horizon.png b/img/database-split-horizon.png
new file mode 100644
index 0000000000000000000000000000000000000000..9f13eb81e8c15addd7607f6f8df7b86c3b95ff8a
GIT binary patch
literal 10791
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
NXnB>}xpEKw{%?-gT9g0)

literal 0
HcmV?d00001

diff --git a/img/database-split-vertically.png b/img/database-split-vertically.png
new file mode 100644
index 0000000000000000000000000000000000000000..21357328786ecf57dffbe6cd26ef249b1ffc9528
GIT binary patch
literal 7590
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
VP{<Tr1a7=Sst+_3D-^7s{TtA?WQPC%

literal 0
HcmV?d00001