shardingSphere分库分表<3>

1.分库分表的需求分析
2.定制分库分表策略
3.实现订单分库分表(分库分表落地)
4.shardingProxy配置
5.分库分表带来的问题
1.什么是分库分表,什么时候需要做分库分表
当单表数据量过大的时候,此时的查询效率就会变慢,
所有关系型数据库的存储能力是有限的,一旦数据量过大
就会影响很多 包括性能问题, 如果数据量更多,并发量大的话,查询比较复杂一些
呢么消耗的时间会更长

在这里插入图片描述

我们之前说的mysql 优化 是不是建好索引 优化sql就可以了 
但是 在大数据量面前 这些作用也都很小
分库分表的作用 单表数据量太大,会影响到我们的查询效率,即便做了索引,真正到了 百万 千万这个级别的话 依然会很慢
我们一旦分库之后我们数据库访问压力就会从一台机器分散到多台机器 这样能提高我们数据库的并发能力
真正到了大数据是时候,我们需要怎么评估我们的分库分表
看下阿里的规范准则,我们要对我们的三年数据量做一个评估,这中间就涉及到之前
我说的数据的增量 ,比如说像订单这样的数据 今年100w 可能明年还得100W,但是
像用户这些数据 可能过个三年就趋近于平稳了

在这里插入图片描述

第二指定分库分表策略
分库分表策略 一般会有很多 比如说取模 对2进行取模,或者说 对数据按照年限进行一些拆分
前者数据比较均匀,但是后期如果扩容的话 的要做数据迁移(比方说 新加一个表  我现在要对3取模,原来是2个表)

后者 不用做数据迁移,但是数据会分配的不均匀(可能数据可能2020 年数据量多  2021年数据量又会少)

所以此时我们应该 主要的点
1.分库分表一般在开发之前设计,和团队多沟通,尽量避免临时设计,只对最核心的表做分库分表(按照该表的三年数据增量)
2. 分库分表以后,对表的查询必须足够简单,不要有跨表,跨库之类的复杂查询,(因为shaedingsphere 对有些sql 不支持)
3. 分库和分表尽量要同时执行
4.我们一定要在项目开始的时候做分库分表 而不是开始一段时间之后再去改.这样的话涉及一个数据迁移
 比方说我们已经有一个项目在跑了,跑着跑着发现数据存储不下了.在做分库分表 这个时候我们可能要做一个数据迁移
#
比如说 order(订单表)和order_item(订单详情表)


## 关于数据分片策略
1.分库策略  将核心的订单表(order)和order_item(订单详情表)从业务库中移出来,单独放到一个库中,我们分成2个库,分散网络压力 
(ds 主库,ds0 从库,ds1 从库)
2.分表策略:在每个库分两个表,尽量将数据平均的分配到这四个表中。分散单表
查询压力。


在这里插入图片描述

# 订单业务分库分表设计  这样就可以
# 配置ds0 和ds1两个数据源


spring.shardingsphere.datasource.names=ds,ds0,ds1
#ds 配置
spring.shardingsphere.datasource.ds.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.ds.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.ds.url=jdbc:mysql://localhost:3306/micromall?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF-8
#初始连接数
spring.shardingsphere.datasource.ds.initialSize=5
##最小空闲连接数
spring.shardingsphere.datasource.ds.minIdle=10
##最大连接数
spring.shardingsphere.datasource.ds.maxActive=30
spring.shardingsphere.datasource.ds.validationQuery=SELECT 1 FROM DUAL
spring.shardingsphere.datasource.ds.username=root
spring.shardingsphere.datasource.ds.password=root
##ds0 配置
spring.shardingsphere.datasource.ds0.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.ds0.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.ds0.url=jdbc:mysql://localhost:3306/micromall_ds_0?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF-8
spring.shardingsphere.datasource.ds0.initialSize=5
spring.shardingsphere.datasource.ds0.minIdle=10
spring.shardingsphere.datasource.ds0.maxActive=30
spring.shardingsphere.datasource.ds0.validationQuery=SELECT 1 FROM DUAL
spring.shardingsphere.datasource.ds0.username=root
spring.shardingsphere.datasource.ds0.password=root
##ds1 配置
spring.shardingsphere.datasource.ds1.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.ds1.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.ds1.url=jdbc:mysql://localhost:3306/micromall_ds_1?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF-8
spring.shardingsphere.datasource.ds1.initialSize=5
spring.shardingsphere.datasource.ds1.minIdle=10
spring.shardingsphere.datasource.ds1.maxActive=30
spring.shardingsphere.datasource.ds1.validationQuery=SELECT 1 FROM DUAL
spring.shardingsphere.datasource.ds1.username=root
spring.shardingsphere.datasource.ds1.password=root
#############################################################################
## 对于没有做任何业务拆分的表,直接走本默认数据源即可  因为 分库分表只对核心表做分库分表

我们默认的数据源ds,我们项目实现过程中  我们分库分表永远只是对业务最繁忙的表。分库分表不会针对所有的表来分.只针对order和order_item 2个表分  其他的默认走ds数据源
spring.shardingsphere.sharding.default-data-source-name=ds
#  默认路由那个 库
spring.shardingsphere.sharding.default-database-strategy.hint.algorithm-class-name=com.lvhao.sharding.OrderAllRangeHintAlgorithm
#  默认路由那个 表
spring.shardingsphere.sharding.default-table-strategy.hint.algorithm-class-name=com.lvhao.sharding.OrderAllRangeHintAlgorithm
#############################################################################
## oms_order分片策略  数据虚拟表 对应的 真实逻辑表
## 节点 ds0.order_0,ds0.order_1,ds1.order_0,ds1.order_1
spring.shardingsphere.sharding.tables.oms_order.actual-data-nodes=ds$->{0..1}.order_$->{0..1}
##分库策略  分成 ds 2个库
spring.shardingsphere.sharding.tables.order.database-strategy.inline.sharding-column=id
spring.shardingsphere.sharding.tables.order.database-strategy.inline.algorithm-expression=ds$->{id % 2}
## 分表策略  4个表
spring.shardingsphere.sharding.tables.order.table-strategy.inline.sharding-column=id
## 注意下,对于除法,groovy会计算出浮点数,而不是整数。即 3/2=1.5,如果需要计算出整数 3.intdiv(2)=1

###  注意这里的分表逻辑  尽量让数据分散一些
spring.shardingsphere.sharding.tables.order.table-strategy.inline.algorithm-expression = order_$->{((id+1) % 4).intdiv(2)}

## 使用SNOWFLAKE算法生成主键
#spring.shardingsphere.sharding.tables.oms_order.key-generator.column=id
#spring.shardingsphere.sharding.tables.oms_order.key-generator.type=SNOWFLAKE
#spring.shardingsphere.sharding.tables.oms_order.key-generator.props.worker.id=123
###################################################  配置order_item 表

## 节点 ds0.order_item_0,ds0.order_item_1,ds1.order_item_0,ds1.order_item_1
#spring.shardingsphere.sharding.tables.order_item.actual-data-nodes=ds$->{0..1}.oms_order_item_$->{0..1}
## 分库策略 按order_id分片
#spring.shardingsphere.sharding.tables.order_item.database-strategy.inline.sharding-column=order_id
#spring.shardingsphere.sharding.tables.order_item.database-strategy.inline.algorithm-expression=ds$->{order_id % 2}
## 分表策略
#spring.shardingsphere.sharding.tables.order_item.table-strategy.inline.sharding-column=order_id
#spring.shardingsphere.sharding.tables.order_item.table-strategy.inline.algorithm-expression=oms_order_item_$->{((order_id+1) % 4).intdiv(2)}
## 使用SNOWFLAKE算法生成主键
#spring.shardingsphere.sharding.tables.order_item.key-generator.column=id
#spring.shardingsphere.sharding.tables.order_item.key-generator.type=SNOWFLAKE
#spring.shardingsphere.sharding.tables.order_item.key-generator.props.worker.id=123
#
## 配置绑定表,防止笛卡尔乘积
#spring.shardingsphere.sharding.binding-tables[0]=order,order_item
## 打印SQL语句
#spring.shardingsphere.props.sql.show=true
#
# 其实 如果是不做分库分表的业务表 y以及库 这里返回默认的

#spring.shardingsphere.sharding.default-data-source-name=ds
就像这样的话
public class OrderAllRangeHintAlgorithm implements HintShardingAlgorithm {
    @Override
    public Collection<String> doSharding(Collection availableTargetNames, HintShardingValue shardingValue) {
        return availableTargetNames;
    }
}

1,上面的分片吧order和order_item 分到2个库4个表了.但是现在默认是的雪花算法生成的id.
我们需要定制我们与业务相关的id,可以通过spi机制

#https://blog.csdn.net/weixin_42437633/article/details/118655327 可以看看这个



第二我也说了分片策略  我们需要定制更加复杂的分片策略
如果我们取模的方式是平均分,现在我们分了4个片 如果以后我们分5个片 或者6个片的话可能的做数据迁移

如果按照年份分的话  如果我以后再扩容的话 我原有的数据不用动, 我只需要再加表或者再加库就可以
但是这样的问题就是数据的不均匀

有没有一种策略 既要有取模数据数据均衡的优点 又能够像范围分片一样减少数据迁移
所以说  配置一个分片策略 往往不是这么简单的。 分片策略,会要考虑很多问题
还是看这里
https://blog.csdn.net/weixin_42437633/article/details/110131407

shardingProxy配置 这个和shardingjdbc类似 配置文件差不多 
我们现在用shardingjdbc完成了配置。在我的应用中自己配置分库分表的逻辑  我们可以吧这些逻辑 不要在我业务中去写
我们可以用shardingproxy 这样对代码侵入性弱一些
shardingProxy 自己会伪装一个mysql。 就像我们看到的mysql库存一样
sharding-jdbc 用的多   作为一个客户端, 所有的配置客户端可以掌控 比较灵活
sharding-proxy 用的少。他的所有的功能必须前提定制好 简化开发但是他不灵活
但是他只支持mysql,PostgreSQL这2种数据库 但是像oracl 这些不支持
使用sharding-jdbc的话 只要jdbc能够连接的数据库他都支持
shardingProxy

在这里插入图片描述
在这里插入图片描述

sharding-proxy中的配置文件server.yaml中有一段有关zk的配置
这个是做注册中心用的   很多个 sharding-proxy实力,我的数据库的配置文件  只需要搞一份
吧所有的配置信息 放在zk 中,其他实例从配置中去读。这样能够保证所有的实例的配置是一致的
类似于kafka集群 就是吧自己注册在zk中 的ids节点上
分库分表 我们能不分尽量不分
因为分库分表带来的问题 我们不一定都能解决好
他不仅仅只是分一个库就完毕了,他的使用门槛很高
比方说很多sql不支持, 例如mybatis中的 批量insert(我们一般用foreach  这个他就不支持)
官网也列举了很多不支持的sql
所以说如果我们决定了使用分库分表,我们的每一个sql都应该尽量简单些,要考虑他的执行策略,shardingSphere能不能支持(如果不用分库分表 我们只需要写对应sql ,我们不用考虑这么多)


还有分布式事务  具体到分库分表下的分布式事务该怎么去做
执行一个insert的sql。会插入到很多库,插入到很多个库,我们的事务怎么做 
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值