MySQL主从复制 介绍
MySQL主从复制是一个异步的复制过程,底层是基于Mysql数据库自带的 二进制日志 功能。就是一台或多台MySQL数据库(slave,即从库)从另一台MySQL数据库(master,即主库)进行日志的复制,然后再解析日志并应用到自身,最终实现 从库 的数据和 主库 的数据保持一致。MySQL主从复制是MySQL数据库自带功能,无需借助第三方工具。
二进制日志:
二进制日志(BINLOG)记录了所有的 DDL(数据定义语言)语句和 DML(数据操纵语言)语句,但是不包括数据查询语句。此日志对于灾难时的数据恢复起着极其重要的作用,MySQL的主从复制, 就是通过该binlog实现的。默认MySQL是未开启该日志的。
MySQL复制过程分成三步:
1). MySQL master 将数据变更写入二进制日志( binary log)
2). slave将master的binary log拷贝到它的中继日志(relay log)
3). slave重做中继日志中的事件,将数据变更反映它自己的数据
1.2 搭建
1.2.1 准备工作
提前准备两台服务器,并且在服务器中安装MySQL,服务器的信息如下:
数据库 | IP | 数据库版本 |
---|---|---|
Master | 192.168.200.200 | 5.7.25 |
Slave | 192.168.200.201 | 5.7.25 |
**并在两台服务器上做如下准备工作:**
1). 防火墙开放3306端口号
firewall-cmd --zone=public --add-port=3306/tcp --permanent 打开3306端口
firewall-cmd --zone=public --list-ports 查看防火墙打开的端口列表
2). 并将两台数据库服务器启动起来:
systemctl start mysqld
登录MySQL,验证是否正常启动
主库配置
1). 修改Mysql数据库的配置文件/etc/my.cnf
在最下面增加配置:
log-bin=mysql-bin #[必须]启用二进制日志
server-id=200 #[必须]服务器唯一ID(唯一即可)
2). 重启Mysql服务
systemctl restart mysqld
3). 创建数据同步的用户并授权
登录mysql,并执行如下指令,创建用户并授权:
GRANT REPLICATION SLAVE ON *.* to 'remedios'@'%' identified by 'Hello@962597';
注:上面SQL的作用是创建一个用户 remedios ,密码为 Root@960904 ,并且给remedios用户授予REPLICATION SLAVE权限。常用于建立复制时所需要用到的用户权限,也就是slave必须被master授权具有该权限的用户,才能通过该用户复制。
目前mysql5.7默认密码校验策略等级为 MEDIUM , 该等级要求密码组成为: 数字、小写字母、大写字母 、特殊字符、长度至少8位
4). 登录Mysql数据库,查看master同步状态
执行下面SQL,记录下结果中File和Position的值
show master status;
注:上面SQL的作用是查看Master的状态,执行完此SQL后不要再执行任何操作
从库配置
1). 修改Mysql数据库的配置文件/etc/my.cnf 添加如下字段
server-id=201 #[必须]服务器唯一ID
2). 重启Mysql服务
systemctl restart mysqld
3). 登录Mysql数据库,设置主库地址及同步位置
change master to master_host='192.168.200.200',master_user='remedios',master_password='Hello@962597',master_log_file='mysql-bin.000001',master_log_pos=154;
start slave;
参数说明:
A. master_host : 主库的IP地址
B. master_user : 访问主库进行主从复制的用户名(上面在主库创建的)
C. master_password : 访问主库进行主从复制的用户名对应的密码
D. master_log_file : 从哪个日志文件开始同步(上述查询master状态中展示的有)
E. master_log_pos : 从指定日志文件的哪个位置开始同步(上述查询master状态中展示的有)
4). 查看从数据库的状态
show slave status;
然后通过状态信息中的 Slave_IO_running 和 Slave_SQL_running 可以看出主从同步是否就绪,如果这两个参数全为Yes,表示主从同步已经配置完成。
MySQL命令行技巧:
\G : 在MySQL的sql语句后加上\G,表示将查询结果进行按列打印,可以使每个字段打印到单独的行。即将查到的结构旋转90度变成纵向;
读写分离
主库负责处理事务性的增删改操作,从库负责处理查询操作,能够有效的避免由数据更新导致的行锁,使得整个系统的查询性能得到极大的改善。
通过读写分离,就可以降低单台数据库的访问压力, 提高访问效率,也可以避免单机故障。
ShardingJDBC介绍
Sharding-JDBC定位为轻量级Java框架,在Java的JDBC层提供的额外服务。 它使用客户端直连数据库,以jar包形式提供服务,无需额外部署和依赖,可理解为增强版的JDBC驱动,完全兼容JDBC和各种ORM框架。
使用Sharding-JDBC可以在程序中轻松的实现数据库读写分离。
Sharding-JDBC具有以下几个特点:
1). 适用于任何基于JDBC的ORM框架,如:JPA, Hibernate, Mybatis, Spring JDBC Template或直接使用JDBC。
2). 支持任何第三方的数据库连接池,如:DBCP, C3P0, BoneCP, Druid, HikariCP等。
3). 支持任意实现JDBC规范的数据库。目前支持MySQL,Oracle,SQLServer,PostgreSQL以及任何遵循SQL92标准的数据库。
1). 在pom.xml中增加shardingJdbc的maven坐标
<dependency> <groupId>org.apache.shardingsphere</groupId> <artifactId>sharding-jdbc-spring-boot-starter</artifactId> <version>4.0.0-RC1</version> </dependency>
2). 在application.yml中增加数据源的配置
spring:
main:
allow-bean-definition-overriding: true #该配置项的目的,就是如果当前项目中存在同名的bean,后定义的bean会覆盖先定义的。
shardingsphere:
datasource:
names: #数据源的名称是master,slave可以随意定义非固定
master,slave
# 主数据源
master:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://192.168.200.200:3306/rw?characterEncoding=utf-8
username: root
password: root
# 从数据源
slave:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://192.168.200.201:3306/rw?characterEncoding=utf-8
username: root
password: root
masterslave:
# 读写分离配置
load-balance-algorithm-type: round_robin #轮询 如果有多个从库 从库的负载均衡策略
# 最终的数据源名称
name: dataSource
# 主库数据源名称
master-data-source-name: master #主库对应的数据源名称
# 从库数据源名称列表,多个逗号分隔 主从库在这里定义 与上面的名称无关
slave-data-source-names: slave1 #从库对应的数据源名称 多个slave1,slave2这样
props:
sql:
show: true #开启SQL显示,默认false
3). 在application.yml中增加配置
spring: main: allow-bean-definition-overriding: true
该配置项的目的,就是如果当前项目中存在同名的bean,后定义的bean会覆盖先定义的。
否则会出现如下错误:
报错信息表明,在声明 org.apache.shardingsphere.shardingjdbc.spring.boot 包下的SpringBootConfiguration中的dataSource这个bean时出错, 原因是有一个同名的 dataSource 的bean在com.alibaba.druid.spring.boot.autoconfigure包下的DruidDataSourceAutoConfigure类加载时已经声明了。
而我们需要用到的是 shardingjdbc包下的dataSource,所以我们需要配置上述属性,让后加载的覆盖先加载的。
Nginx-概述
Nginx是一款轻量级的Web服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器。其特点是占有内存少,并发能力强,事实上nginx的并发能力在同类型的网页服务器中表现较好,中国大陆使用nginx的网站有:百度、京东、新浪、网易、腾讯、淘宝等。
Nginx是由**伊戈尔·赛索耶夫**为俄罗斯访问量第二的Rambler.ru站点(俄文:Рамблер)开发的,第一个公开版本0.1.0发布于2004年10月4日。
官网:https://nginx.org/ 下载地址nginx: download
1). 安装依赖包
由于nginx是基于c语言开发的,所以需要安装c语言的编译环境,及正则表达式库等第三方依赖库。
yum -y install gcc pcre-devel zlib-devel openssl openssl-devel
2). 下载Nginx安装包
yum install wget
wget https://nginx.org/download/nginx-1.16.1.tar.gz
wget :
wget命令用来从指定的URL下载文件。wget非常稳定,它在带宽很窄的情况下和不稳定网络中有很强的适应性,如果是由于网络的原因下载失败,wget会不断的尝试,直到整个文件下载完毕。如果是服务器打断下载过程,它会再次联到服务器上从停止的地方继续下载。
3). 解压nginx压缩包
tar -zxvf nginx-1.16.1.tar.gz
4). 配置Nginx编译环境
cd nginx-1.16.1
./configure --prefix=/usr/local/nginx
5). 编译&安装
make & make install
yum install tree
备注:
上述我们用到的一个指令 tree,该指令可以将我们指定的目录以树状结构展示出来。如果没有这个指令,可以通过以下指令进行安装。
重点目录和文件如下:
目录/文件 | 说明 | 备注 |
---|---|---|
conf | 配置文件的存放目录 | |
conf/nginx.conf | Nginx的核心配置文件 | conf下有很多nginx的配置文件,我们主要操作这个核心配置文件 |
html | 存放静态资源(html, css, ) | 部署到Nginx的静态资源都可以放在html目录中 |
logs | 存放nginx日志(访问日志、错误日志等) | |
sbin/nginx | 二进制文件,用于启动、停止Nginx服务 |
Nginx-命令
Nginx中,我们的二进制可执行文件(nginx)存放在sbin目录下,虽然只有一个可执行文件,但是我们可以通过该指令配合不同的参数达到更加强大的功能。接下来,我们就演示一下Nginx常见指令, 在执行下面的指令时,都需要在/usr/local/nginx/sbin/目录下执行。
1). 查看版本
./nginx -v
2). 检查配置文件
修改了nginx.conf核心配置文件之后,在启动Nginx服务之前,可以先检查一下conf/nginx.conf文件配置的是否有错误,命令如下:
./nginx -t
3). 启动
./nginx
启动之后,我们可以通过ps -ef指令来查看nginx的进程是否存在。
注意: nginx服务启动后,默认就会有两个进程。
启动之后,我们可以直接访问Nginx的80端口, http://192.168.200.200
注意:
要想正常访问Nginx,需要关闭防火墙或开放指定端口号,执行的指令如下:
A. 关闭防火墙
systemctl stop firewalld
B. 开放80端口
firewall-cmd --zone=public --add-port=80/tcp --permanent
firewall-cmd --reload
4). 停止
./nginx -s stop
停止之后,我们可以查看nginx的进程:
5). 重新加载
当修改了Nginx配置文件后,需要重新加载才能生效,可以使用下面命令重新加载配置文件:
./nginx -s reload
环境变量配置
在上述我们在使用nginx命令在进行服务的启动、停止、重新加载时,都需要用到一个指令nginx,而这个指令是在nginx/sbin目录下的,我们每一次使用这个指令都需要切换到sbin目录才可以,使用相对繁琐。那么我们能不能在任意目录下都可以执行该指令来操作nginx呢?答案是可以的,配置nginx的环境变量即可。
通过vim编辑器,打开/etc/profile文件, 在PATH环境变量中增加nginx的sbin目录,如下:
修改完配置文件之后,需要执行 source /etc/profile 使文件生效。 接下来,我们就可以在任意目录下执行nginx的指令了
如果出现Nginx: [error] open() "/usr/local/Nginx/logs/Nginx.pid 错误
使用如下命令解决:
/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
Nginx-应用
配置文件结构
nginx的配置文件(conf/nginx.conf)整体上分为三部分: 全局块、events块、http块。这三块的分别配置什么样的信息呢,看下表:
区域 | 职责 |
---|---|
全局块 | 配置和nginx运行相关的全局配置 |
events块 | 配置和网络连接相关的配置 |
http块 | 配置代理、缓存、日志记录、虚拟主机等配置 |
全局块:
events块:
http块:
在全局块、events块以及http块中,我们经常配置的是http块。
在http块中可以包含多个server块,每个server块可以配置多个location块。
server块:
部署静态资源
Nginx可以作为静态web服务器来部署静态资源。这里所说的静态资源是指在服务端真实存在,并且能够直接展示的一些文件,比如常见的html页面、css文件、js文件、图片、视频等资源。
相对于Tomcat,Nginx处理静态资源的能力更加高效,所以在生产环境下,一般都会将静态资源部署到Nginx中。
将静态资源部署到Nginx非常简单,只需要将文件复制到Nginx安装目录下的html目录中即可。
server {
listen 80; #监听端口
server_name localhost; #服务器名称
location / { #匹配客户端请求url
root html; #指定静态资源根目录
index index.html; #指定默认首页
}
}
1). 将静态资源上传到 /usr/local/nginx/html 目录
反向代理
概念介绍
1). 正向代理
正向代理服务器是一个位于客户端和原始服务器(origin server)之间的服务器,为了从原始服务器取得内容,客户端向代理发送一个请求并指定目标(原始服务器),然后代理向原始服务器转交请求并将获得的内容返回给客户端。
正向代理的典型用途是为在防火墙内的局域网客户端提供访问Internet的途径。
正向代理一般是在客户端设置代理服务器,通过代理服务器转发请求,最终访问到目标服务器。
2). 反向代理
反向代理服务器位于用户与目标服务器之间,但是对于用户而言,反向代理服务器就相当于目标服务器,即用户直接访问反向代理服务器就可以获得目标服务器的资源,反向代理服务器负责将请求转发给目标服务器。用户不需要知道目标服务器的地址,也无须在用户端作任何设定,对于用户来说,访问反向代理服务器是完全无感知的。
在192.168.200.201部署服务并启动
在192.168.200.200中的nginx.conf中配置反向代理
cd /usr/local/nginx/conf/
vim nginx.conf
在http块中,再添加一个server块虚拟主机的配置,监听82端口,并配置反向代理proxy_pass:
server {
listen 82;
server_name localhost;
location / {
proxy_pass http://192.168.200.201:8080; #反向代理配置,将请求转发到指定服务
}
}
上述配置的含义为: 当我们访问nginx的82端口时,根据反向代理配置,会将请求转发到 http://192.168.200.201:8080 对应的服务上。
检查配置文件,并重新加载
nginx -t
nginx -s reload
注意: 在访问82端口时,有可能访问不通,原因是以为防火墙中没有开放端口号。我们可以通过两种方式来解决该问题:
关闭防火墙
systemctl stop firewalld
开放指定端口
firewall-cmd --zone=public --add-port=82/tcp --permanent
firewall-cmd --reload
负载均衡
早期的网站流量和业务功能都比较简单,单台服务器就可以满足基本需求,但是随着互联网的发展,业务流量越来越大并且业务逻辑也越来越复杂,单台服务器的性能及单点故障问题就凸显出来了,因此需要多台服务器组成应用集群,进行性能的水平扩展以及避免单点故障出现。
应用集群:将同一应用部署到多台机器上,组成应用集群,接收负载均衡器分发的请求,进行业务处理并返回响应数据
负载均衡器:将用户请求根据对应的负载均衡算法分发到应用集群中的一台服务器进行处理
在nginx中配置负载均衡
打开nginx的配置文件nginx.conf并增加如下配置:
#upstream指令可以定义一组服务器
upstream remediosserver{
server 192.168.200.201:8080;
server 192.168.200.202:8080;
}
server {
listen 8080;
server_name localhost;
location / {
proxy_pass http://remediosserver; #本质就是反向代理 不过代理对象是一组服务器
}
}
注意: upstream不能修改 后面跟的服务器组名字remediosserver可以修改 底下反向代理指定的随之更改即可
上述所有涉及到的端口号,都需要在对应的服务器的防火墙中开放,或者彻底关闭防火墙
负载均衡策略
处理上述默认的轮询策略以外,在Nginx中还提供了其他的负载均衡策略,如下:
名称 | 说明 | 特点 |
---|---|---|
轮询 | 默认方式 | |
weight | 权重方式 | 根据权重分发请求,权重大的分配到请求的概率大 |
ip_hash | 依据ip分配方式 | 根据客户端请求的IP地址计算hash值, 根据hash值来分发请求, 同一个IP发起的请求, 会发转发到同一个服务器上 |
least_conn | 依据最少连接方式 | 哪个服务器当前处理的连接少, 请求优先转发到这台服务器 |
url_hash | 依据url分配方式 | 根据客户端请求url的hash值,来分发请求, 同一个url请求, 会发转发到同一个服务器上 |
fair | 依据响应时间方式 | 优先把请求分发给处理请求时间短的服务器 |
#upstream指令可以定义一组服务器
upstream targetserver{
server 192.168.200.201:8080 weight=10; #指代201服务器的权重是202服务器的两倍
server 192.168.200.202:8080 weight=5;
}
以此类推负载均衡策略