MySQL数据库读写分离amoeba技术研究分享


目录

MySQL数据库读写分离amoeba技术研究分享讲解

参考资料
1、http://docs.hexnova.com/amoeba/
2、https://www.centos.bz/2012/05/amoeba-for-mysql/

 

一、Mysql主从复制及读写分离概念

wKioL1WA5W_QEGguAAFJ037SQC4936.jpg

英文注释:

transactionsplitting分裂交易

client:客户端

read/write:读写

ConnectionPool:连接池

replication复制

 

1Amoeba 是什么

  Amoeba(变形虫)项目,专注 分布式数据库 proxy 开发。座落与Client、DB Server(s)之间。对客户端透明。具有负载均衡、高可用性、sql过滤、读写分离可路由相关的query到目标数据库、可并发请求多台数据库合并结果

主要解决(优点):

 降低数据切分带来的复杂多数据库结构

 提供切分规则并降低 数据切分规则 给应用带来的影响

 降低db与客户端的连接数

 读写分离

2、为什么要用Amoeba

目前要实现mysql的主从读写分离,主要有以下几种方案:

1  通过程序实现,网上很多现成的代码,比较复杂,如果添加从服务器要更改多台服务器的代码。

2  通过mysql-proxy来实现,由于mysql-proxy的主从读写分离是通过lua脚本来实现,目前lua的脚本的开发跟不上节奏,而写没有完美的现成的脚本,因此导致用于生产环境的话风险比较大,据网上很多人说mysql-proxy的性能不高。

3  自己开发接口实现,这种方案门槛高,开发成本高,不是一般的小公司能承担得起。

4  利用阿里巴巴的开源项目Amoeba来实现,具有负载均衡、高可用性、sql过滤、读写分离、可路由相关的query到目标数据库,并且安装配置非常简单。

3Amoeba不能做什么(缺点)? 

(1)目前还不支持事务 

(2)暂时不支持存储过程(近期会支持) 

(3)不适合从amoeba导数据的场景或者对大数据量查询的query并不合适(比如一次请求返回10w以上甚至更多数据的场合) 

(4)暂时不支持分库分表,amoeba目前只做到分数据库实例,每个被切分的节点需要保持库表结构一致。

二、MySql主从复制详解

1MYSQL主从复制介绍

    现在企业中都会有mysql-proxy或者amoeba 或者开发

    在生产环境中如果是单台mysql服务器,是无法做到高可用,如果没有备份数据的话,假如mysql服务器宕机后,那这样就无法提供后端数据业务。有没有什么方案可以让mysql服务器做到数据备份、读写分离呢?有!mysql主从复制(同步)+amoeba读写分离软件,mysql主从复制主要实现从主服务器实时、异步复制数据到从服务器,其中从服务器可以有多台,这我们叫一主多从模式。

2mysql主从复制的优点

  1、解决WEB应用系统,数据库出现的性能瓶颈,采用数据库集群的方式来实现查询负载;一个系统中数据库的查询操作比更新操作要多得多,通过多台查询服务将数据库的查询分担到不同的查询服务器上从而提高效率。

  2MySql数据库支持数据库的主从复制功能,使用主数据库进行数据的插入、删除与更新操作,而从数据库则专门用来进行数据查询操作,这样可以将更新操作和查询操作分担到不同的数据库上,从而提高了查询效率。

 

3mysql主从复制的原理

   主服务器上面的任何修改会保存在二进制日志文件Binary log里面,从服务器上启动一个I/Othread进程与主服务的I/O联系,并请求从指定日志文件的位置之后的内容。当主服务器接收到Slave服务器I/O线程请求后,通过I/O线程根据请求信息读取指定日志指定位置之后的日志的信息,返回给Slave服务器的I/O线程。在返回的信息中除了日志所包含的信息之外,还有master端的binary log文件的名称和binary log中的位置。然后把读取到的二进制日志内容写到本地的一个Realy log里面,将读取到的master端的bin-log文件名和位置记录到master-info文件中。从服务器上面开启一个SQL thread定时检查Realy log如果发现有更改立即把更改的内容从本机上面执行一遍。这样就实现了在主服务器上操作,从服务器上实时跟着操作。

 wKiom1WA49Chr_F0AAPORwRZa4w392.jpg


三、amoeba代理和mysql主从复制图表说明

1、网络拓扑

wKiom1WA492CK-eJAAKeQEcKBo4009.jpg

2、主机信息

 

主机

操作系统

IP

角色

amoeba

CentOS release  6.5 (Final)

2.6.32-431.el6.x86_64

10.0.0.18/24

(amoeba)分离服务器

Master

CentOS release 6.5 (Final)

2.6.32-431.el6.x86_64

10.0.0.17/24

Mysql主服务器

slave

CentOS release  6.5 (Final)

2.6.32-431.el6.x86_64

10.0.0.19/24

Mysql从服务器

test

CentOS release 6.5 (Final)

2.6.32-431.el6.x86_64

10.0.0.16/24

客户机服务器

3、软件版本:

软件名称

软件版本

数据库编译工具

cmake-2.8.8.tar

 

数据库

mysql-5.5.32.tar

 

amoeba

amoeba-mysql-binary-2.1.0-RC5.tar

 

jdk

jdk-8u40-linux-x64

 

 

四、安装mysql

(一)、SQL编译安装

1、在安装前要安装创建用户、用户组

[root@mysql~]# groupadd mysql

useraddmysql -s /sbin/nologin -M -g mysql

groupadd:group 'mysql' already exists

[root@mysql~]# useradd mysql -s /sbin/nologin -M -g mysql

useradd:user 'mysql' already exists

2cmake安装包

[root@yyh~]# cd /application/tools

[root@yyhtools]# rz -y

rzwaiting to receive.

???a?zmodem ′???£ °′ Ctrl+C ???£

??′?? cmake-2.8.8.tar.gz...

  100%   5558 KB 5558 KB/s 00:00:01       0′?

 

?[root@mysql tools]#

3cmake安装步骤

cd/application/tools/

tarxf cmake-2.8.8.tar.gz

cdcmake-2.8.8

./configure

gmake

gmakeinstall

echo$?

cd..

4、装mysql的时候要安装一些devel

yuminstall ncurses-devel -y

 

(二)、安装mysql

tarzxf mysql-5.5.32.tar.gz

cdmysql-5.5.32

cmake. -DCMAKE_INSTALL_PREFIX=/application/mysql-5.5.32 \

-DMYSQL_DATADIR=/application/mysql-5.5.32/data\

-DMYSQL_UNIX_ADDR=/application/mysql-5.5.32/tmp/mysql.sock\

-DDEFAULT_CHARSET=utf8\

-DDEFAULT_COLLATION=utf8_general_ci\

-DEXTRA_CHARSETS=gbk,gb2312,utf8,ascii\

-DENABLED_LOCAL_INFILE=ON\

-DWITH_INNOBASE_STORAGE_ENGINE=1\

-DWITH_FEDERATED_STORAGE_ENGINE=1\

-DWITH_BLACKHOLE_STORAGE_ENGINE=1\

-DWITHOUT_EXAMPLE_STORAGE_ENGINE=1\

-DWITHOUT_PARTITION_STORAGE_ENGINE=1\

-DWITH_FAST_MUTEXES=1\

-DWITH_ZLIB=bundled\

-DENABLED_LOCAL_INFILE=1\

-DWITH_READLINE=1\

-DWITH_EMBEDDED_SERVER=1\

-DWITH_DEBUG=0

make

makeinstall

ln-s /application/mysql-5.5.32/ /application/mysql

cd..

cpmysql-5.5.32/support-files/my-small.cnf /etc/my.cnf

[[email protected]]# cd ..

cpmysql-5.5.32/support-files/my-small.cnf /etc/my.cnf

[root@yyhtools]# cp mysql-5.5.32/support-files/my-small.cnf /etc/my.cnf

cp:overwrite `/etc/my.cnf'? y

 

如果上述操作未出现错误,则MySQL5.5.32软件cmake方式的安装就算成功了。

1、调整mysql

ll /application/mysql/data 1026  
cp support-files/my-small.cnf /etc/my.cnf
chown -R mysql.mysql /application/mysql/data/

2、初始化数据库

 

/application/mysql/scripts/mysql_install_db --basedir=/application/mysql --datadir=/application/mysql/data --user=mysql

3、复制启动文件,设置开机启动(环境变量)

步骤

[root@Mysql mysql-5.5.32]# cp support-files/mysql.server /etc/init.d/mysqld
[root@Mysql mysql-5.5.32]# chmod +x /etc/init.d/mysqld
[root@Mysql mysql-5.5.32]# chkconfig mysqld on
[root@Mysql ~]# vim /etc/profile
PATH=/application/mysql/bin/:$PATH
[root@Mysql ~]# source /etc/profile
[root@Mysql ~]# mysql

[[email protected]]# source /etc/profile

4、启动数据库,并登录

[root@mysql mysql-5.5.32]# mysql

ERROR2002 (HY000): Can't connect to local MySQL server through socket'/application/mysql-5.5.32/tmp/mysql.sock' (2)

[root@mysql mysql-5.5.32]# /etc/init.d/mysqld start

StartingMySQL... SUCCESS!

[root@mysql mysql-5.5.32]# mysql

Welcometo the MySQL monitor.  Commands end with; or \g.

YourMySQL connection id is 1

Serverversion: 5.5.32 Source distribution

 

Copyright(c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.

 

Oracleis a registered trademark of Oracle Corporation and/or its

affiliates.Other names may be trademarks of their respective

owners.

 

Type'help;' or '\h' for help. Type '\c' to clear the current input statement.

 

mysql>quit

Bye

[root@mysql mysql-5.5.32]#

(三)、SQL安装(以主服务器安装为主从一样的步骤)

  什么是mysql多实例:不同的配置文件,不同的启动文件,不同的数据目录 不同的端口

mysql: www bbs blog
3306 mysql www
3307 mysql blog
3308 mysql bbs

  在这里面我是多实例安装,但是主从服务器我用了两台。只是为了多练习多实例。10.0.0.17主服务器只用了3306这个实例,然后在10.0.0.19从服务器上也用了3306这个实例。

1、创建多实例的数据目录并给相应的权限

 

创建目录文件

[[email protected]]# mkdir /data/{3306,3307}/data -p

[root@mysql mysql-5.5.32]# tree /data

/data

├──3306

│?? └── data

└──3307

    └──data

 

4directories, 0 files

[root@mysql mysql-5.5.32]#

[root@mysql mysql-5.5.32]#

[root@mysql mysql-5.5.32]# tree /data

/data

|--3306

|   `-- data

`--3307

    `-- data

 

4directories, 0 files

[root@mysql mysql-5.5.32]# chown -R mysql.mysql /data/*

 

23306多实例

[[email protected]]# cd /

[root@mysql/]# rz -y

rzwaiting to receive.

???a?zmodem ′???£ °′ Ctrl+C ???£

??′?? data.zip...

  100%      3 KB    3 KB/s 00:00:01       0 ′?

 

?[root@mysql /]# unzip data.zip

Archive:  data.zip

  inflating: data/3306/my.cnf       

  inflating: data/3306/mysql        

  inflating: data/3307/my.cnf       

  inflating: data/3307/mysql        

[root@mysql /]# tree /data

/data

|--3306

|   |-- data

|   |-- my.cnf

|   `-- mysql

`--3307

    |-- data

    |-- my.cnf

    `-- mysql

 

4directories, 4 files

[root@yyh/]#

 

[root@mysql /]# chown -R mysql.mysql /data/*

 

3、初始化数据库

 

[root@mysql /]# /application/mysql/scripts/mysql_install_db--basedir=/application/mysql --datadir=/data/3306/data --user=mysql

 

 

 [root@mysql 3306]# mysqld_safe --defaults-file=/data/3306/my.cnf 2>&1 > /dev/null &
[1] 25767
[root@ mysql 3306]# lsof -i :3306

 

4、开启3306 3307数据库

 

[root@mysql 3306]# /data/3306/mysql start                            

StartingMySQL...

[root@mysql 3306]# lsof -i :3306

COMMAND   PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME

mysqld  53967 mysql  12u  IPv4 182144      0t0 TCP *:mysql (LISTEN)

5、修改密码

 

[root@yyh3306]# mysqladmin password oldboy -S /data/3306/mysql.sock

chown+x /data/3306/mysql.sock

6、登陆3306

优雅重启数据库

[root@mysql 3306]# mysqladmin -S /data/3306/mysql.sock shutdown
[1]-  Done  mysqld_safe --defaults-file=/data/3306/my.cnf 2>&1 > /dev/null
[root@C 3307]# netstat -lntup|grep 3306

给mysql文件执行权限

[root@C data]# find ./ -type f -name "mysql" -exec chmod +x {} \;


数据库启动


[root@ mysql data]# /data/3306/mysql start
Starting MySQL...

用3306登录数据库


[root@C data]# mysql -uroot -poldboy  -S /data/3306/mysql.sock 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 3
Server version: 5.5.32-log Source distribution

Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> create database l3306;
 创建一个数据库


Query OK, 1 row affected (0.00 sec)

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| l3306              |
| mysql              |
| performance_schema |
| test               |
+--------------------+
5 rows in set (0.00 sec)

mysql> quit
Bye
至此主服务器mysql配置完成,从服务也是这样的步骤。这里就不给大家写重复了。

五、配置mysql主从复制

1、配置前说明

    因为读写分离,所以一台负责mysql的写操作,另一台负责mysql的读操作,所以我们这里使用mysql的主从复制再合适不过了。关于这一配置请看以下实现说明:

    实现说明:本实践操作选择的是编译安装数据库,采用的是mysql单实例。

 

2、查看端口是否正常开启

[root@mysql3306]# netstat -lntup |grep 330

tcp        0     0 0.0.0.0:3307               0.0.0.0:*                   LISTEN      46469/mysqld       

tcp        0     0 0.0.0.0:3306               0.0.0.0:*                   LISTEN      45751/mysqld       

3、登陆数据库是否正常

mysql-uroot -poldboy  -S /data/3306/mysql.sock

4Mysql主服务器(10.0.0.17

1)调整my.cnf配置文件中的log-bin server-id

[root@mysql3306]# egrep "server-id|log-bin" my.cnf

log-bin = /data/3306/mysql-bin

server-id = 1

2)登陆数据库创建授权用户

[root@mysql 3306]# mysql -uroot -poldboy -S /data/3306/mysql.sock

mysql>select user,host from mysql.user; #查看下系统的一些账号

mysql> grant replication slave on *.* torep@'10.0.0.%' identified by 'oldboy';

QueryOK, 0 rows affected (0.00 sec) #创建slave从库管理账号并授权

mysql>flush privileges; #刷新上面的操作

QueryOK, 0 rows affected (0.00 sec)

mysql>show master status; #查看主库的binlog位置点等信息

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

|File             | Position |Binlog_Do_DB | Binlog_Ignore_DB |

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

|mysql-bin.000001 |      549 |              |                  |

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

1row in set (0.00 sec)

mysql>show variables like '%log_bin%';   #查看主库二进程binlog开启状态

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

|Variable_name                   | Value |

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

|log_bin                         | ON    |

|log_bin_trust_function_creators | OFF   |

|sql_log_bin                     | ON    |

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

3rows in set (0.00 sec)

mysql>exit

Bye

3)主库做快速全备

[root@mysql3306]# mysqldump -uroot -poldboy -S/data/3306/mysql.sock -A -B -F --master-data=2 -x --event|gzip>/opt/all.sal.gz    

 

提示:-A备份所有库。

      -B 指定多个库增加建库语句和use语句。

      -F 刷新binlog日志,生成新文件,将来增量回复从这个谁的开始。

      --master-data增加binlog日志文件名及对应的位置点(即change master语句)。

      -x 备份的时候锁表。

      --event取消报错信息。

 

[root@mysql3306]# ll /opt/all.sal.gz   #查看

-rw-r--r--1 root root 144466 Mar 24 16:08 /opt/all.sal.gz

至此主库配置完毕

 

5Mysql从服务器(10.0.0.19

1)调整my.cnf配置文件中的log-bin server-id

[root@mysql23306]# pwd

/data/3307

[root@mysql23306]#  egrep"server-id|log-bin" my.cnf

#log-bin = /data/3306/mysql-bin   从库不需要开启binlog

server-id = 3

 

2)把主库的全备数据集回复到从库

[root@mysql2]#gzip -d /opt/all.sal.gz #解压

[root@mysql2]#ll /opt/all.sal

-rw-r--r--1 root root 528992 Mar 24 16:08 /opt/all.sal

[root@mysql3306]# mysql -uroot -poldboy -S /data/3306/mysql.sock </opt/all.sal

#恢复数据

3)恢复从库后,登录从库指定授权

[root@mysql2]#mysql -uroot -poldboy -S /data/3306/mysql.sock

mysql>show databases;  #查看一下的确有我之前3306创建的一个库

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

|Database           |

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

|information_schema |

| db06               |

|db07               |

|mysql              |

|performance_schema |

|test               |

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

6 rowsin set (0.00 sec)

授权

mysql>change master to master_host='10.0.0.15',master_user='rep1',MASTER_PORT=3306,master_password='123456';

QueryOK, 0 rows affected (0.03 sec)

#这里无须指定binlog文件及位置点

 

提示:关于binlog及位置点我们都是从主库上面show master status;查看到的信息

例如:

mysql>show master status;

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

|File             | Position |Binlog_Do_DB | Binlog_Ignore_DB |

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

|mysql-bin.000002 |      107 |              |                  |

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

1row in set (0.00 sec)

4)开启从库开关

mysql>start slave;

QueryOK, 0 rows affected (0.04 sec)

 

mysql>show slave status\G

             Slave_IO_Running: Yes

            Slave_SQL_Running: No

 

提示如果有报错:1007 1008之类的我们需要忽略这些错误。

1007:数据库已存在,创建数据库失败
1008
:数据库不存在,删除数据库失败
操作:

vim/data/3306/my.cnf

slave-skip-errors= 1007,1008,1032,1062

添加完后重启从库

到此从库配置完成啦

 

6、验证MYSQL主从

在主库创建一个数据库yyh然后在从库查看

主库

mysql>create database yyh;

QueryOK, 1 row affected (0.01 sec)

 

mysql>show databases;

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

|Database           |

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

|information_schema |

|db06               |

|mysql              |

|performance_schema |

|test               |

|yyh                |

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

6rows in set (0.00 sec)

从库验证

mysql>show databases;

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

|Database           |

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

|information_schema |

|db06               |

|db07               |

|mysql              |

| performance_schema|

|test               |

| yyh                |

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

7rows in set (0.00 sec)

到些数据库主从复制验证成功!

六、安装amoeba实现读写分离

1、查看amoeba系统的主机信息

[root@amoeba~]# cat /etc/redhat-release

CentOSrelease 6.5 (Final)

[root@amoeba~]# uname -a

Linuxamoeba 2.6.32-431.el6.x86_64 #1 SMP Fri Nov 22 03:15:09 UTC 2013 x86_64 x86_64x86_64 GNU/Linux

[root@amoeba~]# ifconfig eth1

eth1      Link encap:Ethernet  HWaddr 00:50:56:33:5F:E1 

          inet addr:10.0.0.18 Bcast:10.0.0.255 Mask:255.255.255.0

          inet6 addr:fe80::250:56ff:fe33:5fe1/64 Scope:Link

          UP BROADCAST RUNNING MULTICAST  MTU:1500 Metric:1

          RX packets:7396 errors:0 dropped:0overruns:0 frame:0

          TX packets:1118 errors:0 dropped:0overruns:0 carrier:0

          collisions:0 txqueuelen:1000

          RX bytes:1874051 (1.7 MiB)  TX bytes:76589 (74.7 KiB)

2、在主从数据库服务器上配置授权用户

分别在主\从服务器上添加一个授权用amoeba

主服务10.0.0.17授权一个读写权限

mysql>grant select,insert,update,delete on *.* to amoeba@'10.0.0.%' identified by'123456';

QueryOK, 0 rows affected (0.01 sec)

mysql>flush privileges;  

 

 

从库10.0.0.19授权一个用户amoeba只读的权限

   提示:如果开启了主从同步功能,这时当主服务器创建一个用户后会自动同步到从服务器,所以我们要在从服务器删除主服务器建立用户后方可建立用户。

mysql>select user,host from mysql.user;

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

|user   | host      |

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

| amoeba | 10.0.0.%  |

9rows in set (0.01 sec)

mysql>delete from mysql.user whereuser='amoeba';

QueryOK, 1 row affected (0.01 sec)

mysql>grant select  on *.* to amoeba@'10.0.0.%' identified by'123456';

mysql>flush privileges;  

 

查看

mysql> show grants for'amoeba'@'10.0.0.%';

 

 

3、安装amoeba前需要安装JDKjava环境配置)

1)安装JDKjava环境配置

   Amoeba框架是基于Java SE1.5开发的,建议使用JavaSE 1.5版本。目前Amoeba经验证在JavaTM SE 1.5Java SE 1.6能正常运行,(可能包括其他未经验证的版本)。

我这里下载jdk-8u40-linux-x64
下载完成后执行sh jdk-6u45-linux-x64-rpm.bin开始安装,将会安装到/usr/java/jdk1.6.0_32目录。

 

[root@amoeba~]# mkdir /application/tools/ -p

[root@amoeba~]# cd /application/tools/

[root@amoebatools]# rz -y

 

rzwaiting to receive.

???a?zmodem ′???£ °′ Ctrl+C ???£

??′?? amoeba-mysql-binary-2.1.0-RC5.tar.gz...

  100%   3085 KB 3085 KB/s 00:00:01       0′?

??′?? jdk-8u40-linux-x64.rpm...

  100% 148618 KB 21231 KB/s 00:00:07      0 ′?

 

?[root@amoebatools]# ls

amoeba-mysql-binary-2.1.0-RC5.tar.gz  jdk-8u40-linux-x64.rpm

[root@amoebatools]# rpm -ivh jdk-8u40-linux-x64.rpm

Preparing...               ########################################### [100%]

        packagejdk1.8.0_40-2000:1.8.0_40-fcs.x86_64 is already installed

[root@amoebatools]# ll /usr/java/

total4

lrwxrwxrwx.1 root root   16 Mar 25 22:31 default-> /usr/java/latest

drwxr-xr-x.9 root root 4096 Mar 25 22:31 jdk1.8.0_40

lrwxrwxrwx.1 root root   21 Mar 25 22:31 latest-> /usr/java/jdk1.8.0_40

[root@amoebatools]#

 

 

##################################我是分隔线##################################

关于以.bin结尾的安装

[root@amoebatools]# ls

jdk-6u45-linux-x64-rpm.bin

[root@amoebatools]# shjdk-6u45-linux-x64-rpm.bin

提示默认会放到:

[root@amoebatools]# ll /usr/java/

total 4

lrwxrwxrwx. 1root root   16 Mar 25 17:56 default ->/usr/java/latest

drwxr-xr-x. 7root root 4096 Mar 25 17:56 jdk1.6.0_45

lrwxrwxrwx. 1root root   21 Mar 25 17:56 latest ->/usr/java/jdk1.6.0_45

4、安装amoeba

Amoeba的安装

wget http://softlayer.dl.sourceforge.net/project/amoeba/Amoeba%20for%20mysql/2.x/amoeba-mysql-binary-2.1.0-RC5.tar.gz

 

[root@amoeba~]# cd /tmp/

[root@amoeba~]# mkdir /usr/local/amoeba -p

[root@amoebatmp]# rz -y

rzwaiting to receive.

???a?zmodem ′???£ °′ Ctrl+C ???£

??′?? amoeba-mysql-binary-2.1.0-RC5.tar.gz...

  100%   3085 KB 3085 KB/s 00:00:01       0′?

 

?[root@amoebatmp]# tar xzfamoeba-mysql-binary-2.1.0-RC5.tar.gz -C /usr/local/amoeba/

5、配置用户环境变量

[root@amoebatmp]# vi /etc/profile

PATH=$PATH:$HOME/bin:/usr/local/amoeba/bin

JAVA_HOME=/usr/java/jdk1.8.0_40

 

exportJAVA_HOME

exportPATH

[root@amoebatmp]# source /etc/profile

到此amoeba安装完毕下面我们来配置amoeba

七、配置amoeba文件

1、配置说明

配置Amoebafor mysql的读写分离主要涉及两个文件:
  1/usr/local/amoeba/conf/dbServers.xml
  此文件定义由Amoeba代理的数据库如何连接,比如最基础的:主机IP、端口、Amoeba使用的用户名和密码等等。
  2/usr/local/amoeba/conf/amoeba.xml
   此文件定义了Amoeba代理的相关配置。

[root@amoebaamoeba]# cd conf/

[root@amoebaconf]# ls

access_list.conf  dbserver.dtd  functionMap.xml  rule.dtd

amoeba.dtd        dbServers.xml log4j.dtd       ruleFunctionMap.xml

amoeba.xml        function.dtd   log4j.xml        rule.xml

 

2dbserver.xml详解

[root@amoebaconf]# cp amoeba.xml amoeba.xml.ori

[root@amoebaconf]# cp dbServers.xml dbServers.xml.ori

[root@amoebaconf]#

1abstractServer配置:

[root@amoeba conf]# vim dbServers.xml

<?xmlversion="1.0" encoding="gbk"?>

 

<!DOCTYPEamoeba:dbServers SYSTEM "dbserver.dtd">

<amoeba:dbServersxmlns:amoeba="http://amoeba.meidusa.com/">

 

        <!--

            Each dbServer needs to be configuredinto a Pool,

            If you need to configure multipledbServer with load balancing that can be simplified by the followingconfiguration:

             add attribute with name virtual ="true" in dbServer, but the configuration does not allow the elementwith name factoryConfig

             such as 'multiPool' dbServer  

        -->

       

    <dbServer name="abstractServer"abstractive="true">

        <factoryConfigclass="com.meidusa.amoeba.mysql.net.MysqlServerConnectionFactory">

            <propertyname="manager">${defaultManager}</property>

            <propertyname="sendBufferSize">64</property>

            <propertyname="receiveBufferSize">128</property>

               

            <!-- mysql port -->

            <propertyname="port">3306</property> #20mysql服务器的通用端口

           

            <!-- mysql schema -->

            <propertyname="schema">yyh</property>#26mysql服务器的通用数据库名称

           

            <!-- mysql user -->

            <propertyname="user">amoeba</property>//mysql服务器的通用用户

                           

           

            <propertyname="password">123456</property>//mysql服务器的通用用户密码

           

        </factoryConfig>

 

        <poolConfig class="com.meidusa.amoeba.net.poolable.PoolableObjectPool">

            <propertyname="maxActive">500</property>

            <propertyname="maxIdle">500</property>

            <propertyname="minIdle">10</property>

            <propertyname="minEvictableIdleTimeMillis">600000</property>

            <propertyname="timeBetweenEvictionRunsMillis">600000</property>

            <propertyname="testOnBorrow">true</property>

            <propertyname="testWhileIdle">true</property>

        </poolConfig>

    </dbServer>

 

 

#提示:此部分定义真实mysql服务器的端口,数据库名称,mysql用户及密码。

########################我是分隔线#########################

2)主从数据库定义:

    <dbServer name="master"  parent="abstractServer">主库 44行

        <factoryConfig>

            <!-- mysql ip -->

            <propertyname="ipAddress">10.0.0.17</property>

        </factoryConfig>

    </dbServer>

 

        <dbServer name="slave"  parent="abstractServer">从库

                  <factoryConfig>

                         <!-- mysql ip-->

                         <propertyname="ipAddress">10.0.0.19</property>

                  </factoryConfig>

        </dbServer>

 

 

   

    <dbServer name="multiPool" virtual="true">//定义虚拟节点池的名字

        <poolConfigclass="com.meidusa.amoeba.server.MultipleServerPool">

            <!-- Load balancing strategy:1=ROUNDROBIN , 2=WEIGHTBASED , 3=HA-->

            <propertyname="loadbalance">1</property> //负载均衡算法

           

            <!-- Separated by commas,such as:server1,server2,server1 -->

            <propertyname="poolNames">master,slave</property>  //66行虚拟节点池的成员

        </poolConfig>

    </dbServer>

       

</amoeba:dbServers>

 

 

##提示:此部分定义主服务器,从服务器,及从服务器连接池。这里只定义数据库地址,它们的用户及密码就是上面的abstractServer里的设置。注意用来连接真实mysql服务器的用户必须拥有远程连接权限。

3amoeba.xml代理服务详解

1amoeba代理服务配置:

<?xmlversion="1.0" encoding="gbk"?>

 

<!DOCTYPEamoeba:configuration SYSTEM "amoeba.dtd">

<amoeba:configurationxmlns:amoeba="http://amoeba.meidusa.com/">

 

    <proxy>

   

        <!-- service class must implementscom.meidusa.amoeba.service.Service -->

        <service name="Amoeba forMysql"class="com.meidusa.amoeba.net.ServerableConnectionManager">

            <!-- port -->

            <propertyname="port">3306</property>//amoeba监听端口

           

            <!-- bind ipAddress -->

           

            <propertyname="ipAddress">10.0.0.18</property>//amoeba服务器的IP地址

           

           

            <propertyname="manager">${clientConnectioneManager}</property>

           

            <propertyname="connectionFactory">

                <beanclass="com.meidusa.amoeba.mysql.net.MysqlClientConnectionFactory">

                    <propertyname="sendBufferSize">128</property>

                    <propertyname="receiveBufferSize">64</property>

                </bean>

            </property>

提示:以上信息是客户端连接amoeba代理的地址跟端口号

 

##############################我是分割线############################

2amoeba连接验证配置:

            <propertyname="authenticator"> 27

                <beanclass="com.meidusa.amoeba.mysql.server.MysqlClientAuthenticator">

                   

                    <propertyname="user">root</property>//修改amoeba的用户名为root

                   

                    <property name="password">123456</property>//修改amoeba的密码为123456

 

                   

                    <propertyname="filter">

                        <beanclass="com.meidusa.amoeba.server.IPAccessController">

                            <propertyname="ipFile">${amoeba.home}/conf/access_list.conf</property>

                        </bean>

                    </property>

                </bean>

            </property>

           

提示:这里定义连接amoeba时用来验证的用户及密码。

 

        </service>

       

        <!-- server class must implementscom.meidusa.amoeba.service.Service -->

        <service name="Amoeba MonitorServer" class="com.meidusa.amoeba.monitor.MonitorServer">

            <!-- port -->

            <!--  default value: random number

            <propertyname="port">9066</property>

            -->

            <!-- bind ipAddress -->

            <propertyname="ipAddress">127.0.0.1</property>

            <property name="daemon">true</property>

            <propertyname="manager">${clientConnectioneManager}</property>

            <propertyname="connectionFactory">

                <beanclass="com.meidusa.amoeba.monitor.net.MonitorClientConnectionFactory"></bean>

            </property>

           

        </service>

       

        <runtimeclass="com.meidusa.amoeba.mysql.context.MysqlRuntimeContext">

            <!-- proxy server net IO Readthread size -->

            <propertyname="readThreadPoolSize">20</property>

           

            <!-- proxy server client processthread size -->

            <property name="clientSideThreadPoolSize">30</property>

           

            <!-- mysql server data packetprocess thread size -->

            <propertyname="serverSideThreadPoolSize">30</property>

           

            <!-- per connection cacheprepared statement size  -->

            <propertyname="statementCacheSize">500</property>

           

            <!-- query timeout( default: 60second , TimeUnit:second) -->

            <propertyname="queryTimeout">60</property>

        </runtime>

       

    </proxy>

   

    <!--

        Each ConnectionManager will start asthread

        manager responsible for the ConnectionIO read , Death Detection

    -->

    <connectionManagerList>

        <connectionManagername="clientConnectioneManager"class="com.meidusa.amoeba.net.MultiConnectionManagerWrapper">

            <propertyname="subManagerClassName">com.meidusa.amoeba.net.ConnectionManager</property>

            <!--

             default value is avaliable Processors

            <propertyname="processors">5</property>

             -->

        </connectionManager>

        <connectionManagername="defaultManager"class="com.meidusa.amoeba.net.MultiConnectionManagerWrapper">

            <property name="subManagerClassName">com.meidusa.amoeba.net.AuthingableConnectionManager</property>

           

            <!--

             default value is avaliable Processors

            <propertyname="processors">5</property>

             -->

        </connectionManager>

    </connectionManagerList>

   

        <!-- default using file loader -->

    <dbServerLoaderclass="com.meidusa.amoeba.context.DBServerConfigFileLoader">

        <propertyname="configFile">${amoeba.home}/conf/dbServers.xml</property>

    </dbServerLoader>

   

    <queryRouterclass="com.meidusa.amoeba.mysql.parser.MysqlQueryRouter">

        <propertyname="ruleLoader">

            <beanclass="com.meidusa.amoeba.route.TableRuleFileLoader">

                <propertyname="ruleFile">${amoeba.home}/conf/rule.xml</property>

                <propertyname="functionFile">${amoeba.home}/conf/ruleFunctionMap.xml</property>

            </bean>

        </property>

        <propertyname="sqlFunctionFile">${amoeba.home}/conf/functionMap.xml</property>

        <propertyname="LRUMapSize">1500</property>

        <propertyname="defaultPool">master</property>  115

       

       

        <property name="writePool">master</property>

       <propertyname="readPool">slave</property>

       

        <propertyname="needParse">true</property>

    </queryRouter>

</amoeba:configuration>

提示:

defaultPool:配置了默认的数据库节点,一些除了SELECTUPDATE INSERT DELETE的语句都会在defaultPool执行。
writePool:配置了数据库写库,通常配为Master,如这里就配置为之前定义的Master数据库。
readPool:配置了数据库读库,通常配为Slave或者Slave组成的数据库池,如这里就配置之前的virtualSlave数据库池。

 

4amoeba启动

启动命令:

[root@amoeba ~]#amoeba start

此命令以前台的方式启动,会输出启动时的信息,检查没有错误信息后,中断,并后台运行:

[root@amoeba ~]#amoeba start &

 

八、验证mysql读写

1、在master yyh库里面创建一个表。

[root@mysql~]# mysql -uroot -poldboy -S /data/3306/mysql.sock

mysql>use yyh;

Databasechanged

mysql>create table yyh (id int(10),name varchar(10),address varchar(20));

QueryOK, 0 rows affected (0.10 sec)

2、然后把从库给他停掉

[root@yyhopt]# mysql -uroot -poldboy -S /data/3306/mysql.sock

mysql>slave stop;

QueryOK, 0 rows affected (0.03 sec)

 

mysql>show slave status\G

 

3、分别在主库跟从库插入测试数据方便验证。

 

主服务器

mysql>insert into yyh values ('1','xbs','master');

QueryOK, 1 row affected (0.01 sec)

 

mysql>select * from yyh;

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

|id   | name | address |

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

|    1 | xbs | master  |

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

1row in set (0.00 sec)

从服务器

mysql>insert into yyh values ('2','xbs','slave');       

QueryOK, 1 row affected (0.00 sec)

 

mysql>select * from yyh;                        

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

|id   | name | address |

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

|    2 | xbs | slave   |

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

1row in set (0.00 sec)

 

4、用测试机登录amoeba

[root@db ~]# mysql -uroot-p123456  -h 10.0.0.18     

Welcometo the MySQL monitor.  Commands end with; or \g.

YourMySQL connection id is 208924888

Serverversion: 5.1.45-mysql-amoeba-proxy-2.1.0-RC5Source distribution

 

Copyright(c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.

 

Oracleis a registered trademark of Oracle Corporation and/or its

affiliates.Other names may be trademarks of their respective

owners.

 

Type'help;' or '\h' for help. Type '\c' to clear the current input statement.

 

mysql>show databases;

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

|Database           |

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

|information_schema |

|db06               |

|master             |

|mysql              |

|performance_schema |

|slave              |

|test               |

|yyh                |

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

8rows in set (0.08 sec)

mysql> use yyh

Databasechanged

mysql> select * from yyh;

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

|id   | name | address |

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

|    2 | xbs | slave   |

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

1row in set (0.06 sec)

5、测试机插入一条数据

mysql>insert into yyh values('3','xbs','master');

QueryOK, 1 row affected (0.07 sec)

 

mysql> select * from yyh;                         

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

|id   | name | address |

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

|    2 | xbs | slave   |

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

1row in set (0.09 sec)

在这里面我们插入后需要去主库查看

mysql> select * from yyh;    主                      

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

|id   | name | address |

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

|    1 |xbs  | master  |

|   3 | xbs  | master  |

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

2rows in set (0.00 sec)

但是查还是查的是从库的数据,

6、最后我们把从库开启,我们实现数据插入复制

mysql>slave start;

QueryOK, 0 rows affected (0.00 sec)

 

mysql>show slave status\G

     Slave_IO_Running: Yes

     Slave_SQL_Running:Yes

7、最后我们分别在测试机中插入数据跟查询数据

mysql>select * from yyh;                      

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

|id   | name | address |

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

|    2 | xbs | slave   |

|    1 | xbs | master  |

|    3 | xbs | master  |

|    4 | hh  | test    |

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

4rows in set (0.09 sec)

8、分别在主从上验证

主服务器

mysql>select * from yyh;

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

|id   | name | address |

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

|    1 | xbs | master  |

|    3 | xbs | master  |

|    4 | hh  | test    |

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

3rows in set (0.00 sec)

从服务器

mysql>select * from yyh;      

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

|id   | name | address |

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

|    2 | xbs | slave   |

|    1 | xbs | master  |

|    3 | xbs | master  |

|    4 | hh  | test    |

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

4rows in set (0.00 sec)

 

九、报错

1Amoeba启动错误:

Amoeba启动错误:

#amoebastart

Thestack size specified is too small, Specify at least 160k
Error: Could not create the Java Virtual Machine.

Error:A fatal exception has occurred. Program will exit.

解决方法:

打开bin目录下的amoeba启动文件

#vim amoeba

修改58行的Xss参数:

DEFAULT_OPTS="-server-Xms1024m -Xmx1024m -Xss128k"

修改为:
DEFAULT_OPTS="-server-Xms1024m -Xmx1024m -Xss256k"

 

 问题思路 Java报错&解决汇总

 

1Thestack size specified is too small, Specify at least 228k

一个服务应为压力比较大,打算在多部署一台服务器,部署阶段很顺利,到了服务启动阶段就是启动不了,报如下错误:

Thestack size specified is too small, Specify at least 228k
Error: Could not create the Java Virtual Machine.
Error: A fatal exception has occurred. Program will exit.

网上查了一些资料:

ahttp://www.tuicool.com/articles/zEZBNb 

bhttp://www.myexception.cn/software-architecture-design/1473046.html

JDK7启动对xss参数有最小值要求,必须大于228才能启动JVM

2、提示

amoeba上面最好不要安装数据库不然会有冲突

3、细心提示

 在配置的时候一定要注意注释行的一些东西,不然会报错。

4、结束:

  关于amoeba里面有更多的功能还需要小伙伴们自己去研究,相信通过 amoeba这个软件让大家能理解数据库读写分离的一个基本概念。


本文出自 “duffy” 博客,转载请与作者联系!

你可能感兴趣的:(参考资料,变形虫)