分布式_数据库分库分表

1. 总结:

(1) 数据库4大主题:读写分离、分库分表、跨库join排序等、分布式事务

2. 读书笔记《可伸缩服务架构:框架与中间件》

(1)分库分表应用场景

综述:分库分表能有效的突破单机和单库带来的存储瓶颈、IO性能瓶颈、数据库连接数的瓶颈等;

垂直分库分表:--优点是业务拆分后便于业务解耦,冷热分离和长字段分离后有助于提升吞吐量,和单机硬件性能如IO性能、数据库连接数。--缺点是:会出现跨库join问题、分布式事务问题。

水平分库分表:--优点是分表可以解决存储性能瓶颈和数据量过大导致检索变慢的问题(即缩小索引大小,提高查询速度和方便索引和表结构变更),分库提高IO性能和吞吐量,便于将分库迁移到不同的数据库实例;

建议:若希望扩容时对应用层配置改变最少,可在数据库实例中预留足够的数据库数量;

(2)分库分表原则:

垂直拆分:(1)按业务拆分:按照单个表的不同业务进行切分,分布到不同数据库; (2)冷热分离:如微博标题作者等冷数据放在MyISAM引擎的MySQL库中,便于进行数据查询;点赞数、浏览量等热数据放在InnoDB引擎的MySQL数据库,提升更新速度;原理是:数据库以行为单位将数据加载到内存中,这样表中字段长度较短且访问频率较高,内存能加载更多的数据,命中率更高,减少了磁盘IO,从而提升了数据库性能。 (3)将字段较长的拆分一张表,通过拆分列,好处是:避免跨页问题,MySQL底层是通过数据页存储的,一条记录占用空间过大会导致跨页,造成额外的性能开销。

水平拆分:将一个表拆分为相同的几个表;

(3)分库分表实现方案:

a. 客户端分片:具体可通过应用层实现(dpsplit)、ORM层实现(Mybatis配置文件的SQL中增加表索引参数来实现)、JDBC层实现(如shardingJDBC分库分表框架)

b. 代理分片:如MyCat、Cobar框架,本质是实现JDBC协议的解析,缺点是需增加代理层(服务器),对数据库操作增加一层网络传输;

c. 支持事务的分布式数据库:如TiDB可直接提供分库分表、分布式事处理等;

(4)读写分离:

实现mysql主备复制-->利用mycat实现读写分离

读写分离适用于读操作压力大的场景,通过增加从库提升读并发量,当写压力大时,就必须进行分库了;

详见:https://blog.csdn.net/zzy7075/article/details/52836285 mysql+mycat搭建稳定高可用集群主备复制,读写分离

3. 分库分表规则:

(1) 简介:

总体流程为:按照几年的业务量规划分库分表,业务量确认分表数,分库数可进行适当冗余,方便后续进行IO吞吐量扩展时在不同数据库实例上进行分库迁移,如果一开始的分库分表方案后续不满足需求,可进行动态库扩容,即16库*2表->32库*2表(扩容方案见58沈剑公众号:数据库架构设计的一切)

分表相比分库好处:最常见的分表需求是事务问题。同在一个库则不需考虑分布式事务,善于使用同库不同表可有效避免分布式事务带来的麻烦。目前强一致性的分布式事务由于性能问题,导致使用起来并不一定比不分库分表快。目前采用最终一致性的柔性事务居多。分表的另一个存在的理由是,过多的数据库实例不利于运维管理。综上所述,最佳实践是合理地配合使用分库+分表。

常用的有取模、分区或路由服务,MyCat还支持一致性哈希、枚举法、编程法等;

(2) 分库分表规则-取模:包括主键直接取模和主键哈希值取模,如按照交易ID或订单ID分片,通常是数据没有时效性的情况;

若有某个合适的业务字段比较合适作为分片字段,则建议采用此业务字段分片,常见的除了主键之外的其他可能分片字段有“订单创建时间”、店铺类别”或“所在省”等;选择分片字段的条件如下:1、尽可能的比较均匀分布数捤到各个节点上;2、该业务字段是最频繁的或者最重要的查诟条件。

mycat 性能建议:1、使用inner join ,尽量避免使用left join ,right join;2、使用left join,right join时 on条件会先执行,where条件会后执行。在使用时,条件尽量写的on后面,减少where的执行;3、少用子查询,用join

优点:请求均匀性较好

缺点:不易扩展

(3) 分库分表规则-范围:如按照时间分区

优点:易于扩展

缺点:请求负载不一定均衡,如新用户往往比旧用户活跃

(4)动态扩容缩容的分库分表方案:

可设计按照分区规则进行分库分表,方便扩容;

如按照取模规则进行分库分表,初始要最少分2库(无所谓分几个端口),后续按照2、4、8、16方式进行扩容,如2->4扩容时,首先将2备库提升为主库,然后修改路由算法取模2变取模4,这样部分偶数还在0,部分奇数还在1上,最后收尾工作:解除原先主备同步,4个库分别增加备份库,原4库删除不符合路由规则的数据;

详见:58沈剑公众号:数据库架构设计的一切

(9)详见

《亿级网站流量核心架构》14.5.2

详见:https://www.cnblogs.com/756623607-zhang/p/6656022.html Mycat水平拆分之十种分片规则 -- 好!!!

http://gaojingsong.iteye.com/blog/2338725 【Mycat1.6之注解&多租户】--- 详见书籍 --- 好!!!

https://blog.csdn.net/win7system/article/details/53333094 MyCat注解使用指南

https://blog.csdn.net/goslingfly/article/details/78573716 MySQL单库分表

https://blog.csdn.net/tornadojava/article/details/54948662 MyCat关键配置说明

https://www.cnblogs.com/chenmh/p/5165636.html Mycat 月分片方法

https://blog.csdn.net/l1028386804/article/details/77150670?locationNum=9&fps=1 Mycat之——取模分片---时间测试

4. 分库分表后出现的问题:

(0)总结:

分库分表问题:跨库join/排序/分页等问题、非分表字段跨库查询、分布式事务问题、多数据源管理问题

https://www.cnblogs.com/aacoutlook/p/9039378.html --- 分库分表各种问题解决

(1)跨库join

处于性能、安全等方面考虑,一般禁止跨库Join;

解决办法:全局表、表分组、字段冗余、数据组装(在系统层面,分两次查询,第一次查询的结果集中找出关联数据id,然后根据id发起第二次请求得到关联数据。最后将获得到的数据进行字段拼装。)

http://www.360doc.com/content/17/1123/10/16915_706380488.shtml -- 查询结果组装方法

(1)跨库分页/排序

跨库排序:可通过逐个扫描分表,最后通过归并排序进行数据合并;

跨库分页:详见https://mp.weixin.qq.com/s/h99sXP4mvVFsJw6Oh3aU5A --- 58沈剑-《业界难题 跨库分页的4种方法》

(2)非分表键跨库查询

业务侧方案:对数据一致性和实时性要求较高;

方法一:扫描所有订单表(必须按页查找,否则内存溢出-mycat),然后进行内存聚合,这种方法在大流量系统架构中是行不通的;

方法二:建冗余表进行数据异构,以非分表键进行分库分表 & 建立非分表属性和分表属性之间的映射关系:映射表或KV缓存

通过同步双写,优点是数据一致性较高,缺点是请求处理时间增加;

通过发送消息进行异步写达到最终一致性,优点是请求处理时间短,缺点是有不一致时间窗口和消息丢失时数据不一致;

通过cannel等订阅binlog,优点是请求处理时间段,缺点是有不一致时间窗口;

//缺点映射表多一次数据库查询;

方法三:分库基因法,将非分表主键通过一个函数生成基因,作为分表主键的分库基因;或将分表主键的分库基因作为非分表主键的组成成分;即取模8时,最后3位是分库基因;

//优点是一次查询即可,缺点是需提前规划好未来几年容量,预留一定位的分库基因;

//例如:预留64库时,将分表主键uid的末6位作为非分表主键订单ID的组成成分;

运营侧方案:对数据一致性和实时性要求不是很高;

方法:前后台分离,通过binlog异步同步数据到运营库进行访问,和业务库进行分离;在数据量很大的情况下,还可以使用ES搜索引擎或Hive来满足后台复杂的查询方式。

聚合数据异构:

(3)分布式事务问题,即一致性问题

一般通过spring配置,可为不同的数据源配置不同的事务管理器,如果更新操作在一个数据库实例内发生,可以使用数据源的事务来处理;对于跨数据源的事务(如消息事务、数据库事务、远程调用等多场景协同流程),可通过分布式事务来达成事务的一致性;

一致性方案:见H_分布式_调优策略

http://www.infoq.com/cn/articles/solution-of-distributed-system-transaction-consistency 分布式系统事务一致性解决方案 -- 好!!

(3)总结:

5. 分库分表中间件:Shark、MyCat等

(1)中间层分库分表技术选型:

(2)myCat

简介:myCat目前支持跨库两表的join,已经可以满足大部分场景;MyCat增加了对聚合、分组、排序、limit 等聚合功能的支持;

配置方法:分片表、非分片表、表分组和全局表(非业务表/字典表)配置方法;

表分组:子表的记录与所关联的父表记录存放在同一个数据分片上,通过表分组(Table Group)保证数据Join不会跨库操作;

解决跨库join的办法:全局表、ER分片(表分组)、catletT(人工智能)和ShareJoin,ShareJoin在开发版中支持,前面三种方式1.3.0.1支持。

实现原理:

https://blog.csdn.net/u011983531/article/details/78948680 -- 各种分库分表中间件原理图 ----好!!!!

https://www.cnblogs.com/taoxinrui/p/6782791.html 各种分库分表中间件特性对比 --- 好!!

其他参考: https://blog.csdn.net/wangfanbb/article/details/50887108 记录一次经历的数据库从单库到分库分表的过程 好!!

https://blog.csdn.net/leipeng321123/article/details/50401625 ---mycat的一些基本概念+解决跨库join操作

https://blog.csdn.net/wangshuang1631/article/details/62894521 -- myCat分片join---新

https://blog.csdn.net/convict_eva/article/details/51992635 -- mycat分片JOIN,分片规则

(3)JDBC层分库分表技术选型:--- 更好!!

a. 简介:当当网开源框架,相比于MyCat等代理层中间件,ShardingJDBC无需额外部署服务,直接Maven中添加依赖即可,且与主流的ORM框架兼容,便于旧代码迁移;

支持:分库分表、读写分离、跨库join/排序/分组/分页等、弱事务、柔性事务(最大努力达到)、生成分布式ID功能,因此我们场景中需要使用的分库分表弱事务功能它都有;

不支持:having, union&union all, or , 批量insert, distinct, 多个子查询

b. 分库分表:查询方面非常优异,支持聚合(比较型、累加型、平均型)、排序(归并排序)、分组(使用map-reduce算法分组)、分页limit\top\in\=\between等查询操作,对内外连接、笛卡尔积等查询也有良好支持;包括3中分片策略:标准分片(支持单分片键)、复合分片和Inline表达式分片策略;

c. 分布式ID:采用snowflake算法实现,生成数据为64位的整形数据,保证数据的全局唯一性;

d. 事务支持包括:支持逻辑异常导致的跨库事务,不支持因网络或硬件异常导致的跨库事务;

e. 实现原理:

https://blog.csdn.net/qq_22075041/article/details/79490230 解读分库分表中间件Sharding-JDBC与实现分库分表功能 --- 好!!!

(9)总结:

相比于MyCat等代理层中间件,ShardingJDBC无需额外部署服务,直接Maven中添加依赖即可,且与主流的ORM框架兼容,便于旧代码迁移;

9. 数据闭环

猜你喜欢

转载自blog.csdn.net/zxb448126/article/details/81191240