前两天看到一道有意(keng)思(bi)的面试题,大致情景如下。

面试官:“ 用过mysql吧,你们是用自增主键还是UUID

应聘者:“ 用的是自增主键

面试官:“ 为什么是自增主键?

应聘者:“ 因为采用自增主键,数据在物理结构上是顺序存储,性能最好,blabla…

面试官:“ 那自增主键达到最大值了,用完了怎么办?

应聘者:“?(一脸懵逼)….那就改为bigint?

面试官:“你在线上怎么更改?

应聘者:“(再次懵逼)balabala..

当时看到这问题也觉得一脸懵逼。寻思着能把自增主键用完至少得十几亿的数据吧(删除数据后主键依然自增),看到最后才发现其实面试官想考察的还是分库分表思想… 这时,Tomcat (呸!)Mycat就派上用场了。

  • 操作系统 :centos 7.5
  • 安装必备:jkd + mysql

1.下载Linux安装包
Mycat下载可以到官网下载也可以到github上下载

2.上传并解压
把MyCat的压缩包上传到linux服务器,并且解压

cd /usr/local/切换目录
[root@localhost local]# tar -xvf Mycat-server-1.6-RELEASE-20161028204710-linux.tar.gz -C /usr/local/

3.启动

/usr/local/mycat/bin/mycat start		//启动
/usr/local/mycat/bin/mycat stop		        //停止
/usr/local/mycat/bin/mycat restart           	//重启

4.连接

可以使用MySQL自带的客户端进行连接,也可以使用可视化软件进行连接

mycat的默认的账号和密码都是user

客户端连接

mysql -uuser -puser -P8066 -h192.168.82.110

mysql -uroot -p123456 -P8066 -h192.168.82.110

注意:可以使用mysql的客户端直接连接mycat服务。默认服务端口为8066

链接不上,可以执行:vi /etc/my.cfg

在mysqld节点下添加:

skip-name-resolve

开放防火墙8066端口

Mycat分片配置

将指定的一张表分片进行存储,比如存储到三个数据节点上

5.创建三个数据库,准备表

使用一台服务器模拟分片操作,创建三个数据库分别命名

db1

db2

db3

6. MyCat配置文件

server.xml

server.xml几乎保存了所有mycat需要的系统配置信息。最常用的是在此配置用户名、密码及权限

system标签

<property name="charset">utf8</property> 字符集
<property name="processors">1</property> 处理线程数量,默认是cpu数量。
<property name="processorBufferChunk">4096</property> 每次读取留的数量,默认4096。
<property name="processorBufferPool">409600</property> 创建共享buffer需要占用的总空间大小,processorBufferChunk*processors*100。
<property name="processorBufferPoolType">0</property>默认为0。0表示DirectByteBufferPool,1表示ByteBufferArena。
<property name="processorBufferLocalPercent">100</property>二级共享buffer是processorBufferPool的百分比,这里设置的是百分比。
<property name="sequnceHandlerType">100</property>全局ID生成方式。(0:为本地文件方式,1:为数据库方式;2:为时间戳序列方式;3:为ZK生成ID;4:为ZK递增ID生成。
<property name="useCompression">1</property>是否开启mysql压缩协议。1为开启,0为关闭,默认关闭。
<property name="packetHeaderSize">4</property> 指定 Mysql 协议中的报文头长度。默认 4。
<property name="maxPacketSize">16M</property>指定 Mysql 协议可以携带的数据最大长度。默认 16M。
<property name="idleTimeout">1800000</property>指定连接的空闲超时时间。某连接在发起空闲检查下,发现距离上次使用超过了空闲时间,那么这个连接会被回收,就是被直接的关闭掉。默认 30 分钟,单位毫秒。
<property name="txIsolation">3</property>前端连接的初始化事务隔离级别,只在初始化的时候使用,后续会根据客户端传递过来的属性对后端数据库连接进行同步。
默认为 REPEATED_READ,设置值为数字默认 3。 
READ_UNCOMMITTED = 1; 
READ_COMMITTED = 2; 
REPEATED_READ = 3; 
SERIALIZABLE = 4;
<property name="sqlExecuteTimeout">300</property>SQL 执行超时的时间,Mycat 会检查连接上最后一次执行 SQL 的时间,若超过这个时间则会直接关闭这连接。默认时间为 300 秒,单位秒。
<property name="processorCheckPeriod">1000</property>
清理 NIOProcessor 上前后端空闲、超时和关闭连接的间隔时间。默认是 1 秒,单 
位毫秒。
<property name="dataNodeIdleCheckPeriod">300000</property> 对后端连接进行空闲、超时检查的时间间隔,默认是 300 秒,单位毫秒。
<property name="dataNodeHeartbeatPeriod">10000</property>对后端所有读、写库发起心跳的间隔时间,默认是 10 秒,单位毫秒。
<property name="bindIp">0.0.0.0</property>mycat 服务监听的 IP 地址,默认值为 0.0.0.0。
<property name="serverPort">8066</property>定义 mycat 的使用端口,默认值为 8066。
<property name="managerPort">9066</property>定义 mycat 的管理端口,默认值为 9066。
<property name="fakeMySQLVersion">5.6</property>mycat 模拟的 mysql 版本号,默认值为 5.6 版本,如非特需,不要修改这个值,目前支持设置 5.5,5.6,5.7 版本,其他版本可能会有问题。
<property name="useSqlStat">0</property>  是否开启实时统计。1为开启;0为关闭 。
<property name="useGlobleTableCheck">0</property>是否开启全局表一致性检测。1为开启;0为关闭 
<property name="handleDistributedTransactions">0</property>分布式事务开关。0为不过滤分布式事务;1为过滤分布式事务;2 为不过滤分布式事务,但是记录分布式事务日志。
<property name="maxStringLiteralLength">65535</property>默认是65535。 64K 用于sql解析时最大文本长度 
以上举例的属性仅仅是一部分,可以配置的变量很多,具体可以查看SystemConfig这个类的属性内容。 
System标签下的属性,一般是上线后,需要根据实际运行的情况,分析后调优的时候进行修改。

Firewall标签
顾名思义,这个就是关于防火墙的设置,也就是在网络层对请求的地址进行限制,主要是从安全角度来保证Mycat不被匿名IP进行访问

<firewall> 
    <!--白名单-->
       <whitehost>
          <host host="127.0.0.1" user="mycat"/>
          <host host="127.0.0.2" user="mycat"/>
       </whitehost>
  <!--黑名单-->
       <blacklist check="false">
       </blacklist>
</firewall>

Schema.xml

Schema.xml作为MyCat中重要的配置文件之一,管理着MyCat的逻辑库、表、分片规则、DataNode以及DataSource。弄懂这些配置,是正确使用MyCat的前提。这里就一层层对该文件进行解析。

schema 标签用于定义MyCat实例中的逻辑库 数据库
Table 标签定义了MyCat中的逻辑表
dataNode 标签定义了MyCat中的数据节点,也就是我们通常说所的数据分片。
dataHost 标签在mycat逻辑库中也是作为最底层的标签存在,直接定义了具体的数据库实例、读写分离配置和心跳语句。
注意:若是LINUX版本的MYSQL,则需要设置为Mysql大小写不敏感,否则可能会发生表找不到的问题。
在MySQL的配置文件中my.cnf 位置在etc目录下[mysqld] 中增加一行
lower_case_table_names = 1

rule.xml

rule.xml里面就定义了我们对表进行拆分所涉及到的规则定义。我们可以灵活的对表使用不同的分片算法,或者对表使用相同的算法但具体的参数不同。
这个文件里面主要有tableRule和function这两个标签。在具体使用过程中可以按照需求添加tableRule和function。

Server.xml配置

vi server.xml 编辑系统配置信息
找到user节点配置自己的用户名和密码

Schema.xml配置

vi schema.xml  编辑规则配置信息
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://org.opencloudb/">

<schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100">
	<!-- auto sharding by id (long) -->
  <!--按照主键分片规则
	rule 规则:在rulm.xml文件中配置

-->
	<table name="TB_ITEM" dataNode="dn1,dn2,dn3" rule="auto-sharding-long" />
  <!--全局设置-->
	<table name="TB_USER" primaryKey="ID" type="global" dataNode="dn1,dn2" />
</schema>
  <!--数据节点  name 为table比标签中的dataNode指定的值
localhost1:数据主机名
database :链接的数据库
-->
<dataNode name="dn1" dataHost="localhost1" database="db1" />
<dataNode name="dn2" dataHost="localhost2" database="db2" />
<dataNode name="dn3" dataHost="localhost1" database="db3" />

  <!--数据主机
	name属性的值为dataNode节点的 dataHost 属性的值
-->
  
<dataHost name="localhost1" maxCon="1000" minCon="10" balance="0"
	writeType="0" dbType="mysql" dbDriver="native" switchType="1"  slaveThreshold="100">
	<heartbeat>select user()</heartbeat>
	<!-- can have multi write hosts -->
	<writeHost host="hostM1" url="192.168.82.196:3306" user="root"
		password="admin">
		<!-- can have multi read hosts -->

	</writeHost>
</dataHost>
<dataHost name="localhost2" maxCon="1000" minCon="10" balance="0"
	writeType="0" dbType="mysql" dbDriver="native" switchType="1"  slaveThreshold="100">
	<heartbeat>select user()</heartbeat>
	<!-- can have multi write hosts -->
	<writeHost host="hostM1" url="192.168.82.100:3306" user="root"
		password="admin">
		<!-- can have multi read hosts -->
	</writeHost>
</dataHost>
</mycat:schema>

测试:
https://blog.csdn.net/Dreamcode/article/details/50401858

创建表

配置完毕后,重新启动mycat。使用mysql客户端连接mycat,创建表。
注意,需要连接到mycat,执行建表语句,表名与schema.xml中的虚拟表名一致。

创建数据

再看下三个分片的数据

分片测试

所有分片规则都在:rule.xml文件

测试数据:

“auto_sharding_long” 根据主键的值来选择使用哪一个库存储。

create table tb_item (id int primary key auto_increment, title varchar(30), price varchar(30) );

insert into tb_item values(200,’人生’,’路遥’); 不正确 一定要把列列举出来

不列举列会报错:

ERROR 1064 (HY000): partition table, insert must provide ColumnList

由于配置的分片规则为“auto-sharding-long”,所以mycat会根据此规则自动分片。
查看rule.xml文件
搜索auto-sharding-long,可查到如下规则:

<tableRule name="auto-sharding-long">
		<rule>
			<columns>id</columns>
			<algorithm>rang-long</algorithm><!--处理该分片的函数-->
		</rule>
</tableRule>
	
<function name="rang-long"
		class="io.mycat.route.function.AutoPartitionByLong">
		<property name="mapFile">autopartition-long.txt</property>
	</function>

通过rule.xml文件可查,分片规则的文件:autopartition-long.txt
该文件内容:
# range start-end ,data node index
# K=1000,M=10000.
0-500M=0    0-5000000   db1
500M-1000M=1   
1000M-1500M=2

每个datanode中保存一定数量的数据。根据id进行分片
经测试id范围为:
Datanode1:1~5000000
Datanode2:5000000~10000000
Datanode3:10000001~15000000

当15000000以上的id插入时报错:
[Err] 1064 – can’t find any valid datanode :TB_ITEM -> ID -> 15000001
此时需要添加节点了。

发表评论

电子邮件地址不会被公开。 必填项已用*标注