数据库.分库分表mycat

MySQL:

分库分表

前面为基本概念
中间为参考的操作实例
后面为10种分片规则介绍

定义:将存放在数据库(主机)中的数据,按照特定方式进行拆分,分散存放到多个数据库(主机)中,以达到分散单台设备负载的效果

分割的类型
垂直分割也叫纵向切分:将单个表,拆分多个表,分散到不同的数据库(比如,将某几个字段分到一台或多台主机上,另外的字段分到另外的主机) 将单个数据库的多个表进行分类,按业务类别分散到不同的数据库上

水平分割也叫横向切分:按照表中某个字段的某种规则,把表中的许多记录按行切分,分散到多个数据库中(字段不变,横向切开,每一段分到一个主机)

纵向切分可以分表也可以分库
横向切分只能分表

mycat

软件介绍
基于java的分布式数据库系统中间层,为高并发环境的分布式访问提供解决方案(分库分表,把原本只是一台承担的访问量分到多台来承担,就是有效减轻压力的原因所在)
支持MySQL,Oracle,Sqlserver,Mongodb等
提供数据读写分离服务
可实现数据库服务器的高可用
可以提供数据分片服务
适合数据大量写入数据的存储需求

mysql支持提供的10种分片规则
1 枚举法 sharding-by-intfile
2 固定分片 rule1
3 范围约定 auto-sharing-long
4 求模法 mod-long
5 日期列区分法 sharding-by-date
6 通配取模法 sharding-by-pattern
7 ASCII码求模通配 sharding-by-prefixpattern
8 编程指定 sharding-by-substring
9 字符串拆分hash解析 sharding-by-stringhash
10 一致性hash sharding-by-murmur

工作过程
当Mycat收到一个SQL时
会先解析这个SQL查找涉及到的表,然后看此表的定义
如果有分片规则,则获取到SQL里分片字段的值,并匹配分片函数,得到该SQL对应的分片列表
然后SQL发往这些分片去执行,最后收集和处理所有分片返回的结果数据,并输出到客户端

框架结构
客户端访问mycat 再分发到下面的数据库

配置mycat

Rpm -qa | grep -i jdk 检查是否安装jdk,若没有安装则安装jdk
安装mycat
Tar -zxf Mycat-server 解压包,是免安装的,解压即可以用
Mv mycat/ /usr/local/ 移动解压包(到默认路径)
Ls /usr/local/mycat/ 检查是否移动成功

修改配置文件

Mycat目录结构说明
Bin mycat命令 比如:启动 停止等等
Catlet 扩展功能
Conf 配置文件
Lib mycat使用的jar包 mycat是java开发的
Log mycat启动日志和运行日志
Wrapper.log mycat服务的启动日志,启动有问题可以看这个日志内容
Mycat.log 记录sql脚本执行后的具体报错内容

重要配置文件说明
Server.xml 设置连接mycat服务的账号、密码等
Schema.xml 配置mycat使用的真实数据库和表
Rule.xml 定义mycat分片规则

配置标签说明
……
定义连接mycat服务时使用的用户和密码及逻辑库的名字
……
指定数据节点(物理库的主机名和存储分片数据的数据库名)
……
指定数据库服务器的ip地址及连接数据库时使用的授权用户名及密码

修改配置文件/usr/local/mycat/conf/server.xml

   test
   TESTDB


   user
   TESTDB
   true

代码解释
1 连接mycat服务时使用的用户名 test
2 使用test用户连接mycat时使用的密码
3 连接上mycat服务后,可以看见的库名多个时,使用逗号分隔(是逻辑上的库名)
8 定义只读权限,使用定义的user用户连接mycat服务后只有读记录的权限

修改配置文件/usr/local/mycat/conf/schema.xml 定义分片信息

   


   

   

   

   

   


代码解释
1 TEST逻辑库名 要与server.xml定义的一样
2,3,4,5,6,7 定义分片的表

修改配置文件/usr/local/mycat/conf/schema.xml 定义分片信息


range start-end ,data node index

K=1000,M=10000.

0-500M=0
500M-1000M=1
1000M-1500M=2

0-10000000=0
10000001-20000000=1

配置说明:
上面columns 标识将要分片的表字段,algorithm 分片函数,
rang-long 函数中mapFile代表配置文件路径
所有的节点配置都是从0开始,及0代表节点1,此配置非常简单,即预先制定可能的id范围到某个分片

四、求模法


user_id
mod-long




3

配置说明:
上面columns 标识将要分片的表字段,algorithm 分片函数,
此种配置非常明确即根据id与count(你的结点数)进行求模预算,相比方式1,此种在批量插入时需要切换数据源,id不连续

五、日期列分区法


create_time
sharding-by-date



yyyy-MM-dd
2014-01-01
10

配置说明:
上面columns 标识将要分片的表字段,algorithm 分片函数,
配置中配置了开始日期,分区天数,即默认从开始日期算起,分隔10天一个分区

还有一切特性请看源码

Assert.assertEquals(true, 0 == partition.calculate(“2014-01-01”));
Assert.assertEquals(true, 0 == partition.calculate(“2014-01-10”));
Assert.assertEquals(true, 1 == partition.calculate(“2014-01-11”));
Assert.assertEquals(true, 12 == partition.calculate(“2014-05-01”));

六、通配取模


user_id
sharding-by-pattern



256
2
partition-pattern.txt


partition-pattern.txt

id partition range start-end ,data node index

first host configuration

1-32=0
33-64=1
65-96=2
97-128=3

## second host configuration

129-160=4
161-192=5
193-224=6
225-256=7
0-0=7
配置说明:
上面columns 标识将要分片的表字段,algorithm 分片函数,patternValue 即求模基数,defaoultNode 默认节点,如果不配置了默认,则默认是0即第一个结点
mapFile 配置文件路径
配置文件中,1-32 即代表id%256后分布的范围,如果在1-32则在分区1,其他类推,如果id非数字数据,则会分配在defaoultNode 默认节点

String idVal = “0”;
Assert.assertEquals(true, 7 == autoPartition.calculate(idVal));
idVal = “45a”;
Assert.assertEquals(true, 2 == autoPartition.calculate(idVal));

七、ASCII码求模通配


user_id
sharding-by-prefixpattern



256
5
partition-pattern.txt

partition-pattern.txt

range start-end ,data node index

ASCII

48-57=0-9

64、65-90=@、A-Z

97-122=a-z

first host configuration

1-4=0
5-8=1
9-12=2
13-16=3

second host configuration

17-20=4
21-24=5
25-28=6
29-32=7
0-0=7
配置说明:
上面columns 标识将要分片的表字段,algorithm 分片函数,patternValue 即求模基数,prefixLength ASCII 截取的位数
mapFile 配置文件路径
配置文件中,1-32 即代表id%256后分布的范围,如果在1-32则在分区1,其他类推

此种方式类似方式6只不过采取的是将列种获取前prefixLength位列所有ASCII码的和进行求模sum%patternValue ,获取的值,在通配范围内的
即 分片数,
/**
* ASCII编码:
* 48-57=0-9阿拉伯数字
* 64、65-90=@、A-Z
* 97-122=a-z
*
*/

String idVal=”gf89f9a”;
Assert.assertEquals(true, 0==autoPartition.calculate(idVal));

idVal=”8df99a”;
Assert.assertEquals(true, 4==autoPartition.calculate(idVal));

idVal=”8dhdf99a”;
Assert.assertEquals(true, 3==autoPartition.calculate(idVal));

八、编程指定


user_id
sharding-by-substring



0
2
8
0

配置说明:
上面columns 标识将要分片的表字段,algorithm 分片函数
此方法为直接根据字符子串(必须是数字)计算分区号(由应用传递参数,显式指定分区号)。
例如id=05-100000002
在此配置中代表根据id中从startIndex=0,开始,截取siz=2位数字即05,05就是获取的分区,如果没传默认分配到defaultPartition

九、字符串拆分hash解析


user_id
sharding-by-stringhash



512
2
0:2

配置说明:
上面columns 标识将要分片的表字段,algorithm 分片函数
函数中length代表字符串hash求模基数,count分区数,hashSlice hash预算位
即根据子字符串 hash运算

hashSlice : 0 means str.length(), -1 means str.length()-1

/**
* “2” -> (0,2)

* “1:2” -> (1,2)

* “1:” -> (1,0)

* “-1:” -> (-1,0)

* “:-1” -> (0,-1)

* “:” -> (0,0)

*/
public class PartitionByStringTest {

@Test
public void test() {
PartitionByString rule = new PartitionByString();
String idVal=null;
rule.setPartitionLength(“512”);
rule.setPartitionCount(“2”);
rule.init();
rule.setHashSlice(“0:2”);
// idVal = “0”;
// Assert.assertEquals(true, 0 == rule.calculate(idVal));
// idVal = “45a”;
// Assert.assertEquals(true, 1 == rule.calculate(idVal));

  //last 4
  rule = new PartitionByString();
  rule.setPartitionLength("512");
  rule.setPartitionCount("2");
  rule.init();
  //last 4 characters
  rule.setHashSlice("-4:0");
  idVal = "aaaabbb0000";
  Assert.assertEquals(true, 0 == rule.calculate(idVal));
  idVal = "aaaabbb2359";
  Assert.assertEquals(true, 0 == rule.calculate(idVal));

}

十、一致性hash


user_id
murmur



0
2

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值