学习之后的一个实际操作练习笔记
在读写分离前提下又配置了水平分割之分片枚举 (参考MyCat读写分离那篇文章)
实践操作环境规划
MyCat用的是1.4
Centos6.5
jdk1.7
192.168.10.166 slave MySQL
192.168.10.184 master MySQL
192.168.10.185 MyCat 端口8066
MyCat虚拟出来的数据库是mycat_testdb;物理数据库test
root/123456 具有读写权限
user/123456 具有读的权限
物理数据库test中的t_dept用来做读写分离测试
//TODO t_user表用于测试水平分割之分片枚举
//TODO t_order 表用于测试水平分割之取模算法
create database db0;
create database db1;
create database db2;
//在db1 db2 db3 三个数据库中都创建t_user和t_order表
//在主master中创建了数据库和表,通过二进制文件主从复制,salve 也会同样创建数据库和表.
create table t_user(id int,uname varchar(32));
create table t_order(id int ,oname varchar(50));
在MyCat中进行相关配置来实现分片枚举和取模算法的水平分割
//TODO 我的想法是把读写分离的配置和水平分割配置进行综合在一起
水平分割之分片枚举实战操作
根据地区进行分库:湖北数据库、江苏数据库 山东数据库
分表对应db0;db1;db2
在这三个库里面分表创建相同的表t_order表
枚举(定义的常量,是单例的,不会发生改变),进行分类存储
可以使用分片枚举实现根据地区进行分类存储到不同数据库进行存储
环境搭建
①定义枚举(地区) 每个地区指定数据库存放位置
②修改partition-hash-int.txt 规则
hunan=0
shanghai=1
suzhou=2
MyCat/config/
partition-hash-int.txt
这个文件是用来配置枚举的。
配置内容:
hunan=0
shanghai=1
suzhou=2
rule.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mycat:rule SYSTEM "rule.dtd">
<mycat:rule xmlns:mycat="http://io.mycat/">
<!--tableRule表示表的规则
name 表示给这个规则取一个名称-->
<tableRule name="role2">
<rule>
<!--columns 表示以表中那个字段作为分片规则-->
<columns>uname</columns>
<!--algorithm 使用function标签中的name属性。连接表规则和具体路由算法-->
<algorithm>hash-int</algorithm>
</rule>
</tableRule>
<!--MyCat1.4中class = org.opencloudb.route.function.PartitionByFileMa
我用的是1.4 版本所有把class改成这个的.
-->
<function name="hash-int" class="io.mycat.route.function.PartitionByFileMap">
<property name="mapFile">partition-hash-int.txt</property>
<property name="type">1</property>
<property name="defaultNode">1</property>
</function>
</mycat:rule>
shcema.xml
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
<!--
name:逻辑数据库的名称
dataNode:逻辑数据库对应物理数据库节点。
逻辑库下的表默认都走的schema配置的database
sqlMaxLimit:当进行查询的时候Mycat会自动在查询语句后面添加limit语句.
如不配置就会查询所有.
需要注意的是,如果运行的 schema 为非拆分库的,
那么该属性不会生效。需要手动添加 limit 语句
checkSQLschema:该字段就是用户执行sql语句时,
是否检查表明的schema,
实际上与SQL语句语法是有重提的,
强烈建议将该字段设置为false;
-->
<schema name="mycat_testdb" checkSQLschema="false" sqlMaxLimit="100">
<!--指定分片那个表,和对应的数据库 ,rule的值表示指定rule.xml中tableRule的name值-->
<table name="t_user" dataNode="dn1,dn2,dn3" rule="role2" />
</schema>
<!-- database 是MySQL数据库的库名 -->
<dataNode name="dn1" dataHost="localhost1" database="db0" />
<dataNode name="dn2" dataHost="localhost1" database="db1" />
<dataNode name="dn3" dataHost="localhost1" database="db2" />
<!--
dataNode节点中各属性说明:
name:指定逻辑数据节点名称;
dataHost:指定逻辑数据节点物理主机节点名称;
database:指定物理主机节点上。
如果一个节点上有多个库,
可使用表达式db$0-99,
表示指定0-99这100个数据库;
dataHost 节点中各属性说明:
name:物理主机节点名称;
maxCon:指定物理主机服务最大支持1000个连接;
minCon:指定物理主机服务最小保持10个连接;
writeType:指定写入类型;
0,只在writeHost节点写入;
1,在所有节点都写入。慎重开启,
多节点写入顺序为默认写入根据配置顺序,
第一个挂掉切换另一个;
dbType:指定数据库类型;
dbDriver:指定数据库驱动;如果使用MySQL /MariDB 选择native,其他数据库选择JDBC
balance:指定物理主机服务的负载模式。
0,不开启读写分离机制;
1,全部的readHost与stand by writeHost参与select语句的负载均衡,
简单的说,当双主双从模式(M1->S1,M2->S2,并且M1与 M2互为主备),
正常情况下,M2,S1,S2都参与select语句的负载均衡;
2,所有的readHost与writeHost都参与select语句的负载均衡,
也就是说,当系统的写操作压力不大的情况下,
所有主机都可以承担负载均衡;
3.所有读请求随机的分发到 wiriterHost 对应的 readhost 执行,
writerHost 不负担读压力,
注意 balance=3 只在 1.4 及其以后版本有,1.3 没有
-->
<dataHost name="localhost1" maxCon="1000" minCon="10" balance="3" writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<!-- 可以配置多个主从
host 属性:用于标识不同实例,
一般 writeHost 我们使用*M1,readHost 我们用*S1
-->
<writeHost host="hostM1" url="192.168.10.184:3306" user="root" password="root">
<!-- 可以配置多个从库 -->
<readHost host="hostS2" url="192.168.10.166:3306" user="root" password="root" />
</writeHost>
</dataHost>
</mycat:schema>
server.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mycat:server SYSTEM "server.dtd">
<mycat:server xmlns:mycat="http://io.mycat/">
<!--这里
配置的是对虚拟出来的数据账号密码和权限
在实际运用中我们使用这里配置的账号和密码 连接Mycat虚拟出来的数据库.
在实际项目中就会出现多数据源.
springboot2.0.1版本之厚新增了RoutinDataSource
使用这个类+AOP技术实现动态数据源切换.
AOP拦截方法(find /select 开头的切换到只能读的数据库)
(inert/update/delet方法开头的切换到读写数据)
-->
<!-- 读写都可用的用户
root/123456 可以对Mycat虚拟出来的mycat_testdb数据库进行读写操作
-->
<user name="root" defaultAccount="true">
<property name="password">123456</property>
<!--这里定义的值和schema.xml中定义schema中name的值保持一致.-->
<property name="schemas">mycat_testdb</property>
<!-- 表级 DML 权限设置 -->
<!--
<privileges check="false">
<schema name="TESTDB" dml="0110" >
<table name="tb01" dml="0000"></table>
<table name="tb02" dml="1111"></table>
</schema>
</privileges>
-->
</user>
<!-- 只读用户
user/user 这个账户只可以对mycat虚拟出来的数据库:mycat_testdb进行读的操作.
-->
<user name="user">
<property name="password">user</property>
<property name="schemas">mycat_testdb</property>
<property name="readOnly">true</property>
</user>
</mycat:server>
连接的是MyCat虚拟出来的数据库mycat_test
测试数据:
INSERT t_user(id,uname) VALUES(1,'wuhan');
INSERT t_user (id,uname) VALUES(2,'shanghai');
INSERT t_user (id,uname) VALUES(3,'suzhou');
继续操作使用id取模算法进行水平拆分.
rule.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mycat:rule SYSTEM "rule.dtd">
<mycat:rule xmlns:mycat="http://org.opencloudb/">
<tableRule name="role2">
<rule>
<columns>uname</columns>
<algorithm>hash-int</algorithm>
</rule>
</tableRule>
<tableRule name="role1">
<rule>
<columns>id</columns>
<algorithm>mod-long</algorithm>
</rule>
</tableRule>
<function name="hash-int" class="org.opencloudb.route.function.PartitionByFileMap">
<property name="mapFile">partition-hash-int.txt</property>
<property name="type">1</property>
<property name="defaultNode">1</property>
</function>
<!--注意 id取模的时候class 和分片枚举的class是不一样的
我把原来的rule.xml做了一个备份,他里面是官方提供的一个模板,可以进行参考设置
-->
<function name="mod-long" class="org.opencloudb.route.function.PartitionByMod">
<!--指定分片数量,不可以被更改-->
<property name="count">3</property>
</function>
</mycat:rule>
schema.xml
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://org.opencloudb/">
<schema name="mycat_testdb" checkSQLschema="false" sqlMaxLimit="100" >
<table name="t_user" dataNode="dn2,dn3,dn4" rule="role2" />
<table name="t_order" dataNode="dn2,dn3,dn4" rule="role1"/>
</schema>
<dataNode name="dn1" dataHost="localhost1" database="test" />
<dataNode name="dn2" dataHost="localhost1" database="db0" />
<dataNode name="dn3" dataHost="localhost1" database="db1" />
<dataNode name="dn4" dataHost="localhost1" database="db2" />
<dataHost name="localhost1" maxCon="1000" minCon="10" balance="3" writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<writeHost host="hostM1" url="192.168.10.184:3306" user="root" password="root">
<readHost host="hostS2" url="192.168.10.166:3306" user="root" password="root" />
</writeHost>
</dataHost>
</mycat:schema>
server.xml
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE mycat:server SYSTEM "server.dtd">
<mycat:server xmlns:mycat="http://org.opencloudb/">
<user name="root">
<property name="password">123456</property>
<property name="schemas">mycat_testdb</property>
</user>
<user name="user">
<property name="password">123456</property>
<property name="schemas">mycat_testdb</property>
<property name="readOnly">true</property>
</user>
</mycat:server>
连接的是MyCat虚拟出来的数据库mycat_test
SELECT * FROM t_order;
INSERT INTO t_order (id,oname)VALUES(1,'a');
INSERT INTO t_order (id,oname)VALUES(2,'b');
INSERT INTO t_order (id,oname)VALUES(3,'c');
INSERT INTO t_order (id,oname)VALUES(4,'d');
id=1%3 = 1 ----db1数据库中的t_order
id=2%3 =2 ----db2数据库中的t_order
id=3%3 = 0 ----db0数据库中的t_order
id=4%3=1 ----db1数据库中的t_order
这种取模算法应用很广泛,比如dubbo中的负载均衡的算法就是使用取模算法来的。
使用一个全局变量进行统计访问次数,当然也要考虑线程安全问题
请求设置为一个变量num 集群数为count
比如集群有3台机器 count = 3
第一次请求
num = 1 1%3 1
num = 2 2%3 2
num = 3 3%3 0
num = 4 4%3 1
num = 5 5%3 2
num = 6 6%3 0
可以把0当做是第三台机器,从而达到负载均衡的效果。
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/100794.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...