- 1. 海量数据的存储解决方案
- 2. 数据库访问瓶颈解决方案
- 3. MyCat
- 4. 天天吃货架构改造
- 5. Sharding-JDBC
- 6. 分布式全局id
注意:1、2两个项目分析的时候要不考虑其它一条带来的影响,例如
一个数据库之内的切分暂时不考虑,这个是数据库表设计的范畴
例如wiki项目,电子书内容单独拆分一个表,就是表设计问题
分库分表是同时拥有的
1. 海量数据的存储解决方案
分表:可以是本数据库分表这样就是单纯的为了解决海量数据存储问题
分库:分库一定是分表了,既能解决存储问题也能解决数据库访问瓶颈问题
1.1 分表(数据切分)
水平切分:
垂直切分
- 按照业务去切分,例如商品库、订单库、优惠券库,可以同时理解为微服务的领域划分问题
- 每种业务一个数据库
-
2. 数据库访问瓶颈解决方案
2.1 读写分离
2.2 使用场景
对数据实时性不高的业务场景,可以考虑读写分离
- 对于实时性要求高的场景,不建议使用读写分离,从写库写,还是从写库读取
分库分表如果你的网络延迟在
5ms
之内是不错的,可以做到无感知3. MyCat
3.1 原理解析
3.1.1 应用场景
官方文档在:
study/mycat
目录- 读写分离:此时配置最为简单,支持读写分离,主从切换
- 分库分表:对于超过
1000万
的表进行分片,最大支持1000亿
的数据 - 多租户应用:每个应用/服务对应一个数据库,应用只连接
MyCat
,程序本身不许要改动 -
3.1.2 实现原理
它的背后是
Cobar
,它是基于java
开发- 实现了
MySQL
的二进制传输协议,巧妙的将自己伪装成一个MySQL Server
- MyCat对Cobar进行重构,并优化缓存内核,增强了聚合和join等特性
- MyCat就是一个数据库中间件产品,支持MySQL集群,提供高可用数据分片集群
3.2 下载与安装
```makefile官方网站
http://www.mycat.org.cn/
参考视频
https://class.imooc.com/lesson/1236#mid=29443
官网下载mycat
上传到虚拟机/云服务器
/home/software/mycat
解压软件
tar -zvxf Mycat-server-1.6.7.3-release-20190828135747-linux.tar.gz
移动到指定文件,/usr/mycat
mv mycat/ /usr/mycat
相关配置
….
在mycat的bin目录启动,consolg: 代表日志显示在控制台
./mycat consolg
后台启动方式
./mycat start
<a name="mhAP4"></a>
## 3.3 MyCat的简单使用
注意mysql8使用新的加密方式,连接客户端呢,暂不支持,要是有mysql native passpord<br />准备3个节点,一台安装MyCat,另外两台安装MySQL,实验MyCat的分库分表<br />[https://class.imooc.com/lesson/1236#mid=29443](https://class.imooc.com/lesson/1236#mid=29443)
<a name="hL3kG"></a>
## 3.4 配置解析
<a name="V56Pt"></a>
### 3.4.1 server.xml
<a name="gfK5M"></a>
#### 3.4.1.1 基础认知
1. 是MyCat的基础配置,主要是用来配置用户名、密码、权限、schema(表)等
1. 配置完成后如同给MySQL新建用户一样
1. 客户端连接MyCat与连接MySQL没有任何差别
<a name="p0XYK"></a>
#### 3.4.1.2 系统配置模块
略
<a name="vOUly"></a>
#### 3.4.1.3 防火墙配置模块
略
<a name="ngSlp"></a>
#### 3.4.1.4 用户配置模块
```makefile
## 主要是分为三大模块配置
系统配置、防火墙配置、用户配置,前面两者暂时不了解
## 用户模块介绍
<user name="root" defaultAccount="true">
<property name="password">123456</property>
<property name="schemas">testdb</property>
<!-- 表级 DML 权限设置 -->
<privileges check="false">
<schema name="TESTDB" dml="0110" >
<table name="tb01" dml="0000"></table>
<table name="tb02" dml="1111"></table>
</schema>
</privileges>
</user>
<user name="user">
<property name="password">user</property>
<property name="schemas">testdb</property>
<property name="readOnly">true</property>
</user>
## 一个user标签就代表着一个用户权限
## <user name="root" defaultAccount="true">
## root: 连接MyCat的用户名
## defaultAccount: 是否是默认用户
## <property name="password">123456</property>
## password: 连接MyCat的密码
## <property name="schemas">testdb</property>
## schemas: 就是指数据库,配置了那些内容就说明这个用户具有访问哪些数据库的权限
## 例如: <property name="schemas">user,order,pay</property>
## 上述配置就说明该用户拥有访问user、order、pay的权限
## 这里的schemas和schemas.xml里面的配置对应
## <property name="readOnly">true</property>
## readOnly: 代表该用户拥有只读权限
3.4.2 schema.xml
3.4.2.1 基础认知
dataHost
:数据主机,配置你实际连接的数据库的信息dataNode
:数据节点,指定到具体的数据库-
3.4.2.2 dataHost
dataHost
标签的属性介绍name
:数据主机名称maxCon
:最大连接数minCon
:最小连接数balance
:它是查询请求的负载均衡类型,0
:不开启读写分离,所有的查询都落在writeHost
上1
:请求在,全部的读库和其它主库的从主库,随机分配2
:所有读操作都随机的在 writeHost、 readhost 上分发3
:开启查询的读写分离,所有的查询请求落在读库上,注意从1.4
版本开始支持
writeType
:当有多个writeHost
,写请求的负载策略0
:所有的写请求会落在第一个配置的writeHost
,当你的第一个写库挂了,请求才会落在后续的writeHost
1
:表示在所有的writeHost
上随机分配,在MyCat1.5
之后就废弃
dbType
:数据库类型,例如MySQL、MongoDB...
dbDriver
:数据库驱动
writeHost
标签属性介绍dataNode
标签属性介绍schema
标签属性介绍name
:相当于数据库的名称,这个名称相当于一个代理- 例如:命名为
user
,那真实的数据库名称可能叫user_1、user_2...
- 这里要和s
erver.xml
中用户配置的schema
对应起来
- 例如:命名为
checkSQLSchema
:说实话老师没讲太懂,暂不了解sqlMaxLimit
:指检索的时候加上一个limit
语句- 例如:设置为
100
,查询的时候只会查询100
条 - 这个是性能优化做的,例如你的分片库有很多,你全表查询的时候,组装数据太多了,限制一下
- 如果你在写
sql
的时候手动加上limit
,那么配置的limit
将不生效
- 例如:设置为
- dataNode:默认的数据库,不是所有的表都需要进行分片,那么哪些默认的表就会走这个配置
table
标签属性介绍,它就是具体的分片表信息注意:
MyCat
只是提供读写分离的作用,但是并不控制数据同步,数据同步是MySQL
自己配置的事情- 首先
MySQL
要完成主从配置,详细信息查看MySQL
笔记 - 然后
dataHost
标签的balance
属性设置为3
3.5.2 数据库常见的读写模式
1主1从:主食写库,从是读库
1主多从:主是写库、从是读库
2主多从:主库之间互为主从3.6 端口管理
MyCat有两个端口:8066是数据连接、9066是管理端口
可以使用MyCat的9066端口管理MyCat信息,例如reload @@ config
、reload @@ config_all
在不重启MyCat的情况下重新加载配置文件3.7 常用分片规则
3.7.1 分片逻辑设置
3.7.1.1 分片规则的使用
## 整个流程的分析是"按照id自动分片"来解析的
## schema.xml - schema标签 - table标签 - rule属性 - 配置已经存在的规则
<schema name="TESTDB" checkSQLschema="true" sqlMaxLimit="100">
<table name="travelrecord" dataNode="dn1,dn2" rule="auto-sharding-long"/>
</schema>
3.7.1.2 分片规则的实现
```makefileAutoPartitionByLong: 按照id自动分片的实现类
autopartition-long.txt
id: 表示按照表中那个字段进行分片
rang-long: 分片的规则,对应上面的function标签
```makefile
## 整个就是配置id如何分片的
## range start-end ,data node index;范围开始-结束=数据节点索引
## K=1000,M=10000.
0-500M=0
500M-1000M=1
1000M-1500M=2
3.7.2 枚举分片
3.7.3 取模分片
3.7.4 其它分片
3.8 常用概念
3.8.1 全局表
- 定义:在没有个数据节点都保存一份相同的表
- 常见的全局表:字典表、可预估的数据量小的表…
- 为什么这么做:关联查询效率更高
如何设置,如果不设置则默认为分片表
定义:按照分片规则,字表数据和主表数据会落在同一个分片上
- 经典的主子表案例:
order、order_item
- 为什么这么做:提高查询效率
- 如何设置
schema.xml - schema标签 - table标签 - childTable标签
childTable
标签随着业务的不断扩展,订单数据呈几何式增伤,需要对订单表进行分库分表
首先
order
表做为主表,order_item
、order_status
作为字表4.1.2 分片逻辑思考☆☆☆
首先关于这个表的对象就三个用户、卖家、平台运营,分片逻辑必须满足至少一种一个对应的查询效能。平台运营作为官方人员,不用担心用户体验,作为次要考虑对象。
4.1.2.1 order_id分片
会导致一个用户的信息随机落到所有的分片节点,对上诉三个对象全都没有效能提升
4.1.2.2 merchant_id分片
选择
merchant_id
来进行分片是方便了,卖家查询订单信息-
4.1.2.3 user_id分片
在实际操作中按照
user_id
分片还是主流操作,其实上诉三个对象,用户才是平台最最有限考虑的对象- 那么按照这种分片,一个用户的订单会全部落在同一个分片,用户的查询效率将会最高
数据倾斜问题?
电商平台一个大的卖家,每天会产生很多的订单,如果按照merchant_id
进行分库分表,那么同一个商家的所有订单会落在同一个分片库中,那么就会使有的表的数据量十分大,有些表的数据量很小
商户查询订单的解决方案?
可以基于bin-log
或者flink
等准实时的链路同步一张卖家的订单表,这个表只用来查询,不做增删改操作,后续订单新增还是需要根据user_id
来进行分库。
这个商家表只需要提供高性能的查询服务,而且没有事务问题。而且可以不使用MySQL
,更换为HBase、PolarDB、Lindorm...
用订单号查询怎么优化?
一般订单号查询,是查询固定的一个订单,这时候只需要确认订单所在的分片表,换一种说法只需要确认该订单的user_id
即可,那么可以在生成订单的时候把user_id
加进去,查询的时候解析出来,条件就变成了 where user_id = xxx and order_id = xxx;