1+X云计算运维与开发(中级)实战案例——构建读写分离的数据库集群

前言

在本文,你将认识主从复制和读写分离。
在一个数据库系统中,容灾备份时非常重要的,于是,将一个数据库服务器(主服务器)上的数据同步复制到一个或多个其他数据库服务器(从服务器)上,以此提高数据库的可用性和容灾能力,这就是主从复制。
同时,在数据库中,“读”的操作是比“写”的操作快上许多的,如果我们在数据库写入数据时进行查询操作,那么速度将会非常慢,为了进一步提升数据库的性能,就会把"写"的职责交给主服务器,“读”的操作交给从服务器,这便是读写分离。
在实际的生产环境中,通过主从复制的方式来同步数据,再通过一台主、多台从节点,主节点提供写操作,从节点提供读操作来实现读写分离,从而提升数据库的并发负载能力。

如果你是初学者,那么我之前发布的文章对一些简单操作有详细讲解,你可以从中入手,本文对之前讲过的操作不会详细说明。

虚拟机使用的是考试提供的xnode1、xnode2、xnode3
各节点规划如下:

虚拟机IP/24主机名节点
xnode1192.168.200.11mycatmycat中间件
xnode2192.168.200.12db1数据库主节点
xnode3192.168.200.13db2数据库从节点

Mycat数据库中间件服务能够将用户提交的读写操作识别分发给相应的数据库节点。这样将用户的访问操作、数据库的读与写操作分给3台主机,只有数据库集群的主节点接收增、删、改SQL语句,从节点接收查询语句,分担了主节点的查询压力。

操作过程

关闭防火墙和Selinux

#三个节点均关闭防火墙并禁止其开机自启
[root@xnode1 ~]# systemctl stop firewalld && systemctl disable firewalld
[root@xnode2 ~]# systemctl stop firewalld && systemctl disable firewalld
[root@xnode3 ~]# systemctl stop firewalld && systemctl disable firewalld
#临时关闭Selinux
[root@xnode1 ~]# setenforce 0
[root@xnode2 ~]# setenforce 0
[root@xnode3 ~]# setenforce 0

更改主机名

#三个节点更改主机名,xnode1--mycat、xnode2--db1、xnode3--db2
[root@xnode1 ~]# hostnamectl set-hostname mycat
[root@xnode1 ~]# bash
[root@mycat ~]# 

[root@xnode2 ~]# hostnamectl set-hostname db1
[root@xnode2 ~]# bash
[root@db1 ~]# 

[root@xnode3 ~]# hostnamectl set-hostname db2
[root@xnode3 ~]# bash
[root@db2 ~]# 

配置主机映射

#在mycat节点配置好
[root@mycat ~]# cat >> /etc/hosts << EOF
> 192.168.200.11 mycat
> 192.168.200.12 db1
> 192.168.200.13 db2
> EOF
#使用scp命令远程传输给其他主机,去对应主机vi文件修改或者像上面那样操作也行。
[root@mycat ~]# scp /etc/hosts root@db1:/etc/hosts
...
Are you sure you want to continue connecting (yes/no)? yes #输入yes回车
root@db1's password: #输入对方主机的密码
hosts   100%  217     0.2KB/s   00:00  
#db2同理,步骤一样的
[root@mycat ~]# scp /etc/hosts root@db2:/etc/hosts

配置YUM源仓库

#创建挂载目录
[root@mall ~]# mkdir /opt/centos
#挂载
[root@mall ~]# mount -o loop CentOS-7-x86_64-DVD-1511.iso /mnt/	
mount: /dev/loop2 is write-protected, mounting read-only					
[root@mall ~]# cp -rvf /mnt/* /opt/centos																
[root@mall ~]# umount /mnt/		
#删除系统自带的默认源
[root@mall ~]# rm -rf /etc/yum.repos.d/*
#创建新的仓库文件	
[root@mall ~]# vi /etc/yum.repos.d/local.repo    
[centos]
name=centos
baseurl=file:///opt/centos
enabled=1
gpgcheck=0
[gpmall]
name=gpmall
baseurl=file:///root/gpmall-repo
enabled=1
gpgcheck=0
#检查可用性,查出3888个包就没问题
[root@mall ~]# yum clean all && yum repolist

#xnode2和xnode3是没有CentOS的系统镜像的,所以我们在xnode1安装ftp服务,让它们通过ftp服务使用xnode1的软件仓库
#安装ftp服务
[root@mycat ~]# yum -y install vsftpd
...
Complete!
#修改ftp服务的配置文件,共享/opt目录
[root@mycat ~]# echo "anon_root=/opt" >> /etc/vsftpd/vsftpd.conf   
#启动ftp服务并设置开机自启
[root@mycat ~]# systemctl start vsftpd && systemctl enable vsftpd
...
#db1和db2删除系统默认源
[root@db1 ~]# rm -rf /etc/yum.repos.d/*
[root@db2 ~]# rm -rf /etc/yum.repos.d/*
#db1创建新的仓库文件
[root@db1 ~]# vi /etc/yum.repos.d/local.repo
[centos]
name=centos
baseurl=ftp://mycat/centos
enabled=1
gpgcheck=0
#通过scp将仓库文件远程传输给db2(你也可以去db2重新写一个)
[root@db1 ~]# scp /etc/yum.repos.d/local.repo root@db2:/etc/yum.repos.d/local.repo
#检查可用性,3727个包就没问题
[root@db1 ~]# yum clean all && yum repolist
[root@db2 ~]# yum clean all && yum repolist

配置主从数据库

安装配置数据库
#db1和db2安装数据库,并启动和设置开机自启
[root@db1 ~]# yum install -y mariadb mariadb-server
[root@db1 ~]# systemctl start mariadb && systemctl enable mariadb
[root@db2 ~]# yum install -y mariadb mariadb-server
[root@db2 ~]# systemctl start mariadb && systemctl enable mariadb
#初始化数据库
[root@db1 ~]# mysql_secure_installation 
Enter current password for root (enter for none): #回车
Set root password? [Y/n] #回车
New password: #123456
Re-enter new password: #123456
Remove anonymous users? [Y/n] #回车
Disallow root login remotely? [Y/n] n #输入n然后回车
Remove test database and access to it? [Y/n] #回车
Reload privilege tables now? [Y/n] #回车
[root@db2 ~]# mysql_secure_installation 
#操作同上

#修改db1的数据库配置文件,添加以下三个配置
log_bin = mysql-bin	
#启用二进制日志,并将命名规则设置为mysql-bin.xxxxxx
binlog_ignore_db = mysql
#mysql这个数据库存储了数据库管理系统自身的数据和元数据,这里不将mysql数据库本身的操作写入二进制日志,可以减少二进制日志的体积,提高主数据库的性能,同时避免在主从复制时将不必要的系统数据传输到从服务器上。
server_id = 12
#server_id是数据库服务器的唯一标识符,不可一致,这里直接设置为ip地址的主机位

#修改完后的内容如下
[root@db1 ~]# grep -v '^#' /etc/my.cnf
[mysqld]
log_bin = mysql-bin
binlog_ignore_db = mysql
server_id = 12
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
symbolic-links=0

[mysqld_safe]
log-error=/var/log/mariadb/mariadb.log
pid-file=/var/run/mariadb/mariadb.pid

!includedir /etc/my.cnf.d

#严谨起见,db2添加个server_id即可(不添加都行)
[root@db2 ~]# sed -i '2i\server_id = 13' /etc/my.cnf

#配置好后重启服务
[root@db1 ~]# systemctl restart mariadb 
[root@db2 ~]# systemctl restart mariadb 
数据库授权
#db1登录数据库
[root@db1 ~]# mysql -uroot -p123456
#让任何主机都能通过root用户登录数据库
MariaDB [(none)]> grant all privileges on *.* to root@'%' identified by '123456';
#创建一个user用户让从节点db2连接,并赋予从节点同步主节点数据库的权限
MariaDB [(none)]> grant replication slave on *.* to 'user'@'db2' identified by '123456';
从节点同步主节点
#db2登录数据库
[root@db2 ~]# mysql -uroot -p123456
#配置从节点连接主节点的连接信息。master_host为主节点主机名db1,master_user为上个步骤创建的用户user
MariaDB [(none)]> change master to master_host='db1',master_user='user',master_password='123456'; 
#开启从节点服务
MariaDB [(none)]> start slave;
#查看从节点服务状态
MariaDB [(none)]> show slave status\G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: db1
                  Master_User: user
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000001		#这里就是前面设置的日志文件命名规则
          Read_Master_Log_Pos: 526
               Relay_Log_File: mariadb-relay-bin.000002
                Relay_Log_Pos: 810
        Relay_Master_Log_File: mysql-bin.000001
             Slave_IO_Running: Yes					#只要这两个状态都显示Yes
            Slave_SQL_Running: Yes					#就说明从节点服务开启成功了
			...

验证主从复制功能

#我们回到db1,注意是db1,也就是主服务器
#创建一个test数据库
MariaDB [(none)]> create database test;
#使用创建的数据库
MariaDB [(none)]> use test
#创建一个test表
MariaDB [test]> create table test(id int not null primary key,name varchar(20));
#插入数据
MariaDB [test]> insert into test values(1,'kugua');
#查看数据
MariaDB [test]> select * from test;
+----+-------+
| id | name  |
+----+-------+
|  1 | kugua |
+----+-------+
1 row in set (0.00 sec)

#然后回到db2,注意是db2,也就是从服务器
#此时在从服务器,就能看到刚刚在主服务器创建的test数据库
MariaDB [(none)]> show databases like 't%';
+---------------+
| Database (t%) |
+---------------+
| test          |
+---------------+
1 row in set (0.00 sec)
#我们查询一下test数据库的test表的内容
MariaDB [(none)]> select * from test.test;
+----+-------+
| id | name  |
+----+-------+
|  1 | kugua |
+----+-------+
1 row in set (0.00 sec)

配置读写分离

安装JDK环境
#Mycat中间件服务依赖JDK1.7版本以上的环境,我们直接装1.8
[root@mycat ~]# yum install -y java-1.8*
...
Complete!
#安装好后可以看一下java的版本
[root@mall ~]# java -version
openjdk version "1.8.0_222"
OpenJDK Runtime Environment (build 1.8.0_222-b10)
OpenJDK 64-Bit Server VM (build 25.222-b10, mixed mode)
安装Mycat
#使用tar命令解压Mycat软件压缩包,同时使用-C参数指定解压路径
[root@mycat ~]# tar -zxf Mycat-server-1.6-RELEASE-20161028204710-linux.tar.gz -C /usr/local/
#赋予解压后的Mycat目录权限
[root@mycat ~]# chown -R 777 /usr/local/mycat/
#在系统变量文件中添加Mycat服务的系统变量
[root@mycat ~]# echo 'export MYCAT_HOME=/usr/local/mycat/' >> /etc/profile
#生效变量
[root@mycat ~]# source /etc/profile
修改Mycat逻辑库配置文件
#切换至mycat目录,方便操作
[root@mycat ~]# cd /usr/local/mycat/
#vi进入逻辑库配置文件,原内容很多,其中被<!-- -->包裹的内容是注释说明内容,可以不用管
[root@mycat mycat]# vi conf/schema.xml 
#删除多余配置项,稍作修改,只留以下内容
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
<schema name="USERDB" checkSQLschema="true" sqlMaxLimit="100" dataNode="dn1">
</schema>
<dataNode name="dn1" dataHost="localhost1" database="test" />
<dataHost name="localhost1" maxCon="1000" minCon="10" balance="3" writeType="0" dbType="mysql" dbDriver="native" switchType="1"  slaveThreshold="100">
  <heartbeat>select user()</heartbeat>
  <writeHost host="hostM1" url="192.168.200.12:3306" user="root"  password="123456">
    <readHost host="hostS2" url="192.168.200.13:3306" user="root" password="123456" />
  </writeHost>
</dataHost>
</mycat:schema>		
#各字段解析如下:
#XML声明
<?xml version="1.0"?>
#DOCTYPE声明
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
#根元素和命名空间
<mycat:schema xmlns:mycat="http://io.mycat/">

<schema name="TESTDB" checkSQLschema="true" sqlMaxLimit="100" dataNode="dn1">
</schema>
#checkSQLschema="true":设置会检查SQL架构
#sqlMaxLimit="100":指定SQL最大限制为 100
#dataNode="dn1":指定数据节点为 dn1
<dataNode name="dn1" dataHost="localhost1" database="test" />
#name="dn1":定义了名为dn1的数据节点
#ataHost="localhost1":指定数据主机为 localhost1
#database="test":指定数据库为test
<dataHost name="localhost1" maxCon="1000" minCon="10" balance="3" writeType="0" dbType="mysql" dbDriver="native" switchType="1"  slaveThreshold="100">
#name="localhost1":定义了名为localhost1的数据主机
#maxCon="1000" minCon="10":最大连接数和最小连接数,分别为1000和10
#balance="3":指定负载均衡策略为3(根据权重来分配查询负载)
#writeType="0":指定写入类型为0(全部写入第一台writeHost)
#dbType="mysql":指定数据库类型为mysql
#dbDriver="native":指定数据库驱动为native
#switchType="1":指定主从切换类型为1(自动切换)
#slaveThreshold="100":指定从节点阈值为100ms,当从节点延迟超过该阈值,就会触发切换操作
  <heartbeat>select user()</heartbeat>
#心跳查询语句,用来检测数据节点的状态  
  <writeHost host="hostM1" url="192.168.200.12:3306" user="root"  password="123456">
    <readHost host="hostS2" url="192.168.200.13:3306" user="root" password="123456" />
  </writeHost>
#定义了写入主机和读取主机的名称、地址、用户名和密码
</dataHost>
</mycat:schema>		

#最后,修改配置文件权限
[root@mycat mycat]# chown root:root conf/schema.xml
设置mycat的访问用户
#进入server.xml文件,修改文件末尾处访问用户的配置,vi编辑器下,按下G(大写,即Shift+g)可快速跳转至文件最末尾。
[root@mycat mycat]# vi conf/server.xml 
#原先内容如下,<!--  -->包裹的是注释内容
[root@mycat mycat]# tail -n 22 conf/server.xml 
        <user name="root">
                <property name="password">123456</property>
                <property name="schemas">TESTDB</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</property>
                <property name="readOnly">true</property>
        </user>

</mycat:server>
#这里我用sed命令筛除了注释内容输出,更加直观一点
[root@mycat mycat]# sed '/<!--/,/-->/d' conf/server.xml | tail -n 13
        <user name="root">
                <property name="password">123456</property>
                <property name="schemas">TESTDB</property>

        </user>

        <user name="user">
                <property name="password">user</property>
                <property name="schemas">TESTDB</property>
                <property name="readOnly">true</property>
        </user>

</mycat:server>
#要做的很简单,我们直接把user用户那一段删掉就行了
#(在vi编辑器下,光标定位在该段段首,键盘按下5dd,快速删除5行内容,如果不小心按错,按u可以撤销操作)
#删除完后,文件底部内容如下        		
[root@mycat mycat]# sed '/<!--/,/-->/d' conf/server.xml | tail -n 10


        <user name="root">
                <property name="password">123456</property>
                <property name="schemas">USERDB</property>

        </user>


</mycat:server>
启动Mycat服务
#切换至mycat的bin目录
[root@mycat mycat]# cd bin/
#启动服务
[root@mycat bin]# ./mycat start
#查看端口开放情况(该命令使用需要安装net-tools,没有请使用yum工具自行安装)
#看到9066和8066端口开放就说明启动成功了
[root@mycat bin]# netstat -ntpl
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      1109/sshd           
tcp        0      0 127.0.0.1:25            0.0.0.0:*               LISTEN      1598/master         
tcp        0      0 127.0.0.1:32000         0.0.0.0:*               LISTEN      2765/java           
tcp6       0      0 :::9066                 :::*                    LISTEN      2765/java           
tcp6       0      0 :::54740                :::*                    LISTEN      2765/java           
tcp6       0      0 :::22                   :::*                    LISTEN      1109/sshd           
tcp6       0      0 ::1:25                  :::*                    LISTEN      1598/master         
tcp6       0      0 :::34205                :::*                    LISTEN      2765/java           
tcp6       0      0 :::1984                 :::*                    LISTEN      2765/java           
tcp6       0      0 :::8066                 :::*                    LISTEN      2765/java        

验证读写分离功能

[root@mycat bin]# cd ~
#安装数据库客户端工具
[root@mycat ~]# yum -y install MariaDB-client
...
Complete!
#登录数据库
[root@mycat ~]# mysql -h127.0.0.1 -P8066 -uroot -p123456
#1.查看Mycat服务的逻辑库,此时的逻辑库TESTDB对应数据库test
MySQL [(none)]> show databases;
+----------+
| DATABASE |
+----------+
| TESTDB   |
+----------+
1 row in set (0.004 sec)
#使用该数据库
MySQL [(none)]> use TESTDB
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
#2.查看库内表格,和test数据库的内容都是对应的
MySQL [TESTDB]> show tables;
+----------------+
| Tables_in_test |
+----------------+
| test           |
+----------------+
1 row in set (0.002 sec)
#3.查看表格内容
MySQL [TESTDB]> select * from test;
+----+-------+
| id | name  |
+----+-------+
|  1 | kugua |
+----+-------+
1 row in set (0.100 sec)

#A.我们插入一段数据
MySQL [TESTDB]> insert into test values(2,'cloud');
Query OK, 1 row affected (0.014 sec)
#4.查看内容
MySQL [TESTDB]> select * from test;                
+----+-------+
| id | name  |
+----+-------+
|  1 | kugua |
|  2 | cloud |
+----+-------+
2 rows in set (0.003 sec)
#查询数据库读写操作的分离信息
[root@mycat ~]# mysql -h127.0.0.1 -P9066 -uroot -p123456 -e 'show @@datasource;'
#可以看到,我们的主节点(db1)进行了1次写操作(WRITE_LOAD),从节点(db2)进行了4次读操作(READ_LOAD)
#在验证读写分离的过程中,我们确实做了A的写入(插入数据)操作和1、2、3、4的读取(查询)操作
+----------+--------+-------+----------------+------+------+--------+------+------+---------+-----------+------------+
| DATANODE | NAME   | TYPE  | HOST           | PORT | W/R  | ACTIVE | IDLE | SIZE | EXECUTE | READ_LOAD | WRITE_LOAD |
+----------+--------+-------+----------------+------+------+--------+------+------+---------+-----------+------------+
| dn1      | hostM1 | mysql | 192.168.200.12 | 3306 | W    |      0 |   10 | 1000 |      61 |         0 |          1 |
| dn1      | hostS2 | mysql | 192.168.200.13 | 3306 | R    |      0 |    5 | 1000 |      59 |         4 |          0 |
+----------+--------+-------+----------------+------+------+--------+------+------+---------+-----------+------------+

后语

数据库不一定总要读写分离,如果程序使用数据库较多、更新较少、查询较多的情况下会考虑使用。利用数据库主从同步,可以减少数据库压力,提高性能。当然,数据库也有其它优化方案。例如,使用memcache、分表、搜索引擎等方法。

  • 12
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: 云计算运维开发是一本介绍云计算运维开发的PDF电子书。云计算是指将计算资源通过互联网进行集中管理和共享的技术,能够提供可伸缩性、弹性和经济性的计算服务。云计算运维是指对云计算环境下的计算资源进行监控、管理和维护的工作,保证云计算平台的稳定性和可靠性。云计算开发则是指在云计算平台上进行应用程序开发的过程。 这本PDF电子书从云计算运维开发的基础知识入手,介绍了云计算的概念、发展历程和核心技术。它详细介绍了云计算运维的相关工具和技术,包括监控系统、自动化工具、故障处理和容灾备份等。同时,它还介绍了云计算开发的相关技术和框架,例如面向服务架构(SOA)、容器化和微服务等。 此外,该书还介绍了云计算安全、性能优化和资源调度等重要话题。云计算安全涉及到数据隐私保护、身份认证、访问控制等方面的技术。性能优化则是指如何通过优化资源的分配和利用,提高云计算平台的性能和效率。资源调度则涉及到如何根据应用需求,动态地调整计算资源的分配和使用。 总的来说,云计算运维开发这本PDF电子书提供了关于云计算运维开发方面的基础知识和实践经验。它对于那些对云计算领域感兴趣的读者,特别是从事云计算运维开发工作的人员,会有很大的帮助。 ### 回答2: 云计算运维开发PDF是一本介绍云计算运维开发领域的书籍,主要针对云计算技术的运维开发进行了深入的探讨和解析。 首先,在云计算领域,运维是一个至关重要的环节。云计算运维包括服务器的配置、应用程序的安装与管理、故障排除等工作。通过云计算运维,可以确保系统的稳定性和高可用性,提高应用程序的性能和效率。 其次,云计算开发是指在云平台上进行应用程序的开发和部署。通过云计算开发,可以充分利用云计算的优势,如弹性伸缩、按需付费等特性,开发出适应大规模用户需求的应用程序。同时,云计算开发也需要考虑到云平台的规范和限制,合理利用云资源,提高应用程序的可靠性和可扩展性。 这本书从理论知识到实际操作都有所涉及,包括云计算的基本概念与架构、虚拟化技术、容器技术、自动化运维工具的应用等。通过深入的讲解和实例分析,读者可以全面了解云计算运维开发的技术要点和最佳实践。 此外,书中还介绍了一些常用的云计算平台和工具,如AWS、Azure、OpenStack等,以及实际案例的分析和实现。这些内容对于读者更好地理解和应用云计算运维开发提供了有益的参考。 综上所述,云计算运维开发PDF对于从事或有兴趣了解云计算运维开发的读者来说,是一本非常有价值的书籍。它通过系统的讲解和实例演示,帮助读者掌握云计算运维开发的基本知识和技能,提升其在云计算领域的竞争力。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值