MyCat:开源分布式数据库中间件

摘要:MyCat截至到2015年4月,保守估计已经有超过60个项目在使用,主要应用在电信领域、互联网项目,大部分是交易和管理系统,少量是信息系统。比较大的系统中,数据规模单表单月30亿。本文带你全面了解MyCat。 为什么需要MyCat? 虽然云计算时代,传统数据库存在着先天性的弊端,但是NoSQL数据库又无法将其替代。如果传统数据易于扩展,可切分,就可以避免单机(单库)的性能缺陷。 MyCat的目标就是:低成本地将现有的单机数据库和应用平滑迁移到“云”端,解决数据存储和业务规模迅速增长情况下的数据瓶颈问题。2014年MyCat首次在上海的《中华架构师》大会上对外宣讲引发围观,更多的人参与进来,随后越来越多的项目采用了MyCat。 MyCat截至到2015年4月,保守估计已经有超过60个项目在使用,主要应用在电信领域、互联网项目,大部分是交易和管理系统,少量是信息系统。比较大的系统中,数据规模单表单月30亿。 MyCat是什么? 从定义和分类来看,它是一个开源的分布式数据库系统,是一个实现了MySQL协议的服务器,前端用户可以把它看作是一个数据库代理,用MySQL客户端工具和命令行访问,而其后端可以用MySQL原生协议与多个MySQL服务器通信,也可以用JDBC协议与大多数主流数据库服务器通信,其核心功能是分表分库,即将一个大表水平分割为N个小表,存储在后端MySQL服务器里或者其他数据库里。 MyCat发展到目前的版本,已经不是一个单纯的MySQL代理了,它的后端可以支持MySQL、SQL Server、Oracle、DB2、PostgreSQL等主流数据库,也支持MongoDB这种新型NoSQL方式的存储,未来还会支持更多类型的存储。而在最终用户看来,无论是那种存储方式,在MyCat里,都是一个传统的数据库表,支持标准的SQL语句进行数据的操作,这样一来,对前端业务系统来说,可以大幅降低开发难度,提升开发速度 图1 MyCat架构设计图 MyCat解决了哪些问题 1. 连接过多问题,可以通过MyCat统一管理所有的数据源,后端数据库集群对前端应用程序透明。使用MyCat之前系统结构如图2。 图2  MyCat早前系统架构 MyCat引入连接复用解决多应用竞争问题,通过MyCat改造后,如图3所示。 图3  改造后的MyCat 2. 独创的ER关系分片,解决E-R分片难处理问题,存在关联关系的父子表在数据插入的过程中,子表会被MyCat路由到其相关父表记录的节点上,从而父子表的Join查询可以下推到各个数据库节点上完成,这是最高效的跨节点Join处理技术,也是MyCat首创。 图4  独创的ER关系分片,是MyCat首创 3. 采用全局分片技术,每个节点同时并发插入和更新数据,每个节点都可以读取数据,提升读性能的同时,也解决跨节点Join的效率。 图5 采用全局分片技术 4. 通过人工智能的catlet支持跨分片复杂SQL实现以及存储过程支持等。使用方式主要通过MyCat注释的方式来执行,如下: (1)跨分片联合查询注解支持:…

Continue ReadingMyCat:开源分布式数据库中间件

Mycat高级进阶—Mycat注解

注解原理 概念: MyCat对自身不支持的Sql语句提供了一种解决方案——在要执行的SQL语句前添加额外的一段由注解SQL组织的代码,这样Sql就能正确执行,这段代码称之为“注解”。注解的使用相当于对mycat不支持的sql语句做了一层透明代理转发,直接交给目标的数据节点进行sql语句执行,其中注解SQL用于确定最终执行SQL的数据节点。注解的形式是: /*!mycat: sql=注解Sql语句*/ 1 注解的使用方式是: /*!mycat: sql=注解Sql语句*/真正执行Sql 1 使用时将=号后的“注解Sql语句”替换为需要的Sql语句即可,后面会提到具体的用法。 原理: MyCat执行SQL语句的流程是先进行SQL解析处理,解析出分片信息(路由信息)后,然后到该分片对应的物理库上去执行;若传入的SQL语句MyCat无法解析,则MyCat不会去执行;而注解则是告诉MyCat按照注解内的SQL(称之为注解SQL)去进行解析处理,解析出分片信息后,将注解后真正要执行的SQL语句(称之为原始SQL)发送到该分片对应的物理库上去执行。 从上面的原理可以看到,注解只是告诉MyCat到何处去执行原始SQL;因而使用注解前,要清楚的知道该原始SQL去哪个分片执行,然后在注解SQL中也指向该分片,这样才能使用!例子中的sharding_id=10010 即是指明分片信息的。 需要说明的是,若注解SQL没有能明确到具体某个分片,譬如例子中的注解SQL没有添加sharding_id=10010这个条件,则MyCat会将原始SQL发送到persons表所在的所有分片上去执行去,这样造成的后果若是插入语句,则在多个分片上都存在重复记录,同样查询、更新、删除操作也会得到错误的结果! 解决问题: MySql不支持的语法结构,如insert …select… 同一个实例内的跨库关联查询,如用户库和平台库内的表关联 存储过程调用。 表,存储过程创建。 注解规范 注解SQL使用select语句,不允许使用delete/update/insert等语句;虽然delete/update/insert 等语句也能用在注解中,但这些语句在Sql处理中有额外的逻辑判断,从性能考虑,请使用select语句 注解SQL禁用表关联语句 注解SQL尽量用最简单的SQL语句,如select id from tab_a…

Continue ReadingMycat高级进阶—Mycat注解

MyCat1.6带返回参数存储过程调用示例

本例环境:SpringMVC3.x + Mybatis3.x + Mycat1.6 + Mysql5.6 1、创建带出参存储过程 [sql] view plain copy DELIMITER && CREATE  PROCEDURE `test_proc`( in a_id int , out a_goods_id int) BEGIN               SELECT  a.goods_id  INTO  a_goods_id               FROM  es_goods_community a               WHERE  a.id=a_id ; END && DELIMITER ; 备注:这里的存储过程比较简单,就是根据一个表的ID,返回一个表的另外一个字段,本例中a_goods_id为出参。 2、mybatis映射文件 [html] view plain copy <select id="testCallProc" resultType="java.lang.Integer">  <!-- statementType="CALLABLE" -->          <![CDATA[        /*!mycat:sql=select 1 from es_goods_community where seller_id=26*/{call test_proc(               #{id,mode=IN,jdbcType=INTEGER},               @goodsId            )};select @goodsId;        ]]>     </select>…

Continue ReadingMyCat1.6带返回参数存储过程调用示例

MyCat不支持的SQL语句

已知的MyCat不支持的SQL语句类型如下(不完全统计,后续会更新):   SELECT: Ø 跨分片(实体库)的交叉查询 Ø 跨节点的联合查询 (如用户库的表和平台库的表做联合查询) INSERT: Ø 插入的字段不包含分片字段 (如插入tbl_user_base_info表,没有提供user_id列) Ø 插入的分片字段找不到对应分片 Ø 复制插入Insert into…select… Ø 多行插入 insert into tab_a(c1,c2) values(v1,v2),(v11,v21)… UPDATE: Ø 更新的列包含分片列 Ø 多表更新 update a, b set a.nation=’China’, b.pwd=’123456’ where a.id=b.id Ø 复杂更新 update a, b set a.nation=’China’ where a.id=b.id;  但支持子查询方式 update a set a.nation=’China’ where id in (select id from b); DELETE: Ø 复杂删除 delete a from a join b on a.id=b.id;  支持子查询方式 delete from a where a.id in (select id from b), 但表不能起别名 其它: Ø Call procedure()   MyCat未支持存储过程定义, 因而不允许调用存储过程,但可通过注解来调用各个分片上的存储过程 Ø Select func(); 不支持这种方式直接调用自定义函数, 但支持 select id, func() from employee 只需employee所在的所有分片上存在这个函数。MySql自带函数可随意使用。     注意事项: Ø Order by字段必须出现在select中(MyCat先将结果取出,然后排序) Ø Group by务必使用标准语法 select count(1),type from tab_a group by type; Ø MyCat的一些自带函数 sum,min,max等可以正确使用,但多分片执行的avg有bug,执行的结果是错误的 Ø 谨慎使用子查询,外层查询没有分片查询条件, 则会在所有分片上执行(子查询内外层的表一样较为特殊)

Continue ReadingMyCat不支持的SQL语句

vue-cli怎么根据后端接口服务器不同 build不同接口代码?

琢磨了几天vue-cli生成的代码,vue觉得你只需要三种配置:开发(npm run dev)、生产(npm run build)和单元测试(npm run test)。。。 吐槽完。 1.打开config/index.js,修改build里面的env文件名为根据环境变量获取, 修改完大概是下面这样子: module.exports = { build: { env: require('./'+(process.env.VUE_CONFIG||'prod')+'.env'), //...... 2.在config目录里面把prod.env.js复制两份,分别是uat.env.js、testing.env.js 3.修改dev.env.js、uat.env.js、testing.env.js、prod.env.js这四个文件,在大括号里面添加API: '"/api或uat或其他什么"',如下: module.exports = { NODE_ENV: '"production"', API: '"/api"' } 4.然后就可以在任何地方通过process.env.API访问到这个变量了。…

Continue Readingvue-cli怎么根据后端接口服务器不同 build不同接口代码?

chpasswd -e

对系统定期修改密码是一个很重要的安全常识,通常,我们修改用户密码都使用 passwd user 这样的命令来修改密码,但是这样会进入交互模式,即使使用脚本也不能很方便的批量修改,除非使用expect 这样的软件来实现,难道修改一下密码还需要单独安装一个软件包吗? 不,我们其实还有其他很多方法可以让我们避开交互的,下面具体写一下具体的实现方式: 第一种: echo "123456" | passwd --stdin root 优点:方便快捷 缺点:如果你输入的指令能被别人通过history或者其他方式捕获,那么这样的方式是很不安全的,更重要的是如果密码同时含有单引号和双引号,那么则无法通过这种方法修改。 说明: 批量修改linux密码 passwd --stdin user 从标准输入中读取密码,所以用户可以在脚本中使用如 echo NewPasswd | passwd --stdin username 这种方式来批量更改密码 但在其它的一些发行版(如Debian/Suse)所提供的passwd并不支持--stdin这个参数 第二种:…

Continue Readingchpasswd -e

pinpoint 安装部署

阅读目录 1. 环境配置     1.1 获取需要的依赖包     1.2 配置jdk1.7 2. 安装Hbase     2.1 解压Hbase     2.2 修改Hbase的配置     2.3 启动Hbase 3. 安装pinpoint-collector     3.1 部署war包     3.2 配置快速启动 4. 安装pinpoint-web…

Continue Readingpinpoint 安装部署

[转]用linux下常用命令wget进行整站下载(递归下载至本地)

这个命令可以以递归的方式下载整站,并可以将下载的页面中的链接转换为本地链接。 wget加上参数之后,即可成为相当强大的下载工具。 wget -r -p -np -k http://xxx.com/abc/ -r, –recursive(递归) specify recursive download.(指定递归下载) -k, –convert-links(转换链接) make links in downloaded HTML point to local files.(将下载的HTML页面中的链接转换为相对链接即本地链接) -p, –page-requisites(页面必需元素) get all images, etc. needed…

Continue Reading[转]用linux下常用命令wget进行整站下载(递归下载至本地)

Linux wget命令整站下载做网站镜像

在linux下完整的用wget命令整站采集网站做镜像 的命令是: wget -m -e robots=off -U "Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6" "http://www.example.com/" wget命令 参数注释: "-e robots=off"  让wget耍流氓无视robots.txt协议 -U "Mozilla/5.0 (Windows; U; Windows NT 5.1;…

Continue ReadingLinux wget命令整站下载做网站镜像

wget进行整站下载(递归下载至本地)

这个命令可以以递归的方式下载整站,并可以将下载的页面中的链接转换为本地链接。 wget加上参数之后,即可成为相当强大的下载工具。 wget -r -p -np -k /var/lcoal/  http://xxx.com/abc/ -r,  --recursive(递归)          specify recursive download.(指定递归下载) -k,  --convert-links(转换链接)      make links in downloaded HTML point to local files.(将下载的HTML页面中的链接转换为相对链接即本地链接) -p,  --page-requisites(页面必需元素)    get all images, etc. needed…

Continue Readingwget进行整站下载(递归下载至本地)