什么是MyCat?
查看官网的介绍是这样说的
主要特性:
下载及安装:
到官网根据系统类型进行下载:http://mycat.io/
将下载文件解压,目录如下:
各个目录简要说明:
bin:启动目录 catlet: 扩展功能 conf:配置文件目录 server.xml:是Mycat服务器参数调整和用户授权的配置文件 schema.xml:是逻辑库定义和表以及分片定义的配置文件 rule.xml: 是分片规则的配置文件,分片规则的具体一些参数信息单独存放为文件,也在这个目录下,配置文件修改需要重启MyCAT log4j.xml: 日志存放在logs/log中,每天一个文件,日志的配置是在conf/log4j.xml中,根据自己的需要可以调整输出级别为debug,debug级别下,会输出更多的信息,方便排查问题 autopartition-long.txt,partition-hash-int.txt,sequence_conf.properties, sequence_db_conf.properties 分片相关的id分片规则配置文件 lib:jar包目录 logs :日志目录
进入bin目录,通过管理员身份打开DOS窗口,分别执行命令:
mycat install mycat start
这样就可以启动mycat了。
核心配置
server.xml : 设置账号、参数等 schema.xml : 物理数据库和数据库表的配置 rule.xml : 分片(分库分表)规则 关于配置的详细介绍可以参考 https://www.cnblogs.com/joylee/p/7513038.html 或者官网 http://www.mycat.io/document/mycat-definitive-guide.pdf
示例
首次认识mycat,最容易是从示例着手去了解,比如此次示例是结合mysql完成数据的分库分表,进行横向扩展。
首先需要准备几个mysql的服务器,通过docker构建,具体怎么可以参考网上,大致步骤如下:
1、下载mysql镜像: docker pull mysql 2、启动容器:docker run -di -p 32768:3306 --name mysql1 -e MYSQL_ROOT_PASSWORD=123456 mysql ,输入容器id 3、通过容器id进入容器,docker exec -it <id> /bin/bash 4、进入mysql:mysql -u root -p -> 123456 5、添加远程连接用户与密码:GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY '123456'; 6、权限:flush privileges;
如果不出意外则可以连接,因为我是通过本地虚拟机安装docker,默认端口192.168.99.100。现在根据下载的镜像启动3个容器,修改不同的端口。
通过客户端工具分别连接以上三个数据库,并且建表:
创建数据库:TESTDB 建表:
CREATE TABLE `employee` (
`id` int(11) NOT NULL,
`name` varchar(56) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
1、修改server.xml配置文件
<user name="root" defaultAccount="true">
<property name="password">123456</property>
<!-- 连接时用这个名字,比如 jdbc:mysql://localhost:8066/TESTDB -->
<property name="schemas">TESTDB</property>
</user>
2、修改schema.xml
<schema name="TESTDB" checkSQLschema="true" sqlMaxLimit="100">
<table name="employee" primaryKey="ID" dataNode="dn1,dn2,dn3" rule="mod-long" />
</schema>
<!-- name节点名,与上对应;dataHost:真实数据库配置;database:数据库表配置 -->
<dataNode name="dn1" dataHost="host1" database="TESTDB" />
<dataNode name="dn2" dataHost="host2" database="TESTDB" />
<dataNode name="dn3" dataHost="host3" database="TESTDB" />
<dataHost name="host1" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
<heartbeat>select 1</heartbeat>
<writeHost host="hostS1" url="192.168.99.100:32768" user="root" password="123456" />
</dataHost>
<dataHost name="host2" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
<heartbeat>select 1</heartbeat>
<writeHost host="hostS2" url="192.168.99.100:32769" user="root" password="123456" />
</dataHost>
<dataHost name="host3" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
<heartbeat>select 1</heartbeat>
<writeHost host="hostS3" url="192.168.99.100:39770" user="root" password="123456" />
</dataHost>
3、修改rule.xml
上面<table>配置了rule="mod-long",在rule.xml有相关的描述,修改下面参数,与上面dataNode数量对应
<function name="mod-long" class="io.mycat.route.function.PartitionByMod">
<!-- how many data nodes -->
<property name="count">3</property>
</function>
这样mycat的配置就完成了,由于修改了配置,我们将mycat重启,进入bin,mycat restart。
测试
由于之前使用了mybatis-plus+springboot的项目,所有就用了这个:
application-mycat.properties:
mybatis-plus.mapper-locations=classpath*:com/sucl/sbmp/*/mapper/**Mapper.xml
mybatis-plus.type-aliases-package=com.sucl.sbmp.*.entity
mybatis-plus.global-config.refresh=true
#mybatis-plus.global-config.db-config.db-type=mysql
mybatis-plus.configuration.map-underscore-to-camel-case=true
mybatis-plus.configuration.cache-enabled=false
mp.datasource.driver-class-name=com.mysql.jdbc.Driver
mp.datasource.url=jdbc:mysql://localhost:8066/TESTDB?useUnicode=true&useSSL=false&characterEncoding=utf8
mp.datasource.username=root
mp.datasource.password=123456
mp.datasource.validation-query=select '1'
mp.datasource.testOnBorrow=true
实体:
@Data
public class Employee {
@TableId(type = IdType.INPUT)
private long id;
@TableField(value = "name")
private String name;
}
mapper:
public interface EmployeeMapper extends BaseMapper<Employee> {
}
service:
@Service
@Transactional
public class EmployeeServiceImpl extends ServiceImpl<EmployeeMapper,Employee> implements EmployeeService {
}
测试:
@ActiveProfiles("mycat")
@RunWith(SpringRunner.class)
@SpringBootTest
public class SbmpTest {
@Autowired
private EmployeeService employeeService;
@Transactional
@Rollback(false)
@Test
public void save(){
List<Employee> employees = new ArrayList<>();
for(int i=0;i<100;i++){
Employee employee = new Employee();
employee.setId(i);
employee.setName("name"+i);
employees.add(employee);
}
employeeService.saveBatch(employees);
}
@Test
public void get(){
List<Employee> employees = employeeService.list(null);
employees.stream().forEach(System.out::println);
}
}
分别执行两个方法,会根据id在三个数据库中分别插入数据:
查询时则可以查看三个表中所有的数据,可见数据是根据id离散在不同表中,具体的策略在于之前的mod-long相关配置。
此章主要对mycat做一个初步认识,同时根据简单的示例了解其基本的工作原理,当然mycat可以帮助我们实现实现数据库的读写分离、数据库水平垂直拆分、集群等功能,但同时不得不面对相应情况下的问题。