前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >分库分表初探

分库分表初探

作者头像
Joseph_青椒
修改2023-08-09 20:11:12
4470
修改2023-08-09 20:11:12
举报
文章被收录于专栏:java_josephjava_joseph

分库分表,来了,作为高级篇章,肯定会给大家带来不一样的地方,来听我唠

这篇主要是认识分库分表,和抛出一系列问题

场景引入

这里给一个面试题,看过我之前文章的小伙伴可能见过,

面试官:这边有个数据库-单表1千万数据,未来1年还会增长多500万,性能比较慢,说下你的优化思路

回答这道题,不能直接分库分表,应当这样回答

这个可以从两方面来考虑,一种是分库分表,一种是优化,分库分表带来的问题是很多的,所以要先考虑优化

优化分为软优化和硬件优化,

硬件优化,可以提高带宽,cpu,硬盘,

然后就是软优化了,这个就很多了。比如说让运维那边进行数据库参数的调优,数据量不是很大的情况下,先考虑读写分离,引入Nosql,多级缓存架构等等,索引,mysql调优这些,

数据量极大,且增长较快的话,再考虑分库分表

好,这道题就完成了,总之就是不能一上来就直接分库分表,

这里带一个小福利,mysql调优,mysql调优-腾讯云开发者社区-腾讯云 (tencent.com)

引入Nosql,多级缓存架构,多级缓存架构一致性问题解决-腾讯云开发者社区-腾讯云 (tencent.com)

没错!我都搞定了

垂直、水平?分库分表

垂直分库

这个其实很多人都用过,一个单体项目,比如商城,用户表,商品表,订单表,都在一个库中,微服务做的话,一个微服务一个库,这个就是垂直分库。

垂直分表

垂直分表,垂直嘛,就是把一个表从上往下切开,分字段,

代码语言:javascript
复制
//拆分前
CREATE TABLE `product` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `title` varchar(524) DEFAULT NULL COMMENT '视频标题',
  `cover_img` varchar(524) DEFAULT NULL COMMENT '封面图',
  `price` int(11) DEFAULT NULL COMMENT '价格,分',
  `total` int(10) DEFAULT '0' COMMENT '总库存',
  `left_num` int(10) DEFAULT '0' COMMENT '剩余',
  
  `learn_base` text COMMENT '课前须知,学习基础',
  `learn_result` text COMMENT '达到水平',
  `summary` varchar(1026) DEFAULT NULL COMMENT '概述',  
  `detail` text COMMENT '视频商品详情',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;


//拆分后
CREATE TABLE `product` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `title` varchar(524) DEFAULT NULL COMMENT '视频标题',
  `cover_img` varchar(524) DEFAULT NULL COMMENT '封面图',
  `price` int(11) DEFAULT NULL COMMENT '价格,分',
  `total` int(10) DEFAULT '0' COMMENT '总库存',
  `left_num` int(10) DEFAULT '0' COMMENT '剩余',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

CREATE TABLE `product_detail` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `product_id` int(11) DEFAULT NULL COMMENT '产品主键',
  `learn_base` text COMMENT '课前须知,学习基础',
  `learn_result` text COMMENT '达到水平',
  `summary` varchar(1026) DEFAULT NULL COMMENT '概述',  
  `detail` text COMMENT '视频商品详情',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

这个就是垂直分表

水平分库

水平分库,就是冗余一份数据库,db_0,db_1这样,数据分摊进去

水平分表

水平分表就是,把一个表的数据,分摊到多张表

对应功能

首先,垂直的好处:

就是业务的区分了,垂直分库,就是每个微服务一个库,

垂直分表,这个也是业务方面的,比如电商中,商品浏览页,和详情页,做数据的隔离。详情页的点击频次不如浏览页嘛

缺点:垂直分库分表并不能解决单表数据量多的情况

水平:

水平分库,水平分表,他们一般一起做,解决单表数据量多的情况,一般单表到达1000w就到达分库分表的要求了

单单水平分表不能解决数据库性能问题,因为都还是一个库

分库分表的优劣

分库分表为何不提倡无脑引入,就是因为他虽然好处不少,劣势也很多,但是总体肯定利大于弊

优点,

首先就是分库的好处了,摆脱了数据库的性能瓶颈,摆脱了io,cpu,连接数,提高了并发能力,水平分库也可以分摊数据,

分表的好处

主要是水平分表,避免大表性能问题,将数据划分到不同表

劣质:

这里就值得讨论讨论了,

因为要做分库分表,就是要把劣势都搞定,优势是效益!

问题一:

多表join联合查询、多维度查询

这个问题是分库分表下,导致的查询问题,多表联合查询,分表前,直接join就好了,分表后,join就会变的很麻烦

多维度查询,这个就比较有意思了

比如用户的订单表,分表的分片键partionkey是user_id

image-20230722203508665
image-20230722203508665

用户查询订单,可以通过用户的user_id,去找到自己的订单列表,因为就是按照user_id去做的分表,

商家呢????商家咋搞,这样的架构下,只能一个一个,去搞了,笛卡尔积

问题二:

垂直分库后的的分布式事物问题

问题三:

执行复制sql,例如排序、分页、函数计算性能

数据分布在不同的节点,比如排序,需要从每个表里排出来,再在内存中排序,来做到正常的查询需求,很占用内存

问题四:

分布式主键id问题

单表,自增id就搞定了,多表呢?我们不能让主键id重复

问题五:

数据扩容问题,

当分库一次后,可能要分第二次,数据迁移咋搞?这都是问题

问题六:

分库分表技术选型

市面上这么多,选哪个更稳定,效率更高呢??

分库分表策略

我们做海量数据处理,一般指的是水平的分库分表,

那么分的策略是什么?按照什么去分??

一种是按照范围分,range

另一种是hash取模分

range范围划分

对于范围划分,也可分很多,具体看场景

例如数字划分,通过用户id划分,通过时间划分,通过地域范围划分

id划分好处是简单明了,1-10000 10001到2000这样,非常方便,但会有一些问题

比如老用户一般操作就少了,新用户操作多,导致节点承载请求量不均匀

这种方案适合日志、流水的场景,就是单纯记录,复杂操作很少,甚至都不去读这样的

按照时间划分,这个也会有一些问题

比如用户增长,一般都是刚开始增长的慢,中间增长的快,最后慢,那么导致数据分配不均匀

按照地域划分,这个就很常见了,

同样也要考虑问题,

按照省份的话,北京,和黑龙江的能比吗?有时候外卖就因这个而垮掉,又可以把北京分为,北京1区,北京2区….这样

看我们卖阿里云的场景,就是按照地域划分

image-20230722210648406
image-20230722210648406

Hash取模

hash取模就很常用了,通过分配键partionkey取hash值,再取模,分配到对于的数据节点上

比如来一个,一个库4张表,两个库8张表的例子

    • 例子

    userId id % 2 (库-取余) id /2 % 4 (表) 1 1 0 2 0 1 3 1 1 4 0 2 5 1 2 6 0 3 7 1 3 8 0 0 9 1 0

  • 优点
    • 保证数据较均匀的分散落在不同的库、表中,可以有效的避免热点数据集中问题,
  • 缺点
    • 扩容不是很方便,需要数据迁移

中间件选型

问题六:

分库分表技术选型

市面上这么多,选哪个更稳定,效率更高呢??

这里我们先把这个问题解决掉,顺便扫盲一些分库分表的术语

TDDL 头都大了

这是jar包形势的,阿里内部使用,开演功能较少,所以不适合我们学习使用

myCat

这是基于proxy代理的中间件,做了一层代理,对程序来说是透明的,但是做了一层代理,性能自然慢些

ShadingSphere-jdbc

这是Apache旗下的,基于jdbc,以jar包形式引入,无需代理,所以性能犹豫myCat,开源社区强大,缺点是代码侵入,我们需要配置

可以理解为加强版的jdbc驱动,兼容jdbc和ROM框架

这里选择sharingSphere-jdbc,来完善blog

这里面试官可能会问

shadringSphere-jdbc和myCat的区别

这个主要从这几方面来说

相同点是,都是对sql就行解析,路由、改写、合并

shardingSphere-jdbc无需代理,性能快,但是代码有侵入性,而myCat做了一层代理,对于程序透明,无侵入性,但是性能不如sharingSphere-jdbc

shardingSphere-jdbc以jar包形式,轻量型的,而myCat,要拦截所有jdbc请求

扫盲一些shardingSphere-jdbc的术语

  • 数据节点Node
    • 数据分片的最小单元,由数据源名称和数据表组成
    • 比如:ds_0.product_order_0
  • 真实表
    • 在分片的数据库中真实存在的物理表
    • 比如订单表 product_order_0、product_order_1、product_order_2
  • 逻辑表
    • 水平拆分的数据库(表)的相同逻辑和数据结构表的总称
    • 比如订单表 product_order_0、product_order_1、product_order_2,逻辑表就是product_order
  • 绑定表
    • 指分片规则一致的主表和子表
    • 比如product_order表和product_order_item表,均按照order_id分片,则此两张表互为绑定表关系
    • 绑定表之间的多表关联查询不会出现笛卡尔积关联,关联查询效率将大大提升
image-20230722212944804
image-20230722212944804
  • 广播表
    • 指所有的分片数据源中都存在的表,表结构和表中的数据在每个数据库中均完全一致
    • 适用于数据量不大且需要与海量数据的表进行关联查询的场景
    • 例如:字典表、配置表

Sharing-jdbc分片算法

本专栏主要解决分库分表的各种难题,不过于扫盲

仅仅列举常用的

分片键PartionKey,就是按照哪个分片

行表达式分片策略 InlineShardingStrategy

这里举一个分表的例子

image-20230724094410783
image-20230724094410783
  • 标准分片策略StandardShardingStrategy
    • 只支持【单分片键】,提供PreciseShardingAlgorithm和RangeShardingAlgorithm两个分片算法
    • PreciseShardingAlgorithm 精准分片 是必选的,用于处理=和IN的分片
    • RangeShardingAlgorithm 范围分配 是可选的,用于处理BETWEEN AND分片
    • 如果不配置RangeShardingAlgorithm,如果SQL中用了BETWEEN AND语法,则将按照全库路由处理,性能下降
  • 复合分片策略ComplexShardingStrategy
    • 支持【多分片键】,多分片键之间的关系复杂,由开发者自己实现,提供最大的灵活度
    • 提供对SQL语句中的=, IN和BETWEEN AND的分片操作支持
    • prouduct_order_0_0、prouduct_order_0_1、prouduct_order_1_0、prouduct_order_1_1
  • Hint分片策略HintShardingStrategy
    • 这种分片策略无需配置分片健,分片健值也不再从 SQL中解析,外部手动指定分片健或分片库,让 SQL在指定的分库、分表中执行
    • 用于处理使用Hint行分片的场景,通过Hint而非SQL解析的方式分片的策略
    • Hint策略会绕过SQL解析的,对于这些比较复杂的需要分片的查询,Hint分片策略性能可能会更好
  • 不分片策略 NoneShardingStrategy
    • 不分片的策略。

这里做个最基础的认识,为后续方案的解决做铺垫。

本文参与?腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2023-07-22T,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客?前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与?腾讯云自媒体分享计划? ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 场景引入
  • 垂直、水平?分库分表
    • 垂直分库
      • 垂直分表
        • 水平分库
          • 水平分表
            • 对应功能
            • 分库分表的优劣
            • 分库分表策略
              • range范围划分
                • Hash取模
                • 中间件选型
                • Sharing-jdbc分片算法
                相关产品与服务
                云数据库 MySQL
                腾讯云数据库 MySQL(TencentDB for MySQL)为用户提供安全可靠,性能卓越、易于维护的企业级云数据库服务。其具备6大企业级特性,包括企业级定制内核、企业级高可用、企业级高可靠、企业级安全、企业级扩展以及企业级智能运维。通过使用腾讯云数据库 MySQL,可实现分钟级别的数据库部署、弹性扩展以及全自动化的运维管理,不仅经济实惠,而且稳定可靠,易于运维。
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
                http://www.vxiaotou.com