16-MyCat

一 Mycat概述

1 什么是Mycat

在这里插入图片描述

什么是Mycat

Mycat是数据库中间件,所谓数据库中间件是连接Java应用程序和数据库中间的软件。

在这里插入图片描述

为什么要用Mycat

在这里插入图片描述

遇到问题:

  • Java与数据库的紧耦合
  • 高访问量高并发对数据库的压力
  • 读写请求数据不一致

在这里插入图片描述

2 Mycat与其他中间件区别

在这里插入图片描述

目前的数据库中间件有很多,并从各个维度将其与 Mycat进行对比。

Mycat优势

在这里插入图片描述

性能可靠稳定

基于阿里开源的Cobar产品而研发,Cobar的稳定性、可靠性、优秀 的架构和性能以及众多成熟的使用案例使得MYCAT一开始就拥有一 个很好的起点,站在巨人的肩膀上,我们能看到更远。

强大的技术团队

MyCat现在由一支强大的技术团队维护 , 吸引和聚集了一大批业内 大数据和云计算方面的资深工程师、架构师、DBA,优秀的团队保 障了MyCat的稳定高效运行。而且MyCat不依托于任何商业公司, 而且得到大批开源爱好者的支持。

体系完善

MyCat已经形成了一系列的周边产品,比较有名的是 Mycat-web、 Mycat-NIO、Mycat-Balance 等,已经形成了一个比较完整的解决方案,而不仅仅是一个中间件。

3 Mycat应用场景

在这里插入图片描述

Mycat还形成了一系列周边产品,比较有名的是 Mycat-web、 Mycat-NIO、Mycat-Balance等,已成为一个比较完整的数据处理解决方案,而不仅仅是中间件。

高可用性与MySQL读写分离

利用Mycat可以轻松实现热备份,当一台服务器停机时,可以由双机或集群中的另一台服务器自动接管其业务,从而在无须人工干预的情况下,保证系统持续提供服务。这个切换动作由Mycat自动完成。

在这里插入图片描述

注意:

Mycat 的读写分离及自动切换都依赖于数据库产品的主从数据同步。

100亿大表水平分表、集群并行计算

数据切分是Mycat的核心功能,是指通过某种特定的条件,将存放在同一个数据库中的数据分散存放在多个数据库(主机)中,以达到分散单台设备负载的效果。

在这里插入图片描述

数据切分有两种切分模式

  • 按照不同的表将数据切分到不同的数据库中,这种切分可以叫作数据的垂直切分。
  • 根据表中数据的逻辑关系,将同一个表中的数据按照某种条件拆分到多个数据库中,这种切分叫作数据的水平切分。当数据量超过800万行且需要做分片时,可以利用Mycat实现数据切分。

数据库路由器

Mycat基于MySQL 实例的连接池复用机制,可以让每个应用最大程度地共享一个MySQL实例的所有连接池,让数据库的并发访问能力大大提升。

整合多种数据源

当一个项目需要用到多种数据源如Oracle、MySQL、SQL Server、 PostgreSQL时,可以利用Mycat进行整合,只需访问Mycat 这一个数据源就行。

在这里插入图片描述

4 核心概念详解

在这里插入图片描述

逻辑库schema

业务开发人员通常在实际应用中并不需要知道中间件的存在,只需要关注数据库,所以数据库中间件可以被当作一个或多个数据库集群构成的逻辑库。

在这里插入图片描述

注意:

逻辑库,与MySQL中的Database(数据库)对应,⼀个逻辑库中定义了所包括的Table。

逻辑表table

既然有逻辑库,就会有逻辑表。在分布式数据库中,对于应用来说,读写数据的表就是逻辑表。逻辑表可以分布在一个或多个分片库中,也可以不分片。

在这里插入图片描述

注意:
Table:表,即物理数据库中存储的某⼀张表,与传统数据库不同,这⾥的表格需要声明其所存储的逻辑数据节点DataNode。

分片节点DataNode

数据切分后,一个大表被分到不同的分片数据库上面,每个表分片所在的数据库就是分片节点dataNode。

在这里插入图片描述

节点主机DataHost

数据切分后,每个分片节点(dataNode)不一定都会独占一台机器, 同一机器上面可以有多个分片数据库,这样一个或多个分片节点 (dataNode)所在的机器就是节点主机(dataHost),为了规避单节点主机并发数限制,尽量将读写压力高的分片节点(dataNode)均衡的放 在不同的节点主机(dataHost)。

用户

MyCat的用户(类似于MySQL的用户,支持多用户)

在这里插入图片描述

5 Mycat原理

在这里插入图片描述

Mycat 的原理中最重要的一个动词是“拦截”,它拦截了用户发送过来的SQL 语句。

在这里插入图片描述

流程:

首先对 SQL 语句做了一些特定的分析:如分片分析、路由分析、读写分离分析、缓存分析等,然后将此 SQL 发往后端的真实数据库,并将返回的结果做适当的处理,最终再返回给用户。

流程示例

在这里插入图片描述

  • 解析SQL语句涉及的表。
  • 查看表的定义,如果表存在分片规则,则获取SQL语句的分片字段。
  • 将SQL语句发送到相应的分片去执行。
  • 最后处理所有分片返回的数据并返回给客户端。

二 Mycat部署安装

1 MySQL主从复制概述

在这里插入图片描述

为什么要主从复制

在这里插入图片描述

注意:

MySQL是现在普遍使用的数据库,但是如果宕机了必然会造成数据丢失。为了保证MySQL数据库的可靠性。就要会一些提高可靠性的技术。

如何解决性能问题

生活中有很形象的例子,比如你在自助咖啡厅买咖啡(如果只有一 台咖啡机)

在这里插入图片描述

如果有多台咖啡机,很明显大家买咖啡的效率就上去了:

在这里插入图片描述

MySQL主从复制原理

在这里插入图片描述

原理:

主从复制的原理则是采用binlog文件进行复制,我们都知道 MySQL的数据库会产生一个二进制日志,就是binlog,该日志文件记录了数据的任何修改,所以我们的从机Slave会往主机读取二进制的binlog日志到本机的I/O thread中,然后写入一个Relay log文件中,从机开启一个SQL thread 定时检查Realy log 文件,如果发现有更新立即把更新的内容在本地的数据库上执行。

binlog 日志的三种格式

  • Statement:每一条会修改数据的sql都会记录在binlog中
  • Row: 仅保存哪条记录被修改
  • Mixed: 以上两种的混合使用,一般的语句修改用statement,全表更新使用Row,但是无法使用 @@host name。

在这里插入图片描述

二进制日志管理

二进制日志位置

在my.cnf文件中使用 log-bin = 指定;命名规则为 mysqlbin.000000 (后为6位数字)

mysql> show variables like '%log_bin%' ;

查看二进制日志格式

mysql> show variables like '%format%';

查看当前使用的二进制日志文件

mysql> show master status;

2 搭建MySQL主从复制

在这里插入图片描述

安装MySQL数据库

下载YUM库

wget http://dev.mysql.com/get/mysql57-community-release-el7-10.noarch.rpm

安装YUM库

rpm -ivh mysql57-community-release-el7-10.noarch.rpm

安装MySQL服务

yum -y install mysql-community-server

遇到报错

Failing package is: mysql-community-libscompat-5.7.37-1.el7.x86_64GPG Keys are configured as:
file:///etc/pki/rpm-gpg/RPM-GPG-KEY-mysql

失败原因: GPG对于包的源key的验证没有通过。

解决办法

在yum install 版本后面加上 --nogpgcheck

yum -y install mysql-community-server --nogpgcheck

完成安装,重启mysql

systemctl restart mysqld

日志文件中找出密码

grep "password" /var/log/mysqld.log

修改密码策略

set global validate_password_policy=0;
set global validate_password_policy=LOW;
set global validate_password_length=6;

密码策略修改完以后可以修改密码

ALTER USER 'root'@'localhost' IDENTIFIED BY '123456';

开启远程连接

use mysql;
update user set host="%" where user="root";

刷新信息

 flush privileges;

开启bin-log日志

修改主服务器Master

修改配置文件:vim /etc/my.cnf
#主服务器唯一ID
server-id=1
#启用二进制日志
log-bin=mysql-bin

修改从服务器slave

修改配置文件:vim /etc/my.cnf
#从服务器唯一ID
server-id=2
#启用中继日志,从主服务器上同步日志文件记录到本地
relay-log=mysql-relay

重启两台服务器的mysql

service mysqld restart

在主服务器上建立帐户并授权slave

mysql>GRANT REPLICATION SLAVE ON *.* to 'slave'@'%' identified by '123456';

注意:

mysql权限管理语法:GRANT 权限 ON 数据库.表 TO 用户名@登录主机 IDENTIFIED BY “密码”

登陆主机:

字段含义
%匹配所有主机

权限列表:

权 限作用范围作 用
replication slave服务器主从复制

一般不用root帐号,“%”表示所有客户端都可能连,只要帐号, 密码正确,此处可用具体客户端IP代替,如192.168.145.226, 加强安全。

查询Master的状态

mysql>show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000001 |      430 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+

注意:

执行完此步骤后不要再操作主服务器MYSQL,防止主服务器状态值变化。

配置从服务器Slave

mysql>change master to master_host='192.168.66.111',master_user='slave',master_password='123456',master_log_file='mysql-bin.000001',master_log_pos=430;

注意: 注意不要断开,430数字前后无单引号。

启动从服务器复制功能

mysql>start slave;

检查从服务器复制功能状态

show slave status \G;

在这里插入图片描述

注意:

Slave_IO及Slave_SQL进程必须正常运行,即YES状态,否则都是错误的状态(如:其中一个NO均属错误)。

主从服务器测试

主服务器Mysql,建立数据库,并在这个库中建表插入一条数据

mysql> create database test;
Query OK, 1 row affected (0.00 sec)mysql> use test;
Database changedmysql> create table dog(id int(3),name varchar(255));
Query OK, 0 rows affected (0.00 sec)mysql> insert into dog values(001,'zhuti');
Query OK, 1 row affected (0.00 sec)

从服务器Mysql查询

mysql>show databases;
mysql>use test;
mysql>select * from dog; 

3 基于Docker搭建MySQL主从复制

在这里插入图片描述

首先拉取Docker镜像

docker pull mysql:5.7

启动两个容器

#启动Master
docker run -p 3350:3306 --name master -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7
#启动Slave
docker run -p 3340:3306 --name slave -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7

注意:

  • –name:为容器指定名称,这里是master
  • -p:将容器的指定端口映射到主机的指定端口,这里是将容器的3306端口映射到主机的3306 端口
  • -e:设置环境变量,这里是指定root账号的密码为123456
  • -d:后台运行容器,并返回容器ID

获取两个容器IP地址

[root@localhost mycat]# docker inspect master
[root@localhost mycat]# docker inspect slave

检验是否启动成功

docker ps -a 显示所有的容器,包括未运行的

注意:

是UP状态,表示正在运行中。

配置Master

进入master容器内部

docker exec -it master /bin/bash

修改mysqld.cnf配置

#切换目录
vim /etc/mysql/mysql.conf.d/mysqld.cnf
#修改配置文件加入
[mysqld]
## 同一局域网内注意要唯一
server-id=100  
## 开启二进制日志功能,可以随便取(关键)
log-bin=mysql-bin

注意:

vi my.cnf 对my.cnf进行编辑。此时会报出 bash: vi: command not found , 需要我们在docker容器内部自行安装vim。使用 apt-get install vim 命令安装vim

如果报错:

Reading package lists… Done Building dependency tree Reading state information… Done E: Unable to locate package vim

更新apt-get

apt-get update

安装vim

apt-get install vim

CentOS5.4

# apt-get install vim

bash: apt-get: command not found

解答

CentOS的软件安装工具不是apt-get 是yum
# yum -y install vim

重启mysql服务

service mysql restart
docker start master

在Master数据库创建数据同步用户

mysql> GRANT replication SLAVE ON *.* TO 'slave' @'%' IDENTIFIED BY '123456';

配置Slave

和配置Master(主)一样,在Slave配置文件mysqld.cnf中添加如下配置

#切换目录
vim /etc/mysql/mysql.conf.d/mysqld.cnf
[mysqld]
## 设置server_id,注意要唯一
server-id=101  
## 开启二进制日志功能,以备Slave作为其它Slave的Master时使用
log-bin=mysql-slave-bin  
## relay_log配置中继日志
relay_log=edu-mysql-relay-bin

注意:

配置完成后也需要重启mysql服务和docker容器,操作和配置 Master(主)一致。

连接接Master(主)和Slave(从)

在Master进入mysql

show master status;

在这里插入图片描述

在Slave 中进入 mysql

mysql>change master to master_host='172.17.0.2',master_user='slave',master_password='123456',master_log_file='mysql-bin.000001',master_log_pos=443;

参数:

  • master_host: Master 的IP地址
  • master_user: 在 Master 中授权的用于数据同步的用户
  • master_password: 同步数据的用户的密码
  • master_port: Master 的数据库的端口号
  • master_log_file: 指定 Slave 从哪个日志文件开始复制数据,即上文中提到的 File 字段的值
  • master_log_pos: 从哪个 Position 开始读,即上文中提到的 Position 字段的值
  • master_connect_retry: 当重新建立主从连接时,如果连接失败,重试的时间间隔,单位是秒,默认是60秒。

在Slave中开启主从复制

mysql> start slave;

在 Slave 的 MySQL 终端执行查看主从同步状态

show slave status \G;

在这里插入图片描述

4 Mycat安装以及管理命令详解

在这里插入图片描述

由于mycat是java语言编写,所以得先安装jdk

解压jdk安装包

tar -zxvf jdk-8u201-linux-x64.tar.gz -C /usr/local

配置环境变量

vim /etc/profile
底部加入如下配置
export JAVA_HOME=/usr/local/jdk
export PATH=$PATH:$JAVA_HOME/bin

生效环境变量

source /etc/profile

下载解压Mycat安装包

MyCAT 有提供编译好的安装包,支持 windows、Linux、Mac、 Solaris 等系统上安装与运行。

tar -zxvf Mycat-server-1.6.7.1-release-20190627191042-linux.tar.gz -C /usr/local

将MyCat配置到环境变量中

vim /etc/profile
#增加如下配置
export MYCAT_HOME=/usr/local/mycat
export PATH=$PATH:$MYCAT_HOME/bin

MyCat常用操作命令

mycat start           #启动MyCat
mycat stop           #停止MyCat
mycat console         #前台运行MyCat带控制台输出
mycat restart         #重启MyCat
mycat pause           #暂停MyCat
mycat status         #查看启动状态

使用MySQL命令进行MyCat的连接

Mycat 提供类似数据库的管理监控方式,可以通过MySQL命令行登录管理端口(9066)执行相应的SQL语句进行管理,也可以通过 JDBC方式进行远程连接管理。

在这里插入图片描述

管理端口

9066用于查看MyCat的运行状态

mysql -uroot -p123456 -h 192.168.66.111 -P9066 -DTESTDB

参数

  • -h:后面是主机。 即当前Mycat安装的主机IP地址。
  • -u:Mycat server.xml中配置逻辑库的用户。
  • -p:Mycat server.xml中配置逻辑库的密码。
  • -P:后面是管理端口号。注意P是大写。
  • -d:Mycat server.xml中配置逻辑库。

数据端口

8066用于进行数据的CRUD操作

mysql -uroot -p123456 -h 192.168.66.111 -P8066 -DTESTDB

MyCat的连接用户名相关信息在配置文件 /usr/local/mycat/conf/server.xml 中查 看编辑

<user name="root"><property name="password">123456</property><property name="schemas">TESTDB</property>
</user>

Show命令

-- 查看所有的可用命令
show @@help;  
-- 查看所有的逻辑数据库
show @@database;
-- 查看所有的数据节点
show @@datanode;
-- 查看所有的数据源
show @@datasource;

5 核心配置文件及目录结构

在这里插入图片描述

目录结构

在这里插入图片描述

说明:

  • bin:可执行命令
  • conf:配置文件
  • lib:存放jar包
  • logs:日志信息
  • tmlogs:临时日志
  • version.txt:版本信息

三个配置文件

  • schema.xml:定义逻辑库,表、分片节点等内容
  • rule.xml:定义分片规则
  • server.xml:定义用户以及系统相关变量,如端口等

三 Mycat高级特性

1 读写分离概述

在这里插入图片描述

什么是读写分离

读写分离,基本的原理是让数据库处理事务性增、改、删操作, 而数据库处理查询操作。

为什么使用读写分离

从集中到分布,最基本的一个需求不是数据存储的瓶颈,而是在于计算的瓶颈,即 SQL 查询的瓶颈,我们知道,正常情况下,Insert SQL 就是几十个毫秒的时间内写入完成,而系统中的大多数 Select SQL 则要几秒到几分钟才能有结果,很多复杂的 SQL,其消耗服务器 CPU 的能力超强,不亚于死循环的威力。

读写分离方案

MyCat的读写分离是建立在MySQL主从复制基础之上实现的,所以必须先搭建MySQL的主从复制。数据库读写分离对于大型系统或者访问量很高的互联网应用来说,是必不可少的⼀个重要功能。

在这里插入图片描述

注意:

Mycat实现的读写分离和自动切换机制,需要MySQL的主从复制机制配合。

Mysql 主从复制的常用拓扑结构

一主一从

在这里插入图片描述

注意:

最基础的复制结构,用来分担之前单台数据库服务器的压力, 可以进行读写分离。

一主多从

在这里插入图片描述

注意:

一台 Slave 承受不住读请求压力时,可以添加多台,进行负载均衡,分散读压力。

双主复制

在这里插入图片描述

注意:

双主结构就是用来解决这个问题的,互相将对方作为自己的 Master,自己作为对方的 Slave 来进行复制,但对外来讲,还是一个主和一个从。

级联复制

在这里插入图片描述

注意:

级联结构就是通过减少直接从属于 Master 的 Slave 数量,减轻 Master 的压力,分散复制请求,从而提高整体的复制效率。

双主级联

在这里插入图片描述

注意:

Mysql 的复制结构有很多种方式,复制的最大问题是数据延时,选择复制结构时需要根据自己的具体情况,并评估好目标结构的延时对系统的影响。

2 搭建读写分离

在这里插入图片描述

修改配置文件schema.xml

<schema name="TESTDB" checkSQLschema="false" dataNode="db_node" sqlMaxLimit="100">
</schema>

参数:

  • schema:逻辑库
  • name :逻辑库名称
  • sqlMaxLimit:一次取多少条数据
  • table:逻辑表
  • dataNode:分片节点 对应 dataNode标签
  • rule:分片规则 对应 rule.xml
  • primaryKey: 分片主键 可缓存

分片配置

<dataNode name="db_node" dataHost="db_host" database="db_test" />

参数

  • name:分片名字
  • dataHost:节点主机
  • database:真实的数据库

配置读写分离

<dataHost name="host1" maxCon="1000" minCon="10" balance="2"
writeType="0" dbType="mysql" dbDriver="native" switchType="1"
slaveThreshold="100"><writeHost host="" url="" user="" password=""></writeHost>
</dataHost>

参数:

  • dataHost:数据主机(节点主机)
  • dbType:数据库驱动native:MySQL JDBC: oracle SQLServer
  • switchType: 是否主动读 1

Balance参数设置:

  • balance=“0”, 所有读操作都发送到当前可⽤的writeHost上。
  • balance=“1”,所有读操作都随机的发送到readHost。
  • balance=“2”,所有读操作都随机的在writeHost、readhost上分发

WriteType参数设置:

  • writeType=“0”, 所有写操作都发送到可⽤的writeHost上。
  • writeType=“1”,所有写操作都随机的发送到readHost。
  • writeType=“2”,所有写操作都随机的在writeHost、readhost分上发。

witchType参数设置:

  • switchType=“1”, 主从自动切换
  • switchType=“2”,从机延时超过slaveThreshold值时切换为主读

启动Mycat

mycat restart

在这里插入图片描述

配置文件

<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/"><!-- 数据库配置 与server.xml 中的数据库对应 --><schema name="TESTDB" checkSQLschema="false" dataNode="db_node" sqlMaxLimit="100">  </schema><!-- 分片配置 --><!-- dataNode的database对应物理数据库(实际存在) --><!-- dataNode里设置的database为我们做主从同步的数据库名 --><dataNode name="db_node" dataHost="db_host" database="test" /><!-- 物理数据库配置 --><dataHost name="db_host" maxCon="1000" minCon="10" balance="1"writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100"><heartbeat>select user()</heartbeat><writeHost host="hostM1" url="192.168.66.111:3350" user="root" password="123456"><readHost host="hostS2" url="192.168.66.111:3340" user="root" password="123456" /></writeHost></dataHost></mycat:schema>

验证读写分离

在mycat中插入

insert into dog values(1,@@hostname);

注意: @@代表系统变量。

在mycat查询

select * from dog;

结果为writeHost的主机名

3 MySQL双主双从原理

在这里插入图片描述

一主一从

在这里插入图片描述

注意:

是最基础的复制结构,用来分担之前单台数据库服务器的压力,可以进行读写分离。

一主多从

在这里插入图片描述

问题:

一台 Slave 承受不住读请求压力时,可以添加多台,进行负载均衡,分散读压力。

如何解决

在这里插入图片描述

介绍:

互相将对方作为自己的 Master,自己作为对方的 Slave 来进行复制,但对外来讲,还是一个主和一个从。

4 搭建双主双从

在这里插入图片描述

环境准备

编号角色IP地址端口机器名
1Master1192.168.66.1113350node-1
2Slave1192.168.66.1113360node-2
3Master2192.168.66.1113370node-3
4Slave2192.168.66.1113380node-4

创建docker容器

#启动第一台
docker run -d -p 3350:3306 -e MYSQL_ROOT_PASSWORD=123456 --name=master1 mysql:5.7
#启动第二台
docker run -d -p 3360:3306 -e MYSQL_ROOT_PASSWORD=123456 --name=slave1 mysql:5.7
#启动第三台
docker run -d -p 3370:3306 -e MYSQL_ROOT_PASSWORD=123456 --name=master2 mysql:5.7
#启动第四台
docker run -d -p 3380:3306 -e MYSQL_ROOT_PASSWORD=123456 --name=slave2 mysql:5.7

修改容器内MySQL配置文件

vim /etc/mysql/mysql.conf.d/mysqld.cnf

1、修改master1配置文件

[mysqld]
#主服务器唯一ID
server-id=1
#启用二进制日志
log-bin=mysql-bin# 设置不要复制的数据库(可设置多个)
binlog-ignore-db=mysql
binlog-ignore-db=information_schema#设置需要复制的数据库
binlog-do-db=test#设置logbin格式
binlog_format=STATEMENT# 在作为从数据库的时候,有写入操作也要更新二进制日志文件
# 由于主机宕机后会变成备用主机,所以有写操作的时候也需要更新日志
log-slave-updates#指自增字段的起始值,其默认值是1,取值范围是1 .. 65535
auto-increment-increment=2# 指字段一次递增多少,他的取值范围是1 .. 65535
auto-increment-offset=1

2、修改master2配置文件

[mysqld]
#主服务器唯一ID
server-id=3 
#启用二进制日志
log-bin=mysql-bin# 设置不要复制的数据库(可设置多个)
binlog-ignore-db=mysql
binlog-ignore-db=information_schema#设置需要复制的数据库
binlog-do-db=test#设置logbin格式
binlog_format=STATEMENT# 在作为从数据库的时候,有写入操作也要更新二进制日志文件
# 由于主机宕机后会变成备用主机,所以有写操作的时候也需要更新日志
log-slave-updates#指自增字段的起始值,其默认值是1,取值范围是1 .. 65535
auto-increment-increment=2# 指字段一次递增多少,他的取值范围是1 .. 65535
auto-increment-offset=1

3、修改slave1配置文件

[mysqld]
#从服务器唯一ID
server-id=2
#启用中继日志
relay-log=mysql-relay

4、修改slave2配置文件

[mysqld]
#从服务器唯一ID
server-id=4 
#启用中继日志
relay-log=mysql-relay

双主双从重启服务

service mysql restart
docker start master

配置数据库

1、分别在两个主库中执行创建从库连接账号命令

GRANT replication SLAVE ON *.* TO 'slave' @'%' IDENTIFIED BY '123456';

2、查看两主库的master状态

show master status;

两个从库连接到主库

# 在slave1中执行
change master to
master_host='192.168.66.111',
master_user='slave',
master_port=3350,
master_password='123456',
master_log_file='mysql-bin.000001',
master_log_pos=443;# 在slave2中执行
change master to
master_host='192.168.66.111',
master_user='slave',
master_port=3370,
master_password='123456',
master_log_file='mysql-bin.000001',
master_log_pos=443;

参数:

  • master_host:这里的ip就是mysql所在服务器对应的ip
  • master_user:就是在第一步配置的账号
  • master_port:mysql的端口
  • master_password:配置的密码
  • master_log_file:file参数
  • master_log_pos:Position参数

两个从库启动复制功能

start slave;

查看连接状态

show slave status \G;

两个主库再互相成为对方的从库

# 在master1上执行
change master to
master_host = '192.168.66.111',
master_user = 'slave',
master_password = '123456',
master_port = 3370,
master_log_file = 'mysql-bin.000001',
master_log_pos = 443;# 在master2上执行
change master to
master_host = '192.168.66.111',
master_user = 'slave',
master_password = '123456',
master_port = 3350,
master_log_file = 'mysql-bin.000001',
master_log_pos = 443;

两个主库启动复制功能

start slave;

查看连接状态

show slave status \G;

双主双从配置MyCat

vim schema.xml

<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/"><!-- 数据库配置 与server.xml 中的数据库对应 --><schema name="TESTDB" checkSQLschema="false" dataNode="db_node" sqlMaxLimit="100">  </schema><!-- 分片配置 --><dataNode name="db_node" dataHost="db_host" database="test" /><!-- 物理数据库配置 --><dataHost name="db_host" maxCon="1000" minCon="10" balance="1"  writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100"><heartbeat>select user()</heartbeat><writeHost host="hostM1" url="192.168.66.111:3350" user="root" password="123456"><readHost host="hostS1" url="192.168.66.111:3360" user="root" password="123456" /></writeHost><writeHost host="hostM2" url="192.168.66.111:3370" user="root" password="123456"><readHost host="hostS2" url="192.168.66.111:3380" user="root" password="123456" /></writeHost></dataHost></mycat:schema>

注意:

  • writeType=“0”:所有写操作发送到配置的第一个 writeHost,第一个挂了切到还生存的第二个writeHost,重新启动后已切换后的为准,切换记录在配置文件中:dnindex.properties.
  • writeType=“1”:所有写操作都随机的发送到配置的 writeHost,1.5 以后废弃不推荐。
  • switchType=“-1” :表示不自动切换 mysql 实例
  • switchType=“1” :默认值,自动切换

四 Mycat分片技术

1 垂直拆分

在这里插入图片描述

前沿

目前很多互联网系统都存在单表数据量过大的问题,这就降低了查询速度,影响了客户体验。为了提高查询速度,我们可以优化sql语句,优化表结构和索引,不过对那些百万级千万级的数据库表,即便是优化过后,查询速度还是满足不了要求。

垂直分割

垂直拆分是指数据表列的拆分,把一张列比较多的表拆分为多张表。表的记录并不多,但是字段却很长,表占用空间很大,检索表的时候需要执行大量的IO,严重降低了性能。这时需要把大的字段拆分到另一个表,并且该表与原表是一对一的关系。

在这里插入图片描述

拆分原则:

  • 把不常用的字段单独放在一张表
  • 把text,blob等大字段拆分出来放在附表中
  • 经常组合查询的列放在一张表中

在这里插入图片描述

举个例子

在这里插入图片描述

拆分思路:

如果我们只想查询id为8的学生的分数:select 分数 from 答题表 where id = 8;虽然知识查询分数,但是题目和回答这两个大字段也是要被扫描的,很消耗性能。但是我们只关心分数,并不想查询题目和回答。这就可以使用垂直分割。

实现分库

环境准备

编号IP地址端口机器名
1192.168.66.1113350node-1
2192.168.66.1113360node-2

创建docker容器

#启动第一台
docker run -d -p 3350:3306 -e MYSQL_ROOT_PASSWORD=123456 --name=node-1 mysql:5.7
#启动第二台
docker run -d -p 3360:3306 -e MYSQL_ROOT_PASSWORD=123456 --name=node-2 mysql:5.7

修改schema.xml配置文件

<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/"><schema name="TESTDB" checkSQLschema="false" dataNode="dn1" sqlMaxLimit="100"><table name="customer" dataNode="dn2"/></schema><dataNode name="dn1" dataHost="host1" database="orders" /><dataNode name="dn2" dataHost="host2" database="orders" /><dataHost name="host1" maxCon="1000" minCon="10" balance="0"writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100"><heartbeat>select user()</heartbeat><writeHost host="hostM1" url="192.168.66.111:3350" user="root" password="123456"></writeHost></dataHost><dataHost name="host2" maxCon="1000" minCon="10" balance="0"writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100"><heartbeat>select user()</heartbeat><writeHost host="hostM2" url="192.168.66.111:3360" user="root" password="123456"></writeHost></dataHost></mycat:schema>

新增两个空白库

分库操作不是在原来的老数据库上进行操作,需要准备两台机器分别安装新的数据库

#在数据节点 dn1、dn2 上分别创建数据库 orders
CREATE DATABASE orders;

启动Mycat

mycat start

Mycat进行分库

创建表

mysql -uroot -p123456 -h 192.168.66.111 -P8066mysql> use TESTDB;# 使用 mycat 创建四个表
create table customer(id int auto_increment,name varchar(200),primary key(id)
);
create table orders(id int auto_increment,order_type int,customer_id int,amount decimal(10,2),primary key(id)
);
create table orders_detail(id int auto_increment,order_id int,detail varchar(200),primary key(id)
);
create table dict_order_type(id int auto_increment,order_type varchar(200),primary key(id)
);

查看结果

在node-1中

mysql> use orders;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -ADatabase changed
mysql> show tables;
+------------------+
| Tables_in_orders |
+------------------+
| dict_order_type  |
| orders           |
| orders_detail    |
+------------------+
3 rows in set (0.00 sec)

在node-2中

mysql> use orders;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -ADatabase changed
mysql> show tables;
+------------------+
| Tables_in_orders |
+------------------+
| customer         |
+------------------+
1 row in set (0.00 sec)

2 水平拆分

在这里插入图片描述

前言

上面谈到垂直切分只是把表按模块划分到不同数据库,但没有解决单表大数据量的问题。

水平拆分

相对于垂直拆分,水平拆分不是将表做分类,而是按照某个字段的某种规则来分散到多个库之中,每个表中包含一部分数据。

在这里插入图片描述

理解:

我们可以将数据的水平切分理解为是按照数据行的切分,就是将表中的某些行切分到一个数据库,而另外的某些行又切分到其他的数据库中。

实现分表

1、 选择要拆分的表

MySQL 单表存储数据条数是有瓶颈的,单表达到 1000 万条数据就达到了瓶颈,会影响查询效率,需要进行水平拆分(分表)进行优化。

2、分表字段

以 orders 表为例,可以根据不同字段进行分表

编号分表字段效果
1id查询订单注重时效,历史订单被查询的次数少,如此分片会造成一个节点访问多,一个访问少,不平均。
2customer_id根据客户 id 去分,两个节点访问平均

3、 修改配置文件 schema.xml

为 orders 表设置数据节点为 dn1、dn2,并指定分片规则为 mod_rule(自定义的名字)

<table name="orders" dataNode="dn1,dn2" rule="mod_rule" ></table>

4、修改配置文件rule.xml

在这里插入图片描述

分片规则:

在 rule 配置文件里新增分片规则 mod_rule,并指定规则适用字段为 customer_id, 还有选择分片算法 mod-long(对字段求模运算),customer_id 对两个节点求模,根据结果分片配置算法 mod-long 参数 count 为 2,两个节点。

<tableRule name="mod_rule"><rule><columns>customer_id</columns><algorithm>mod-long</algorithm></rule>
</tableRule>
<function name="mod-long" class="io.mycat.route.function.PartitionByMod"><!-- 物理主机节点数量 --><property name="count">2</property>
</function>

5、 在数据节点dn2上建orders表(注意:承接上文中的环境,因为dn1中已经有orders表)

create table orders(id int auto_increment,order_type int,customer_id int,amount decimal(10,2),primary key(id)
);

6、 重启Mycat,让配置生效

mycat restart

7、 访问Mycat实现分片

mysql -uroot -p123456 -h 192.168.66.111 -P8066mysql> use TESTDB;INSERT INTO
orders(id,order_type,customer_id,amount)
VALUES (1,101,100,100100);
INSERT INTO
orders(id,order_type,customer_id,amount)
VALUES(2,101,100,100300);
INSERT INTO
orders(id,order_type,customer_id,amount)
VALUES(3,101,101,120000);
INSERT INTO
orders(id,order_type,customer_id,amount)
VALUES(4,101,101,103000);
INSERT INTO
orders(id,order_type,customer_id,amount)
VALUES(5,102,101,100400);
INSERT INTO
orders(id,order_type,customer_id,amount)
VALUES(6,102,100,100020);

查看结果

在node-1中

mysql> select * from orders;
+----+------------+-------------+-----------+
| id | order_type | customer_id | amount    |
+----+------------+-------------+-----------+
|  1 |        101 |         100 | 100100.00 |
|  2 |        101 |         100 | 100300.00 |
|  6 |        102 |         100 | 100020.00 |
+----+------------+-------------+-----------+
3 rows in set (0.00 sec)

在node-2中

mysql> select * from orders;
+----+------------+-------------+-----------+
| id | order_type | customer_id | amount    |
+----+------------+-------------+-----------+
|  3 |        101 |         101 | 120000.00 |
|  4 |        101 |         101 | 103000.00 |
|  5 |        102 |         101 | 100400.00 |
+----+------------+-------------+-----------+
3 rows in set (0.00 sec)

3 ER表

在这里插入图片描述

分片 join

在这里插入图片描述

遇到问题:

orders表分片了,那和他相关的orders_detail 表未分片, join联查的时候, node1正常查询出结果, node2上由于没有 orders_detail 表,则报错, 最后聚合结果肯定也是错误的。

ER 表

在这里插入图片描述

将子表的存储位置依赖于主表,并且物理上紧邻存放因此彻底解决了JION的效率和性能问题,根据这一思路,提出了基于E-R关系的数据分片策略,子表的记录与所关联的父表记录存放在同一个数据分片上。

修改配置文件schema.xml

<table name="orders" dataNode="dn1,dn2" rule="mod_rule" ><childTable name="orders_detail" primaryKey="id" joinKey="order_id" parentKey="id" />
</table>

参数:

  • childTable:子表

node2上没有订单详情表创建一下

create table orders_detail(
id int auto_increment,
order_id int,
detail varchar(200),
primary key(id)
);

重启Mycat服务

mycat restart

Mycat服务添加数据

mysql -uroot -p123456 -h 192.168.66.111 -P8066mysql> use TESTDB;insert into orders_detail(detail, order_id)
values('detail1',1);
insert into orders_detail(detail, order_id)
values('detail1',2);
insert into orders_detail(detail, order_id)
values('detail1',3);
insert into orders_detail(detail, order_id)
values('detail1',4);
insert into orders_detail(detail, order_id)
values('detail1',5);

测试数据

select a.*,b.detail from orders a join orders_detail b on a.id=b.order_id;

4 全局表

在这里插入图片描述

全局表描述

在分片的情况下,当业务表因为规模而进行分片以后,业务表与这些附属的字典表之间的关联,就成了比较棘手的问题,考虑到字典表具有以下几个特性:

  • 变动不频繁
  • 数据量总体变化不大
  • 数据规模不大,很少有超过数十万条记录。

全局表特征

  • 全局表的插入更新操作会实时在所有节点上执行,保持各个分片的数据一致。
  • 全局表的查询操作,只从一个节点获取。
  • 全局表可以和任何一个表进行 JOIN 操作。

注意:

将字典表或者符合字典表特性的一些表定义为全局表,则从另外一个方面,很好的解决了数据JOIN 的难题。通过全局表+基于E-R 关系的分片策略,Mycat 可以满足 80%以上的企业应用开发。

配置全局表

<!--全局表配置比较简单,不用写 Rule 规则,修改schema.xml,如下配置即可-->
<table name="dict_order_type" dataNode="dn1,dn2" type="global"></table>

在dn2创建 dict_order_type 表

#订单类型字典表
create table dict_order_type(id int auto_increment,order_type varchar(200),primary key(id)
);

重启Mycat

mycat restart

Mycat上添加数据

mysql -uroot -p123456 -h 192.168.66.111 -P8066mysql> use TESTDB;insert into
dict_order_type(id,order_type)values(101,'type1');
insert into
dict_order_type(id,order_type)values(102,'type2');

测试数据

select * from dict_order_type;

五 Mycat分片规则

1 取模

在这里插入图片描述

实现方式

取模分片就是根据数据表的某一个字段,通常是某一个整数型的字段,对其进行十进制的求模运算,将运算结果作为Mycat的路由结果。

注意:

  • 优点:这种策略可以很好的分散数据库写的压力。

  • 缺点:出现了范围查询,就需要MyCAT去合并结果,当数据量偏高的时候,这种跨库查询 +合并结果消耗的时间有可能会增加很多,尤其是还出现了order by的时候。

tableRule 标签

这个标签定义表规则。

<tableRule name="mod-long"><rule><columns>user_id</columns><algorithm>mod-long</algorithm></rule>
</tableRule>

参数:

  • name :属性指定唯一的名字,用于标识不同的表规则。 内嵌的 rule 标签则指定对物理表中的哪一列进行拆分和使用什么路由算法。
  • columns :内指定要拆分的列名字。
  • algorithm:使用 function 标签中的 name 属性。连接表规则和具体路由算法。当然,多个表规则可以连接到同一个路由算法上。

function标签

定义具体路由算法

<function name="mod-long" class="io.mycat.route.function.PartitionByMod"><!-- how many data nodes --><property name="count">2</property>
</function>

注意:

  • name 指定算法的名字。
  • class 制定路由算法具体的类名字。
  • property 为具体算法需要用到的一些属性。
  • count:表示需要取模的最大值,将数据分成该配置的切片。

2 分片枚举

在这里插入图片描述

实现原理

有些业务需要按照省份或区县来做保存,这类业务使用本条规则。

实现过程

在这里,需定义三个值,规则均是在rule.xml中定义。

  • tableRule
  • function
  • mapFile

创建示例表

#订单归属区域信息表
CREATE TABLE orders_ware_info(`id` INT AUTO_INCREMENT comment '编号',`order_id` INT comment '订单编号',`address` VARCHAR(200) comment '地址',`areacode` VARCHAR(20) comment '区域编号',PRIMARY KEY(id)
);

修改schema.xml配置文件

<table name="orders_ware_info" dataNode="dn1,dn2" rule="sharding-by-intfile"></table>

定义tableRule

<tableRule name="sharding-by-intfile"><rule><columns>areacode</columns><algorithm>hash-int</algorithm></rule>
</tableRule>

注意:

其中,sharding-by-intfile是规则名,会在schema.xml中 用到。columns指的是对省份进行分片。algorithm是算法名, 该算法必须在function中定义。

定义funtion

<function name="hash-int" class="io.mycat.route.function.PartitionByFileMap"><property name="mapFile">partition-hashint.txt</property><property name="type">1</property><property name="defaultNode">0</property></function>

注意:

  • mapFile:指的是配置文件名
  • type:默认值为0,0表示Integer,非零表示String。因为我接下来的测试是基于省份分片, 所以需type指定为1。
  • defaultNode 默认节点:小于0表示不设置默认节点,大于等于0表示设置默认节点 默认节点的作用:枚举分片时,如果碰到不识别的枚举值,就让它路由到默认节点。

修改partition-hash-int.txt配置文件

110=0
120=1

注意:

其中,110会被分发到第一个节点中,120分发被第二个节点中。

重启Mycat

mycat restart

插入数据

mysql -uroot -p123456 -h 192.168.66.111 -P8066mysql> use TESTDB;INSERT INTO orders_ware_info(id,order_id,address,areacode) VALUES (1,1,'beijing','110');
INSERT INTO orders_ware_info(id,order_id,address,areacode) VALUES (2,2,'tianjing','120');

3 范围约定

在这里插入图片描述

实现原理

此分片适用于,提前规划好分片字段某个范围属于哪个分片。

举个例子

比如将id在0-500W的数据分片在第一个节点上面,将id在500W1000W的数据分片在第二个节点上,依次类推下去。

优缺点:

  • 优点:适用于想明确知道某个分片字段的某个范围具体在哪一个节点;
  • 缺点:如果短时间内有大量的批量插入操作,那么某个分片节点可能一下子会承受比较大的 数据库压力,而别的分片节点此时可能处于闲置状态,无法利用其它节点进行分担压力(热点数据问题);

实现过程

创建示例表

#支付信息表
CREATE TABLE payment_info
(
`id` INT AUTO_INCREMENT comment '编号',
`order_id` INT comment '订单编号',
`payment_status` INT comment '支付状态',
PRIMARY KEY(id)
);

修改schema.xml配置文件

<table name="payment_info" dataNode="dn1,dn2" rule="auto-sharding-long" ></table>

定义tableRule

<tableRule name="auto-sharding-long"><rule><columns>order_id</columns><algorithm>rang-long</algorithm></rule>
</tableRule>

注意:

其中,auto_sharding_long是规则名,会在schema.xml中用到。columns指的是对订单id进行分片。algorithm是算法名, 该算法必须在function中定义。

定义function

<function name="rang-long" class="io.mycat.route.function.AutoPartitionByLong"><property name="mapFile">autopartitionlong.txt</property><property name="defaultNode">0</property>
</function>

注意:

  • mapFile:指的是配置文件名
  • type:默认值为0,0表示Integer,非零表示String。
  • defaultNode 默认节点:小于0表示不设置默认节点,大于等于0表示设置默认节点

修改autopartition-long.txt配置文件

0-102=0
103-200=1

重启Mycat

mycat restart

插入数据

mysql -uroot -p123456 -h 192.168.66.111 -P8066mysql> use TESTDB;INSERT INTO payment_info
(id,order_id,payment_status) VALUES (1,101,0);
INSERT INTO payment_info
(id,order_id,payment_status) VALUES (2,102,1);
INSERT INTO payment_info 
(id,order_id,payment_status) VALUES (3,103,0);
INSERT INTO payment_info
(id,order_id,payment_status) VALUES(4,104,1);

4 按日期(天)分片

在这里插入图片描述

实现原理

此规则为按天分片,设定时间格式、范围。

实现过程

创建示例表

#用户信息表
create table login_info(id int auto_increment comment '编号',user_id int comment '用户编号',login_date date comment '登录时间',primary key(id)
);

修改schema.xml配置文件

<table name="login_info" dataNode="dn1,dn2" rule="sharding-by-date" ></table>

修改rule.xml配置文件

<tableRule name="sharding-by-date"><rule><columns>login_date</columns><algorithm>shardingByDate</algorithm></rule>
</tableRule>

参数:

  • columns:分片字段,
  • algorithm:分片函数

定义function

<function name="shardingByDate" class="io.mycat.route.function.PartitionByDate"><property name="dateFormat">yyyy-MM-dd</property><property name="sBeginDate">2040-01-01</property><property name="sEndDate">2040-01-04</property><property name="sPartionDay">2</property>
</function>

在这里插入图片描述

参数:

  • dateFormat :日期格式
  • sBeginDate :开始日期
  • sEndDate:结束日期,则代表数据达到了这个日期的分片后循环从开始分片插入
  • sPartionDay :分区天数,即默认从开始日期算起,分隔 2 天一个分区

重启Mycat

mycat restart

插入数据

mysql -uroot -p123456 -h 192.168.66.111 -P8066mysql> use TESTDB;insert into login_info(id,user_id,login_date)
values(1,101,'2040-01-01');
insert into login_info(id,user_id,login_date)
values(2,102,'2040-01-02');
insert into login_info(id,user_id,login_date)
values(3,103,'2040-01-03');
insert into login_info(id,user_id,login_date)
values(4,104,'2040-01-04');
insert into login_info(id,user_id,login_date)
values(5,105,'2040-01-05');
insert into login_info(id,user_id,login_date)
values(6,106,'2040-01-06');

5 全局序列

在这里插入图片描述

在实现分库分表的情况下,数据库自增主键已无法保证全局唯一。

解决方案

本地文件

此方式Mycat将sequence配置到文件中,当使用到 sequence中的配置后,Mycat会更下classpath中的 sequence_conf.properties 文件中sequence当前的值。

在这里插入图片描述

注意:

  • 优点:本地加载,读取速度较快
  • 缺点:抗风险能力差,Mycat 所在主机宕机后,无法读取本地文件。

本地时间戳方式

全局序列ID=64位二进制 (42(毫秒)+5(机器 ID)+5(业务编码)+12(重 复累加) 换算成十进制为18位数的long类型,每毫秒可以并发12位 二进制的累加。

**优缺点: **

  • 优点:配置简单
  • 缺点:18位ID过长

数据库方式

利用数据库一个表来进行计数累加。但是并不是每次生成序列都读写数据库,这样效率太低。Mycat 会预加载一部分号段到 Mycat 的内存中,这样大部分读写序列都是在内存中完成的。如果内存中的号段用完了 Mycat 会再向数据库要一次。

在这里插入图片描述

原理:

在数据库中建立一张表,存放 sequence 名称(name), sequence 当前值(current_value),步长(increment int 类型每次读取多少个 sequence,假设为 K)等信息;

数据库解决全局序列

修改Mycat配置文件server.xml

# 全局序列类型:0-本地文件,1-数据库方式,2-时间戳方式。此处应该修改成1。
<property name="sequnceHandlerType">1</property>

修改Mycat配置文件schema.xml

<table name="test" primaryKey="id" autoIncrement="true" dataNode="dn1,dn2" rule="mod-long"/>
<table name="mycat_sequence" primaryKey="name" dataNode="dn2"/>

修改Mycat 配置文件 sequence_db_conf.properties

最下面添加MYCAT=dn2

GLOBAL=dn1
COMPANY=dn1
CUSTOMER=dn1
ORDERS=dn1
MYCAT=dn2

在dn2节点的orders数据库中添加 MYCAT_SEQUENCE表

DROP TABLE IF EXISTS MYCAT_SEQUENCE;CREATE TABLE MYCAT_SEQUENCE (name VARCHAR(50) NOT NULL,current_value INT NOT NULL,increment INT NOT NULL DEFAULT 100, PRIMARY KEY(name))
ENGINE=InnoDB;

MYCAT_SEQUENCE 表插入sequence初始记录

INSERT INTO MYCAT_SEQUENCE(name,current_value,increment) VALUES ('mycat', -99, 100);

注意:

代表插入了一个名为mycat的sequence,当前值为-99,步长为 100。

创建全局序列所需存储过程

#获取当前sequence的值
DELIMITER $$
CREATE FUNCTION mycat_seq_currval(seq_name VARCHAR(50)) 
RETURNS VARCHAR(64)
DETERMINISTIC
BEGIN
DECLARE retval VARCHAR(64);
SET retval="-999999999,null";
SELECT CONCAT(CAST(current_value AS CHAR),",",CAST(increment AS CHAR)) 
INTO retval 
FROM MYCAT_SEQUENCE 
WHERE NAME = seq_name;
RETURN retval;
END $$
DELIMITER ;#设置sequence值
DELIMITER $$
CREATE FUNCTION mycat_seq_setval(seq_name VARCHAR(50),VALUE INTEGER) 
RETURNS VARCHAR(64)
DETERMINISTIC
BEGIN
UPDATE MYCAT_SEQUENCE
SET current_value = VALUE
WHERE NAME = seq_name;
RETURN mycat_seq_currval(seq_name);
END $$
DELIMITER ;#获取下一个sequence值
DELIMITER $$
CREATE FUNCTION mycat_seq_nextval(seq_name VARCHAR(50)) 
RETURNS VARCHAR(64)
DETERMINISTIC
BEGIN
UPDATE MYCAT_SEQUENCE
SET current_value = current_value + increment 
WHERE NAME = seq_name;
RETURN mycat_seq_currval(seq_name);
END $$
DELIMITER ;

重启Mycat

mycat restart

向dn1,dn2添加test表

create table test(id int,name varchar(10));

在Mycat中向test表中添加测试数据

mysql -uroot -p123456 -h 192.168.66.111 -P8066mysql> use TESTDB;insert into test(id,name) values(next value for MYCATSEQ_MYCAT,(select database()));

查询数据验证

SELECT * FROM test order by id asc;

六 Mycat高可用

1 Mycat高可用概述

在这里插入图片描述

MyCat实现读写分离架构

通过MyCat来实现MySQL的读写分离, 从而完成MySQL集群的负载均衡 , 如下面的结构图:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

问题:

但是以上架构存在问题 , 由于MyCat中间件是单节点的服务, 前端客户端所有的压力过来都直接请求这一台MyCat , 存在单点故障。所以这个时候, 我们就需要考虑MyCat的集群 ;

MyCat集群架构

通过MyCat来实现后端MySQL的负载均衡 , 通过HAProxy再实现 MyCat集群的负载均衡。

在这里插入图片描述

介绍:

HAProxy负责将请求分发到MyCat上,起到负载均衡的作用, 同时 HAProxy也能检测到MyCat是否存活,HAProxy只会将请求转发到存活的 MyCat 上。如果一台MyCat服务器宕机, HAPorxy 转发请求时不会转发到宕机的MyCat 上,所以 MyCat 依然可用。

HAProxy介绍

HAProxy是一个开源的、高性能的基于TCP(第四层)和HTTP(第七层) 应用的负载均衡软件。 使用HAProxy可以快速、可靠地实现基于 TCP与HTTP应用的负载均衡解决方案。

问题:

因为所以的客户端请求都是先到达HAProxy, 由HAProxy再将请求再向下分发, 如果HAProxy宕机的话, 就会造成整个MyCat集 群不能正常运行, 依然存在单点故障。

MyCat的高可用集群

在这里插入图片描述

图解说明:

  • HAProxy实现了MyCat多节点的集群高可用和负载均衡,而HAProxy自身的高可用则可以通过Keepalived来实现。因此,HAProxy主机上要同时安装 HAProxy和Keepalived, Keepalived负责为该服务器抢占vip(虚拟 ip),抢占到vip后,对该主机的访问可以通过原来的ip访问,也可以直接通过vip访问。
  • HAProxy负责将对vip的请求分发到MyCat集群节点上,起到负载均衡的作用。同时HAProxy 也能检测到MyCat是否存活,HAProxy只会将请求转发到存活的MyCat 上。
  • 如果Keepalived+HAProxy高可用集群中的一台服务器宕机,集群中另外一台服务器上的 Keepalived会立刻抢占vip 并接管服务,此时抢占了 vip 的HAProxy节点可以继续提供服务。
  • 如果一台MyCat服务器宕机,HAPorxy 转发请求时不会转发到宕机的 MyCat 上,所以 MyCat 依然可用。

keepalived介绍

Keepalived是一种基于VRRP协议来实现的高可用方案,可以利用其 来避免单点故障。 通常有两台甚至多台服务器运行Keepalived,一 台为主服务器(Master), 其他为备份服务器, 但是对外表现为一个虚 拟IP(VIP), 主服务器会发送特定的消息给备份服务器, 当备份服务器 接收不到这个消息时, 即认为主服务器宕机, 备份服务器就会接管虚 拟IP, 继续提供服务, 从而保证了整个集群的高可用。

2 安装配置HAProxy

在这里插入图片描述

安装配置HAProxy

查看列表

yum list | grep haproxy

yum安装

yum -y install haproxy

修改配置文件

$ vim /etc/haproxy/haproxy.cfg

启动HAProxy

$ haproxy -f /etc/haproxy/haproxy.cfg

HAProxy配置文件

HAProxy配置文件主要由全局设定和代理设定两部分组成,包含5个 域:global、default、frontend、backend、listen。

global

# 全局配置,定义haproxy进程的工作特性和全局配置
globallog         127.0.0.1 local2chroot      /var/lib/haproxy		#chroot运行的路径pidfile     /var/run/haproxy.pid	#haproxy pid的存放位置maxconn     4000					#最大连接数user        haproxy					#haproxy的运行用户group       haproxy					#haproxy的运行用户的所属组daemon								 #守护进程的方式在后台工作# turn on stats unix socketstats socket /var/lib/haproxy/stats

注意:

全局配置,通常是一些进程级别的配置,与操作系统相关。

default

defaultsmode                    http				#默认使用的七层协议,也可以是tcp四层协议,如果配置为health,则表示健康检查,返回oklog                     globaloption                  httplog				#详细记录tcp日志option                  dontlognull			#不记录健康检查的日志信息option http-server-closeoption forwardfor       except 127.0.0.0/8option                  redispatchretries                 3					#重试次数为3次,失败3次以后则表示服务不可用timeout http-request    10s					#http请求超时时间,客户端建立连接5s但不请求数据的时候,关闭客户端连接timeout queue           1m					#等待最大时间,表示等待最大时长为1stimeout connect         10s					#连接超时时间,表示客户端请求转发至服务器所等待的时长为10stimeout client          1m					#客户端超时时间,表示客户端非活跃状态的时间为1mintimeout server          1m					#服务器超时时间,表示客户端与服务器建立连接后,等待服务器的超时时间为1mintimeout http-keep-alive 10s					#持久连接超时时间,表示保持连接的超时时长为10stimeout check           10s					#心跳检测超时时间,表示健康状态监测时的超时时间为10smaxconn                 3000

参数:

默认参数配置,主要是涉及的公共配置,在 defaults 中一次性添加。 frontend 、 backend 、 listen 未配置时,都可以默认 defaults 中的参数配置。若配置了,会覆盖。

frontend & backend


frontend  main *:5000acl url_static       path_beg       -i /static /images /javascript /stylesheetsacl url_static       path_end       -i .jpg .gif .png .css .jsuse_backend static          if url_staticdefault_backend             appbackend staticbalance     roundrobinserver      static 127.0.0.1:4331 checkbackend appbalance     roundrobinserver  app1 127.0.0.1:5001 checkserver  app2 127.0.0.1:5002 checkserver  app3 127.0.0.1:5003 checkserver  app4 127.0.0.1:5004 check

参数:

  • frontend 可以看作是前端接收请求的部分,内部指定后端;
  • backend 可以看作是后端服务接收请求的部分;

listen

listen 是frontend和backend的组合,haproxy的监控ui可以通过这个进行配置。

向配置文件中插入以下配置信息,并保存

globallog 127.0.0.1 local0#log 127.0.0.1 local1 notice#log loghost local0 infomaxconn 4096chroot /var/lib/haproxypidfile /var/run/haproxy.pid#uid 99#gid 99daemon#debug#quietdefaultslog globalmode tcpoption abortoncloseoption redispatchretries 3maxconn 2000timeout connect 5000timeout client 50000timeout server 50000listen proxy_statusbind :48066mode tcpbalance roundrobinserver mycat_1 192.168.66.111:8066 check inter 10sserver mycat_2 192.168.66.112:8066 check inter 10sfrontend admin_statsbind :7777mode httpstats enableoption httplogmaxconn 10stats refresh 30sstats uri /adminstats auth admin:123123stats hide-versionstats admin if TRUE

启动验证

haproxy -f /etc/haproxy/haproxy.cfg

查看HAProxy进程

ps -ef|grep haproxy

打开浏览器访问

http://192.168.66.111:7777/admin
在弹出框输入用户名:
admin密码:123123

验证负载均衡,通过HAProxy访问Mycat

mysql -uroot -p123456 -h 192.168.66.111 -P 48066

3 安装配置Keepalived

在这里插入图片描述

高可用架构

在这里插入图片描述

查看列表

yum list | grep keepalived

yum安装

yum install -y keepalived

查看yum安装的配置文件

rpm -ql keepalived

修改主节点配置文件

vim /etc/keepalived/keepalived.conf

! Configuration File for keepalived
global_defs {router_id baizhan
}
vrrp_script chk_haproxy {script "/etc/keepalived/haproxy_check.sh"interval 2weight 2
}
vrrp_instance VI_1 {state MASTERinterface ens33virtual_router_id 35priority 120nopreemptadvert_int 1authentication {auth_type PASSauth_pass 1111}track_script {chk_haproxy}virtual_ipaddress {192.168.66.200}
}

带注释如下:

! Configuration File for keepalived
global_defs {
## keepalived 自带的邮件提醒需要开启 sendmail 服务。建议用独立的监控或第三方 SMTProuter_id baizhan ## 标识本节点的字条串,通常为 hostname
}## keepalived 会定时执行脚本并对脚本执行的结果进行分析,动态调整 vrrp_instance 的优先级。
## 如果脚本执行结果为 0,并且 weight 配置的值大于0,则优先级相应的增加。
## 如果脚本执行结果非 0,并且 weight 配置的值小于0,则优先级相应的减少。
## 其他情况,维持原本配置的优先级,即配置文件中priority 对应的值。
vrrp_script chk_haproxy {script "/etc/keepalived/haproxy_check.sh" 	## 检测haproxy 状态的脚本路径interval 2 						## 检测时间间隔weight 2 							## 如果条件成立,权重+2
}## 定义虚拟路由, VI_1 为虚拟路由的标示符,自己定义名称
vrrp_instance VI_1 {state MASTER ## 默认主设备(priority 值大的)和备用设备(priority 值小的)都设置为 BACKUP,## 由 priority 来控制同时启动情况下的默认主备,否则先启动的为主设备interface ens33 ## 绑定虚拟 IP 的网络接口,与本机 IP 地址所在的网络接口相同virtual_router_id 35 ## 虚拟路由的 ID 号,两个节点设置必须一样,可选 IP 最后一段使用,## 相同的 VRID 为一个组,他将决定多播的 MAC 地址priority 120 ## 节点优先级,值范围 0-254,MASTER 要比 BACKUP 高nopreempt ## 主设备(priority 值大的)配置一定要加上 nopreempt,否则非抢占也不起作用advert_int 1 ## 组播信息发送间隔,两个节点设置必须一样,默认 1s## 设置验证信息,两个节点必须一致authentication {auth_type PASSauth_pass 1111 ## 真实生产,按需求对应该过来}## 将 track_script 块加入 instance 配置块track_script {chk_haproxy ## 检查 HAProxy 服务是否存活}## 虚拟 IP 池, 两个节点设置必须一样virtual_ipaddress {192.168.66.200}
}

修改备用节点配置文件

vim /etc/keepalived/keepalived.conf

! Configuration File for keepalived
global_defs {router_id baizhan
}
vrrp_script chk_haproxy {script "/etc/keepalived/haproxy_check.sh"interval 2weight 2
}
vrrp_instance VI_1 {state BACKUPinterface ens33virtual_router_id 35priority 110advert_int 1authentication {auth_type PASSauth_pass 1111}track_script {chk_haproxy}virtual_ipaddress {192.168.66.200}
}

编写 Haproxy 状态检测脚本

我们编写的脚本为/etc/keepalived/haproxy_check.sh (已在 keepalived.conf 中配置)

脚本要求:如果 haproxy 停止运行,尝试启动,如果无法启动则杀死本机的 keepalived 进程,keepalied将虚拟 ip 绑定到 BACKUP 机器上。

内容如下:

mkdir -p /usr/local/keepalived/log

vi /etc/keepalived/haproxy_check.sh

#!/bin/bash
START_HAPROXY="/usr/sbin/haproxy start"
STOP_HAPROXY="/usr/sbin/haproxy stop"
LOG_FILE="/usr/local/keepalived/log/haproxycheck.log"
HAPS=`ps -C haproxy --no-header |wc -l`
date "+%Y-%m-%d %H:%M:%S" >> $LOG_FILE
echo "check haproxy status" >> $LOG_FILE
if [ $HAPS -eq 0 ];then
echo $START_HAPROXY >> $LOG_FILE
$START_HAPROXY >> $LOG_FILE 2>&1
sleep 3
if [ `ps -C haproxy --no-header |wc -l` -eq
0 ];then
echo "start haproxy failed, killall
keepalived" >> $LOG_FILE
killall keepalived
fi
fi

注意添加权限

chmod +x /etc/keepalived/haproxy_check.sh

启动Keepalived

service keepalived start

七 Mycat安全设置

1 user标签权限控制

在这里插入图片描述

目前 Mycat 对于中间件的连接控制并没有做太复杂的控制,目前只做了中间件逻辑库级别的读写权限控制。是通过 server.xml 的 user 标签进行配置。

#server.xml配置文件user部分
<user name="mycat"><property name="password">123456</property><property name="schemas">TESTDB</property>
</user>
<user name="user"><property name="password">user</property><property name="schemas">TESTDB</property><property name="readOnly">true</property>
</user>

参数:

  • name:应用连接中间件逻辑库的用户名
  • password:该用户对应的密码
  • schemas :应用当前连接的逻辑库。
  • readOnly:应用连接中间件逻辑库所具有的权限。true 为只读,false 为读写都有,默认为 false

测试案例

使用user用户,权限为只读(readOnly:true),验证是否可以查 询出数据,验证是否可以写入数据。

1、用user用户登录,运行命令如下:

 mysql -uuser -puser -h 192.168.140.128 -P8066

2、切换到TESTDB数据库,查询orders表数据,如下:

use TESTDB
select * from orders;

3、执行插入数据sql

insert into
orders(id,order_type,customer_id,amount)
values(7,101,101,10000);

4、可看到运行结果,插入失败,只有只读权限

mysql> insert into orders(id,order_type,customer_id,amount) values(7,101,101,10000);
ERROR 1495 (HY000): User readonly

2 privileges标签权限控制

在这里插入图片描述

在 user 标签下的 privileges 标签可以对逻辑库(schema)、表 (table)进行精细化的 DML 权限控制。

<!--server.xml配置文件privileges部分-->
<!--#配置orders表没有增删改查权限-->
<user name="mycat"><property name="password">123456</property><property name="schemas">TESTDB</property><!-- 表级 DML 权限设置 --><privileges check="true"><schema name="TESTDB" dml="1111" ><table name="orders" dml="0000"></table><!--<table name="tb02" dml="1111"></table>--></schema></privileges>
</user>

配置说明

DML权限新增更新查询删除
0000禁止禁止禁止禁止
0010禁止禁止可以禁止
1110可以禁止禁止禁止
1111可以可以可以可以

测试案例

使用mycat用户,privileges配置orders表权限为禁止增删改查 (dml=“0000”) 验证是否可以查询出数据,验证是否可以写入数据。

1、重启mycat,用mycat用户登录,运行命令如下:

mysql -umycat -p123456 -h 192.168.66.101 -P8066

2、切换到TESTDB数据库,查询orders表数据,如下:

use TESTDB
select * from orders;

3、禁止该用户查询数据

mysql> use TESTDB
Database changed
mysql> select* from orders;
ERROR 3012(HY000): The statement DML privilege check is not passed,reject for user
'mycat'

4、执行插入数据sql,如下

insert into orders(id,order_type,customer_id,amount) values(8,101,101,10000);

5、可看到运行结果,禁止该用户插入数据

mysql> insert into orders(id,order_type,customer_id,amount) values(8,101,101,10000);
ERROR 3012 (HY000): The statement DMLprivilege check is not passed,reject for use

3 SQL拦截白名单

在这里插入图片描述

firewall标签用来定义防火墙;firewall下whitehost标签用来定义IP 白名单 ,blacklist 用来定义SQL 黑名单。

白名单

可以通过设置白名单,实现某主机某用户可以访问 Mycat,而其他主机用户禁止访问。

#设置白名单
#server.xml配置文件firewall标签
#配置只有192.168.66.101主机可以通过mycat用户访问
<firewall><whitehost><host host="192.168.66.101" user="mycat"/></whitehost>
</firewall>

4 SQL拦截黑名单

在这里插入图片描述

可以通过设置黑名单,实现Mycat对具体SQL操作的拦截,如增删改查等操作的拦截。

设置黑名单
#server.xml配置文件firewall标签
#配置禁止mycat用户进行删除操作
<firewall><whitehost><host host="192.168.140.128" user="mycat"/></whitehost><blacklist check="true"><property name="deleteAllow">false</property>
</blacklist>
</firewall>

黑名单 SQL 拦截功能列表

在这里插入图片描述

八 Mycat性能监控

1 Mycat-web安装

在这里插入图片描述

Mycat-web是Mycat可视化运维的管理和监控平台。Mycat-web引 入了 ZooKeeper作为配置中心,可以管理多个节点。

在这里插入图片描述

注意:

Mycat-web 主要管理和监控 Mycat 的流量、连接、活动线程和 内存等,具备IP白名单、邮件告警等模块,还可以统计SQL并分 析慢SQL和高频 SQL等。为优化SQL提供依据。

Docker安装Zookeeper

docker run --name myzk -d -p 2181:2181 zookeeper

解压Mycat-web

tar -zxvf Mycat-web-1.0-SNAPSHOT20170102153329-linux.tar.gz -C /usr/local

设置Zookeeper的地址

在/usr/local/mycat-web/mycat-web/WEBINF/classes/mycat.properties文件中配置

在这里插入图片描述

zookeeper=192.168.66.101:2181

进入mycat-web的目录下运行启动命令

cd /usr/local/mycat-web/
./start.sh &

查看服务已经启动

lsof -i:8082

通过地址访问服务

 http://192.168.66.101:8082/mycat/

九 Mycat性能优化

在这里插入图片描述

JVM调优

Java堆内存和直接内存映射,建议堆内存大小适度,直接映射的内存尽可能大,总计占用操作系统50%~67%的内存。

示例

下面以16GB内存的服务器为例,Mycat堆内存为4GB,直接内存映 射为6GB,修改文件 /usr/local/mycat/bin/startup_nowrap.sh

JAVA_OPTS="-server -Xms4G -Xmx2G -XX:MaxPermSize=64M -XX:+AggressiveOpts -XX:MaxDirectMemorySize=6G"

Mycat调优

MyCAT所有的调优参数都可以才server.xml中找到

主要讨论两个内容:

processors数值的影响范围

<system><property name="processors">1</property><property name="processorExecutor">16</property>
</system>

参数:

  • processors:CPU核心数越多,可以越大,当发现系统CPU压力很小的情况下,可以适当调 大此参数,如4核心的4CPU,可以设置为16,24核的可以最大设置为128
  • processorExecutor:每个processor的线程池大小,建议可以是16-64,根据系统能力来测试和确定。

设置连接数

<dataHost name="localhostl" maxCon="500" mincon="10" balance="O"
dbType="MySQL"dbDriver="native" banlance="0">

注意: 最大连接池maxCon的值可以改为1000~2000,同一个MySQL 实例上的所有dataNode节点共享本dataHost上的所有物理连接。

十 Mycat实施指南

在这里插入图片描述

分表分库原则

  • 原则一:能不分就不分;
  • 原则二:分片数量尽量少;
  • 原则三:分片规则需要慎重选择;
  • 原则四:尽量不要在一个事务中的SQL跨越多个分片;
  • 原则五:查询条件尽量优化

注意:

这里特别强调一下分片规则的选择问题,如果某个表的数据有明显的时间特征,比如订单、交易记录等,则他们通常比较合 适用时间范围分片,因为具有时效性的数据。

数据拆分原则

  • 达到一定数量级才拆分(800 万);
  • 不到 800 万但跟大表(超 800 万的表)有关联查询的表也要拆分,在此称为大表关联表 ;
  • 小于100万的使用全局表;
  • 大于100万小于800 万跟大表使用同样的拆分策略。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/67873.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【USRP】调制解调系列6:16APSK、32APSK 、基于labview的实现

APSK APSK是&#xff0c;与传统方型星座QAM&#xff08;如16QAM、64QAM&#xff09;相比&#xff0c;其分布呈中心向外沿半径发散&#xff0c;所以又名星型QAM。与QAM相比&#xff0c;APSK便于实现变速率调制&#xff0c;因而很适合目前根据信道及业务需要分级传输的情况。当然…

分布式环境下的数据同步

一般而言elasticsearch负责搜索&#xff08;查询&#xff09;&#xff0c;而sql数据负责记录&#xff08;增删改&#xff09;&#xff0c;elasticsearch中的数据来自于sql数据库&#xff0c;因此sql数据发生改变时&#xff0c;elasticsearch也必须跟着改变&#xff0c;这个就是…

jmeter调试错误大全

一、前言 在使用jmeter做接口测试的过程中大家是不是经常会遇到很多问题&#xff0c;但是无从下手&#xff0c;不知道从哪里开始找起&#xff0c;对于初学者而言这是一个非常头痛的事情。这里结合笔者的经验&#xff0c;总结出以下方法。 二、通过查看运行日志调试问题 写好…

STM32存储左右互搏 I2C总线读写FRAM MB85RC16

STM32存储左右互搏 I2C总线读写FRAM MB85RC16 在较低容量存储领域&#xff0c;除了EEPROM的使用&#xff0c;还有铁电存储器FRAM的使用&#xff0c;相对于EEPROM, 同样是非易失性存储单元&#xff0c;FRAM支持更高的访问速度&#xff0c; 其主要优点为没有EEPROM持续写操作跨页…

Python虚拟环境venv下安装playwright介绍及记录

playwright介绍 Playwright是一个用于自动化Web浏览器测试和Web数据抓取的开源库。它由Microsoft开发&#xff0c;支持Chrome、Firefox、Safari、Edge和WebKit浏览器。Playwright的一个主要特点是它能够在所有主要的操作系统&#xff08;包括Windows、Linux和macOS&#xff09…

计算机毕设 大数据商城人流数据分析与可视化 - python 大数据分析

文章目录 0 前言课题背景分析方法与过程初步分析&#xff1a;总体流程&#xff1a;1.数据探索分析2.数据预处理3.构建模型 总结 最后 0 前言 &#x1f525; 这两年开始毕业设计和毕业答辩的要求和难度不断提升&#xff0c;传统的毕设题目缺少创新和亮点&#xff0c;往往达不到…

SMU200A/罗德与施瓦茨SMU200A信号发生器

181/2461/8938产品概述 R&S SMU200A信号发生器旨在满足现代通信系统研发及其生产中遇到的所有要求。R&S SMU200A矢量信号发生器不仅将多达两个独立的信号发生器组合在一个只有四个高度单位的机柜中&#xff0c;还提供无与伦比的RF和基带特性。 Rohde & Schwarz S…

Vue3数值动画(NumberAnimation)

效果如下图&#xff1a;在线预览 APIs 参数说明类型默认值必传from数值动画起始数值number0falseto数值目标值number1000falseduration数值动画持续时间&#xff0c;单位msnumber3000falseautoplay是否自动开始动画booleantruefalseprecision精度&#xff0c;保留小数点后几位…

NineData 中标移动云数据库传输项目

导读近日&#xff0c;玖章算术 NineData 智能数据管理平台成功中标《2023 年移动云数据库传输服务软件项目》&#xff0c;中标金额为 406 万。这标志着玖章算术 NineData 平台已成功落地顶级运营商行业&#xff0c;并在数据管理方面实现了大规模应用实践。 NineData 中标 2023 …

SQLite简单介绍

一.简单介绍 SQLite是一款轻型的数据库&#xff0c;是遵守ACID的关系型数据库管理系统&#xff0c;它包含在一个相对小的C库中。它是D.RichardHipp建立的公有领域项目。它的设计目标是嵌入式的&#xff0c;而且已经在很多嵌入式产品中使用了它&#xff0c;它占用资源非常的低&…

音频基础知识

文章目录 前言一、音频基本概念1、音频的基本概念①、声音的三要素②、音量与音调③、几个基本概念④、奈奎斯特采样定律 2、数字音频①、采样②、量化③、编码④、其他相关概念<1>、采样位数<2>、通道数<3>、音频帧<4>、比特率&#xff08;码率&#…

02-Flask-对象初始化参数

对象初始化参数 前言对象初始化参数import_namestatic_url_pathstatic_foldertemplate_floder 前言 本篇来学习Flask中对象初始化参数 对象初始化参数 import_name Flask程序所在的包(模块)&#xff0c;传__name__就可以 _name_ 是一个标识 Python 模块的名字的变量&#x…

2023_Spark_实验六:Scala面向对象部分演示(二)(IDEA开发)

7、Scala中的apply方法&#xff08;&#xff09; 遇到如下形式的表达式时&#xff0c;apply方法就会被调用&#xff1a; Object(参数1,参数2,......,参数N) 通常&#xff0c;这样一个apply方法返回的是伴生类的对象&#xff1b;其作用是为了省略new关键字 Object的apply方法…

MATLAB旋转动图的绘制

MATLAB旋转动图的绘制 文章目录 MATLAB旋转动图的绘制1、动图效果2、matlab代码 利用matlab实现三维旋转动图的绘制。 1、动图效果 2、matlab代码 close all clear clcf(x,y,z)(x.^2 (9./4).*y.^2 z.^2 - 1).^3 - x.^2.*z.^3 - (9./80).*y.^2.*z.^3; [x,y,z]meshgrid(linspac…

linux并发服务器 —— linux网络编程(七)

网络结构模式 C/S结构 - 客户机/服务器&#xff1b;采用两层结构&#xff0c;服务器负责数据的管理&#xff0c;客户机负责完成与用户的交互&#xff1b;C/S结构中&#xff0c;服务器 - 后台服务&#xff0c;客户机 - 前台功能&#xff1b; 优点 1. 充分发挥客户端PC处理能力…

RK开发板的USB连接(Ubuntu)

一、安装连接工具 sudo apt-get install putty 二、启动putty工具 sudo putty 三、连接usb&#xff0c;并查看相关的信息 # 查看接入的是否有usb ls /dev/tty* 显示如下&#xff1a;&#xff08;含有usb接口&#xff1a; /dev/ttyUSB0&#xff09; /dev/tty /dev/tty23 /d…

2.4 PE结构:节表详细解析

节表&#xff08;Section Table&#xff09;是Windows PE/COFF格式的可执行文件中一个非常重要的数据结构&#xff0c;它记录了各个代码段、数据段、资源段、重定向表等在文件中的位置和大小信息&#xff0c;是操作系统加载文件时根据节表来进行各个段的映射和初始化的重要依据…

微信小程序 通过响应式数据控制元素class属性

我想大家照这个和我最初的目的一样 希望有和vue中v-bind:class一样方便的指令 但答案不太尽人意 这里 我们只能采用 三元运算符的形式 参考代码如下 <view class"item {{ userId item.userId ? isThisUser : }}"> </view>这里 我们判断 如果当前ite…

【Java】关于JDK 8的HashMap

文章目录 HashMap 简介数据结构Hash构造方法get(key)方法步骤一&#xff1a;通过key获取所在桶的第一个元素是否存在步骤二:该节点的hash和key是否与要查询的hash和key匹配步骤三:当对应桶中不止一个节点时&#xff0c;根据不同节点类型查询 put(key,value)为什么树化&#xff…

elasticsearch分析插件 安装analysis-ik

首先下载安装es 和 插件 &#xff0c;注意 两者的版本要保持一致,如果要用到kibana 则三者保持一致 ik&#xff1a;https://github.com/medcl/elasticsearch-analysis-ik/releases es/kibana&#xff1a;https://www.elastic.co/cn/downloads/past-releases/ 然后在 es— elast…