模块十三_MySQL海量数据存储与优化(下)

序言:

文章内容输出来源:拉勾教育Java高薪训练营。
本篇文章是学习课程中的一部分课后笔记

一、分库分表介绍

1.遇到的问题
  • 用户请求量太大
    单服务器TPS、内存、IO都是有上限的,需要将请求打散分布到多个服务器
  • 单库数据量太大
    单个数据库处理能力有限;单库所在服务器的磁盘空间有限;单库上的操作IO有瓶颈
  • 单表数据量太大
    查询、插入、更新操作都会变慢,在加字段、加索引、机器迁移都会产生高负载,影响服务
2.解决方案
  • 垂直拆分
    • 垂直分库
      微服务架构时,业务切割得足够独立,数据也会按照业务切分,保证业务数据隔离,大大提
      升了数据库的吞吐能力

      垂直分库.png

    • 垂直分表
      表中字段太多且包含大字段的时候,在查询时对数据库的IO、内存会受到影响,同时更新数
      据时,产生的binlog文件会很大,MySQL在主从同步时也会有延迟的风险

      垂直分表.png

  • 水平拆分
    • 水平分库
      将单张表的数据切分到多个服务器上去,每个服务器具有相应的库与表,只是表中数据集合
      不同。 水平分库分表能够有效的缓解单机和单库的性能瓶颈和压力,突破IO、连接数、硬件
      资源等的瓶颈


      水平分库.png
    • 水平分表
      针对数据量巨大的单张表(比如订单表),按照规则把一张表的数据切分到多张表里面去。
      但是这些表还是在同一个库中,所以库级别的数据库操作还是有IO瓶颈。


      水平分表.png
3.分库分表规则
  • 水平分库规则
    不跨库、不跨表,保证同一类的数据都在同一个服务器上面。
    数据在切分之前,需要考虑如何高效的进行数据获取,如果每次查询都要跨越多个节点,就需要谨
    慎使用。

  • 水平分表规则

    • RANGE
      时间:按照年、月、日去切分。例如order_2020、order_202005、order_20200501
      地域:按照省或市去切分。例如order_beijing、order_shanghai、order_chengdu
      大小:从0到1000000一个表。例如1000001-2000000放一个表,每100万放一个表

    • HASH
      用户ID取模
      不同的业务使用的切分规则是不一样,就上面提到的切分规则,举例如下:

    • 站内信
      用户维度:用户只能看到发送给自己的消息,其他用户是不可见的,这种情况下是按照
      用户ID hash分库,在用户查看历史记录翻页查询时,所有的查询请求都在同一个库内

    • 用户表
      范围法:以用户ID为划分依据,将数据水平切分到两个数据库实例,如:1到1000W在
      一张表,1000W到2000W在一张表,这种情况会出现单表的负载较高
      按照用户ID HASH尽量保证用户数据均衡分到数据库中

      用户表.png

      • 流水表
        时间维度:可以根据每天新增的流水来判断,选择按照年份分库,还是按照月份分库,
        甚至也可以按照日期分库
4.分库分表其他情况
  • 主键选择
    UUID:本地生成,不依赖数据库,缺点就是作为主键性能太差
    SNOWFLAKE:百度UidGenerator、美团Leaf、基于SNOWFLAKE算法实现
  • 数据一致性
    强一致性:XA协议
    最终一致性:TCC、saga、Seata
  • 数据库扩容
    成倍增加数据节点,实现平滑扩容
    成倍扩容以后,表中的部分数据请求已被路由到其他节点上面,可以清理掉
  • 业务层改造
    基于代理层方式:Mycat、Sharding-Proxy、MySQL Proxy
    基于应用层方式:Sharding-jdbc
  • 分库后面临的问题
    • 事务问题:一次投递需要插入两条记录,且分布在不同的服务器上,数据需要保障一致性。
    • 跨库跨表的join问题:
      • 全局表(字典表):基础数据/配置数据,所有库都拷贝一份
      • 字段冗余:可以使用字段冗余就不用join查询了
      • 系统层组装:可以在业务层分别查询出来,然后组装起来,逻辑较复杂
    • 额外的数据管理负担和数据运算压力:数据库扩容、维护成本变高

二、ShardingSphere简介

1.ShardingSphere

Apache ShardingSphere是一款开源的分布式数据库中间件组成的生态圈。它由Sharding-JDBC、
Sharding-Proxy和Sharding-Sidecar(规划中)这3款相互独立的产品组成。 他们均提供标准化的数据分片、分布式事务和数据库治理功能,可适用于如Java同构、异构语言、容器、云原生等各种多样化的应用场景。


shardingsphere.png
  • Sharding-JDBC:被定位为轻量级Java框架,在Java的JDBC层提供的额外服务,以jar包形式使用。
  • Sharding-Proxy:被定位为透明化的数据库代理端,提供封装了数据库二进制协议的服务端版
    本,用于完成对异构语言的支持。
  • Sharding-Sidecar:被定位为Kubernetes或Mesos的云原生数据库代理,以DaemonSet的形式代
    理所有对数据库的访问。
对比.png
2.Sharding-JDBC

Sharding-JDBC定位为轻量级Java框架,在Java的JDBC层提供的额外服务。 它使用客户端直连数据库,以jar包形式提供服务,无需额外部署和依赖,可理解为增强版的JDBC驱动,完全兼容JDBC和各种ORM框架的使用。

  • 适用于任何基于Java的ORM框架,如:JPA, Hibernate, Mybatis, Spring JDBC Template或直接使用JDBC。
  • 基于任何第三方的数据库连接池,如:DBCP, C3P0, BoneCP, Druid, HikariCP等。
  • 支持任意实现JDBC规范的数据库。目前支持MySQL,Oracle,SQLServer和PostgreSQL。


    jdbc.png

Sharding-JDBC主要功能

  • 数据分片
    分库、分表
    读写分离
    分片策略
    分布式主键
  • 分布式事务
    标准化的事务接口
    XA强一致性事务
    柔性事务
  • 数据库治理
    配置动态化
    编排和治理
    数据脱敏
    可视化链路追踪

Sharding-JDBC内部结构

内部结构.png

初始化过程:

  1. 根据配置的信息生成Configuration对象
  2. 通过Factory会将Configuration对象转化为Rule对象
  3. 通过Factory会将Rule对象与DataSource对象封装
  4. Sharding-JDBC使用DataSource进行分库分表和读写分离操作
3.Sharding-Proxy

harding-Proxy是ShardingSphere的第二个产品,定位为透明化的数据库代理端,提供封装了数据库
二进制协议的服务端版本,用于完成对异构语言的支持。
目前先提供MySQL版本,它可以使用任何兼容MySQL协议的访问客户端(如:MySQL Command Client, MySQL Workbench等操作数据,对DBA更加友好。

  • 向应用程序完全透明,可直接当做MySQL使用
  • 适用于任何兼容MySQL协议的客户端
proxy.png

Sharding-Proxy使用过程

  • 下载Sharding-Proxy的最新发行版;
  • 解压缩后修改conf/server.yaml和以config-前缀开头的文件,进行分片规则、读写分离规则配置
    编辑%SHARDING_PROXY_HOME%\conf\config-xxx.yaml
    编辑%SHARDING_PROXY_HOME%\conf\server.yaml
  • 引入依赖jar
    如果后端连接MySQL数据库,需要下载MySQL驱动, 解压缩后将mysql-connector-java-
    5.1.48.jar拷贝到${sharding-proxy}\lib目录。
    如果后端连接PostgreSQL数据库,不需要引入额外依赖。
  • Linux操作系统请运行bin/start.sh,Windows操作系统请运行bin/start.bat启动Sharding-Proxy。
    使用默认配置启动: start.sh
    配置端口启动:start.sh ${port}
  • 使用客户端工具连接。如: mysql -h 127.0.0.1 -P 3307 -u root -p root

若想使用Sharding-Proxy的数据库治理功能,则需要使用注册中心实现实例熔断和从库禁用功能。
Sharding-Proxy默认提供了Zookeeper的注册中心解决方案。只需按照配置规则进行注册中心的配置,即可使用。

注意事项:

  • Sharding-Proxy 默认不支持hint,如需支持,请在conf/server.yaml中,将props的属性proxy.hint.enabled设置为true。在Sharding-Proxy中,HintShardingAlgorithm的泛型只能是
    String类型。
  • Sharding-Proxy默认使用3307端口,可以通过启动脚本追加参数作为启动端口号。如:
    bin/start.sh 3308
  • Sharding-Proxy使用conf/server.yaml配置注册中心、认证信息以及公用属性。
  • Sharding-Proxy支持多逻辑数据源,每个以"config-"做前缀命名yaml配置文件,即为一个逻辑数
    据源。
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容