CentOS安装MySQL
环境:CentOS7 MySQL5.7
# 检查是否安装了mariadb,如果安装了则卸载
yum list installed | grep mariadb
# 如果执行结果如下,表示安装了mariadb需要卸载
mariadb-libs.x86_64 1:5.5.52-1.el7 @anaconda
# 卸载命令如下
yum -y remove mariadb*
#如果 CentOS 上没有 wget 命令,首先通过如下命令安装 wget:
yum install wget
# 下载rpm
wget https://dev.mysql.com/get/mysql57-community-release-el7-11.noarch.rpm
#安装rpm包
rpm -ivh mysql57-community-release-el7-11.noarch.rpm
# 检查MySQL是否安装成功
yum repolist enabled | grep "mysql.*-community.*"
执行结果如下,表示安装成功
安装MySQL
# 安装MySQL
yum install mysql-server
#启动MySQL
systemctl start mysqld.service
# 停止MySQL
systemctl stop mysqld.service
#登录MySQL
mysql -u root -p
默认无密码。有的版本有默认密码,查看默认密码,首先去 /etc/my.cnf 目录下查看 MySQL 的日志位置,然后打开日志文件,可以看到日志中有一个提示,生成了一个临时的默认密码,使用这个密码登录,登录成功后修改密码即可。
修改密码
# 修改密码策略(这一步不是必须的,如果不修改密码策略,需要取一个比较复杂的密码,松哥这里简单起见,就修改下密码策略):
set global validate_password_policy=0
# 重置密码
set password=password("123")
flush privileges;
# 授权远程登录方式一
grant all privileges on *.* to 'root'@'%' identified by '123' with grant option;
flush privileges;
# 方式二:修改 mysql 库中的 user 表,将 root 用户的 Host 字段的值改为 % ,然后重启 MySQL 即可。
关闭防火墙和禁止firewall开机启动
systemctl stop firewalld.service
systemctl disable firewalld.service
========================================================================
主从复制
①、配置主机
系统库不需要复制
- log-bin:同步的日志路径及文件名,一定注意这个目录要是 MySQL 有权限写入的
- binlog-do-db:要同步的数据库名,当从机连上主机后,只有这里配置的数据库才会被同步,其他的不会被同步
- server-id: MySQL 在主从环境下的唯一标志符,给个任意数字,注意不能和从机重复。
在主库中授权一个用户可以访问主节点进行日志复制
查看主库状态
②、配置从机
告诉从库要同步哪一个主机(主机ip)
start slave开始同步
然后执行start slave
测试效果:
- 在master运行一段sql(或者导入文件),创建库及其库里面的各种数据表
- 查看salve中的变化
Docker实现主从复制
一、规划两个MySQL实例
192.168.66.131:33061/主机
192.168.66.131:33062/从机
在Docker中创建按两个MySQL实例:
docker run --name mysql1 -p 33061:3306 -e MYSQL_ROOT_PASSWORD=123 -d mysql:5.7 --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
docker run --name mysql2 -p 33062:3306 -e MYSQL_ROOT_PASSWORD=123 -d mysql:5.7 --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
docker ps 命令查看运行情况
二、配置主机
①、给从机配置一个登录账户
Docker 中创建的 MySQL 实例,默认只有一个用户,就是 root,需要进入到 MySQL 命令行,再给它分配一个用户。在宿主机中通过如下命令连接上主机:
mysql -u root -h 192.168.66.131 -P 33061 -p
# 宿主机上也安装了 MySQL,可以直接执行 mysql 命令,如果宿主机没有安装 MySQL,建议通过 docker exec 进入到 MySQL 容器中,然后执行如下命令
GRANT REPLICATION SLAVE ON *.* to 'rep1'@'%' identified by '123';
表示从机一会使用 rep1/123 来登录主机,% 表示这个账户可以从任意地址登录,也可以给一个固定的 IP,表示这个账户只能从某一个 IP 登录
②、开启binlog
# 进入容器内部
docker exec -it mysql1 /bin/bash
#找到 MySQL 配置文件的位置:
因为 MySQL 容器中,默认没有 VI 编辑器,安装费事,所以我们可以在宿主机中将配置文件写好,然后拷贝到 MySQL 容器中,覆盖原有配置。
# 第一行表示配置 binlog 的位置,理论上 binlog 可以放在任意位置,但是该位置,MySQL 一定要有操作权限
log-bin=/var/lib/mysql/binlog
# server-id 表示集群中,每个实例的唯一标识符
server-id=1
# bindlog-do-db 表示要同步的数据库有哪些。当从机连上主机后,并不是主机中的每一个库都要同步,这里表示配置哪些库需要同步
binlog-do-db = cmdb
将宿主机中的 mysqld.cnf 拷贝到容器中:
docker cp ./mysqld.cnf mysql1:/etc/mysql/mysql.conf.d/
重启容器
docker restart mysql1
查看是否配置成功
File 和 Position 需要记着,这两个标记了二进制日志的起点位置,在从机的配置中将使用到这两个参数
三、配置从机
不用开启 binlog,也不用配置要同步的库,只需要在配置文件中,添加一个 server-id 即可
配置完成后,一样拷贝到容器中。拷贝方式和主机一样:
docker cp ./mysqld.cnf mysql2:/etc/mysql/mysql.conf.d/
配置完成后,重启从机容器:
docker restart mysql2
重启完成后,进入到 mysql2 的命令行,执行如下命令,开启数据同步:
change master to master_host='192.168.66.131',master_port=33061,master_user='rep1',master_password='123',master_log_file='binlog.000001',master_log_pos=154;
配置完成后,开启从机进程。在从机命令行执行如下命令:
start slave;
执行 show slave status\G;查看从机状态:
重点查看 Slave_IO_Running 和 Slave_SQL_Running ,这两个的值必须为 Yes。如果有一个的值不为 Yes,表示配置失败,一般情况下,配置失败,下面会有失败提示。
双主双从
一、Master1
修改配置文件:vim/etc/my.cnf
server-id=1
二、Master2配置
三、Slave1配置
四、Slave2配置
五、双主双从进行重启mysql,并且关闭防火墙
六、在两台主机上建立账户并授权slave
七、两台主机相互复制
=======================================================
ShardingSphere
分布式数据库中间件解决方案(三个产品,主要学习以下两个)
垂直分表: 把表中的一部分字段存到一种新表中,把另一部分字段存到另外一张新表中
垂直分库:把单一数据表按照业务划分,专库专表。
水平分表:同一个数据库内,拆分成相同结构的表(根据课程id放到不同的数据表中)
水平分库:根据课程id的奇偶性来存放到不同库中。
Sharding-JDBC
一、工程环境搭建SpringBoot+MyBatisPlus+Sharding-JDBC+Druid连接池
druid-spring-boot-starter
mysql-connector-java
sharding-jdbc-spring-boot-starter
mybatis-plus-boot-starter
lombok
配置文件application.properties(官方中查找手册)
# 数据源,并且取一个别名
spring.shardingsphere.datasource.names=m1
# 一个实体类对应两张表的覆盖
spring.main.allow-bean-definition-overriding=true
#配置数据源具体内容(连接池、驱动、地址、用户名和密码)
spring.shardingsphere.datasource.m1.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.m1.driver-class-name=com.mysql.dj.jdbc.Driver
spring.shardingsphere.datasource.m1.url=jdbc:mysql://localhost:3306/course_db?serverTimezone=GMT%2B8
spring.shardingsphere.datasource.m1.username=root
spring.shardingsphere.datasource.m1.password=123
#指定course表分布情况,配置表在哪个数据库里面,表名称都是什么
spring.shardingsphere.sharding.tables.course.actual-data-nodes=m1.course_${1..2}
#指定course表里面主键生成策略 SNOWFLAKE雪花算法
spring.shardingsphere.sharding.tables.course.key-generator.column=cid
spring.shardingsphere.sharding.tables.course.key-generator.type=SNOWFLAKE
# 指定分片策略,如果cid偶数添加到course_1,如果是奇数添加到course_2中
spring.shardingsphere.sharding.tables.course.table-strategy.inline.sharding-column=cid
spring.shardingsphere.sharding.tables.course.table-strategy.inline.algorithm-expression=course_$->{cid % 2 +1}
#打开sql输出日志
spring.shardingsphere.props.sql.show=true
二、按照水平分表的方式,在一个数据库内创建两个结构一样的数据表
三、创建Mapper(启动类中通过注解@MapperScan(“com.michael.mapper”))
@Repository
public interface CourseMapper extends BaseMapper<Course>{
}
测试
@RunWith(SpringRunner.class)
@SpringBootTest
public class ShardingjdbcdemoApplicationTests{
@Autowired
private CourseMapper courseMapper;
@Test
public void addCourse(){
Course course = new Course();
course.setCname("java");
course.setUserId(100L);
course.setCstatus("Normal");
courseMapper.insert(course);
}
@Test
public void findCourse(){
QueryWrapper<Course> wrapper = new QueryWrapper<>();
wrapper.eq("cid",xxxxx);
Course course = courseMapper.selectOne(wrapper);
System.out.println(course);
}
}
按照水平分库
配置分片规则
spring.shardingsphere.datasource.names=m1,m2
#配置数据源具体内容(连接池、驱动、地址、用户名和密码)
spring.shardingsphere.datasource.m1.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.m1.driver-class-name=com.mysql.dj.jdbc.Driver
spring.shardingsphere.datasource.m1.url=jdbc:mysql://localhost:3306/edu_db_1?serverTimezone=GMT%2B8
spring.shardingsphere.datasource.m1.username=root
spring.shardingsphere.datasource.m1.password=123
spring.shardingsphere.datasource.m2.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.m2.driver-class-name=com.mysql.dj.jdbc.Driver
spring.shardingsphere.datasource.m2.url=jdbc:mysql://localhost:3306/edu_db_2?serverTimezone=GMT%2B8
spring.shardingsphere.datasource.m2.username=root
spring.shardingsphere.datasource.m2.password=123
# 指定数据库分布(两个数据库),每个数据库有两个表
spring.shardingsphere.sharding.tables.course.actual-data-nodes=m${1..2}.course_$->{1..2}
#指定course表里面主键生成策略 SNOWFLAKE雪花算法
spring.shardingsphere.sharding.tables.course.key-generator.column=cid
spring.shardingsphere.sharding.tables.course.key-generator.type=SNOWFLAKE
# 指定库分片策略
spring.shardingsphere.sharding.tables.course.database-strategy.inline.charding-column=user_id
spring.shardingsphere.sharding.tables.course.database-strategy.inline.algorithm-expression=m$->{user_id % 2 +1}
# 指定表分片策略,如果cid偶数添加到course_1,如果是奇数添加到course_2中
spring.shardingsphere.sharding.tables.course.table-strategy.inline.sharding-column=cid
spring.shardingsphere.sharding.tables.course.table-strategy.inline.algorithm-expression=course_$->{cid % 2 +1}
#打开sql输出日志
spring.shardingsphere.props.sql.show=true
按照垂直分库(专库专表)
配置垂直分库策略
# 配置user_db数据库里面的t_user专库专表(别名m0库里面的t_user表)
sprig.shardingsphere.sharding.tables.t_user.actual-data-nodes=m$->{0}.t_user
spring.shardingsphere.sharding.tables.t_user.key-generator.colunm=user_id
spring.shardingsphere.sharding.tables.t_user.key-generator.type=SNOWFLAKE
spring.shardingsphere.sharding.tables.t_user.table-strategy.inline.sharding-column=user_id
spring.shardingsphere.sharding.tables.t_user.table-strategy.inline.algorithm-expression=t_user
公共表
项目中存储固定数据的表,数据很少变化,查询时候经常关联
在多个数据库都创建公共表
# 配置公共表
spring.shardingsphere.sharding.broadcast-tables=t_udict
spring.shardingsphere.sharding.tables.t_udict.key-generator.column=dictid
spring.shardingsphere.sharding.tables.t_udict.key-generator.type=SHOWFLAKE
当操作时,多个数据源(三个数据库)的公共表都会被操作。
读写分离
前提是数据库实现了主从复制。
读写分离的配置(实现主库进行写,从库进行读)
# 配置从服务器数据源(略)
# ds0数据库(逻辑数据源user_db)下的主从配置
spring.shardingsphere.sharding.master-slave-rules.ds0.master-data-source-name=m0
spring.shardingsphere.sharding.master-slave-rules.ds0.slave-data-source-names=s0
spring.shardingsphere.sharding.tables.t_user.actual-data-nodes=ds0.t_user
Sharding-Proxy
属于独立应用,使用安装服务,进行分库分表或者读写分离配置,启动
一、下载
二、解压,启动bin(如果出现找不到jar包的错误,则通过压缩工具将lib目录中显示不全的.jar后缀,重新补充完整)
三、进入conf目录,修改配置文件
①、将server.yaml源文件中的注释打开
②、config-sharding.yaml
复制mysql驱动到lib目录中
打开注释(配置分库分表)
四、启动Sharding-Proxy服务(默认端口号3307)
五、通过cmd窗口端口进行连接(同连接mysql数据库一样)
添加数据(实际的mysql也会得到响应的操作)
Sharding-Proxy分库配置
①、创建两个数据库
②、配置文件config-sharding.yaml
配置两个数据源以及分不分表策略
③、启动bin目录下的服务
④、打开cmd进行连接
创建表并添加数据操作
Sharding-Proxy读写分离配置
①、创建三个数据库,一主两从
②、修改conf目录下的配置文件,config-master-slave.yml
SpringBoot集成 Sharding-jdbc + Mybatis-Plus
①、三层项目架构
②、依赖pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.6.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.macky</groupId>
<artifactId>spring-boot-shardingjdbc</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>spring-boot-shardingjdbc</name>
<description>Demo project for spring-boot-shardingjdbc</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--mysql-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<!--Mybatis-Plus-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.1.1</version>
</dependency>
<!--shardingsphere start-->
<!-- for spring boot -->
<dependency>
<groupId>io.shardingsphere</groupId>
<artifactId>sharding-jdbc-spring-boot-starter</artifactId>
<version>3.1.0</version>
</dependency>
<!-- for spring namespace -->
<dependency>
<groupId>io.shardingsphere</groupId>
<artifactId>sharding-jdbc-spring-namespace</artifactId>
<version>3.1.0</version>
</dependency>
<!--shardingsphere end-->
<!--lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
③、实体类
@Data
@EqualsAndHashCode(callSuper = true)
@Accessors(chain = true)
@TableName("book")
public class Book extends Model<Book> {
private int id;
private String name;
private int count;
}
④、业务类
@RestController
public class BookController {
@Autowired
BookService bookService;
@RequestMapping(value = "/book", method = RequestMethod.GET)
public List<Book> getItems(){
return bookService.getBookList();
}
@RequestMapping(value = "/book",method = RequestMethod.POST)
public Boolean saveItem(Book book){
return bookService.save(book);
}
}
@Service
public class BookServiceImpl extends ServiceImpl<BookMapper, Book> implements BookService {
@Override
public List<Book> getBookList() {
return baseMapper.selectList(Wrappers.<Book>lambdaQuery());
}
@Override
public boolean save(Book book) {
return super.save(book);
}
}
public interface BookMapper extends BaseMapper<Book> {
}
⑤、创建表以及配置类中配置策略
#创建数据库表数据
CREATE DATABASE IF NOT EXISTS `db0`;
USE `db0`;
DROP TABLE IF EXISTS `book_0`;
CREATE TABLE `book_0` (
`id` INT ( 11 ) NOT NULL,
`name` VARCHAR ( 255 ) DEFAULT NULL,
`count` INT ( 11 ) DEFAULT NULL,
PRIMARY KEY ( `id` )
) ENGINE = INNODB DEFAULT CHARSET = utf8mb4;
DROP TABLE IF EXISTS `book_1`;
CREATE TABLE `book_1` (
`id` INT ( 11 ) NOT NULL,
`name` VARCHAR ( 255 ) DEFAULT NULL,
`count` INT ( 11 ) DEFAULT NULL,
PRIMARY KEY ( `id` )
) ENGINE = INNODB DEFAULT CHARSET = utf8mb4;
CREATE DATABASE IF NOT EXISTS `db1`;
USE `db1`;
DROP TABLE IF EXISTS `book_0`;
CREATE TABLE `book_0` (
`id` INT ( 11 ) NOT NULL,
`name` VARCHAR ( 255 ) DEFAULT NULL,
`count` INT ( 11 ) DEFAULT NULL,
PRIMARY KEY ( `id` )
) ENGINE = INNODB DEFAULT CHARSET = utf8mb4;
DROP TABLE IF EXISTS `book_1`;
CREATE TABLE `book_1` (
`id` INT ( 11 ) NOT NULL,
`name` VARCHAR ( 255 ) DEFAULT NULL,
`count` INT ( 11 ) DEFAULT NULL,
PRIMARY KEY ( `id` )
) ENGINE = INNODB DEFAULT CHARSET = utf8mb4;
CREATE DATABASE IF NOT EXISTS `db2`;
USE `db2`;
DROP TABLE IF EXISTS `book_0`;
CREATE TABLE `book_0` (
`id` INT ( 11 ) NOT NULL,
`name` VARCHAR ( 255 ) DEFAULT NULL,
`count` INT ( 11 ) DEFAULT NULL,
PRIMARY KEY ( `id` )
) ENGINE = INNODB DEFAULT CHARSET = utf8mb4;
DROP TABLE IF EXISTS `book_1`;
CREATE TABLE `book_1` (
`id` INT ( 11 ) NOT NULL,
`name` VARCHAR ( 255 ) DEFAULT NULL,
`count` INT ( 11 ) DEFAULT NULL,
PRIMARY KEY ( `id` )
) ENGINE = INNODB DEFAULT CHARSET = utf8mb4;
# 数据源 db0,db1,db2
sharding.jdbc.datasource.names=db0,db1,db2
# 第一个数据库
sharding.jdbc.datasource.db0.type=com.zaxxer.hikari.HikariDataSource
sharding.jdbc.datasource.db0.driver-class-name=com.mysql.cj.jdbc.Driver
sharding.jdbc.datasource.db0.jdbc-url=jdbc:mysql://localhost:3306/db0?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC
sharding.jdbc.datasource.db0.username=root
sharding.jdbc.datasource.db0.password=Aa123456
# 第二个数据库
sharding.jdbc.datasource.db1.type=com.zaxxer.hikari.HikariDataSource
sharding.jdbc.datasource.db1.driver-class-name=com.mysql.cj.jdbc.Driver
sharding.jdbc.datasource.db1.jdbc-url=jdbc:mysql://localhost:3306/db1?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC
sharding.jdbc.datasource.db1.username=root
sharding.jdbc.datasource.db1.password=Aa123456
# 第三个数据库
sharding.jdbc.datasource.db2.type=com.zaxxer.hikari.HikariDataSource
sharding.jdbc.datasource.db2.driver-class-name=com.mysql.cj.jdbc.Driver
sharding.jdbc.datasource.db2.jdbc-url=jdbc:mysql://localhost:3306/db2?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC
sharding.jdbc.datasource.db2.username=root
sharding.jdbc.datasource.db2.password=Aa123456
# 水平拆分的数据库(表) 配置分库 + 分表策略 行表达式分片策略
# 分库策略
sharding.jdbc.config.sharding.default-database-strategy.inline.sharding-column=id
sharding.jdbc.config.sharding.default-database-strategy.inline.algorithm-expression=db$->{id % 3}
# 分表策略 其中book为逻辑表 分表主要取决于id行
sharding.jdbc.config.sharding.tables.book.actual-data-nodes=db$->{0..2}.book_$->{0..1}
sharding.jdbc.config.sharding.tables.book.table-strategy.inline.sharding-column=count
# 分片算法表达式
sharding.jdbc.config.sharding.tables.book.table-strategy.inline.algorithm-expression=book_$->{count % 2}
# 主键 UUID 18位数 如果是分布式还要进行一个设置 防止主键重复
#sharding.jdbc.config.sharding.tables.user.key-generator-column-name=id
# 打印执行的数据库以及语句
sharding.jdbc.config.props..sql.show=true
spring.main.allow-bean-definition-overriding=true
#读写分离
sharding.jdbc.datasource.dsmaster =
⑥、接口测试使用postman
GET请求------>http://localhost:8080/book
POST请求:------->http://localhost:8080/book?id=1&name=java编程思想&count=8
===================================================================
MyCat
一、MyCat安装
这里选用解压使用的方式:opt目录下(主要放置安装包),解压后的文件放到/usr/local目录下 cp -r mycat
CentOS7
JDK1.8 (MyCat 使用 Java 开发,因此,运行 MyCat ,一定要具备 Java 环境)
# 下载MyCat
wget http://dl.mycat.io/1.6.7.1/Mycat-server-1.6.7.1-release-20190213150257-linux.tar.gz
# 解压
tar -zxvf Mycat-server-1.6.7.1-release-20190213150257-linux.tar.gz
解压成功后,会出现一个 mycat 目录,进入到 mycat/conf 目录(其中需要关注的三个配置文件),对 mycat 进行配置:
①、修改schema.xml配置文件
- 首先在 schema 中指定逻辑库的名字,逻辑库是指 MyCat 中的库,这个库不存储数据,数据存储在 MySQL 中的物理库中
- 逻辑库中配置逻辑表,配置逻辑表时,需要指定 dataNode 节点, dataNode 就是指数据库存储的位置
- 配置 dataNode , dataNode 指定 dataHost 和物理库的名字
- dataHost 则配置 MySQL 的主机和从机的位置,登录密码等。主机和从机都可以配置多个。
②、配置 server.xml(server.xml 中主要配置 MyCat 的登录用户名和密码,以及需要操作的逻辑库)
③、配置完成后,进行验证
④、接下来就可以启动 MyCat 了 。
后台启动:执行 MyCat 解压目录下的 bin 目录下的 mycat 命令,可以启动 MyCat
./bin/mycat start
如果启动后,提示无法创建 mycat.pid 文件,就自己手动创建一个 mycat.pid 文件。启动成功之后,就可以在本地连接 MyCat 了,连接方式和 MySQL 一样,唯一的区别在于端口号不同
在连接 MyCat 之前,先在 MySQL 物理库中创建 db1、 db2 以及 db3 三个数据库
使用SQLyog连接
也可以在 cmd 命令行登录 MyCat :
登录成功后 ,在 MyCat 的窗口中,执行如下命令,创建表:
create table t_user
(
id integer primary key
,
username varchar
(
255
))
执行成功后,我们会发现物理库中出现了相应的表。接下来,手动往各个物理库的物理表中存储一条数据,然后在 MyCat 窗口中查询:
修改配置文件schema.xml
实际应用的五种规则
一、global
该表会在所有的库中都创建,而且每一个库中都保存了该表的完整数据。
配置完成后,重启 mycat
./bin/mycat restart
重启完成后,要删除之前已经创建的 t_user 表,然后重新创建表,创建完成后,向表中插入数据,可以看到,db1、db2 以及 db3 中都有数据了
这里 虽然查询出来的记录只有一条,实际上 db1、db2 以及 db3 中都有该条记录。
总结:global 适合于 数据量不大、以查询为主、增删改较少的表。
二、sharding-by-intfile
枚举分片,就是在数据表中专门设计一个字段,以后根据这个字段的值来决定数据插入到哪个 dataNode 上
注意,在配置 sharding-by-intfile 规则时,一定要删除 type=“global” ,否则配置不会生效。具体配置如下:
配置完成后,还需要指定枚举的数据。枚举的数据可以在 rule.xml 中查看。
在 rule.xml 文件中,首先找到 tableRule 的名字为 sharding-by-intfile 的节点,这个节点中定义了两个属性,
一个是 columns 表示一会在数据表中定义的枚举列的名字(数据表中一会需要创建一个名为 sharding_id 的列,这个列的值决定了该条数据保存在哪个数据库实例中),这个名字可以自定义;另外一个属性叫做 algorithm ,这是指 sharding-by-intfile 所对应的算法名称。根据这个名称,可以找到具体的算法:
还是在 rule.xml 文件中,我们找到了 hash-int ,class 表示这个算法对应的 Java 类的路径。第一个属性 mapFile 表示相关的配置文件,从这个文件名可以看出,这个文件 就在 conf 目录下。
打开 conf 目录下的 partition-hash-int.txt 文件,内容如下:
前面的数字表示枚举的值 ,后面的数字表示 dataNode 的下标,所以前面的数字可以自定义,后面的数字不能随意定义。
配置完成后,重启 MyCat ,然后进行测试:
drop table if EXISTS t_user ;
create table t_user ( id integer primary key , username varchar ( 255 ), sharding_id integer );
insert into t_user ( id , username , sharding_id ) values ( 1 , 'www.javaboy.org' , 0 );
insert into t_user ( id , username , sharding_id ) values ( 1 , 'www.javaboy.org' , 1 );
insert into t_user ( id , username , sharding_id ) values ( 1 , 'www.javaboy.org' ,2 );
SELECT * FROM t_user ;
执行完后,sharding_id 对应值分别为 0 、1 、2 的记录分别插入到 db1 、db2 以及 db3 中。
三、auto-sharding-long
auto-sharding-long 表示按照既定的范围去存储数据。就是提前规划好某个字段的值在某个范围时,相应的记录存到某个 dataNode 中。
配置方式,首先修改路由规则:
然后去 rule.xml 中查看对应的算法了规则相关的配置:
可以看到,默认是按照 id 的范围来划分数据的存储位置的,对应的算法就是 rang-long 。
继续查看,可以找到算法对应的类,以及相关的配置文件,这个配置文件也在 conf 目录下,打开该文件:
如上配置,表示 当 id 的取值在 0-5之间时,将数据存储到 db1 中,当 id 在 5-10 之间时,存储到 db2 中,当 id 的取值在 10-1500W 之间时,存储到 db3 中。
配置完成后,重启 MyCat ,测试:
四、mod-long
取模:根据表中的某一个字段,做取模操作。根据取模的结果将记录存放在不同的 dataNode 上。这种方式不需要再添加额外字段。
然后去 rule.xml 中配置一下 dataNode 的个数
可以看到,取模的字段是 id ,取模的算法名称是 mod-long ,再看具体的算法:
在具体的算法中,配置了 dataNode 的个数为 3。
然后保存退出,重启 MyCat,进行测试:
五、sharding-by-murmur
前面介绍的几种方式,都存在一个问题,如果数据库要扩容,之前配置会失效,可能会出现数据库查询紊乱。因此我们要引入一致性 hash 这样一种分片规则,可以解决这个问题。具体配置和前面一样:
另外需要注意,在 rule.xml 中修改默认 dataNode 的数量:
修改完后,重启 MyCat ,进行测试。
六、sharding_by_date
按天分片、设定时间格式、范围
实操:
一、水平分表
schema.xml文件中,为orders表设置数据节点dn1\dn2,并指定分片规则为mod_rule(自定义的名字)
rule.xml文件中,新增分片规则,并指定规则使用字段customer_id
选择分片算法mod-long(对字段求模运算),customer_id对两个节点求模,根据结果分片配置算法mod-long参数count为2
在两个节点中创建orders表,然后重启mycat
ER表
①、schema.xml配置文件中,主表里面添加子表(订单详情表)
②、关联查询
全局表
当业务表因为规模进行分片,业务表和这些附属的字典表之间的关联,考虑以下几个特性:
- 变动不频繁
- 数据量总体变化不大
- 数据规模不大
多个数据节点都需要,称之为全局表。全局表的插入、更新需要在所有节点上执行
全局表的操作,只从一个节点获取
全局表可以跟任何一个表进行join操作
全局序列
实现分库分表的主键唯一性,MyCat提供了全局sequence
提供了本地配置和数据库配置等多种实现方式
一、本地文件
此方式MyCat将sequence配置到文件中,当使用到sequence中的配置后,MyCat会更改classpath中的sequence_conf.properties文件中的sequence当前的值。
优点:本地加载,读取速度较快
缺点:抗风险能力差,MyCat所在主机宕机后,无法读取本地文件
二、数据库
利用数据库一个表,来进行计数累加,但并不是每次生成序列都读写数据库,这样效率太低。
MyCat会预加载一部分号段到内存,大部分读写序列都在内存中完成的。
如果内存中的号段用完了,MyCat会再向数据库要一次。
①、创建全局序列表
②、创建三个函数
③、初始化序列表
④、修改mycat配置
⑤、插入数据并验证
三、时间戳方式
全局序列ID=64位二进制(42位毫秒数字+5位机器ID+5位业务编码+12重复累加)换成十进制位18位数的long类型
每毫秒并发12位二进制的累加
优点:配置简单
缺点:18位ID过长
四、自主生成全局序列
可在java项目里生成全局序列:
①、根据业务逻辑组合
②、利用redis单线程原子性incr生成序列
基于HA机制的MyCat高可用
HAProxy+Keepalived高可用
HAProxy实现了MyCat多节点的集群高可用和负载均衡
其自身的高可用可通过keepalived实现
一、HaProxy安装
①、上传HaProxy安装包到/opt目录下
②、解压到/usr/local/src目录
tar -zxvf haproxy-1.5.18.tar.gz -C /usr/local/src
③、进入解压目录后查看内核版本,进行编译
④、编译完成,进行安装
make install PREFIX=/usr/local/haproxy
⑤、安装完成后,创建目录,创建HAProxy配置文件
mkdir -p /usr/data/haproxy/
vim /usr/local/haproxy/haproxy.conf
⑥、向配置文件中插入以下配置信息,并保存
⑦、启动验证
输入以上配置文件时设定的用户名和密码
验证负载均衡,通过HaProxy访问MyCat
mysql -umycat -p123456 -h 192.168.140.125 -P 48066
二、Keepalived安装
①、上传安装包到/opt目录下,解压到/usr/local/src
tar -zxvf keepalived-1.4.2.tar.gz -C /usr/local/src
②、安装依赖插件
yum install -y gcc openssl-devel popt-devel
③、进入解压后的目录,进行配置,进行编译
cd /usr/local/src/keepalived-1.4.2
./configure --prefix=/usr/local/keepalived
④、进行编译,完成后进行安装
make && make install
⑤、运行前配置
⑥、修改配置文件
vim /etc/keepalived/keepalived.conf
⑦、启动验证
MyCat安全
一、权限配置
①、server.xml中的user标签权限控制
启动./mycat console
查询数据成功
插入数据失败
②、user标签下的privileges标签对逻辑库(schema)、表(table)进行精细化DML权限控制
privileges标签下的check属性,如为true开启权限检查,为false不开启,默认为false
由于mycat一个用户的schemas属性可配置多个逻辑库,所以privileges的下级节点schema节点同样可配置多个
对多库多表进行细粒度的DML权限控制
二、SQL拦截白名单、黑名单
firewall标签:定义防火墙
- whitehost标签定义IP白名单
- blacklist定义SQL黑名单
①、白名单,实现某主机某用户访问MyCat,其他主机用户禁止访问
②、黑名单,实现对具体SQL操作的拦截,如增删改查等操作的拦截
监控平台
MyCat-web,引入了ZooKeeper配置中心,管理多个节点
一、安装zooKeeper
①、官网http://zookeeper.apache.org下载安装包,上传到/opt目录下
②、解压tar -zxvf zooleeper-3.4.11.tar.gz
③、进入ZooKeeper解压后打的配置目录conf,复制配置文件并改名 cp zoo_sample.cfg zoo.cfg
④、进入ZooKeeper的命令目录bin,运行启动命令 ./zkServer.sh start
⑤、ps -ef|grep zookeeper 查看是否启动 或者查看netstat -ant | grep 2181
二、安装MyCat-web
①、下载安装包http://www.mycat.io
②、安装包拷贝到/opt目录下,并解压tar -zxvf MyCat-web-1.0-xxx.tar.gz
③、拷贝mycat-web文件夹到/usr/local目录下
cp -r mycat-web /usr/local
④、进入mycat-web目录下运行启动命令 ./start.sh & 后台启动。
⑤、查看netstat -ant | grep 8082
三、配置指标
①、配置zookeeper地址
②、mycat配置(注意mycat配置的白名单防火墙和linux本身的防火墙)