引言

先给大家介绍2个概念:数据的切分(Sharding)根据其切分规则的类型,可以分为两种切分模式。

切分模式

一种是按照不同的表(或者Schema)来切分到不同的数据库(主机)之上,这种切可以称之为数据的垂直(纵向)切分;另外一种则是根据表中的数据的逻辑关系,将同一个表中的数据按照某种条件拆分到多台数据库(主机)上面,这种切分称之为数据的水平(横向)切分

垂直切分的最大特点就是规则简单,实施也更为方便,尤其适合各业务之间的耦合度非常低,相互影响很小,业务逻辑非常清晰的系统。在这种系统中,可以很容易做到将不同业务模块所使用的表分拆到不同的数据库中。根据不同的表来进行拆分,对应用程序的影响也更小,拆分规则也会比较简单清晰。

水平切分于垂直切分相比,相对来说稍微复杂一些。因为要将同一个表中的不同数据拆分到不同的数据库中,对于应用程序来说,拆分规则本身就较根据表名来拆分更为复杂,后期的数据维护也会更为复杂一些。

为什么用MyCat

不管怎么来说,数据切分虽然分散了单台服务器负载,但是带来了是设计和开发的复杂度。MyCat是一个开源的分布式数据库中间件,实现了MySQL协议的服务器,前端用户可以把它看作是一个数据库代理,用MySQL客户端工具和命令行访问,而其后端可以用MySQL原生协议与多个MySQL服务器通信,在MyCat里,我们面向的是一个传统的数据库表,支持标准的SQL语句进行数据的操作,这样一来,对前端业务系统来说,可以大幅降低开发难度,提升开发速度。

分库分表实践

基本环境

操作系统:CentOS / 7.1 (64bit)

JDK:1.8

MySQL:5.7

MyCat:1.6

业务目标

比如说我们现在有个实际的业务上设计需求,要将student和grade表进行垂直划分,分别存储不同的database中;还需要将student水平拆分,也要3个不同database存分别储。如下图所示,MyCat可以帮助实现这4个database的管理,而对于终端用户来说,就像只操作student和grade两张表,保证了中间件分库分页对程序员的透明性。

创建实际数据库

首先,我们肯定需要创建4个database:beijing、shanghai、guangzhou、basic,并生成对应的表。可以看出,student和grade表存在于不同的数据库,而且student表中的数据,分散存储在3个不同的数据库中:

  1. create database beijing;
  2. use beijing;
  3. create table student(
  4. id int primary key,
  5. name varchar(8) not null,
  6. grade int not null
  7. );
  8. create database shanghai;
  9. use shanghai;
  10. create table student(
  11. id int primary key,
  12. name varchar(8) not null,
  13. grade int not null
  14. );
  15. create database guangzhou;
  16. use guangzhou;
  17. create table student(
  18. id int primary key,
  19. name varchar(8) not null,
  20. grade int not null
  21. );
  22. create database basic;
  23. use basic;
  24. create table grade(
  25. id int primary key,
  26. name varchar(8) not null
  27. );

安装配置MyCat

比较简单,下载Mycat-1.6-RELEASE,直接解压缩即可。

为了方便,将/mycat/bin目录添加到环境变量:

/etc/profile文件后增加设置export PATH=/data/mycat/bin:$PATH

让profile立即生效:

# source /etc/profile

配置server

编辑\mycat\conf\server.xml:

  1. <user name="test">
  2. <property name="password">test</property>
  3. <property name="schemas">TESTDB</property>
  4. </user>

这里MyCat会帮助我们生成一个虚拟的逻辑database,我们命名为TESTDB,并设置可以访问的用户名和密码,默认访问的端口号8066,其实MyCat还会提供一个管理端口:9066,方便我们对MyCat管理和监测,这个我们以后有机会再说。

配置schema

编辑\mycat\conf\schema.xml:

  1. <mycat:schema xmlns:mycat="http://io.mycat/">
  2. <schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100">
  3. <!-- 取模分片 -->
  4. <table name="student" primaryKey="id" dataNode="dn1,dn2,dn3" rule="mod-long" />
  5. <table name="grade" primaryKey="id" dataNode="dn4"/>
  6. </schema>
  7. <!-- 申明节点对应的database -->
  8. <dataNode name="dn1" dataHost="localhost1" database="beijing" />
  9. <dataNode name="dn2" dataHost="localhost1" database="shanghai" />
  10. <dataNode name="dn3" dataHost="localhost1" database="guangzhou" />
  11. <dataNode name="dn4" dataHost="localhost1" database="basic" />
  12. <dataHost name="localhost1" maxCon="1000" minCon="10" balance="0"
  13. writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
  14. <heartbeat>select user()</heartbeat>
  15. <!-- 可读写的数据库实例 -->
  16. <writeHost host="hostM1" url="localhost:3306" user="root" password="******">
  17. </writeHost>
  18. </dataHost>
  19. </mycat:schema>

schema是比较重要的一块配置,主要维护了虚拟库与实际库的映射关系:

可以看到,虚拟的逻辑库TESTDB中维护了2张表student和grade;

grade对应存储在实际的数据库节点dn4,也就是basic;

而student被拆分为存储在3个实际的数据库节点,分别是beijing、shanghai、guangzhou,分片的算法取模,根据取模映射到不同的节点;

最后,我们将实际的访问地址、访问权限配置完成,当然,这里还可以配置主从/读写分离配置,这块不是本文讨论的重点,我们以后单独说。

启动MyCat

这时候,我们敲入命令:# mycat start ,正常的话可以启动MyCat,输入# mycat status,可以查看是否运行正常,如果运行停止,证明启动有误,可以进入控制台启动,# mycat console,进行调试。(有可能报内存错误,一般是由于配置java虚拟机的默认大小的问题,我们可以根据命令行的提示,去wrapper.conf中修改)

MyCat插入和查询

MyCat启动后,我们就可以连接MyCat帮我们生成的逻辑库了:

# mysql -utest -ptest -h127.0.0.1 -P8066 -DTESTDB



接下来,我们在逻辑库中插入一下数据验证一下:

  1. insert into grade (id,name) values (1,'一年级');
  2. insert into grade (id,name) values (2,'二年级');
  3. insert into grade (id,name) values (3,'三年级');
  4. insert into student (id,name,grade) values (1,'张三',2);
  5. insert into student (id,name,grade) values (2,'李四',1);
  6. insert into student (id,name,grade) values (3,'王五',3);
  7. insert into student (id,name,grade) values (4,'甲',3);
  8. insert into student (id,name,grade) values (5,'乙',2);
  9. insert into student (id,name,grade) values (6,'丙',1);

我们插入了6条student记录,这时应该根据不同的取模结果,存在不同的实际数据库的student表中,所以我们切换到实际数据库:# mysql -uroot -ppassword

分别查看实际数据库:



再看此时的逻辑数据库:



逻辑数据库,查询grade和student两张表,已经数据聚合,还可以进行排序;



如果我们需要将2张表进行关联,也是可以的:

/*!mycat:catlet=io.mycat.catlets.ShareJoin */select * from student s,grade g on s.grade=g.id where g.name='一年级';

附录

附:个人研究整理和总结(查看原图或者打开原地址链接)

MyCat | 分库分表实践的更多相关文章

  1. 分布式数据库中间件 MyCat | 分库分表实践

    MyCat 简介 MyCat 是一个功能强大的分布式数据库中间件,是一个实现了 MySQL 协议的 Server,前端人员可以把它看做是一个数据库代理中间件,用 MySQL 客户端工具和命令行访问:而 ...

  2. MySQL+MyCat分库分表 读写分离配置

    一. MySQL+MyCat分库分表 1 MyCat简介 java编写的数据库中间件 Mycat运行环境需要JDK. Mycat是中间件.运行在代码应用和MySQL数据库之间的应用. 前身 : cor ...

  3. 《MyCat分库分表策略详解》

    在我们的项目发展到一定阶段之后,随着数据量的增大,分库分表就变成了一件非常自然的事情.常见的分库分表方式有两种:客户端模式和服务器模式,这两种的典型代表有sharding-jdbc和MyCat.所谓的 ...

  4. MariaDB Spider 数据库分库分表实践

    分库分表 一般来说,数据库分库分表,有以下做法: 按哈希分片:根据一条数据的标识计算哈希值,将其分配到特定的数据库引擎中: 按范围分片:根据一条数据的标识(一般是值),将其分配到特定的数据库引擎中: ...

  5. 3.Mysql集群------Mycat分库分表

    前言: 分库分表,在本节里是水平切分,就是多个数据库里包含的表是一模一样的. 只是把字段散列的分到不同的库中. 实践: 1.修改schema.xml 这里是在同一台服务器上建立了4个数据库db1,db ...

  6. mycat 分库分表

    单库分表已经在上篇写过了,这次写个分库分表,不同在于配置文件上的一点点不同 <!DOCTYPE mycat:schema SYSTEM "schema.dtd"> &l ...

  7. MyCat分库分表入门

    1.分区 对业务透明,分区只不过把存放数据的文件分成了许多小块,例如mysql中的一张表对应三个文件.MYD,MYI,frm. 根据一定的规则把数据文件(MYD)和索引文件(MYI)进行了分割,分区后 ...

  8. 分库分表实践-Sharding-JDBC

    最近一段时间在研究分库分表的一些问题,正好周末有点时间就简单做下总结,也方便自己以后查看. 关于为什么要做分库分表,什么是水平分表,垂直分表等概念,相信大家都知道,这里就不在赘述了. 本文只讲述使用S ...

  9. Mycat分库分表(一)

    随着业务变得越来越复杂,用户越来越多,集中式的架构性能会出现巨大的问题,比如系统会越来越慢,而且时不时会宕机,所以必须要解决高性能和可用性的问题.这个时候数据库的优化就显得尤为重要,在说优化方案前,先 ...

随机推荐

  1. Java打包商用化软件

    这是我在博客中写的第一篇文章.还请各位大神们多多指教!我会详细讲解如何将我们由java的swing以及awt组件编写出的java可视化窗口程序编制成一个我们能够让用户使用的,商业化,可安装的软件.网上 ...

  2. 微信小程序setData()方法的详解以及对数组/json操作

    此篇文章是本人对setData方法的一些理解,是查阅文档和查找一些其他资料综述的,有所不足希望指正! 直接进入正题! 一.setData()方法: 1.参数接受一个对象,以key,value的形式表示 ...

  3. [Swift]LeetCode400. 第N个数字 | Nth Digit

    Find the nth digit of the infinite integer sequence 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, ... Note:n is ...

  4. [Swift]LeetCode494. 目标和 | Target Sum

    You are given a list of non-negative integers, a1, a2, ..., an, and a target, S. Now you have 2 symb ...

  5. [Swift]LeetCode845. 数组中的最长山脉 | Longest Mountain in Array

    Let's call any (contiguous) subarray B (of A) a mountain if the following properties hold: B.length ...

  6. [Swift]LeetCode849. 到最近的人的最大距离 | Maximize Distance to Closest Person

    In a row of seats, 1 represents a person sitting in that seat, and 0 represents that the seat is emp ...

  7. TCP/IP 详解常用术语

    业务需要,最近看TCP/IP 这本书,专业名词太多了,总结一下,给后来着参考,直接使用. 后续会在读书时慢慢添加. ACK:(ACKnowledgment)TCP首部中的确认标志. ARP:地址解析协 ...

  8. 客户端通过Feign发起请求 服务端通过request取 json对象

    @RestController @RequestMapping(value = "test") public class TestServer { @RequestMapping( ...

  9. 网络协议 5 - ICMP 与 ping:投石问路的侦察兵

        日常开发中,我们经常会碰到查询网络是否畅通以及域名对应 IP 地址等小需求,这时候用的最多的应该就是 ping 命令了. 那你知道 ping 命令是怎么工作的吗?今天,我们就来一起认识下 pi ...

  10. EF实现批量插入

    Z.EntityFramework.BulkInsert EntityFramework 最被人诟病的地方就是它的性能,处理大量数据时的效率.此种条件下,通常会转回使用 ADO.NET 来完成任务.而 ...