Chinaunix首页 | 论坛 | 博客
  • 博客访问: 140448
  • 博文数量: 70
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 770
  • 用 户 组: 普通用户
  • 注册时间: 2017-11-04 11:19
文章分类

全部博文(70)

文章存档

2018年(69)

2016年(1)

我的朋友

分类: LINUX

2018-09-05 09:20:38

通过amoeba实现mysql 读写分离


Mysql作为目前世界上使用最广泛的免费数据库,相信我们都有所了解。但在实际的生产环境中,由单台Mysql作为独立的数据库是完全不能满足实际需求的,无论是在安全性,高可用性以及高并发等各个方面。因此,一般来说都是通过 主从复制(Master-Slave)的方式来同步数据,再通过读写分离(MySQL-Proxy)来提升数据库的并发负载能力 这样的方案来进行部署与实施的。为了确保数据库产品的稳定性,很多数据库拥有双机热备功能。也就是,第一台数据库服务器,是对外提供增删改业务的生产服务器;第二台数据库服务器,主要进行读的操作。


  1. 读写分离的原理:


让主数据库(master)处理事务性增、改、删操作(INSERTUPDATEDELETE),而从数据库(slave)处理SELECT查询操作。


 


2、为什么使用读写分离


为了确保数据库产品的稳定性,很多数据库拥有双机热备功能。也就是,第一台数据库服务器,是对外提供增删改查业务的生产服务器;第二台数据库服务器,仅仅接收来自第一台服务器的备份数据(注意,不同数据库产品,第一台数据库服务器,向第二台数据库服务器发送备份数据的方式不同)。当第一台数据库崩溃后,第二台数据库服务器,可以立即上线来代替第一台数据库服务器,并且,在第一台数据库服务器崩溃后,宝贵的数据,依然会存在于第二台数据库服务器里(根据目前业界的备份数据发送方式来看,当第一台数据库崩溃后,第一台数据库里的仍然会有少量的新数据,没能来得及被发送到第二台数据库服务器,所以,这部分数据就丢失了)。


   一般来说,为了配置方便,以及稳定性,这两台数据库服务器,都用的是相同的配置(思考一下,如果两台服务器的配置不同,会导致什么结果)。


   在实际运行中,第一台数据库服务器的压力,远远大于第二台数据库服务器。因此,很多人希望合理利用第二台数据库服务器的空闲资源。那么,第二台数据库服务器能做些什么事情呢?


   从数据库的基本业务来看,数据库的操作无非就是增删改查这4个操作。但对于增删改这三个操作,如果是双机热备的环境中做,一台机器做了这三个操作的某一个之后,需要立即将这个操作,同步到另一台服务器上。单向的同步,不复杂。但如果两台机器都需要向对方进行同步,那逻辑就非常复杂,而且还会大大降低性能。(从保证ACID特性的角度,思考一下为什么双向同步会非常复杂且低性能?而单向同步却不会?)出于这个原因,第二台备用的服务器,就只做了查询操作。进一步,为了降低第一台服务器的压力,干脆就把查询操作全部丢给第二台数据库服务器去做,第一台数据库服务器就只做增删改了。


    到这一步,就实现了所谓的读写分离。这样做,缺点也非常明显了。本来第二台数据库服务器,是用来做热备的,它就应该在一个压力非常小的环境下,保证运行的稳定性。而读写分离,却增加了它的压力,也就增加了不稳定性。因此,读写分离,实质上是一个在资金比较缺乏,但又需要保证数据安全的需求下,在双机热备方案上,做出的一种折中的扩展方案。


 


3、实现MySQL主从读写分离的方案


1)通过程序实现读写分离(性能和效率最佳,推荐)


PHPJava程序都可以通过设置多个连接文件轻松地实现对数据库的读写分离,即当语句关键字为select时,就去连接读库的连接文件,若为updateinsertdelete时,则连接写库的连接文件。


通过程序实现读写分离的缺点就是需要开发人员对程序进行改造,使其对下层不透明,但是这种方式更容易开发和实现,适合互联网业务场景。


  1. 通过开源的软件实现读写分离

    MySQL-proxyAmoeba等代理软件也可以实现读写分离功能,这些软件的稳定性和功能一般,不建议生产使用。绝大多数公司常用的还是在应用端开发程序实现读写分离。

  2. 大型门户独立开发DAL层综合软件

         百度、阿里等大型门户都有牛人开发,会花大力气开发合适自己业务的读写分离、负载均衡、监控报警、自动扩容、自动收缩等一系列功能的DAL层软件。

     

    MySQL读写分离

    --------client--------------amoeba-------------MySQL----------------MySQL------------MySQL---------

    192.168.1.10 192.168.1.100 192.168.1.200 192.168.1.201 192.168.1.202

    构建步骤:

     

    一、在amoeba服务器中:

    安装java环境

    1、安装java

    [root@localhost ~]# chmod +x jdk-6u14-linux-x64.bin

    [root@localhost ~]# ./jdk-6u14-linux-x64.bin //yes,按回车

    [root@localhost ~]# mv jdk1.6.0_14/ /usr/local/java

    [root@localhost ~]# rm -rf /usr/bin/java //删除原有的java

    [root@localhost ~]# rm -rf /usr/bin/javac //删除原有的javac

    [root@localhost ~]# ln -s /usr/local/java/bin/* /usr/bin/java 没有mkdir创建jav

    [root@localhost ~]# vim /etc/profile

    添加:

    export JAVA_HOME=/usr/local/java

    export CLASSPATH=$CLASSPATH:$JAVA_HOME:/lib:$JAVA_HOME/jre/lib

    export PATH=$JAVA_HOME/lib:$JAVA_HOME/bin:$PATH:$JAVA_HOME/bin

    export AMOEBA_HOME=/usr/local/amoeba

    export PATH=$PATH:$AMOEBA_HOME/bin

     

    [root@localhost ~]# source /etc/profile

    [root@localhost ~]# java -version

    [root@localhost ~]# java -version

    java version "1.6.0_14"

    Java(TM) SE Runtime Environment (build 1.6.0_14-b08)

    Java HotSpot(TM) 64-Bit Server VM (build 14.0-b16, mixed mode)

     

    2、安装amoeba(变形虫)

    [root@localhost ~]# mkdir /usr/local/amoeba

    [root@localhost ~]# tar -zxvf amoeba-mysql-binary-2.2.0.tar.gz -C /usr/local/amoeba/

    [root@localhost ~]# chmod 755 /usr/local/amoeba/ -R

    [root@localhost ~]# /usr/local/amoeba/bin/amoeba //验证amoeba是否安装成功

     

    [root@localhost ~]# /usr/local/amoeba/bin/amoeba start & //启动amoeba

    [root@localhost ~]# netstat -anpt | grep java

     

    3、配置Amoeba(实现读写分离,两个Slave读负载均衡)

     

    1)主MySQL服务器、从MySQL服务器(3台)开放权限

    [root@localhost ~]# mysql -u root -p redhat

    mysql> grant all on *.* to 'root'@'192.168.1.%' identified by 'redhat';

    mysql> flush privileges; 主 从 从都要给权限

    2)修改amoeba配置文件

    [root@localhost ~]# vim /usr/local/amoeba/conf/amoeba.xml

    修改:

    authenticator">

    8066

    192.168.1.100 //修改本机IP地址

    amoeba //修改

    redhat //修改

     

    1500

    master //修改

    master //修改

    slaves //修改

    true

     

    3)修改dbServer.xml配置文件

    [root@localhost ~]# vim /usr/local/amoeba/conf/dbServers.xml

    修改:

    root //修改用户为root(授权用户)

    redhat //修改密码(授权密码)

    ...部分省略....

    //修改服务名称为master

    192.168.1.200 //修改为主数据库服务器的IP

    //修改服务名称为slave1

    192.168.1.201 //修改为从数据库服务器的IP

    //修改服务名称为slave2

    192.168.1.202 //修改为从数据库服务器的IP

     

    //修改为 slaves

    1

    slave1,slave2 //修改为 slave1,slave2

    wq!

    [root@localhost ~]# /usr/local/amoeba/bin/amoeba stop

    [root@localhost ~]# /usr/local/amoeba/bin/amoeba start & 后台运行

    [root@localhost ~]# netstat -anpt | grep java 检测

     

    二、MySQL数据库服务器中(三台):

     

    1、在主数据库上安装ntp时间服务

    [root@localhost ~]# yum -y install ntp

    [root@localhost ~]# vim /etc/ntp.conf

    添加:

    server 127.127.1.0

    fudge 127.127.1.0 stratum 8

    [root@localhost ~]# service ntpd restart

     

    2、在从数据库上安装ntp时间服务

    [root@localhost ~]# yum -y install ntpdate

    [root@localhost ~]# ntpdate 192.168.1.1

     

    3、安装MySQL服务(三台数据库服务器安装保持一致)

    1)安装cmake软件

    [root@localhost ~]# tar -zxvf cmake-2.8.6.tar.gz -C /usr/src/

    [root@localhost ~]# cd /usr/src/cmake-2.8.6/

    [root@localhost cmake-2.8.6]# ./configure && gmake && gmake install

    2)安装mysql软件

    [root@localhost ~]# tar -zxvf mysql-5.5.22.tar.gz -C /usr/src/

    [root@localhost ~]# cd /usr/src/mysql-5.5.22/

    [root@localhost mysql-5.5.22]# cmake -

    DCMAKE_INSTALL_PREFIX=/usr/local/mysql -DDEFAULT_CHARSET=utf8 -

    DDEFAULT_COLLATION=utf8_general_ci -DSYSCONFDIR=/etc -

    DWITH_EXTRA_CHARSETS=all

    [root@localhost mysql-5.5.22]# make && make install

    [root@localhost ~]# cp /usr/src/mysql-5.5.22/support-files/my-

    medium.cnf /etc/my.cnf

    [root@localhost ~]# cp /usr/src/mysql-5.5.22/support-files/mysql.server

    /etc/init.d/mysqld

    [root@localhost ~]# chmod +x /etc/init.d/mysqld

    [root@localhost ~]# chown -R mysql:mysql /usr/local/mysql

    [root@localhost ~]# ln -s /usr/local/mysql/bin/* /usr/local/bin/

     

    [root@localhost ~]# /usr/local/mysql/scripts/mysql_install_db --

    user=mysql --basedir=/usr/local/mysql/ --datadir=/usr/local/mysql/data/

    [root@localhost ~]# service mysqld restart

    [root@localhost ~]# chkconfig --add mysqld

    [root@localhost ~]# chkconfig mysqld on

    验证:

    [root@localhost ~]# mysqladmin -u root password 'redhat'

    [root@localhost ~]# mysql -u root -p

     

    4、主从配置

    1)主数据库服务器配置

    [root@localhost ~]# vim /etc/my.cnf

    添加:

    server-id=11 //修改

    log-bin=master-bin //修改

    log-slave-updates=true //添加

    [root@localhost ~]# service mysqld restart

     

    [root@localhost ~]# mysql -u root -p

    mysql> grant replication slave on *.* to 'slave'@'192.168.1.%' identified by 'redhat';

    mysql> flush privileges;

    mysql> show master status;

    mysql> quit

     

    2)从数据库服务器配置

    [root@localhost ~]# vim /etc/my.cnf

    添加:

    server-id=22 //修改

    relay-log=relay-log-bin //添加

    relay-log-index=slave-relay-bin.index //添加

    注意:主从的ID不能相同。

     

    [root@localhost ~]# service mysqld restart

    [root@localhost ~]# mysql -u root -p

    mysql> change master to

    master_host='192.168.1.200',

    master_user='slave',

    master_password='redhat',

    master_log_file='master-bin.000001',

    master_log_pos=336;

    mysql> start slave;

    mysql> show slave status\G; //结尾不能加; 否则或报错。

    Slave_IO_Running: Yes //确保为YES

    Slave_SQL_Running: Yes //确保为YES

    mysql> quit

     

    问题说明:

    1、如果出现ERROR: No query specified

    则:原因是语法错误,去掉语句后的;号。

    2、如果bin-log日志不更新,或者无法进行数据同步,

    则:删除bin-log日志,重新启动服务即可。

    3、导致lave_IO_Running connecting 的原因主要有以下 3 个方面:

    1)网络不通

    2)密码不对

    3pos不对

     

    4、验证:

    1)主数据库服务器:

    [root@localhost ~]# mysql -u root -p

    mysql> show databases;

    mysql> create database masterdb;

    mysql> show databases;

    mysql> use masterdb;

    mysql> create table count (id int(5),name char(12));

    mysql> show tables;

    mysql> quit

     

    2)从数据库服务器:

    [root@localhost ~]# mysql -u root -p

    mysql> show databases;

    mysql> show databases;

    mysql> use masterdb

    mysql> show tables;

    mysql> quit

     

    三、验证:

    1、在client上:

    [root@localhost ~]# mysql -u amoeba -predhat -h 192.168.1.100 -P8066

    mysql> use masterdb;

    mysql> create table biao1 (id int(5),name char(10),address char(10));

     

    2、在主MySQL服务器上:

    mysql> insert into biao1 values(1,'hehe','master');

     

    3、在2台从MySQL服务器上:

    slave1

    mysql> stop slave;

    mysql> insert into biao1 values(2,'hehe','slave1');

    slave2

    mysql> stop slave;

    mysql> insert into biao1 values(3,'hehe','slave2');

     

    4、在客户端测试:

    查询biao1

    mysql> select * from biao1;

    +------+------+---------+

    | id | name | address |

    +------+------+---------+

    | 1 | hehe | slave1 |

    +------+------+---------+

    1 row in set (0.00 sec)

    mysql> select * from biao1;

    +------+------+---------+

    | id | name | address |

    +------+------+---------+

    | 3 | hehe | slave2 |

    +------+------+---------+

    1 row in set (0.00 sec)

    mysql> select * from biao1;

    +------+------+---------+

    | id | name | address |

    +------+------+---------+

    | 2 | hehe | slave1 |

    +------+------+---------+

    1 row in set (0.00 sec)

    mysql> select * from biao1;

    +------+------+---------+

    | id | name | address |

    +------+------+---------+

    | 3 | hehe | slave2 |

    +------+------+---------+

    1 row in set (0.01 sec)

     

    查到记录,说明记录分别从两台从MySQL数据库读取

     

    插入一条记录:

    mysql> insert into biao1 values(4,'hehe','write_zhu');

    Query OK, 1 row affected (0.01 sec)

     

    mysql> select * from biao1;

    +------+------+---------+

    | id | name | address |

    +------+------+---------+

    | 3 | hehe | slave2 |

    +------+------+---------+

    1 row in set (0.01 sec)

     

    mysql> select * from biao1;

    +------+------+---------+

    | id | name | address |

    +------+------+---------+

    | 2 | hehe | slave1 |

    +------+------+---------+

    1 row in set (0.01 sec)

     

    没有查到记录,说明这条记录只写入主MySQL数据库中

     

    错误代码2006解决方案

    mysql> set global max_allowed_packet=1024*1024*16;


阅读(1656) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~