基于mysql主从同步的proxy读写分离

架构示意图

		           ___ master_mysql(10.10.10.3)
    			  |          |
   mysql-proxy(10.10.10.2)   |
			      |___       |
			           slave_mysql(10.10.10.4)

(一)mysql主从同步

1、mysql-master设置

(1)

server-id = 1    //master端ID号
binlog-ignore-db =    //设置不同步的sql库
binlog-do-db=    //设置同步的数据

(2)设置完上面以后重启mysql

(3)添加用户访问主库,并且只有备份权限

mysql > grant replication slave  on *.* to ‘rsync‘@‘10.10.%‘ identified by ‘1q2w3e4rys‘ with grant option;
mysql > flush privileges;

(4)锁表,主库数据继续写入

mysql > flush tables with read lock;

(5)记录 master file与position的值,slave库配置同步时候要使用

(6)导出mysql主库数据

mysqldump -uuser -p databases > databases.sql

注:这里有个问题,当主库数据上G,较大时需要做如下操作

--max_allowed_packet=XXX    //客户端/服务器之间通信的缓存区的最大大小;
--net_buffer_length=XXX    //TCP/IP和套接字通信缓冲区大小,创建长度达net_buffer_length的行;

注意:max_allowed_packet和net_buffer_length不能比目标数据库的配置数值大,否则可能出错。

首先确定目标库的参数值

mysql>show variables like ‘max_allowed_packet‘;
mysql>show variables like ‘net_buffer_length‘;

根据参数值书写mysqldump命令,如:

mysql > mysqldump -uuser -p? 数据库名 -e --max_allowed_packet=1048576 --net_buffer_length=16384 > databases.sql

(7)master库同步到slave服务器上

# scp databases.sql  [email protected]:/path

2、mysql-slave设置

(1)

server-id = 2

(2)登录mysql创建sql数据库

mysql > CREATE DATABASE `?sql_db?` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;

(3)导入master库数据到slave库中

mysql -uuser -p? sql_db < databases.sql

(4)登录mysql停止slave

mysql > stop slave;

(5)配置从库同步

mysql > change master to master_host=’10.10.10.2’,master_user=’rsync’,master_password=’1q2w3e4rys’,master_port=3306,master_log_file=’mysql-bin.000047’,master_log_pos=107;

(6)启动同步功能

mysql > start slave;

(7)解除主库锁表

unlock tables;

(8)查看slave同步状态

mysql > show slave status\G    //多执行几遍,查看数据写入后的状态

注:查看上面的Slave_IO_Running: Yes 和Slave_SQL_Running: Yes  2个都为yes则证明主从同步正常,如果有任一个显示NO,则证明同步有问题.可以查看数据库日志文件,里面基本上会显示出错误之处,根据错误一步一步排查,基本上都可以解决的.

(二)mysql-proxy读写分离

1、安装mysql-proxy

(1)

# wget http://ftp.ntu.edu.tw/pub/MySQL/Downloads/MySQL-Proxy/mysql-proxy-0.8.5-linux-el6-x86-64bit.tar.gz
# tar xf mysql-proxy-0.8.5-linux-el6-x86-64bit.tar.gz -C /usr/local
# cd /usr/local
# ln -sv mysql-proxy-0.8.5-linux-el6-x86-64bit mysql-proxy

2、设置mysql-proxy属主属组

(1)

# groupadd mysql-proxy
# useradd -g mysql-proxy -s /sbin//nologin -M mysql-proxy

3、配置mysql-proxy

(1)为mysql-proxy提供SysV服务脚本,脚本如下:

#!/bin/bash
#
# mysql-proxy This script starts and stops the mysql-proxy daemon
#
# chkconfig: - 78 30
# processname: mysql-proxy
# description: mysql-proxy is a proxy daemon for mysql

# Source function library.
. /etc/rc.d/init.d/functions

prog="/usr/local/mysql-proxy/bin/mysql-proxy"

# Source networking configuration.
if [ -f /etc/sysconfig/network ]; then
    . /etc/sysconfig/network
fi

# Check that networking is up.
[ ${NETWORKING} = "no" ] && exit 0

# Set default mysql-proxy configuration.
ADMIN_USER="admin"
ADMIN_PASSWD="admin"
ADMIN_LUA_SCRIPT="/usr/local/mysql-proxy/share/doc/mysql-proxy/admin.lua"
PROXY_OPTIONS="--daemon"
PROXY_PID=/var/run/mysql-proxy.pid
PROXY_USER="mysql-proxy"

# Source mysql-proxy configuration.
if [ -f /etc/sysconfig/mysql-proxy ]; then
    . /etc/sysconfig/mysql-proxy
fi

RETVAL=0

start() {
    echo -n $"Starting $prog: "
    daemon $prog $PROXY_OPTIONS --pid-file=$PROXY_PID --proxy-address="$PROXY_ADDRESS" --user=$PROXY_USER --admin-username="$ADMIN_USER" --admin-lua-script="$ADMIN_LUA_SCRIPT" --admin-password="$ADMIN_PASSWORD"
    RETVAL=$?
    echo
    if [ $RETVAL -eq 0 ]; then
        touch /var/lock/subsys/mysql-proxy
    fi
}

stop() {
    echo -n $"Stopping $prog: "
    killproc -p $PROXY_PID -d 3 $prog
    RETVAL=$?
    echo
    if [ $RETVAL -eq 0 ]; then
        rm -f /var/lock/subsys/mysql-proxy
        rm -f $PROXY_PID
    fi
}
# See how we were called.
case "$1" in
    start)
        start
        ;;
    stop)
        stop
        ;;
    restart)
        stop
        start
        ;;
    condrestart|try-restart)
        if status -p $PROXY_PIDFILE $prog >&/dev/null; then
            stop
            start
        fi
        ;;
    status)
        status -p $PROXY_PID $prog
        ;;
    *)
        echo "Usage: $0 {start|stop|restart|reload|status|condrestart|try-restart}"
        RETVAL=1
        ;;
esac

exit $RETVAL

(2)将上述内容保存为/etc/rc.d/init.d/mysql-proxy,给予执行权限,而后加入到服务列表。

# chmod +x /etc/rc.d/init.d/mysql-proxy
# chkconfig --add mysql-proxy

(3)为服务脚本提供配置文件/etc/sysconfig/mysql-proxy,内容如下所示:

# Options for mysql-proxy 
ADMIN_USER="admin"
ADMIN_PASSWORD="admin"
ADMIN_ADDRESS=""
ADMIN_LUA_SCRIPT="/usr/local/mysql-proxy/share/doc/mysql-proxy/admin.lua"
PROXY_ADDRESS=""
PROXY_USER="mysql-proxy"
PROXY_OPTIONS="--daemon --log-level=info --log-use-syslog --plugins=proxy --plugins=admin --proxy-backend-addresses=10.10.10.3:3306 --proxy-read-only-backend-addresses=10.10.10.4:3306 --proxy-lua-script=/usr/local/mysql-proxy/share/doc/mysql-proxy/rw-splitting.lua"

(4)mysql-proxy配置选项注解

--help
--help-admin
--help-proxy
--help-all ———— 以上四个选项均用于获取帮助信息;

--proxy-address=host:port ———— 代理服务监听的地址和端口;
--admin-address=host:port ———— 管理模块监听的地址和端口;
--proxy-backend-addresses=host:port ———— 后端mysql服务器的地址和端口;
--proxy-read-only-backend-addresses=host:port ———— 后端只读mysql服务器的地址和端口;
--proxy-lua-script=file_name ———— 完成mysql代理功能的Lua脚本;
--daemon ———— 以守护进程模式启动mysql-proxy;
--keepalive ———— 在mysql-proxy崩溃时尝试重启之;
--log-file=/path/to/log_file_name ———— 日志文件名称;
--log-level=level ———— 日志级别;
--log-use-syslog ———— 基于syslog记录日志;
--plugins=plugin,.. ———— 在mysql-proxy启动时加载的插件;
--user=user_name ———— 运行mysql-proxy进程的用户;
--defaults-file=/path/to/conf_file_name ———— 默认使用的配置文件路径;其配置段使用[mysql-proxy]标识;
--proxy-skip-profiling ———— 禁用profile;
--pid-file=/path/to/pid_file_name ———— 进程文件名;

(5)复制如下内容建立admin.lua文件,将其保存至/usr/local/mysql-proxy/share/doc/mysql-proxy/目录中.

--[[ $%BEGINLICENSE%$
 Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.

 This program is free software; you can redistribute it and/or
 modify it under the terms of the GNU General Public License as
 published by the Free Software Foundation; version 2 of the
 License.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 02110-1301  USA

 $%ENDLICENSE%$ --]]

function set_error(errmsg) 
	proxy.response = {
		type = proxy.MYSQLD_PACKET_ERR,
		errmsg = errmsg or "error"
	}
end

function read_query(packet)
	if packet:byte() ~= proxy.COM_QUERY then
		set_error("[admin] we only handle text-based queries (COM_QUERY)")
		return proxy.PROXY_SEND_RESULT
	end

	local query = packet:sub(2)

	local rows = { }
	local fields = { }

	if query:lower() == "select * from backends" then
		fields = { 
			{ name = "backend_ndx", 
			  type = proxy.MYSQL_TYPE_LONG },

			{ name = "address",
			  type = proxy.MYSQL_TYPE_STRING },
			{ name = "state",
			  type = proxy.MYSQL_TYPE_STRING },
			{ name = "type",
			  type = proxy.MYSQL_TYPE_STRING },
			{ name = "uuid",
			  type = proxy.MYSQL_TYPE_STRING },
			{ name = "connected_clients", 
			  type = proxy.MYSQL_TYPE_LONG },
		}

		for i = 1, #proxy.global.backends do
			local states = {
				"unknown",
				"up",
				"down"
			}
			local types = {
				"unknown",
				"rw",
				"ro"
			}
			local b = proxy.global.backends[i]

			rows[#rows + 1] = {
				i,
				b.dst.name,          -- configured backend address
				states[b.state + 1], -- the C-id is pushed down starting at 0
				types[b.type + 1],   -- the C-id is pushed down starting at 0
				b.uuid,              -- the MySQL Server‘s UUID if it is managed
				b.connected_clients  -- currently connected clients
			}
		end
	elseif query:lower() == "select * from help" then
		fields = { 
			{ name = "command", 
			  type = proxy.MYSQL_TYPE_STRING },
			{ name = "description", 
			  type = proxy.MYSQL_TYPE_STRING },
		}
		rows[#rows + 1] = { "SELECT * FROM help", "shows this help" }
		rows[#rows + 1] = { "SELECT * FROM backends", "lists the backends and their state" }
	else
		set_error("use ‘SELECT * FROM help‘ to see the supported commands")
		return proxy.PROXY_SEND_RESULT
	end

	proxy.response = {
		type = proxy.MYSQLD_PACKET_OK,
		resultset = {
			fields = fields,
			rows = rows
		}
	}
	return proxy.PROXY_SEND_RESULT
end

(6)测试

#mysql -uadmin -padmin -h110.10.10.2 --port=4041 
mysql > SELECT * FROM backends;
+-------------+-------------------+-------+------+------+-------------------+
| backend_ndx | address           | state | type | uuid | connected_clients |
+-------------+-------------------+-------+------+------+-------------------+
|           1 | 10.10.10.3:3306   | up    | rw   | NULL |                 0 | 
|           2 | 10.10.10.4:3306   | up    | ro   | NULL |                 0 | 
+-------------+-------------------+-------+------+------+-------------------+
2 rows in set (0.00 sec)
时间: 2024-11-08 09:14:30

基于mysql主从同步的proxy读写分离的相关文章

Mysql主从配置,实现读写分离

大型网站为了软解大量的并发访问,除了在网站实现分布式负载均衡,远远不够.到了数据业务层.数据访问层,如果还是传统的数据结构,或者只是单单靠一台服务器扛,如此多的数据库连接操作,数据库必然会崩溃,数据丢失的话,后果更是 不堪设想.这时候,我们会考虑如何减少数据库的联接,一方面采用优秀的代码框架,进行代码的优化,采用优秀的数据缓存技术如:memcached,如果资金丰厚的话,必然会想到假设服务器群,来分担主数据库的压力.Ok切入今天微博主题,利用MySQL主从配置,实现读写分离,减轻数据库压力.这种

mysql数据库的主从同步,实现读写分离 g

https://blog.csdn.net/qq_15092079/article/details/81672920 前言 1 分别在两台centos 7系统上安装mysql 5.7 2 master主服务器的配置 2.1 配置文件my.cnf的修改 2.2 创建从服务器的用户和权限 2.3 重启mysql服务 2.4 查看主服务器状态 3 slave从服务器的配置 3.1 配置文件my.cnf的修改 3.2 重启mysql服务 3.3 连接master主服务器 3.4 启动slave数据同步

MySQL主从配置及实现读写分离

大型网站为了软解大量的并发访问,除了在网站实现分布式负载均衡,远远不够.到了数据业务层.数据访问层,如果还是传统的数据结构,或者只是单单靠一台服务器扛,如此多的数据库连接操作,数据库必然会崩溃,数据丢失的话,后果更是 不堪设想.这时候,我们会考虑如何减少数据库的联接,一方面采用优秀的代码框架,进行代码的优化,采用优秀的数据缓存技术如:memcached,如果资金丰厚的话,必然会想到假设服务器群,来分担主数据库的压力.Ok切入今天主题,利用MySQL数据库主从配置,实现读写分离,减轻数据库压力.这

MySQL第六天(主从同步,数据读写分离)

day05一.数据备份与恢复-增量备份和增量恢复a.binlog日志介绍(二进制文件):使用Mysql数据库服务日志文件类型的一种.记录除查询之外的sql命令.默认没启用 查询的sql包括:select desc show 不是查询的命令:insert update delete create drop grant revoke b.启用binlog日志如何启用日志默认存放位置/var/lib/mysql日志默认名称主机名-bin.00000151-bin.000001 (大于500M自动生成0

MySQL主从同步读写分离的集群配置

大型网站为了解决大量的高并发访问问题,除了在网站实现分布式负载均衡,远远不够.到了数据业务层.数据访问层,如果还是传统的数据结构,或者只是单单靠一台服务器支持,如此多的数据库连接操作,服务器性能再好数据库必然会崩溃.数据丢失的话,后果更是不堪设想.这时候,我们会考虑如何减少数据库的连接,一方面采用优秀的代码框架,进行代码的优化,采用优秀的数据缓存技术如:memcached等.如果资金充足的话,必然会想到假设服务器集群,来分担主数据库的压力.或者在硬件设备上,投入大量资金,购买高性能的服务器.出名

MySQL主从同步、读写分离配置步骤、问题解决笔记

根据要求配置MySQL主从备份.读写分离,结合网上的文档,对搭建的步骤和出现的问题以及解决的过程做了如下笔记:       现在使用的两台服务器已经安装了MySQL,全是rpm包装的,能正常使用.       为了避免不必要的麻烦,主从服务器MySQL版本尽量保持一致; 环境:192.168.0.1 (Master)           192.168.0.2 (Slave) MySQL Version:Ver 14.14 Distrib 5.1.48, for pc-linux-gnu (i6

【纯干货】Amoeba实现MySQL主从同步与读写分离

[纯干货]Amoeba实现MySQL主从同步与读写分离 一.简介 amoeba简介 Amoeba(变形虫)项目,该开源框架于2008年开始发布一款 Amoeba for Mysql软件.这个软件致力于MySQL的分布式数据库前端代理层,它主要在应用层访问MySQL的 时候充当SQL路由功能,专注于分布式数据库代理层(Database Proxy)开发.座落与 Client.DB Server(s)之间,对客户端透明.具有负载均衡.高可用性.SQL 过滤.读写分离.可路由相关的到目标数据库.可并发

如何实现 MySQL 的读写分离?MySQL 主从复制原理的是啥?如何解决 MySQL 主从同步的延时问题?

高并发这个阶段,肯定是需要做读写分离的,啥意思?因为实际上大部分的互联网公司,一些网站,或者是 app,其实都是读多写少.所以针对这个情况,就是写一个主库,但是主库挂多个从库,然后从多个从库来读,那不就可以支撑更高的读并发压力了吗? 如何实现 MySQL 的读写分离? 其实很简单,就是基于主从复制架构,简单来说,就搞一个主库,挂多个从库,然后我们就单单只是写主库,然后主库会自动把数据给同步到从库上去. MySQL 主从复制原理的是啥? 主库将变更写入 binlog 日志,然后从库连接到主库之后,

mysql主从同步+mycat读写分离+.NET程序连接mycat代理

背景 最近新项目需要用到mysql数据库,并且由于数据量大的原因,故打算采用1主1从(主数据库负责增.删.改操作:从数据库负责查操作)的数据库架构,在实现主从之后还要实现读写分离的代理,在网上搜寻了很久,自己也了解了一些资料,目前有三种代理组件:1.mysql_proxy   2.amoeba   3.mycat   我采用了第3种,选择mycat的原因下面会提到. 部署环境 我在我虚拟机下面装了三台Centos7_x64系统: 1.192.168.8.47 主mysql服务器 2.192.16