Mycat 高可用
目前Mycat 没有实现对多Mycat 集群的支持,可以暂时使用HAProxy 来做负载
思路:HAProxy 对Mycat 进行负载。Keepalived 实现VIP。
Mycat 注解
注解的作用
当关联的数据不在同一个节点的时候,Mycat 是无法实现跨库join 的。
举例:
如果直接在150 插入主表数据,151 插入明细表数据,此时关联查询无法查询出来。
-- 150 节点插入
INSERT INTO `order_info` (`order_id`, `uid`, `nums`, `state`, `create_time`, `update_time`) VALUES (9, 1000003, 3, 1,
'2019-9-25 11:35:49', '2019-9-25 11:35:49');
-- 151 节点插入
INSERT INTO `order_detail` (`order_id`, `id`, `goods_id`, `price`, `is_pay`, `is_ship`, `status`) VALUES (9, 20180001,
85114752, 19.99, 1, 1, 1);
在mycat 数据库查询,直接查询没有结果。
select a.order_id,b.goods_id from order_info a, order_detail b where a.order_id = b.order_id;
Mycat 作为一个中间件,有很多自身不支持的SQL 语句,比如存储过程,但是这些语句在实际的数据库节点上是可以执行的。有没有办法让Mycat 做一层透明的代理转发,直接找到目标数据节点去执行这些SQL 语句呢?
那我们必须要有一种方式告诉Mycat 应该在哪个节点上执行。这个就是Mycat 的注解。我们在需要执行的SQL 语句前面加上一段代码,帮助Mycat 找到我们的目标节点。
注解的用法
注解的形式是:
/!mycat: sql=注解SQL 语句/
注解的使用方式是:
/!mycat: sql=注解SQL 语句/ 真正执行的SQL
使用时将= 号后的"注解SQL 语句" 替换为需要的SQL 语句即可。
使用注解有一些限制,或者注意的地方:
select
如果需要确定分片,则使用能确定分片的注解,比如
/!mycat: sql=select * from users where user_id=1/
如果要在所有分片上执行则可以不加能确定分片的条件
insert
使用insert 的表作为注解SQL,必须能确定到某个分片原始SQL 插入的字段必须包括分片字段非分片表(只在某个节点上):必须能确定到某个分片
delete 使用delete 的表作为注解SQL
update 使用update 的表作为注解SQL
使用注解并不额外增加MyCat 的执行时间;从解析复杂度以及性能考虑,注解SQL 应尽量简单,因为它只是用来做路由的。
注解可以帮我们解决什么问题呢?
注解使用示例
创建表或存储过程
customer.id=1 全部路由到146
-- 存储过程
/*!mycat: sql=select * from customer where id =1 */ CREATE PROCEDURE test_proc() BEGIN END ;
-- 表
/*!mycat: sql=select * from customer where id =1 */ CREATE TABLE test2(id INT);
特殊语句自定义分片
Mycat 本身不支持insert select,通过注解支持
/*!mycat: sql=select * from customer where id =1 */ INSERT INTO test2(id) SELECT id FROM order_detail;
多表ShareJoin
/*!mycat:catlet=io.mycat.catlets.ShareJoin */
select a.order_id,b.goods_id from order_info a, order_detail b where a.order_id = b.order_id;
读写分离
读写分离: 配置Mycat 读写分离后,默认查询都会从读节点获取数据,但是有些场景需要获取实时数据,如果从读节点获取数据可能因延时而无法实现实时,Mycat 支持通过注解/balance/ 来强制从写节点(write host)查询数据。
/*balance*/ select a.* from customer a where a.id=6666;
读写分离数据库选择(1.6 版本之后)
/*!mycat: db_type=master */ select * from customer;
/*!mycat: db_type=slave */ select * from customer;
/*#mycat: db_type=master */ select * from customer;
/*#mycat: db_type=slave */ select * from customer;
注解支持的'! '不被mysql 单库兼容
注解支持的'#'不被MyBatis 兼容
随着Mycat 的开发,更多的新功能正在加入。
注解原理
Mycat 在执行SQL 之前会先解析SQL 语句,在获得分片信息后再到对应的物理节点上执行。如果SQL 语句无法解析,则不能被执行。如果语句中有注解,则会先解析注解的内容获得分片信息,再把真正需要执行的SQL 语句发送对对应的物理节点上。
所以我们在使用主机的时候,应该清楚地知道目标SQL 应该在哪个节点上执行,注解的SQL 也指向这个分片,这样才能使用。如果注解没有使用正确的条件,会导致原始SQL 被发送到所有的节点上执行,造成数据错误。
分片策略详解
Mycat 权威指南.pdf Page 116
分片的目标是将大量数据和访问请求均匀分布在多个节点上,通过这种方式提升数
据服务的存储和负载能力。
Mycat 分片策略详解
总体上分为连续分片和离散分片,还有一种是连续分片和离散分片的结合,例如先范围后取模。
image.png
比如范围分片(id 或者时间)就是典型的连续分片,单个分区的数量和边界是确定的。离散分片的分区总数量和边界是确定的&#