这应该是最详尽的 MySQL 分库分表文章了
Java 里的 for (;;) 与 while (true),哪个更快?
2、 基本概念
2.1 谈数据库分片需要首先确定以下概念
单库,就是一个库
分片(sharding),分片解决 扩展性
问题,属于水平拆分,引入分片,就引入了数据路由
和分区键
的概念。分表解决的是数据量过大的问题,分库解决的是数据库性能瓶颈的问题。
分组(group),分组解决 可用性
问题,分组通常通过主从复制(replication
)的方式实现。(各种可用级别方案单独介绍)
互联网公司数据库实际软件架构是( 大数据量下
):又分片,又分组(如下图)
3、 分片
3.1 水平拆分,垂直拆分都是什么?
分区表?1)若不走分区键很容易出现全表锁,并发上来后简直是灾难。2)自己分库分表,自己掌控业务场景、访问模式,可控。mysql分区表官方介绍是针对myisam做的优化,你知道他怎么玩的?分半天还是一个ibdata是不是很尴尬
3.2 为什么分表?
数据量阀值
。这个单表可承受的数据量阀值,需根据数据库和并发量的差异,通过实际测试获得。水平拆分如果能预估规模,越早做成本越低。
3.3 为什么分库?
水平拆分都至少要采用分库
的方式,用于一并解决大数据量和高并发
的问题。这也是部分开源的分片数据库中间件只支持分库的原因。3.4 分布式事务?
mysql本身?消息补偿?2PC?
3.5 小结
3.6 如何自己实现分库分表?
dao层,首先 通过分区键算出库名表名
(如shardKey%shardNum 算出来表index如y,然后y/(shardNum/sourceNum)=x,y是表下标,x是库下标)。把source从spring容器中拿出来
,把表名当参数传进去,拼成分片后的sql。思路大概是(select … from order where … -> 先拿到db_x的source 然后 select … from order_y where …)
你想这么干?你已经成功了。当然淘宝和当当的架构师也是这么干的。
3.7 SO,不需要我们亲自动手,其实你需要做的只是按照实际需求挑选而已。
3.8 重点介绍两个产品,先不说具体配置,只说思想
sharding-jdbc(所处位置,通用数据访问层,部署在客户端的jar包,用于将用户的SQL路由到指定的数据库中)
盗一波图
jproxy
jproxy是什么?
为什么分片都是2的n次方?a % (2^n) 等价于 a & (2^n - 1) 其中一个原因就是位运算 扩容?虚拟桶。极限就是一片一库。
演变过程 cobar->mycat->jproxy
mycat是什么?
其优势具有: 基于阿里开源的Cobar产品而研发,Cobar的稳定性、可靠性、优秀的架构和性能 拥有众多成熟的使用案例 强大的团队(其参与者都是5年以上资深软件工程师、架构师、DBA等) 开源,创新,持续更新
盗一波图
4、 分组
4.1 为什么分组?
可用性
问题mysql的ha 网洛上的都是vip漂移实现的
4.2 同步,异步,半同步
异步复制 (mysql默认)
Master将事件写入binlog,但并不知道Slave是否或何时已经接收且已处理。当Slave准备好才会向Master请求binlog。缺点:不能保证一些事件都能够被所有的Slave所接收。
同步复制
Master提交事务,直到事务在 所有的Slave
都已提交,此时才会返回客户端,事务执行完毕。缺点:完成一个事务可能会有很大的延迟。
半同步复制
半同步复制工作的机制处于同步和异步之间,Master的事务提交阻塞, 只要一个Slave
已收到该事务的事件且已记录。它不会等待所有的Slave都告知已收到,且它只是接收,并不用等其完全执行且提交。
4.3 ha方案
MHA MMM
5、 应用案例
5.1 记录一次mongo迁移mysql的过程(分库分表使用jproxy)
mongo怎么了?跟分片无关的部分简单说。
迁移数据库的一个方案 中心化(统一入口) 双写(先同步写mysql如果发生异常改异步,尽量避免服务不可用) 倒库(jproxy支持通过游标形式全量遍历库-逐个表操作,可以利用其异步同步数据) 数据校验 切库提供服务
去mongo+优化方案(此处引入了分片的概念)
压测与性能
去mongo任务线
5.2 记录一次异构具有复杂分片规则数据库的过程
5.2.1 难点
回到本源,缓存+队列
5.2.2 不跑题,我们就说分片部分,如何接手一个复杂分片规则的数据库?
参考案例如何异构一个数十亿级别的数据库 有多复杂? 6000+表,28个库,4套分片规则。(解决方案 sharding-jdbc)
扫以下二维码并回复“828”即可获取
评论