当前位置:网站首页>mysql实现读写分离
mysql实现读写分离
2022-07-06 09:15:00 【乘风破BUG】
简介
传统的MySql读写分离方案是通过在代码中根据SQL语句的类型动态切换数据源来实现的,那么有没有什么中间件可以自动实现读写分离呢?小米开源的数据库中间件Gaea就可以实现,接下来我们将详细讲解如何使用Gaea来实现MySql的读写分离。
Gaea是小米中国区电商研发部研发的基于MySql协议的数据库中间件,目前在小米商城大陆和海外得到广泛使用,包括订单、社区、活动等多个业务。Gaea支持分库分表、SQL路由、读写分离等基本特性,其中分库分表方案兼容了mycat和kingshard两个项目的路由方式。
前提
要实现读写分离的前提条件是要先实现MySql主从复制,具体实现可在这里查看:Mysql主从复制
安装Gaea
目前官方提供的是在Linux下直接安装的方式
安装Go语言环境
由于Gaea是使用Go语言编写的,所以我们需要先安装Go语言的环境。
- 先下载安装包
wget https://dl.google.com/go/go1.13.5.linux-amd64.tar.gz
如果提示wegt命令找不到,可执行
yum -y install wget
- 下载完成后解压到/mydata目录下
tar -zxvf go1.13.5.linux-amd64.tar.gz -C /mydata/
- 添加/mydata/go/bin目录到PATH变量中
# 编辑环境变量配置文件
vim /etc/profile
# 在最后一行添加
export GOROOT=/mydata/go
export PATH=$PATH:$GOROOT/bin
# 刷新配置文件
source /etc/profile
- 查看版本号,测试是否安装成功
go version
- 返回以下信息表示Go语言环境已经安装成功了
go version go1.13.5 linux/amd64
安装Gaea
由于Gaea并没有提供安装包,所以我们需要自行编译源码获取可执行文件
- 下载Gaea的源码,直接下载zip包即可
下载地址:https://github.com/XiaoMi/Gaea - 将下载好的压缩包进行解压操作,这里我们解压到/mydata/gaea/目录下:
unzip Gaea-master.zip
- 进入/mydata/gaea/目录下,使用make命令对源码编译:
make build
tip:某些Go的依赖会下载不下来导致编译失败,这里可能会出现连接失败
这时可以执行一下命令:
#切换成一个国内能访问的代理地址
go env -w GOPROXY=https://goproxy.cn;
##配置 GOPROXY 环境变量
export GOPROXY=https://goproxy.io;
这时再去执行make build 命令就能编译成功了
- 编译完成后在/mydata/gaea/bin目录下会生成Gaea的执行文件gaea
- 由于我们没有搭建etcd配置中心,所以需要修改本地配置文件/mydata/gaea/etc/gaea.ini,将配置类型改为file
config_type=file
- 添加namespace配置文件,用于配置我们的主从数据库信息,配置文件地址:/mydata/gaea/etc/file/namespace/wdj_namespace_1.json
- 配置文件内容如下
{
"name": "wdj_namespace_1",
"online": true,
"read_only": false,
"allowed_dbs": {
"mall": true
},
"slow_sql_time": "1000",
"black_sql": [
""
],
"allowed_ip": null,
"slices": [
{
"name": "slice-0",
"user_name": "root",
"password": "root",
"master": "192.168.131.3:3307",
"slaves": ["192.168.131.3:3308"],
"statistic_slaves": null,
"capacity": 12,
"max_capacity": 24,
"idle_timeout": 60
}
],
"shard_rules": null,
"users": [
{
"user_name": "wdj",
"password": "123456",
"namespace": "wdj_namespace_1",
"rw_flag": 2,
"rw_split": 1,
"other_property": 0
}
],
"default_slice": "slice-0",
"global_sequences": null
}
namespace配置文件
namespace的配置格式为json,包含分表、非分表、实例等配置信息,都可在运行时改变
- 整体配置说明
- slice配置
- users配置
在Docker容器中运行
打包成Docker镜像
Docker Hub 中并没有打包好的Gaea镜像,我们需要自行构建一个
- 这里我们使用Dockerfile构建Docker镜像,Dockerfile中的内容如下
# 该镜像需要依赖的基础镜像
FROM golang:latest
# 将当前目录下的gaea源码包复制到docker容器的/go/Gaea-master目录下,对于.tar.gz文件会自动解压
ADD Gaea-master.tar.gz /go/Gaea-master
# 将解压后的源码移动到/go/gaea目录中去
RUN bash -c 'mv /go/Gaea-master/Gaea-master /go/gaea'
# 进入/go/gaea目录
WORKDIR /go/gaea
RUN bash -c 'go env -w GOPROXY=https://goproxy.cn'
RUN bash -c 'export GOPROXY=https://goproxy.io'
# 将gaea源码进行打包编译
RUN bash -c 'make build'
# 声明服务运行在13306端口
EXPOSE 13306
# 指定docker容器启动时执行的命令
ENTRYPOINT ["/go/gaea/bin/gaea"]
# 指定维护者的名字
MAINTAINER wdj
TIP;在此之前我们需要把Gaea的源码压缩包转换为.tar.gz格式
转换命令:
#将xxx.zip解压
unzip xxx.zip
#会得到xxx文件夹
#将xxx压缩成tar.gz
tar -czf xxx.tar.gz xxx
#就得到了xxx.tar.gz
- 之后使用Docker命令构建Gaea的Docker镜像
docker build -t gaea:1.0.2 .
- 构建成功控制台输出
- 将本地安装的Gaea配置文件复制到/mydata/gaea-docker/etc/目录下
cp -r /mydata/gaea/etc/ /mydata/gaea-docker/etc/
- 使用Docker命令启动Gaea容器
docker run -p 13306:13306 --name gaea \
-v /mydata/gaea-docker/etc:/go/gaea/etc \
-d gaea:1.0.2
测试读写分离
测试思路:首先我们关闭从实例的主从复制,然后通过Gaea代理来操作数据库,插入一条数据,如果主实例中有这条数据而从实例中没有,说明写操作是走的主库。然后再通过Gaea代理查询该表数据,如果没有这条数据,表示读操作走的是从库,证明读写分离成功。
- 通过Navicat连接到Gaea代理,注意此处账号密码为Gaea的namespace中配置的内容,端口为Gaea的服务端口
- 通过Navicat分别连接到主库和从库,用于查看数据,此时建立了以下三个数据库连接
- 通过stop slave命令关闭mysql-slave实例的主从复制功能
- 通过Gaea代理在test表中插入一条数据
- 在主库中查看test表的数据,发现已有该数据
- 在从库中查看test表的数据,发现没有该数据,证明写操作走的是主库
- 直接在代理中查看test表中的数据,发现没有该数据,证明读操作走的是从库
结合SpringBoot使用
在我们的SpringBoot应用中,我们只需要把Gaea的代理服务直接当做数据库服务来使用就可以实现读写分离了。
测试连接代码
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
/**
* @author wdj
* Created on 2021/2/5 11:40
*/
public class JdbcTest {
//属性
private static String driver="com.mysql.jdbc.Driver";
//JDBC驱动类名
private static final String URL="jdbc:mysql://192.168.131.3:13306/mall?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&useSSL=false";
private static final String USER="wdj";
//用户名
private static final String PASSWORD="123456";
//密码
//创建连接
public static Connection getConnection(){
Connection conn=null;
try {
Class.forName(driver);
//加载jdbc驱动
conn=DriverManager.getConnection(URL, USER, PASSWORD);
//创建连接
//System.out.println("创建连接成功!");
} catch (Exception e) {
e.printStackTrace();
}
return conn;
}
//关闭连接
public static void close(Connection conn,Statement st,ResultSet rs){
if(rs!=null){
try {
rs.close();
//System.out.println("关闭rs成功!");
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
if(st!=null){
try {
st.close();
//System.out.println("关闭st成功!");
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
if(conn!=null){
try {
conn.close();
//System.out.println("关闭conn成功!");
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
}
public static void main(String[] args) {
try {
Connection conn = JdbcTest.getConnection();
if(conn!=null)
{
System.out.println("数据库连接正常!");
}
else {
System.out.println("数据库连接异常!");
}
}
catch(Exception ex)
{
ex.printStackTrace();
}
}
}
边栏推荐
- MTCNN人脸检测
- Codeforces Round #753 (Div. 3)
- [蓝桥杯2020初赛] 平面切分
- 机器学习笔记-Week02-卷积神经网络
- ImportError: libmysqlclient. so. 20: Cannot open shared object file: no such file or directory solution
- Codeforces Round #753 (Div. 3)
- yarn安装与使用
- [MRCTF2020]套娃
- 【presto】presto 参数配置优化
- 2020 WANGDING cup_ Rosefinch formation_ Web_ nmap
猜你喜欢
How to configure flymcu (STM32 serial port download software) is shown in super detail
快来走进JVM吧
Did you forget to register or load this tag
Word排版(小计)
[Flink] Flink learning
Machine learning notes week02 convolutional neural network
【yarn】Yarn container 日志清理
[蓝桥杯2017初赛]方格分割
Valentine's Day flirting with girls to force a small way, one can learn
AcWing 1298. Solution to Cao Chong's pig raising problem
随机推荐
Software testing - interview question sharing
Aborted connection 1055898 to db:
Deoldify project problem - omp:error 15:initializing libiomp5md dll,but found libiomp5md. dll already initialized.
Test objects involved in safety test
Codeforces Round #771 (Div. 2)
Wangeditor rich text component - copy available
Solution to the practice set of ladder race LV1 (all)
[mrctf2020] dolls
牛客Novice月赛40
Vs2019 desktop app quick start
[BSidesCF_2020]Had_ a_ bad_ day
PHP - whether the setting error displays -php xxx When PHP executes, there is no code exception prompt
vs2019 使用向导生成一个MFC应用程序
4. Install and deploy spark (spark on Yan mode)
Rhcsa certification exam exercise (configured on the first host)
How to configure flymcu (STM32 serial port download software) is shown in super detail
[MRCTF2020]套娃
使用lambda在循环中传参时,参数总为同一个值
In the era of DFI dividends, can TGP become a new benchmark for future DFI?
Are you monitored by the company for sending resumes and logging in to job search websites? Deeply convinced that the product of "behavior awareness system ba" has not been retrieved on the official w