1.安装
Mycat官网:http://www.mycat.io/
可以了解下Mycat的背景和应用情况,这样使用起来比较有信心。
Mycat下载地址:http://dl.mycat.io/
官网有个文档,属于详细的介绍,初次入门,看起来比较花时间。
下载:
建议大家选择 1.6-RELEASE 版本,毕竟是比较稳定的版本。
安装:
根据不同的系统选择不同的版本。包括linux、windows、mac,作者考虑还是非常周全的,当然,也有源码版的。
Mycat的安装其实只要解压下载的目录就可以了,非常简单。
安装完成后,目录如下:
当一张表的数据达到几千万时,你查询一次所花的时间会变多,如果有联合查询的话,我想有可能会死在那儿了。分表的目的在于,减小数据库的负担,缩短查询时间。
数据的切分(Sharding)根据其切分规则的类型,可以分为两种切分模式。一种是按照不同的表(或者Schema)来切分到不同的数据库(主机)之上,这种切可以称之为数据的垂直(纵向)切分;另外一种则是根据表中的数据的逻辑关系,将同一个表中的数据按照某种条件拆分到多台数据库(主机)上面,这种切分称之为数据的水平(横向)切分。 一个数据库由很多表的构成,每个表对应着不同的业务,垂直切分是指按照业务将表进行分类,分布到不同的数据库上面,这样也就将数据或者说压力分担到不同的库上面,如下图: 系统被切分成了,用户,订单交易,支付几个模块。 相对于垂直拆分,水平拆分不是将表做分类,而是按照某个字段的某种规则来分散到多个库之中,每个表中包含一部分数据。简单来说,我们可以将数据的水平切分理解为是按照数据行的切分,就是将表中的某些行切分到一个数据库,而另外的某些行又切分到其他的数据库中,如图:
站在巨人的肩膀上能省力很多,目前分库分表已经有一些较为成熟的开源解决方案:
Mycat是数据库中间件,就是介于数据库与应用之间,进行数据处理与交互的中间服务。由于前面讲的对数据进行分片处理之后,从原有的一个库,被切分为多个分片数据库,所有的分片数据库集群构成了整个完整的数据库存储。
既然有逻辑库,那么就会有逻辑表,分布式数据库中,对应用来说,读写数据的表就是逻辑表。逻辑表,可以是数据切分后,分布在一个或多个分片库中,也可以不做数据切分,不分片,只有一个表构成。
分片表,是指那些原有的很大数据的表,需要切分到多个数据库的表,这样,每个分片都有一部分数据,所有分片构成了完整的数据。 例如在mycat配置中的t_node就属于分片表,数据按照规则被分到dn1,dn2两个分片节点(dataNode)上。 <table name="t_node" primaryKey="vid" autoIncrement="true" dataNode="dn1,dn2" rule="rule1" />
一个数据库中并不是所有的表都很大,某些表是可以不用进行切分的,非分片是相对分片表来说的,就是那些不需要进行数据切分的表。 <table name="t_node" primaryKey="vid" autoIncrement="true" dataNode="dn1" />
关系型数据库是基于实体关系模型(Entity-Relationship Model)之上,通过其描述了真实世界中事物与关系,Mycat中的ER表即是来源于此。根据这一思路,提出了基于E-R关系的数据分片策略,子表的记录与所关联的父表记录存放在同一个数据分片上,即子表依赖于父表,通过表分组(Table Group)保证数据Join不会跨库操作。 表分组(Table Group)是解决跨分片数据join的一种很好的思路,也是数据切分规划的重要一条规则。
一个真实的业务系统中,往往存在大量的类似字典表的表,这些表基本上很少变动,字典表具有以下几个特性:
对于这类的表,在分片的情况下,当业务表因为规模而进行分片以后,业务表与这些附属的字典表之间的关联,就成了比较棘手的问题,所以Mycat中通过数据冗余来解决这类表的join,即所有的分片都有一份数据的拷贝,所有将字典表或者符合字典表特性的一些表定义为全局表。 数据冗余是解决跨分片数据join的一种很好的思路,也是数据切分规划的另外一条重要规则。
Mycat官网:http://www.mycat.io/ 可以了解下Mycat的背景和应用情况,这样使用起来比较有信心。 Mycat下载地址:http://dl.mycat.io/ 官网有个文档,属于详细的介绍,初次入门,看起来比较花时间。
建议大家选择 1.6-RELEASE 版本,毕竟是比较稳定的版本。
根据不同的系统选择不同的版本。Mycat的安装其实只要解压下载的目录就可以了,非常简单。安装完成后,目录如下:
进入bin目录,双击startup_nowrap.bat文件启动。
Mycat的配置文件都在conf目录里面,这里介绍几个常用的文件:
参考资料:https://www.cnblogs.com/fxwl/p/7990906.html
server.dtd文件中 <!ELEMENT privileges (schema)*> 说明可以有多个schema的配置。
负载均衡类型,目前的取值有3种: 1.balance=“0”, 所有读操作都发送到当前可用的writeHost上。 2.balance=“1”,所有读操作都随机的发送到readHost。 3.balance=“2”,所有读操作都随机的在writeHost、readhost上分发。
负载均衡类型,目前的取值有3种: 1.writeType=“0”, 所有写操作都发送到可用的writeHost上。 2.writeType=“1”,所有写操作都随机的发送到readHost。 3.writeType=“2”,所有写操作都随机的在writeHost、readhost分上发。
switchType指的是切换的模式,目前的取值也有4种: 1.switchType='-1' 表示不自动切换。 2.switchType='1' 默认值,表示自动切换。 3.switchType='2' 基于MySQL主从同步的状态决定是否切换,心跳语句为 show slave status。 4. switchType='3'基于MySQL galary cluster的切换机制(适合集群)(1.4.1),心跳语句为 show status like 'wsrep%'。
指定后端连接的数据库类型,目前支持二进制的mysql协议,还有其他使用JDBC连接的数据库。例如:MongoDB、Oracle、Spark等。
参考资料:https://www.cnblogs.com/756623607-zhang/p/6656022.html
配置说明: 上面columns 标识将要分片的表字段,algorithm 分片函数, 此种配置非常明确即根据id与count(你的结点数)进行求模预算,相比方式1,此种在批量插入时需要切换数据源,id不连续
配置说明: 上面columns 标识将要分片的表字段,algorithm 分片函数, 配置中配置了开始日期,分区天数,即默认从开始日期算起,分隔10天一个分区
autopartition-long.txt内容: 特别说明: 数据条数范围要和数据表节点数对应上。比如在数据库db1,db2下存在users表, 那按条数分表时节点数要和数据表节点数对应上,否则超过的数据将不会在存储。 例如1: 0-5=0 6-10=1 如果插入15条数据,只会插入前10条。 例如2: 0-5=0 6-10=1 11-20=2 配置节点数大于数据表数mycat启动就会报错。
表users和三个数据库db01,db02,db03(三个库在一个数据库实例上) 首先在MySQL上创建三个数据库:db1,db2,db3。 users只在db1,db2中存储。 DROP TABLE IF EXISTS `users`; CREATE TABLE `users` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(50) DEFAULT NULL, `indate` datetime DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
在mycat数据库中插入数据,看数据能否按照前面配置的路由规则进行分表: insert into users(id,name,indate) values(1,'kk',now()); insert into users(id,name,indate) values(2,'ss',now()); 在mycat上查看是否插入成功: 然后登录实际的数据库,看分表是否成功。下图显示分表成功: db1数据库users表 db2数据库users表
修改项目中数据库配置链接即可使用。
分库分表能有效的环节单机和单库带来的性能瓶颈和压力,突破网络IO、硬件资源、连接数的瓶颈,同时也带来了一些问题。下面将描述这些技术挑战以及对应的解决思路。 参考资料: https://blog.csdn.net/u013235478/article/details/53178657 https://www.cnblogs.com/leeSmall/p/9539370.html
在对应的分片上去查询分页数据的时候是从第一条记录开始扫描,然后再取出对应的分页数据,如 SELECT * FROM customer ORDER BY id LIMIT 1000100, 100; 这个sql语句被Mycat转化后 1 -> dn1{SELECT * FROM customer ORDER BY id LIMIT 0, 1000100} 2 -> dn2{SELECT * FROM customer ORDER BY id LIMIT 0, 1000100} 所以要在Mycat的server.xm里面开启使用非堆内存。否则内存会爆掉 <property name="useOffHeapForMerge">1</property>
mysql>select * from table limit 2; Mycat将该SQL请求分发到各个DB节点去执行,并接收各个DB节点的返回结果 DB1: [0,1] DB2: [5,6] DB3: [20,21] 但Mycat向应用返回的结果集取决于哪个DB节点最先返回结果给Mycat。如果Mycat最先收到DB1节点的结果集,那么Mycat返回给应用端的结果集为 [0,1],如果Mycat最先收到DB2节点的结果集,那么返回给应用端的结果集为 [5,6]。也就是说,相同情况下,同一个SQL,在Mycat上执行时会有不同的返回结果。 在Mycat中执行分页操作时必须显示加上排序条件才能保证结果的正确性,下面看一下Mycat对排序分页的处理逻辑。 假如在前面的分页查询中加上了排序条件(假如表数据的列名为id) mysql>select * from table order by id limit 2;
当更新内容同时分布在不同库中,不可避免会带来跨库事务问题。跨分片事务也是分布式事务,没有简单的方案,一般可使用"XA协议"和"两阶段提交"处理。 分布式事务能最大限度保证了数据库操作的原子性。但在提交事务时需要协调多个节点,推后了提交事务的时间点,延长了事务的执行时间。导致事务在访问共享资源时发生冲突或死锁的概率增高。随着数据库节点的增多,这种趋势会越来越严重,从而成为系统在数据库层面上水平扩展的枷锁。
对于那些性能要求很高,但对一致性要求不高的系统,往往不苛求系统的实时一致性,只要在允许的时间段内达到最终一致性即可,可采用事务补偿的方式。与事务在执行中发生错误后立即回滚的方式不同,事务补偿是一种事后检查补救的措施,一些常见的实现方法有:对数据进行对账检查,基于日志进行对比,定期同标准数据来源进行同步等等。事务补偿还要结合业务系统来考虑。
详见开发指南5.6 Mycat 目前存在的限制章节,P275 切分之前,系统中很多列表和详情页所需的数据可以通过sql join来完成。而切分之后,数据可能分布在不同的节点上,此时join带来的问题就比较麻烦了,考虑到性能,尽量避免使用join查询。 解决这个问题的一些方法:
全局表:也可看做是"数据字典表",就是系统中所有模块都可能依赖的一些表,为了避免跨库join查询,可以将这类表在每个数据库中都保存一份。这些数据通常很少会进行修改,所以也不担心一致性的问题。 ER分片:关系型数据库中,如果可以先确定表之间的关联关系,并将那些存在关联关系的表记录存放在同一个分片上,那么就能较好的避免跨分片join问题。 配置 以上述例子为例,schema.xml 中定义如下的分片配置:
例子: /*!mycat:catlet= io.mycat.catlets.ShareJoin */ select a.* from player a,team b
一种典型的反范式设计,利用空间换时间,为了性能而避免join查询。例如:订单表保存userId时候,也将userName冗余保存一份,这样查询订单详情时就不需要再去查询"买家user表"了。 但这种方法适用场景也有限,比较适用于依赖字段比较少的情况。而冗余字段的数据一致性也较难保证,就像上面订单表的例子,买家修改了userName后,是否需要在历史订单中同步更新呢?这也要结合实际业务场景进行考虑。
在系统层面,分两次查询,第一次查询的结果集中找出关联数据id,然后根据id发起第二次请求得到关联数据。最后将获得到的数据进行字段拼装。
1)某些SQL语法,如insert into......select..... 2)跨库关联查询 3存储过程创建 4存储过程调用
/*!mycat:sql=Mycat注解SQL语句*/真正执行的SQL!号方式 /*#mycat:sql=Mycat注解SQL语句*/真正执行的SQL#号方式 /**mycat:sql=Mycat注解SQL语句*/真正执行的SQL*号方式
注解SQL使用select语句,不允许使用delete/update/insert等语句;虽然delete/update/insert等语句也能用在注解中,但这些语句在Sql处理中有额外的逻辑判断,从性能考虑,请使用select语句。 注解SQL禁用表关联语句。 无论是原始SQL 还是注解SQL,禁止DDL语句 能不用注解的尽量不用
/*!mycat: sql=解析用的Sql*/真正执行Sql /*!mycat: sql=select * from base_user where id_=1;*/ CALL proc_test(); /*!mycat:sql=select 1 from test */create procedure 'test_proc()' begin end; /*!mycat:catlet=demo.catlets.ShareJoin / select bu.,sg.* from base_user bu,sam_glucose sg where bu.id_=sg.user_id /*!mycat: sql=select 1 from test */insert into t_user(id,name) select id,name from t_user2; /*!mycat:sql=select 1 from test */create table test2(id int); 分片聚合的SQL也可以注解 /*!mycat: sql=select a,count(a) from test group by a limit 100 */xxxxxxxxxxxxx
https://issues.apache.org/jira/secure/attachment/12436620/ZooInspector.zip
下载解压后,进入目录ZooInspector\build,运行zookeeper-dev-ZooInspector.jar java -jar zookeeper-dev-ZooInspector.jar //执行成功后,会弹出java ui client
进入mycat/conf/myid.properties目录,修改以下信息 loadZk=true # zk集群地址,多个用","隔开 zkURL=127.0.0.1:2181 # zk集群内Mycat集群ID clusterId=mycat-cluster-1 # Mycat集群内本实例ID,禁止重复 myid=mycat_fz_01 # Mycat集群内节点个数 clusterSize=3 clusterNodes=mycat_fz_01,mycat_fz_02,mycat_fz_03 #server booster ; booster install on db same server,will reset all minCon to 1 type=server boosterDataHosts=dataHost1
boosterDataHosts说明: boosterDataHosts 代表本 mycat booster 节点负责哪些 dataHost 的迁移工作,支持多个DataHost,以英文 逗号,分隔,迁移任务所需的 dataHost 需要在此写清楚,并且与schema.xml(即 zookeeper 中的 schema)中的 298 dataNode节点中的DataHost 属性对应如果迁移用到 dataHost 不在 boosterDataHosts 里,涉及的 dataHost 将不会运行迁移任务。
连接成功后,可看到mycat集群的配置信息。
| |||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
参考资料:https://www.jianshu.com/p/2d1a81b2dafc
参考资料:https://yq.aliyun.com/articles/619968
读写分离:https://blog.csdn.net/wt077521/article/details/80469015
与springboot整合:https://www.jianshu.com/p/f81422b1c915
https://www.cnblogs.com/sanshengshui/p/9702904.html
mycat集群:http://www.cnblogs.com/atomicbomb/p/7233402.html
servce.xml详解:https://www.cnblogs.com/li3807/p/8461814.html
配置文件详解:https://www.cnblogs.com/fxwl/p/7990906.html
zookeeper集群mycat:https://blog.csdn.net/ygqygq2/article/details/78292828
存在问题:https://blog.csdn.net/u013235478/article/details/53178657
分库分表思路:https://www.cnblogs.com/butterfly100/p/9034281.html
MyCat详细介绍:https://www.cnblogs.com/leeSmall/p/9539370.html
Mysql系列八:Mycat和Sharding-jdbc的区别、Mycat分片join、Mycat分页中的坑、Mycat注解、Catlet使用
https://www.cnblogs.com/leeSmall/p/9539370.html