文章目录

  • 概述
  • 描述
  • 使用场景
  • 实现方式
  • 主从复制(mysql为例)
  • 复制类型
  • 主从同步原理
  • 实现
  • 读写分离
  • 实现方式
  • MyCat搭建
  • 配置文件
  • 代码实现读写分离


概述

描述

读写分离是数据库集群的一种方式,这种方式可以将对数据库访问的压力分散到集群的各个节点上,但是因为是通过与主服务器进行同步,存储的数据量并没有减少,所有读写分离并没有解决如何减少存储压力。像微信的朋友圈,上亿人发布,这些数据还是必不可删的,数据量大,服务器数据库的存储却是有限的。读写分离无法解决。

使用场景

在存储量不大的情况下,并且访问量大的情况,当然,如果是访问量比较小的程序,也没有必要去使用读写分离。

实现方式

通过主从复制实现,主服务器复制数据同步到从服务器,可以进行一主一从,一主多从,主服务器进行读写(主要是写),从服务器进行读数据。还有一种热备功能(主备),当主服务器挂掉后,从服务器顶替主服务器。

PostgreSQL主从读写分离 主从数据库读写分离_mycat

主从复制(mysql为例)

复制类型

1.基于语句复制,也就是执行sql语句,mysql默认。
2.基于行的复制,把改变的内容复制到从服务器。
3.混合类型的复制。默认采用基于语句的复制,一旦发现基于语句无法精确复制时,就会采用基于行的复制。

主从同步原理

binlog:一个二进制的文件,记录了数据库更改的操作,不记录查询操作。可使用mysqlbinlog查看该文件。

  • master有一个log dump线程,给slave传输bin log文件。
  • slave有两个线程,一个I/O线程,去请求主库的binlog日志,将master的biglog拷贝到slave的relay(中继)log文件中。
  • slave的第二个线程sql线程会读取relay log,执行具体操作,实现主从复制。

实现

我是通过虚拟机创建两个centos7系统模拟,ip地址(主:192.168.52.131,从:192.168.52.133)。各自安装mysql。
master配置:
vi /etc/my.cnf 修改配置文件
在[mysqld]下添加

server-id=1                 //用作标识
log-bin=master-bin     //二进制文件
log-slave-updates=true  //级联复制

service mysqld restart //重启服务

show master status; //查看数据库状态

PostgreSQL主从读写分离 主从数据库读写分离_mycat_02


slave配置:

修改配置文件添加

server-id=10
log-bin=slave-bin
relay-log=relay-log
read_only=ON

重启mysql服务
修改要同步的master:
change master to master_host=‘192.168.52.131’,
master_port=3306,
master_user=‘root’,
master_password=‘123456’,
master_log_file=‘master-bin.000001’,
master_log_pos=120;
启动slave:start slave;
这时,我们在master进行的增删改等操作会在slave中会同步操作。可以自行测试。

读写分离

实现方式

  • 代码方面使用spring路由数据源以及aop进行实现
  • MySql中间件

第一种方式是把写在代码的配置中,所以在动态增加数据库节点时会出现问题,耦合度高,推荐使用中间件的形式。
MySql各类中间件:
1.Cobar:是阿里巴巴团队开发,由于最近几年不维护了,不推荐使用
2.MyCat:基于Cobar进行的二次开发,社区维护
3.mysql-proxy:其是mysql官方提供的mysql中间件服务
4.sharding-proxy:也是蛮常用的一个吧,并且该社区还有sharding-JDBC通过jdbc协议实现读写分离

MyCat搭建

MyCat:开源的分布式数据库系统,用java开发,所以安装MyCat前必须安装JDK,实现MySql、JDBC协议,通过Mysql协议与多个Mysql服务器通信,通过JDBC协议与其它主流数据库通信。
下载地址 http://dl.mycat.io/1.6.5/ 自行下载所需版本
解压:tar -zxvf Mycat-server-1.6.5-release-20180122220033-linux.tar.gz
配置环境变量,不用每次都进入bin目录执行命令
vi /etc/profile

//参考,只加mycat的就行了,其它不用管
    export MYCAT_HOME=/usr/mycat
    export CLASS_PATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib:$JAVA_HOME/lib
    export PATH=$JAVA_HOME/bin:$JRE_HOME/bin:$ZOOKEEPER_HOME/bin:$MYCAT_HOME/bin:$PATH

测试是否安装成功:
开启:mycat start
查看其它命令:mycat -h

配置文件

server.xml:mycat配置信息和用户授权信息
schema.xml:保存了mycat的逻辑库、表以及分片配置
rule.xml:分片规则
wrapper.xml:jvm内存配置
zkconf:zookeeper配置目录

<!-- 配置主机信息和用户 -->
	<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="192.168.52.131" url="192.168.52.131:3306" user="root"
				   password="123456">
			<!-- can have multi read hosts -->
			<readHost host="192.168.52.133" url="192.168.52.133:3306" user="root" password="123456" />
		</writeHost>
		<!-- 192.168.52.134是备份数据库,当131节点宕机时当作主机使用,测试的话可以不写 -->
		<writeHost host="192.168.52.134" url="192.168.52.134:3306" user="root"
				   password="123456" />
	</dataHost>

datahost:配置主机信息和
在dataHost节点的属性

  • balance:
    0是不开起读写分离
    1是指所有的readHost(读服务器)与standby writeHost(备用服务器:主机宕机后切换到的服务器)都进行查询的负载均衡
    2是指所有writeHost节点都不进行读操作,只有readHost进行读操作
  • writeType:
    0是所有写操作请求到可用writeHost
    1是所有写操作随机请求到readHost
    2是所有写操作随机请求到writeHost和readHost
    dbDriver:
    native:mysql与mysql通信
    jdbc:mysql与其它主流数据库通信
代码实现读写分离

在代码中修改数据源

spring:
  datasource:
    password: 123456
    url: jdbc:mysql://127.0.0.1:8066/mycatTest
    username: root
    driver-class-name: com.mysql.cj.jdbc.Driver

在master添加数据库mycatTest和表user后配置
server.xml

<user name="root" defaultAccount="true">
		<property name="password">123456</property>
		<!-- 添加mycatTest数据库 -->
		<property name="schemas">TESTDB,mycatTest</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="user">
		<property name="password">user</property>
		<property name="schemas">TESTDB,mycatTest</property>
		<property name="readOnly">true</property>
	</user>

schema.xml

<schema name="mycatTest" checkSQLschema="false" sqlMaxLimit="100">
	    <table name="user" primaryKey="ID" dataNode="mycatTest"/>
</schema>
<dataNode name="mycatTest" dataHost="localhost1" database="mycatTest" />
<!-- 配置主机信息和用户 -->
	<dataHost name="localhost1" maxCon="1000" minCon="10" balance="0"
			  writeType="0" dbType="mysql" dbDriver="native" switchType="1"  slaveThreshold="100">
	    <!-- 心跳检测语句 -->
		<heartbeat>select user()</heartbeat>
		<!-- 远程数据库配置信息 -->
		<writeHost host="192.168.52.131" url="192.168.52.131:3306" user="root"
				   password="123456">
			<!-- can have multi read hosts -->
			<readHost host="192.168.52.133" url="192.168.52.133:3306" user="root" password="123456" />
		</writeHost>
		<writeHost host="192.168.52.134" url="192.168.52.134:3306" user="root"
				   password="123456" />
	</dataHost>

navicat建立mycat连接方便查看,mycat默认端口:8066

PostgreSQL主从读写分离 主从数据库读写分离_分布式_03


此时在代码进行数据库访问便是读写分离啦!