一,主从复制
1,为什么要做主从复制
单台mysql在安全性,高可用和高并发方面都无法满足实际的需求,所以可以选择配置多台主从数据库服务器以实现读写分离。
2,主从复制的原理
主从复制是为了保证数据的完整性,由slave角色复制master角色的数据并存放在二进制日志。
主从复制有三个进程:主的dump进程,从的io进程和sql进程。其中当有数据写入主的时候,会被存储为二进制日志,从服务器的io进程会每隔一段时间定时访问主的dump进程,主的dump进程监听到访问后会发送二进制日志给io,从会将二进制日志存储为中继日志,最后由sql将中继日志捞出并执行到自己数据库内部。
slave无法执行master上并行更新的操作。
3,主从复制类型:
异步复制:master只要完成就会返回给客户端,不关心从库是否已经处理数据。
同步复制:等从完成同步之后才向客户端返回结果。
半同步复制:只要有一个从完成同步数据,master就返回给客户端。
4,主从复制的搭建
master服务器:Master 服务器:192.168.10.15
Slave1 服务器:192.168.10.14
Slave2 服务器:192.168.10.16
- 一,安装mysql
- 安装环境
- yum -y install pcre-devel zlib-devel gcc gcc-c++ make ncurses ncurses-devel bison cmake
-
- 创建运行用户
- useradd -M -s /sbin/nologin mysql
-
- 编译安装
- cd /opt
- tar -xf mysql-boost-5.7.20.tar.gz
- cd /opt/mysql-5.7.20/
-
- 编译
- cmake \
- -DCMAKE_INSTALL_PREFIX=/usr/local/mysql \
- -DMYSQL_UNIX_ADDR=/usr/local/mysql/mysql.sock \
- -DSYSCONFDIR=/etc \
- -DSYSTEMD_PID_DIR=/usr/local/mysql \
- -DDEFAULT_CHARSET=utf8 \
- -DDEFAULT_COLLATION=utf8_general_ci \
- -DWITH_EXTRA_CHARSETS=all \
- -DWITH_INNOBASE_STORAGE_ENGINE=1 \
- -DWITH_ARCHIVE_STORAGE_ENGINE=1 \
- -DWITH_BLACKHOLE_STORAGE_ENGINE=1 \
- -DWITH_PERFSCHEMA_STORAGE_ENGINE=1 \
- -DMYSQL_DATADIR=/usr/local/mysql/data \
- -DWITH_BOOST=boost \
- -DWITH_SYSTEMD=1
-
- 安装
- make && make install
-
- 修改mysql配置文件
- vim /etc/my.cnf
-
- 清除所有,写入下面内容
-
- [client]
- port = 3306
- socket=/usr/local/mysql/mysql.sock
-
- [mysqld]
- user = mysql
- basedir=/usr/local/mysql
- datadir=/usr/local/mysql/data
- port = 3306
- character-set-server=utf8
- pid-file = /usr/local/mysql/mysqld.pid
- socket=/usr/local/mysql/mysql.sock
- bind-address = 0.0.0.0
- skip-name-resolve
- max_connections=2048
- default-storage-engine=INNODB
- max_allowed_packet=16M
- server-id = 1
-
- sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_AUTO_VALUE_ON_ZERO,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,PIPES_AS_CONCAT,ANSI_QUOTES
-
- 更改mysql安装目录和配置文件的属主属组
- chown -R mysql:mysql /usr/local/mysql/
- chown mysql:mysql /etc/my.cnf
-
- 设置环境变量
- echo 'export PATH=/usr/local/mysql/bin:/usr/local/mysql/lib:$PATH' >> /etc/profile
- source /etc/profile
-
- 初始化数据库
- cd /usr/local/mysql/bin/
- ./mysqld \
- --initialize-insecure \
- --user=mysql \
- --basedir=/usr/local/mysql \
- --datadir=/usr/local/mysql/data
-
- 添加mysqld系统服务
- cp /usr/local/mysql/usr/lib/systemd/system/mysqld.service /usr/lib/systemd/system/
- systemctl daemon-reload
- systemctl start mysqld.service
- systemctl enable mysqld
-
- 使用mysql -uroot -p登陆后在里面修改登陆密码为123456
- ALTER USER 'root'@'localhost' IDENTIFIED BY '123456';
- FLUSH PRIVILEGES;
- 二,搭建主从复制
- 进行时间同步
- 主服务器:
- yum install ntp -y
-
- vim /etc/ntp.conf 在末尾添加
- server 127.127.80.0
- fudge 127.127.80.0 stratum 8
-
- service ntpd start
-
- 从服务器:
- yum install ntp ntpdate -y
-
- service ntpd start /usr/sbin/ntpdate 192.168.10.15
-
- crontab -e
- */30 * * * * /usr/sbin/ntpdate 192.168.80.10
-
- mysql设置
- 主服务器:
- vim /etc/my.cnf
- server-id = 11 #修改id,需要三台机器都不一样
- log-bin=master-bin #添加
- binlog_format = MIXED
- log-slave-updates=true #添加
-
- systemctl restart mysqld
-
- mysql -u root -p123456
- GRANT REPLICATION SLAVE ON *.* TO 'myslave'@'192.168.10.%' IDENTIFIED BY '123456';
- FLUSH PRIVILEGES;
-
- show master status;
- 记住展示的file日志名和position偏移量
-
- 从服务器:
- vim /etc/my.cnf
- server-id = 22
- relay-log=relay-log-bin #添加
- relay-log-index=slave-relay-bin.index #添加
- relay_log_recovery = 1 #可选项,若从服务器当即后relay-log损坏导致一部分中继日志没有处理,就选择放弃未执行的relay-log并从主服务器从新获取。
-
- systemctl restart mysqld
- mysql -u root -p123456
- master_host='192.168.10.15',master_user='myslave',master_password='123456',master_log_file='在主查询的日志名',master_log_pos=在主查询的偏移量;
-
- start slave;
-
- show slave status\G
- 在显示的内容确保下面两项是yes
- Slave_IO_Running: Yes
- Slave_SQL_Running: Yes
二,读写分离
1,什么是读写分离
读写分离,基本的原理是让主数据库处理事务性增、改、删操作(INSERT、UPDATE、DELETE),而从数据库处理SELECT查询操作。数据库复制被用来把事务性操作导致的变更同步到集群中的从数据库。
2,为什么要读写分离
因为数据库的“写”(写10000条数据可能要3分钟)操作是比较耗时的,但是数据库的“读”(读10000条数据可能只要5秒钟)。所以读写分离,解决的是,数据库的写入,影响了查询的效率。
3,什么时候要进行读写分离
数据库不一定要读写分离,如果程序使用数据库较多时,而更新少,查询多的情况下会考虑使用。利用数据库主从同步,再通过读写分离可以分担数据库压力,提高性能。
4,什么时候要读写分离
数据库不一定要读写分离,如果程序使用数据库较多时,而更新少,查询多的情况下会考虑使用。利用数据库主从同步,再通过读写分离可以分担数据库压力,提高性能。
5,mysql支持的复制类型
(1)STATEMENT:基于语句的复制。在服务器上执行sql语句,在从服务器上执行同样的语句,mysql默认采用基于语句的复制,执行效率高。
(2)ROW:基于行的复制。把改变的内容复制过去,而不是把命令在从服务器上执行一遍。
(3)MIXED:混合类型的复制。默认采用基于语句的复制,一旦发现基于语句无法精确复制时,就会采用基于行的复制。
6,实现方式
(1)基于程序代码内部实现
在代码中根据 select、insert 进行路由分类,这类方法也是目前生产环境应用最广泛的。优点是性能较好,因为在程序代码中实现,不需要增加额外的设备为硬件开支;缺点是需要开发人员来实现,运维人员无从下手。但是并不是所有的应用都适合在程序代码中实现读写分离,像一些大型复杂的Java应用,如果在程序代码中实现读写分离对代码改动就较大。
(2)基于中间代理层实现
代理一般位于客户端和服务器之间,代理服务器接到客户端请求后通过判断后转发到后端数据库,有以下代表性程序。
MySQL-Proxy。MySQL-Proxy 为 MySQL 开源项目,通过其自带的 lua 脚本进行SQL 判断。
Atlas。是由奇虎360的Web平台部基础架构团队开发维护的一个基于MySQL协议的数据中间层项目。它是在mysql-proxy 0.8.2版本的基础上,对其进行了优化,增加了一些新的功能特性。360内部使用Atlas运行的mysql业务,每天承载的读写请求数达几十亿条。支持事物以及存储过程。
Amoeba。由陈思儒开发,作者曾就职于阿里巴巴。该程序由Java语言进行开发,阿里巴巴将其用于生产环境。但是它不支持事务和存储过程。
7,读写分离的搭建
因为amoeba入门门槛最低,所以这次使用amoeba。
继续主从复制搭建的环境,需要额外准备两台虚拟机:
Amoeba 服务器:192.168.10.13,安装jdk1.6和amoeba
客户端 服务器:192.168.10.13,安装mysql
- amoeba服务器:
- 安装java(java推荐1.5或1.6,高版本不推荐使用)
- cd /opt/
- cp jdk-6u14-linux-x64.bin /usr/local/
- cd /usr/local/
- chmod +x jdk-6u14-linux-x64
- ./jdk-6u14-linux-x64.bin
- 一直回车,最后yes
-
-
- mv jdk1.6.0_14/ /usr/local/jdk1.6
-
- vim /etc/profile #末尾写入
- export JAVA_HOME=/usr/local/jdk1.6
- export CLASSPATH=$CLASSPATH:$JAVA_HOME/lib:$JAVA_HOME/jre/lib
- export PATH=$JAVA_HOME/lib:$JAVA_HOME/jre/bin/:$PATH:$HOME/bin
- export AMOEBA_HOME=/usr/local/amoeba
- export PATH=$PATH:$AMOEBA_HOME/bin
-
- source /etc/profile
- java -version
-
- 安装amoeba
- mkdir /usr/local/amoeba
- tar zxvf amoeba-mysql-binary-2.2.0.tar.gz -C /usr/local/amoeba/
- chmod -R 755 /usr/local/amoeba/
- /usr/local/amoeba/bin/amoeba
- 出现amoeba start|stop说明安装成功
-
- 配置读写分离
- 先在Master、Slave1、Slave2 的mysql上开放权限给 Amoeba 访问
- grant all on *.* to test@'192.168.10.%' identified by '123456';
-
- 回到amoeba配置服务
- cd /usr/local/amoeba/conf/
- cp amoeba.xml amoeba.xml.bak
- vim amoeba.xml
-
- --30行--
- <property name="user">amoeba</property>
- --32行--
- <property name="password">123456</property>
- --115行--
- <property name="defaultPool">master</property>
- --117-去掉注释-
- <property name="writePool">master</property>
- <property name="readPool">slaves</property>
-
- cp dbServers.xml dbServers.xml.bak
- vim dbServers.xml
- --23行--注释掉 作用:默认进入test库 以防mysql中没有test库时,会报错
- <!-- <property name="schema">test</property> -->
- --26--修改
- <property name="user">test</property>
- --28-30--去掉注释
- <property name="password">123456</property>
- --45--修改,设置主服务器的名Master
- <dbServer name="master" parent="abstractServer">
- --48--修改,设置主服务器的地址
- <property name="ipAddress">192.168.10.15</property>
- --52--修改,设置从服务器的名slave1
- <dbServer name="slave1" parent="abstractServer">
- --55--修改,设置从服务器1的地址
- <property name="ipAddress">192.168.10.14</property>
- --58--复制上面6行粘贴,设置从服务器2的名slave2和地址
- <dbServer name="slave2" parent="abstractServer">
- <property name="ipAddress">192.168.10.16</property>
- --65行--修改
- <dbServer name="slaves" virtual="true">
- --71行--修改
- <property name="poolNames">slave1,slave2</property>
-
- /usr/local/amoeba/bin/amoeba start&
- 通过查看8066端口是否运行来看amoeba是否成功启动
-
- 客户机:
- yum install -y mariadb-server mariadb
- systemctl start mariadb.service