wget http://dl.mycat.org.cn/1.6-RELEASE/Mycat-server-1.6-RELEASE-20161028204710-linux.tar.gz (包地址)
一、概念
将存放在一台数据库服务器中的数据,按照特定方式进行拆分,分散存放到多台数据库服务器中,以达到分散单台服务器负载的效果
二、分割方式
(1)水平分割。按照表中指定字段的分片规则,将表记录按行切分分散存储到多个数据库中。(拆分一个表中的数据,可以分散存储在多个表中)
(2)垂直分割。将单个数据库的多个表按业务类型分类,分散存储到不同的数据库。(拆分一个库中的表,分散到多个服务器或者数据库中)
三、软件介绍
适合大量写入的场景
可以提供读写分离
可以提供分片
四、分片规则
枚举法sharding-by-intfile 固定分片rule1 范围约定auto-sharding-long 求模法mod-long 日期列分区法sharding-by-date 通配取模sharding-by-pattern ASCII码求模通配sharding-by-prefixpattern 编程指定sharding-by-substring 字符串拆分hash解析sharding-by-stringhash 一致性hash sharding-by-murmur
五、工作过程
当mycat收到一个SQL命令时
(1)解析SQL命令涉及到的表
(2)然后看对表的配置,如果有分片规则,则获取SQL命令里分片字段的值,并匹配分片函数,获得分片列表
(3)然后将SQL命令发往对应的分片服务器去执行
(4)最后收集和处理所有分片结果数据,并返回到客户端
六、配置文件
(1)*.xml 文件是配置文件
(2)*.txt ,*.propertits 文件是规则配置文件
server.xml //设置连接账号及逻辑库 schema.xml //配置数据分片 rule.xml //分片规则 其他文件 //函数调用文件
七、修改配置文件
(一)定义连接用户和逻辑库(客户端访问的用户和逻辑库)
vim /usr/local/mycat/conf/server.xml <user name="root"> //连接mycat服务时使用的用户名(用户名可以不用root,可以自定义) <property name="password">123456</property> #用户连接mycat用户时使用的密码 <property name="schemas">TESTDB</property> #逻辑库名 </user> <user name="user"> <property name="password">user</property> <property name="schemas">TESTDB</property> <property name="readOnly">true</property> #只读权限,连接mycat服务后只有读记录的权限,不写这一行则是可读可写 </user>
(二)数据分片配置(再删除16~18,39~42,56~77行之后,以防万一可以先把schema.xml文件备份一下)
[root@mycat56 conf]# vim /usr/local/mycat/conf/schema.xml <?xml version="1.0"?> <!DOCTYPE mycat:schema SYSTEM "schema.dtd"> <mycat:schema xmlns:mycat="http://io.mycat/"> <schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100">//对TESTDB库下的表做分片存储 <!-- auto sharding by id (long) --> <table name="travelrecord" dataNode="dn1,dn2,dn3" rule="auto-sharding-long" /> //对travelrecord表做分片存储 <!-- global table is auto cloned to all defined data nodes ,so can join with any table whose sharding node is in the same data node --> <table name="company" primaryKey="ID" type="global" dataNode="dn1,dn2,dn3" /> //对company表做分片存储 <table name="goods" primaryKey="ID" type="global" dataNode="dn1,dn2,dn3" /> <!-- random sharding using mod sharind rule --> <table name="hotnews" dataNode="dn1,dn2,dn3" rule="mod-long" /> <table name="employee" primaryKey="ID" dataNode="dn1,dn2,dn3" rule="sharding-by-intfile" /> <table name="customer" primaryKey="ID" dataNode="dn1,dn2,dn3" rule="sharding-by-intfile"> <childTable name="orders" primaryKey="ID" joinKey="customer_id" parentKey="id"> <childTable name="order_items" joinKey="order_id" parentKey="id" /> </childTable> <childTable name="customer_addr" primaryKey="ID" joinKey="customer_id" parentKey="id" /> </table> <!-- <table name="oc_call" primaryKey="ID" dataNode="dn1$0-743" rule="latest-month-calldate" /> --> </schema> //定义数据库主机名及存储数据的库 (localhost53可以自定义,db1也可以自定义,但是定义了db1库时就必须在库中创建对应库名的库) <dataNode name="dn1" dataHost="localhost53" database="db1" /> <dataNode name="dn2" dataHost="localhost54" database="db2" /> <dataNode name="dn3" dataHost="localhost55" database="db3" /> //定义localhost53主机名对应的数据库服务器ip地址 <dataHost name="localhost53" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100"> <heartbeat>select user()</heartbeat> <writeHost host="hostM53" url="192.168.4.53:3306" user="adminplj" password="123qqq...A"> </writeHost> </dataHost> //定义localhost54主机名对应的数据库服务器ip地址 <dataHost name="localhost54" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100"> <heartbeat>select user()</heartbeat> <writeHost host="hostM54" url="192.168.4.54:3306" user="adminplj" password="123qqq...A"> </writeHost> </dataHost> //定义localhost54主机名对应的数据库服务器ip地址 <dataHost name="localhost55" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100"> <heartbeat>select user()</heartbeat> <writeHost host="hostM55" url="192.168.4.55:3306" user="adminplj" password="123qqq...A"> </writeHost> </dataHost>
<schema> ......</schema> #定义分片信息
<table>..... </table> #定义表 name #逻辑库名或逻辑表名
dataNode #指定数据节点名
rule #指定使用的分片规则 type=global #数据不分片存储
(三)配置数据库服务器
1.创建存储数据的库
2.添加授权用户(这授权用户是在schema.xml文件中 的授权用户)
(四)启动服务
启动时要装 Java环境
在mycat文件中 /bin/mycat start
如果没有端口号 就是没启动 就要看wapper.log 这个文件的报错信息
(五)测试
客户端访问
客户端要有数据库服务 mysql -h mycat服务器ip -P 8066 -uroot -p密码 (这里的账号密码是server文件中的用户密码)
(六)分片规则介绍
在创建表格时 要先看文件schema.xml 分片规则之后看rule.xml文件 查看对应的分片规则的文档是那个
比如下面:
<table name="employee" primaryKey="ID" dataNode="dn1,dn2,dn3" rule="sharding-by-intfile" />
<tableRule name="sharding-by-intfile"> <rule> <columns>sharding_id</columns> //数据分片字段名 <algorithm>hash-int</algorithm> //使用的函数名 </rule> </tableRule>
<function name="hash-int" class="io.mycat.route.function.PartitionByFileMap"> <property name="mapFile">partition-hash-int.txt</property> //函数调用的配置文件 </function>
vim /usr/local/mycat/conf/partition-hash-int.txt
(如果是4台的话,可以创建10030=3可以自动识别前提是在schema.xml文件中有设置
也可以手动设置 10000=0 dn1 localhost5 数据库ip 库名)
10000=0 //当sharding_id字段的值是10000时,数据存储在数据节点dn1里 10010=1 //当sharding_id字段的值是10010时,数据存储在数据节点dn2里 10020=2 //当sharding_id字段的值是10020时,数据存储在数据节点dn3里
在创建表示的sharding_id字段 只能是 上图中10000 10010 10020 自己设置的字段(这个值可以随便写但是后面 0 1 2 代表 dn1 dn2 dn3)
总结:
<table name="employee" primaryKey="ID" dataNode="dn1,dn2,dn3" rule="sharding-by-intfile" />
<tableRule name="sharding-by-intfile"> <rule> <columns>sharding_id</columns> //数据分片字段名 <algorithm>hash-int</algorithm> //使用的函数名 </rule> </tableRule>
<function name="hash-int" class="io.mycat.route.function.PartitionByFileMap"> <property name="mapFile">partition-hash-int.txt</property> //函数调用的配置文件 </function>
在创建表的时候
(1)要有一个主键的id字和 sharding_id字段
(2)要查看schema.xml中定义的表(一个tables就是一个表) 看分片规则之后,在rule.xml查看在 对应的数据分片字段名称以及函数名称,看到函数名称之后在下方有函数调用的配置文件,在配置文件中配置添加、删除主机
插入数据时的sharding_id字段必须和对应的函数文件配置文件中的定义的数值(10000、 10010、10020)
(七)创建表
create table employee( ID int primary key auto_increment, (必须有,因为在定义时有primary=‘ID’) sharding_id int, 必须要(因为在分片规则表中有这个字段的名称) name char(15) , age int ); 还可以继续添加字段随便添加
创建表时会在每个数据下都会创建这个表
insert into employee(ID,sharding_id,name,age) //插入表记录 values (1,10000,"bob",19), //存储在53服务器的db1库的employee表里 (2,10010,"tom",21), //存储在54服务器的db2库的employee表里 (3,10020,"lucy2",16); //存储在55服务器的db3库的employee表里
sherding_id 字段只能写定义的数值
insert into employee(ID,sharding_id,name,age) //插入表记录 values (1,10000,"bob",19), //存储在53服务器的db1库的employee表里 (2,10010,"tom",21), //存储在54服务器的db2库的employee表里 (3,10020,"lucy2",16); //存储在55服务器的db3库的employee表里