需求
需求是什么呢?
MySQL集群分布式,要求主从同步(实时备份),且读写分离
虚拟机
由于第一次接触MySQL主从同步,所以我要在自己的虚拟机上来练习一下。
准备一个CentOS7.4的虚拟机。
CentOS7.4下载
官网下载地址:http://vault.centos.org/
-
进入官网,找到CentOS7.4版本
-
找到isos
-
接着点进去
-
根据自己实际情况选择,我选择的是CentOS-7-x86_64-DVD-1708.iso
CentOS7.4安装
- 打开你的VMware Workstation Pro,当然你也可以用其他加载虚拟机的工具
- 选典型(推荐)(T),并点击“下一步”
- 选稍后安装操作系统(S),并点击“下一步”
- 选Linux(L),因为我们之前下载的 CentOS-7-x86_64-DVD-1708.iso 是64位 7.4版本的,所以这里我们选择CentOS 7 64位,并点击“下一步”
- 虚拟机名称可以更改也可以不更改看自己需求,修改虚拟机的安装路径,并点击“下一步”
- 磁盘选择默认为20.0GB,点选将虚拟磁盘存储为单个文件(O),并点击“下一步”
- 点击“完成”
- 点击“编辑虚拟机设置”
- 选“使用ISO映像文件(M)”,并添加我们之前下载好的CentOS-7-x86_64-DVD-1708.iso
- 默认为NAT 模式(N):用于共享主机的IP地址即可
- “开启此虚拟机”
- 正在开启虚拟机,鼠标移入到虚拟机中,并按下“↑”键,选择Install CentOS 7,最后按下“Enter 键”
提示: 鼠标移动到虚拟机内部单击或者按下Ctrl + G,鼠标即可移入到虚拟机中
按下Ctrl + Alt,鼠标即可移出虚拟机
注意: 在虚拟机中的操作,鼠标必须要移入到虚拟机中,否则虚拟机感应不到,无法对其进行操作
-
按ENTER
-
默认安装过程中的安装界面使用English (英语),点击“Continue”
-
配置时区 (DATE & TIME)
配置时区 (DATE & TIME)
(1)选择DATE & TIME
(2)时区设置为 Region:Asia City:Shanghai
日期和时间 设置与自己的电脑时间同步,最后点击“Done”
-
设置软件选择 (SOFTWARE SELECTION)
(1)选择SOFTWARE SELECTION
(2)点击勾选 Compatibility Libraries 和 Development Tools
如果希望安装带有界面的CentOS,请在左边Base Environment中,选择Server with GUI(带图形用户界面的服务器),默认为Minimal Install (最小安装),提示:如果安装有界面版本的,在如下的第22步骤中的操作会有所不同 (安装有界面版本的其实用处不大,都是可以通过命令行来设置的),这里我没有安装有界面版本的
-
设置安装位置 (INSTALLATION DESTINATION)
(1)选择INSTALLATION DESTINATION
(2)点选 I will configuire parttioning,然后再点击“Done”
(3)更改模式,标准分区Standard Partition,点击“+”按钮添加分区
(4)添加 /boot分区,大小300MB,Add mount point
(5)添加 swap分区,一般情况是物理内存的2倍大小,用于物理内存不足时使用,但可能造成系统不稳定,所以看情况,可以设置小一点,甚至设置为0MB,这里我设置为512MB,Add mount point
(6)增加根分区,不填写大小,即默认剩余的空间都给根分区,Add mount point
(7)点击“Done”
(8)点击“Accept Changes”
-
点击“Begin Installation”,开始安装
-
设置系统用户root的密码 (ROOT PASSWORD)
(1)选择ROOT PASSWORD
(2)为root设置密码 ,然后点击“Done”
-
等待安装完成,然后点击“Reboot”
CentOS7.4基本设置
- 登录CentOS,默认账号为root,密码为 你在前面安装时设置的root密码
提示:在输入密码时,linux为了安全起见,是看不到你输入的密码。同时,如果是使用的是键盘右边的数字键盘输入密码的话,建议查看一下,数字键盘是否开启 (建议使用字母按键上面一排的 数字键输入密码)
- 配置IP地址,网关
vi /etc/sysconfig/network-scripts/ifcfg-ens32 //编辑network-scripts目录下的ifcfg-ens32配置文件
//修改以下内容
BOOTPROTO=static //启用静态IP地址
ONBOOT=yes //开启自动启用网络连接
//添加以下内容
IPADDR=192.168.30.1 //设置IP地址
NETMASK=255.255.255.0 //子网掩码
GATEWAY=192.168.131.2 //设置网关
如何设置Linux的IP地址
如何设置Linux的IP地址
- 在本地电脑打开“命令行窗口”,输入命令ipconfig,查看 以太网适配器 VMware Network Adapter VMnet8下的IPv4 地址
- 可以看到 以太网适配器 VMware Network Adapter VMnet8下的IPv4 地址为 192.168.30.2
- 当我们设置Linux的IP地址时,需要保证Linux的IP地址 与 VMnet8下的IPv4地址 的前面三位数必须相同,即 192.168.30 必须相同,这样Linux就能跟我们本地电脑互相通信,最后一位数不相同即可,例如Linux的IP地址可以设置为192.168.30.1 或者 192.168.30.124等
如何设置网关
- 点击编辑(E) → 虚拟网络编辑器(N)
- 如何设置Linux的网关,选择VMnet8,再点击"NAT设置"按钮,查看VMnet8 (NAT 模式)下的子网掩码
- 查看VMnet8 (NAT 模式)下的网关,选择VMnet8,再点击"NAT设置"按钮
重启网络服务
service network restart
- 设置DNS地址
vi /etc/resolv.conf //编辑 resolv.conf文件
可以添加多个DNS地址,格式为:
nameserver xxx1.xxx1.xxx1.xxx1
nameserver xxx2.xxx2.xxx2.xxx2
常用的DNS地址:
阿里 223.5.5.5 或者 223.6.6.6
谷歌 8.8.8.8
国内移动、电信和联通通用的DNS 114.114.114.114
- 永久关闭 firewalld防火墙(centos7默认的防火墙是firewalld防火墙,不是使用iptables,因此需要关闭firewalld服务)
systemctl stop firewalld.service // 停止firewalld服务
systemctl disable firewalld.service // 开机禁用firewalld服务
iptables -L //列出所有iptables规则
- 永久关闭SELinux防火墙
vi /etc/sysconfig/selinux //编辑selinux文件
SELINUX=disabled //把文件中的SELINUX=enforcing 改成 SELINUX=disabled 即可
sestatus //查看SELinux状态
获取当前selinux防火墙的安全策略
sestatus
这时需要我们重启,再去查看SELinux防火墙的状态,可以看到已经关闭了
可以设置快照来保存当前的虚拟机,恢复的时候方便
用上面的方法在创建一个虚拟机或者用克隆的方式在创建一个,当然uuid需要改一下,不能让两个虚拟机的uuid完全相同
MySQL
上面的步骤配置好,能连上外网就可以继续安装mysql了。
下载
在CentOS中默认安装有MariaDB,这个是MySQL的分支,但为了需要,还是要在系统中安装MySQL,而且安装完成之后可以直接覆盖掉MariaDB。
用yum命令下载安装包
yum -y install mysql57-community-release-el7-10.noarch.rpm
之后它就报错了
换了一个命令,成功
sudo rpm -Uvh http://dev.mysql.com/get/mysql-community-release-el7-5.noarch.rpm
开始安装MySQL服务器
yum -y install mysql-community-server
稍微等待一小会,安装完成后就会覆盖掉之前的mariadb
至此MySQL就安装完成了
MySQL配置
启动MySQL
systemctl start mysqld.service
查看MySQL的运行状态
systemctl status mysqld.service
MySQL已经开始正常运行
看别人的配置是需要找到密码,但是我还真没找到
虽然我没找到但你还是尝试一下找一找,说不定你的有呢!通过如下命令可以在日志文件中找出密码
grep "password" /var/log/mysqld.log
我没有密码,那么我只能直接进入数据库了,因为没找到密码,我猜测是没有密码,果然回车就进入了
mysql -uroot -p
这个是mysql修改密码的语句,我没有修改,一直默认是没有密码
ALTER USER 'root'@'localhost' IDENTIFIED BY 'new password';
开启MySQL的远程访问
执行以下命令开启远程访问限制(注意:下面命令开启的IP是 192.168.0.1,如要开启所有的,用%代替IP),password是自己设置的密码
grant all privileges on *.* to 'root'@'192.168.0.1' identified by 'password' with grant option;
然后执行下面两条命令
flush privileges;
exit
firewalld添加开放端口
当然如果是按照创建虚拟的步骤一起弄得话,这步可以省略,因为我上面已经把防火墙关了(狗头保命)。
下面的两条命令分别是开启MySQL端口3306和Tomcat端口8080
firewall-cmd --zone=public --add-port=3306/tcp --permanent
firewall-cmd --zone=public --add-port=8080/tcp --permanent
在重新载入
firewall-cmd --reload
更改MySQL语言
重新登录,查看状态,status
可以看到箭头处的编码不是utf-8
退出MySQL,修改/etc/my.cnf文件
可以看到我添加了四处,注意是utf8而不是utf-8,写后面的形式会报错
重启MySQL,再次查看状态
service mysqld restart
另一个虚拟机也作同样操作
MySQL主从复制配置
首先,为了保证数据同步必须先保证时间同步,在三台服务器均做时间同步
由于我的是新创建的虚拟机所以需要先下载ntpdate
yum install ntpdate
之后再执行时间同步
ntpdate ntp.aliyun.com
主服务器
修改配置文件:
vim /etc/my.cnf
#在[Mysqld]模块修改
server-id = 11 //三台主从数据库的id必须不同
log-bin = master-bin //主服务器日志文件
log-slave-updates=true //允许从服务器更新
[root@master ~]# systemctl restart mysqld.service //配置文件修改后必须重启
登录主数据库给从数据库授权:
[root@master ~]# mysql -uroot -p
Enter password:
mysql> grant replication slave on *.* to 'myslave'@'192.168.247.%' identified by 'abc123'';
Query OK, 0 rows affected, 1 warning (0.01 sec)
//给从服务器授权,允许192.168.247.网段的服务器使用myslave访问所有库的所有表
mysql> flush privileges; //策略刷新
Query OK, 0 rows affected (0.00 sec)
mysql> show master status; //查看主服务器状态,日志用于从服务器同步,position是当前定位
+-------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+-------------------+----------+--------------+------------------+-------------------+
| master-bin.000001 | 154 | | | |
+-------------------+----------+--------------+------------------+-------------------+
1 row in set (
从服务器
修改配置文件:
vim /etc/my.cnf
server-id = 22 //另一个从服务器为33
relay-log = relay-log-bin //从主服务器上同步日志文件记录到本地
relay-log-index = slave-relay-bin.index //建立索引文件,定义relay-log的位置和名称
[root@slave1 ~]# systemctl restart mysqld
登录数据库配置:
mysql> change master to master_host='192.168.247.130',master_user='myslave',master_password='abc123',master_log_file='master-bin.000001',master_log_pos=154;
Query OK, 0 rows affected, 2 warnings (0.01 sec)
##指明从哪里找什么文件的什么位置进行复制
mysql> start slave; //开启从复制
Query OK, 0 rows affected (0.00 sec)
master_log_file:需要同步的二进制日志文件名,即主服务器上查询到的状态中file
master_log_pos:断点位置,即主服务器上查询到的状态position
查看从服务器状态:
mysql> show slave status \G
修改master配置
- 找到
主数据库
的配置文件my.cnf(或者my.ini),我的在/etc/my.cnf,在[mysqld]部分插入如下
[mysqld]
#开启二进制日志
log-bin=mysql-bin
#设置server-id,建议使用ip最后3位
server-id=140
- 找到
从数据库
的配置文件my.cnf(或者my.ini),我的在/etc/my.cnf,在[mysqld]部分插入如下:
#开启中继日志
relay-log=mysql-relay
#设置server-id,建议使用ip最后3位
server-id=141
- 重启MySQL服务
systemctl restart mysqld.service
I/O线程与SQL线程都为Yes,主从复制完成
MaCat
安装及启动
MyCat:
MyCat的官方网站:
下载地址:
https://github.com/MyCATApache/Mycat-download
因为我是在win10系统上安装的MyCat,所以如有其他系统请自行百度。
下载压缩包,解压,进入mycat目录的bin目录,启动mycat
安装完成后,目录如下:
目录 | 说明 |
---|---|
bin | mycat命令,启动、重启、停止等 |
catlet | catlet为Mycat的一个扩展功能 |
conf | Mycat 配置信息,重点关注 |
lib | Mycat引用的jar包,Mycat是java开发的 |
logs | 日志文件,包括Mycat启动的日志和运行的日志。 |
这里建议用管理员权限的cmd
开启
./mycat start
停止
./mycat stop
mycat 支持的命令{ console | start | stop | restart | status | dump }
Mycat的默认端口号为:8066
MyCat分片配置
配置
Mycat的配置文件都在conf目录里面,这里介绍几个常用的文件:
目录 | 说明 |
---|---|
server.xml | Mycat的配置文件,设置账号、参数等 |
schema.xml | Mycat对应的物理数据库和数据库表的配置 |
rule.xml | Mycat分片(分库分表)规则 |
配置server.xml
<user name="root" defaultAccount="true">
<property name="password">123456</property>
<property name="schemas">volun</property>
<property name="readOnly">false</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 | 用户配置节点 |
–name | 登录的用户名,也就是连接Mycat的用户名 |
–password | 登录的密码,也就是连接Mycat的密码 |
–schemas | 数据库名,这里会和schema.xml中的配置关联,多个用逗号分开,例如需要这个用户需要管理两个数据库db1,db2,则配置db1,dbs |
–privileges | 配置用户针对表的增删改查的权限,具体见文档吧 |
我配置了一个账号root,密码123456,针对数据库volun,读写权限都有,没有针对表做任何特殊的权限。
配置schema.xml
schema.xml是最主要的配置项
数据库读写分离
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
<schema name="volun" checkSQLschema="false" sqlMaxLimit="100" >
<!-- auto sharding by id (long) -->
<!--splitTableNames 启用<table name 属性使用逗号分割配置多个表,即多个表使用这个配置-->
<!--fetchStoreNodeByJdbc 启用ER表使用JDBC方式获取DataNode-->
<table name="sys_user" primaryKey="id" dataNode="dn1" ></table>
<table name="sys_user_post" primaryKey="id" dataNode="dn1" ></table>
<table name="sys_user_role" primaryKey="id" dataNode="dn1" ></table>
</schema>
<dataNode name="dn1" dataHost="localhost1" database="volun" />
<dataHost name="localhost1" 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.240.3:3306" user="root" password="">
<readHost host="hostM1" url="192.168.240.4:3306" user="root" password="">
</readHost>
</writeHost>
</dataHost>
</mycat:schema>
这样的配置与前一个示例配置改动如下:
删除了table分配的规则,以及datanode只有一个
datahost也只有一台,但是writehost总添加了readhost,balance改为1,表示读写分离。
以上配置达到的效果就是102.168.0.2为主库,192.168.0.3为从库。
注意:Mycat主从分离只是在读的时候做了处理,写入数据的时候,只会写入到writehost,需要通过mycat的主从复制将数据复制到readhost,这个问题当时候我纠结了好久,数据写入writehost后,readhost一直没有数据,以为是自己配置的问题,后面才发现Mycat就没有实现主从复制的功能,毕竟数据库本身自带的这个功能才是最高效稳定的。
参数 | 说明 |
---|---|
schema | 数据库设置,此数据库为逻辑数据库,name与server.xml中schema对应 |
dataNode | 分片信息,也就是分库相关配置 |
dataHost | 物理数据库,真正存储数据的数据库 |
每个节点的属性逐一说明:
schema
属性 | 说明 |
---|---|
name | 逻辑数据库名,与server.xml中的schema对应 |
checkSQLschema | 数据库前缀相关设置,建议看文档,这里暂时设为folse |
sqlMaxLimit | select 时默认的limit,避免查询全表 |
table
属性 | 说明 |
---|---|
name | 表名,物理数据库中表名 |
dataNode | 表存储到哪些节点,多个节点用逗号分隔。节点为下文dataNode设置的name |
primaryKey | 主键字段名,自动生成主键时需要设置 |
autoIncrement | 是否自增 |
rule | 分片规则名,具体规则下文rule详细介绍 |
dataNode
属性 | 说明 |
---|---|
name | 节点名,与table中dataNode对应 |
datahost | 物理数据库名,与datahost中name对应 |
database | 物理数据库中数据库名 |
dataHost
属性 | 说明 |
---|---|
name | 物理数据库名,与dataNode中dataHost对应 |
balance | 均衡负载的方式 |
writeType | 写入方式 |
dbType | 数据库类型 |
heartbeat | 心跳检测语句,注意语句结尾的分号要加。 |
rule.xml
主要关注rule属性,rule属性的内容来源于rule.xml这个文件,Mycat支持10种分表分库的规则,基本能满足你所需要的要求,这个必须赞一个,其他数据库中间件好像都没有这么多。
table中的rule属性对应的就是rule.xml文件中tableRule的name,具体有哪些分表和分库的实现,建议还是看下文档。我这里选择的mod-long就是将数据平均拆分。因为我后端是两台物理库,所以rule.xml中mod-long对应的function count为2,见下面部分代码:
<tableRule name="mod-long">
<rule>
<columns>id</columns>
<algorithm>mod-long</algorithm>
</rule>
</tableRule>
<function name="mod-long" class="io.mycat.route.function.PartitionByMod">
<!-- how many data nodes -->
<property name="count">2</property>
</function>
使用
Mycat的启动也很简单,启动命令在Bin目录:
#启动
mycat start
#停止
mycat stop
#重启
mycat restart