MyCat
是一个功能强大的分布式数据库中间件,是一个实现了 MySQL
协议的 Server
,前端人员能够把它看作是一个数据库代理中间件,用 MySQL
客户端工具和命令行访问;然后端人员能够用 MySQL
原生协议与多个 MySQL
服务器通讯,也能够用 JDBC
协议与大多数主流数据库服务器通讯。能够用做 读写分离、分库分表(分片)、容灾备份、多租户应用开发、大数据基础设施,使底层数据架构具有很强的适应性和灵活性。前端
MyCat
的智能优化模块可使系统的数据访问瓶颈和热点一目了然,而且能够将这些统计分析数据自动或手工调整后端存储,将不一样的表映射到不一样存储引擎上,而整个应用的代码能够一行也不用变。node
Hbase
:用于分析大数据;本文主要实践核心功能 分库分表。mysql
指经过某种特定的条件,将存放在同一个数据库中的数据分散存放到多个数据库上面,以达到分散单台设备负载的效果。git
根据切分规则的类型能够分为如下两种切分模式。github
垂直切分:最大特色是规则简单,适合各业务之间的的耦合度很是低、相互影响小、业务逻辑很是清晰的系统。在这种系统中,能够很容易 将不一样业务模块所使用的的表切到不一样的数据库中。sql
一个数据库由不少表构成,每一个表对应着不一样的业务,垂直切分就是按照业务将表进行分类,从而分布到不一样的数据库上面,这样也就将压力分担到不一样的数据库上,如图。docker
一个架构设计好的系统其整体功能一般是由多个功能模块所组成的,而每个功能模块的数据对应到数据库中就是一个或多个表。而在架构设计中,各个功能模块相互之间的交互点越少和越统一,系统的耦合度就越低,系统各个模块的维护性以及扩展性也就越好,这样的系统也就越容易实现垂直切分。数据库
可是每每系统中有些表难以作到彻底的独立,存在跨库 join
的状况,对于这类分库,能够共用一个数据源,业务之间经过接口来调用。后端
优势:规则明确、业务清晰、更易于整合和扩展、维护简单。服务器
缺点:部分业务表没法 join
,须要经过业务接口方式解决,提升系统复杂度;各业务存在单库性能瓶颈,不易于数据扩展和性能提升;事务处理复杂问题。
因为垂直切分是将表按照业务分类切分到不一样的单库中,全部致使某些业务表过于庞大,存在单库读写与存储瓶颈,则须要水平切分来解决。
水平切分不是将表按照业务分类,而是按照某个字段的某种规则分散到多个库中,每一个表中包含一部分数据,如图。
拆分数据须要定义分片规则,拆分的第一原则是找到 拆分维度。好比:从会员的角度来分析,须要查询会员某天某月某个订单,那么就须要按照日期来拆分,不一样的数据按照会员 ID 作分组。
优势:拆分规则抽象好;不存在单库数据瓶颈问题;提升系统稳定性和负载能力。
缺点:事务一致性难以解决;数据扩展和维护的难度极大;跨库 join 性能差。
均采用 Docker Compose 搭建服务
分别建立 3 份 docker-compose.yml
文件
mysql-01
version: '3.1' services: mysql-1: image: mysql container_name: mysql-01 environment: MYSQL_ROOT_PASSWORD: 123456 command: --default-authentication-plugin=mysql_native_password --character-set-server=utf8mb4 --collation-server=utf8mb4_general_ci --explicit_defaults_for_timestamp=true --lower_case_table_names=1 ports: - 3306:3306 volumes: - ./data:/var/lib/mysql
mysql-02
version: '3.1' services: mysql-2: image: mysql container_name: mysql-02 environment: MYSQL_ROOT_PASSWORD: 123456 command: --default-authentication-plugin=mysql_native_password --character-set-server=utf8mb4 --collation-server=utf8mb4_general_ci --explicit_defaults_for_timestamp=true --lower_case_table_names=1 ports: - 3307:3306 volumes: - ./data:/var/lib/mysql
mysql-03
version: '3.1' services: mysql-3: image: mysql container_name: mysql-03 environment: MYSQL_ROOT_PASSWORD: 123456 command: --default-authentication-plugin=mysql_native_password --character-set-server=utf8mb4 --collation-server=utf8mb4_general_ci --explicit_defaults_for_timestamp=true --lower_case_table_names=1 ports: - 3308:3306 volumes: - ./data:/var/lib/mysql
分别启动 3 台容器
$ docker-compose up -d
克隆项目
$ git clone https://github.com/antoniopeng/docker.mycat.git
构建镜像
$ cd docker.mycat $ docker-compose build
启动容器
$ docker-compose up -d
此处以 水平切分 为例
$ vi config/mycat/server.xml
找到第 90 行,参考配置以下:
<mycat:server xmlns:mycat="http://io.mycat/"> <user name="root"> <property name="password">123456</property> <property name="schemas">hellomycat</property> <property name="usingDecrypt">0</property> </user> </mycat:server>
$ vi config/mycat/schema.xml
参考配置以下:
<?xml version="1.0"?> <!DOCTYPE mycat:schema SYSTEM "schema.dtd"> <mycat:schema xmlns:mycat="http://io.mycat/"> <schema name="hellomycat" checkSQLschema="true" sqlMaxLimit="100"> <table /> </schema> <dataNode name="dataNode1" dataHost="dataHost1" database="hellomycat_1" /> <dataNode name="dataNode2" dataHost="dataHost2" database="hellomycat_2" /> <dataNode name="dataNode3" dataHost="dataHost3" database="hellomycat_3" /> <dataHost name="dataHost1" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="jdbc" switchType="-1" slaveThreshold="100"> <heartbeat>select user()</heartbeat> <writeHost host="192.168.127.130" url="jdbc:mysql://192.168.127.130:3306?useSSL=false&serverTimezone=UTC&characterEncoding=utf8" user="root" password="123456"> </writeHost> </dataHost> <dataHost name="dataHost2" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="jdbc" switchType="-1" slaveThreshold="100"> <heartbeat>select user()</heartbeat> <writeHost host="192.168.127.130" url="jdbc:mysql://192.168.127.130:3307?useSSL=false&serverTimezone=UTC&characterEncoding=utf8" user="root" password="123456"> </writeHost> </dataHost> <dataHost name="dataHost3" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="jdbc" switchType="-1" slaveThreshold="100"> <heartbeat>select user()</heartbeat> <writeHost host="192.168.127.130" url="jdbc:mysql://192.168.127.130:3308?useSSL=false&serverTimezone=UTC&characterEncoding=utf8" user="root" password="123456"> </writeHost> </dataHost> </mycat:schema>
$ vi config/mycat/rule.xml
第 32 行配置
<tableRule name="auto-sharding-long"> <rule> <columns>id</columns> <algorithm>rang-long</algorithm> </rule> </tableRule>
第 105 行配置
<function name="rang-long" class="io.mycat.route.function.AutoPartitionByLong"> <property name="mapFile">autopartition-long.txt</property> </function>
$ vi config/mycat/autopartition-long.txt
配置以下:
# range start-end ,data node index # K=1000,M=10000. # ID 0-5000000 保存在 dataNode1 0-500M=0 # ID 5000000-10000000 保存在 dataNode2 500M-1000M=1 # ID 10000000-15000000 保存在 dataNode3 1000M-1500M=2
使用 MySQL 客户端工具链接 MyCat,默认端口号为 8066
。
分别在 3 个数据库中建立表,只须要 ID 一个字段便可:
create table sys_user (id int not null primary key);
新增数据:
insert into sys_user(id) values(2000000); insert into sys_user(id) values(7000000); insert into sys_user(id) values(1200000);
新增后若是 3 个数据库的表中都出现了一条数据,则说明分片成功。
- 文章做者:彭超
- 本文首发于我的博客:https://antoniopeng.com/2020/08/20/%E5%88%86%E5%B8%83%E5%BC%8F/%E5%88%86%E5%B8%83%E5%BC%8F%E6%95%B0%E6%8D%AE%E5%BA%93%E4%B8%AD%E9%97%B4%E4%BB%B6%20MyCat%20-%20%E5%88%86%E5%BA%93%E5%88%86%E8%A1%A8%E5%AE%9E%E8%B7%B5/
- 版权声明:本博客全部文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 彭超的博客 | Antonio Blog