qiuyadong's Homepage

Mycat

2020-02-19

签到23!

学习总结

三军可夺气,将军可夺心。是故朝气锐,昼气惰,暮气归。

善用兵者,避其锐气,击其惰归,此治气者也。

以治待乱,以静待哗,此治心者也。

以近待远,以佚待劳,以饱待饥,此治力者也。

无邀正正之旗,勿击堂堂之阵,此治变者也。

1、为什么要分库分表

数据库出现瓶颈

  • 无法获取连接

    高并发情况下连接数不够

  • 操作数据变慢

    数据库处理数据出了问题

  • 存储出现问题

    单机保存的数据量太大

总结:受到了硬件的限制:CPU、内存、网络、磁盘等;

数据库优化方案

  • SQL和索引

    优化SQL,最终目标其实使用索引,最容易最常见的方案

  • 表和存储引擎

    数据放在表,表存在存储引擎上,不同的存储引擎特性有利于特定业务的处理;

    对表的进行分区、表结构进行优化、表字段进行冗余或者表字段定义的优化等;

  • 架构

    如果是一个数据库服务器,建立多个实例,进行集群,负载均衡

    主从服务器,从服务器为读数据库,主服务器用于写

    数据库之上加一层缓存,如redis

    为了减轻数据库的存储压力和访问压力,分库分表

  • 配置

    优化数据库的配置,如缓存区大小、连接数等,其实更高效的利用硬件

  • 操作系统和硬件

总结:优化从上到下,成本越高

什么时候进行分库分表

  • 一个表存储多少条数据之后
  • 一天能产生多少数据以后
  • 访问数据的话,查询时间超过多少秒以后

2、架构演进

  • 单体架构

    所有代码打包成一个war包,部署到一个tomcat中,运行在一个进程中;

    当业务渐渐增加后,业务代码也越来越多,系统越来越臃肿。

    为了优化系统,搭载集群,负载均衡,加缓存、优化数据库、优化业务代码;

    问题依然存在;

  • 多应用单数据库

    对代码进行解耦,对职责进行拆分,出现问题可以快速定位和修改;

    业务系统拆分为,客户系统、订单系统、财务系统等;

    但访问同一个数据库,数据库的压力依然存在;

  • 多应用多数据库

    每一个应用系统对应一个数据库;

    分库解决了具体实际问题

  • 分表

    分库之后,有些库的表依然会增长很快,进行分表,单表分多个;

总结:架构的演进不是一开始就确定了的,而是一步一步进行,不要过度架构,增加复杂度;

3、如何分库分表

分库分表的维度:

  • 垂直拆分

    基于表结构的拆分,表结构不同;有单库的分表、多库的分库;并没有解决单表数据量大的问题

    • 单库垂直分表

      如将商品信息表,分基本信息表、联系方式表、结算信息表等

    • 多库的垂直分表

      将以前一个库中的表根据业务拆分到不同的数据库中,如将与客户相关的表,拆分到客户数据库中;

  • 水平拆分

    基于数据的拆分,表结构相同;有同库的水平切分也有多库的水平拆分;为了解决单表数据量大需要水平拆分

    • 单库水平分表

      把一个表按照创建时间,分当月表、当天表、历史数据表等;

      如每一天建一个当天表

      解决了单表的查询问题,单并不能解决存储问题,单库数据依然很多

    • 多库水平分表

      能解决实际问题,也带来新的问题

4、分库分表的问题

跨库关联查询

解决方案:

  • 字段冗余

  • 数据同步

    如商品库要查产品库,干脆在商品库中创建产品表,做一个定时任务去同步数据

  • 全局表

    每个库中都有该表,数据一致

  • ER表(关联表)

    相互关联的表及数据一定在同一个库中

  • 重新组装

    每个库每个表查询出来,重新过滤组装,实在没办法的办法

分布式事务

CAP原则:一致性、可用性、分区隔离性;

BASE原则:基本可用、软状态、最终一致性;

解决方案:

  • 全局事务

    询问每一个事务是否可以提交,两阶段提交

  • 基于可靠消息服务的事务方案

    使用消息中间件提供可靠消息服务

  • TCC柔性事务

    请求多系统预留资源处理,两阶段提交

  • 最大努力通知

    通过消息中间件,重复提交、定期校对

排序、翻页、函数计算问题等

全局主键避重问题

解决方案:

  • UUID

  • 数据库

    在数据库中定义一个表来存储字段规则,如起始位置、位数、类型及当前值等。先用for update 行锁,性能问题大;

  • redis

    incr原子递增特性

  • 雪花算法

    41位的时间戳+10位机器id+12毫秒内的流水号+0

    依赖于机器时间

5、多数据源的读写解决方案

在javaweb中一般的sql运行流程:

Dao—->Mapper(ORM)—>Jdbc—>代理—–>数据库服务

  • DAO层

    在选择数据源之前,根据一定的规则选择数据源进行操作;

    Spring中提供了AbstractRoutingDataSource



Comments