Mycat分片与读写分离(mysql主从)

    技术2023-07-23  84

    Mycat目录标题

    Mycat学习笔记Mycat的部署与安装Mycat的分片什么是数据库分片逻辑库(schema)逻辑表(table)分片节点(dataNode)节点主机(dataHost)分片规则(rule)数据库分片操作 Mycat读写分离MySQL主从复制操作实现准备工作MySQL主服务器配置MySQL从服务器配置 Mycat配置

    Mycat学习笔记


    安装所需环境

    1、jdk:要求jdk必须是1.7及以上版本

    2、Mysql:推荐mysql是5.5以上版本

    3、Mycat:

    Mycat的官方网站:

    http://www.mycat.org.cn/

    下载地址:

    https://github.com/MyCATApache/Mycat-download

    Mycat的部署与安装

    1、下载并解压

    下载 Mycat-server-xxxx-linux.tar.gz

    我的版本:Mycat-server-1.6-RELEASE-20161028204710-linux.tar.gz

    解压后 /usr/local/ 目录下会有一个名为Mycat的文件夹

    tar -zvxf Mycat-server-1.6-RELEASE-20161028204710-linux.tar.gz -C /usr/local

    2、启动Mycat

    进入到 Mycat的bin目录下

    ①启动

    ./mycat start

    ②查看状态

    ./mycat status

    ③停止

    ./mycat stop

    mycat 支持的命令{ console | start | stop | restart | status | dump }

    Mycat的默认端口号为:8066

    Mycat的分片


    mycat位于应用与数据库的中间层,可以灵活解耦应用与数据库,后端数据库可以位于不同的主机上。在mycat中将表分为两大类;对于数据量小且不需要做数据切片的表,称之为分片表;对于数据量大到单库性能,容量不足以支撑,数据通常需要通过水平切分均匀分布到不同的数据库中的表,称之为分片表。而中间件最终需要处理的数据是对数据切分,聚合。

    什么是数据库分片

    简单来说,就是指通过某种特定的条件,将我们存放在同一个数据库中的数据分散存放到多个数据库(主机)上面,以达到分散单台设备负载的效果。

    数据的切分(Sharding)根据其切分规则的类型,可以分为两种切分模式。

    (1)一种是按照不同的表(或者Schema)来切分到不同的数据库(主机)之上,这种切可以称之为数据的垂直(纵向)切分

    (2)另外一种则是根据表中的数据的逻辑关系,将同一个表中的数据按照某种条件拆分到多台数据库(主机)上面,这种切分称之为数据的水平(横向)切分。

    逻辑库(schema)

    数据库中间件,通常对实际应用来说,并不需要知道中间件的存在,业务开发人员只需要知道数据库的概念,所以数据库中间件可以被看做是一个或多个数据库集群构成的逻辑库。

    逻辑表(table)

    既然有逻辑库,那么就会有逻辑表,分布式数据库中,对应用来说,读写数据的表就是逻辑表。逻辑表,可以是数据切分后,分布在一个或多个分片库中,也可以不做数据切分,不分片,只有一个表构成。

    分片表:是指那些原有的很大数据的表,需要切分到多个数据库的表,这样,每个分片都有一部分数据,所有分片构成了完整的数据。 总而言之就是需要进行分片的表。

    非分片表:一个数据库中并不是所有的表都很大,某些表是可以不用进行切分的,非分片是相对分片表来说的,就是那些不需要进行数据切分的表。

    分片节点(dataNode)

    数据切分后,一个大表被分到不同的分片数据库上面,每个表分片所在的数据库就是分片节点(dataNode)。

    节点主机(dataHost)

    数据切分后,每个分片节点(dataNode)不一定都会独占一台机器,同一机器上面可以有多个分片数据库,这样一个或多个分片节点(dataNode)所在的机器就是节点主机(dataHost),为了规避单节点主机并发数限制,尽量将读写压力高的分片节点(dataNode)均衡的放在不同的节点主机(dataHost)。

    分片规则(rule)

    前面讲了数据切分,一个大表被分成若干个分片表,就需要一定的规则,这样按照某种业务规则把数据分到某个分片的规则就是分片规则,数据切分选择合适的分片规则非常重要,将极大的避免后续数据处理的难度。

    数据库分片

    更确切来说,应该是数据分片。

    数据库分库、分表、分区都是指对数据库进行操作,分片更多的是针对数据本身进行操作。

    在分布式存储系统中,数据需要分散存储在堕胎设备上,数据分片(Sharding)就是用来确定数据在堕胎存储设备上分布的技术。

    操作

    前提:存在上述提到的所需安装环境

    1、创建数据库

    两台mysql数据库服务器:

    Host1:192.168.100.11 master

    Host2:192.168.100.12 salve1

    host1环境

    操作系统版本 : centos7

    数据库版本 : mysql-5.6

    mycat版本 :1.6 release

    数据库名 : db1、db3

    host2环境

    操作系统版本 : centos7

    数据库版本 : mysql-5.6

    mycat版本 :1.6 release

    数据库名 : db2

    MyCat安装到节点1上

    ①登录到mysql数据库

    mysql -uroot -p123456

    ②创建数据库

    create database db1; create database db3;

    PS:这里的数据库名要和配置文件中的相对应

    2、配置文件

    ①schema.xml

    schema.xml文件主要配置数据库的信息,例如逻辑数据库名称,物理上真实的数据源以及表和数据源之间的对应关系和路由策略等。

    Schema.xml作为MyCat中重要的配置文件之一,管理着MyCat的逻辑库、表、分片规则、DataNode以及DataSource。弄懂这些配置,是正确使用MyCat的前提。这里就一层层对该文件进行解析。

    标签含义

    # schema 标签用于定义MyCat实例中的逻辑库

    # Table 标签定义了MyCat中的逻辑表

    # dataNode 标签定义了MyCat中的数据节点,也就是我们通常说所的数据分片。

    # dataHost标签在mycat逻辑库中也是作为最底层的标签存在,直接定义了具体的数据库实例、读写分离配置和心跳语句。

    注意:若是LINUX版本的MYSQL,则需要设置为Mysql大小写不敏感,否则可能会发生表找不到的问题。

    在MySQL的配置文件中/etc/my.cnf [mysqld] 中增加一行

    lower_case_table_names=1

    配置内容如下:

    <?xml version="1.0"?> <!DOCTYPE mycat:schema SYSTEM "schema.dtd"> <mycat:schema xmlns:mycat="http://io.mycat/"> <schema name="TESTDB" checkSQLschema="true" sqlMaxLimit="100"> <table name="t_student" primaryKey="id" dataNode="dn1,dn3" rule="student_id" /> </schema> <dataNode name="dn1" dataHost="master" database="db1" /> <dataNode name="dn2" dataHost="slave1" database="db2" /> <dataNode name="dn3" dataHost="master" database="db3" /> <dataHost name="master" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100"> <heartbeat>select user()</heartbeat> <writeHost host="master" url="192.168.100.11:3306" user="root" password="123456"> </writeHost> </dataHost> <dataHost name="slave1" maxCon="1000" minCon="10" balance="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100"> <heartbeat>select user()</heartbeat> <writeHost host="slave1" url="192.168.100.12:3306" user="root" password="123456"></writeHost> </dataHost> </mycat:schema>

    如图所示:

    ②service.xml

    service.xml主要配置mycat服务的参数,比如端口号,myact用户名和密码使用的逻辑数据库等。最常用的是在此配置用户名、密码及权限。

    <!-- 此处定义了一个root用户,可以管理的逻辑库为database,对应schema.xml中的<schema name="TESTDB" > --> <user name="user"> <property name="password">123456</property> <property name="schemas">TESTDB</property> <property name="readOnly">false</property> </user>

    如图所示:

    ③rule.xml

    rule.xml里面就定义了我们对表进行拆分所涉及到的规则定义。我们可以灵活的对表使用不同的分片算法,或者对表使用相同的算法但具体的参数不同。这个文件里面主要有tableRule和function这两个标签。在具体使用过程中可以按照需求添加tableRule

    和function。

    rule.xml主要配置路由策略,主要有分片的片键,拆分的策略(取模还是按区间划分等)

    此配置文件可以不用修改,使用默认即可。

    Funcation标签

    <function name="rang-long" class="io.mycat.route.function.AutoPartitionByLong"> <property name="mapFile">autopartition-long.txt</property> </function>

    # name属性指定算法的名称,在该文件中唯一。 # class属性对应具体的分片算法,需要指定算法的具体类。 # property属性根据算法的要求指定。

    tableRule标签

    <tableRule name="auto-sharding-long"> <rule> <columns>id</columns> <algorithm>rang-long</algorithm> </rule> </tableRule>

    # name属性指定分片规则的名称,在该文件中唯一。 # rule属性指定分片算法的具体内容,包含columns和algorithm两个属性。 # columns属性指定对应的表中用于分片的列名。 # algorithm属性对应function中指定的算法的名称。

    <!--schema.xml中配置的rule="student_id" 所对应的分表规则, columns为id需要与数据库的列名对应,algorithm对应下方function--> <tableRule name="student_id"> <rule> <columns>id</columns> <algorithm>student_text</algorithm> </rule> </tableRule> <!--在conf中需要添加student_text.txt规则文件--> <function name="student_text" class="io.mycat.route.function.AutoPartitionByLong"> <property name="mapFile">student_text.txt</property> </function>

    如图所示:

    3、在Mycat的conf目录下创建一个student_text.txt

    内容如下:

    0-1M=0 1M-2M=1

    4、在bin目录下启动并连接Mycat

    ①启动

    ./mycat start

    ②查看mycat的状态

    ./mycat status

    ③查看mycat的控制台

    ./mycat console

    ④连接

    连接时指定端口号和IP地址

    mysql -uroot -p123456 -h 192.168.100.11 -P8066

    Debug:

    报错:

    [root@master bin]# mysql -u root -h 192.168.100.11 -P8066 -p123456 Warning: Using a password on the command line interface can be insecure. ERROR 2003 (HY000): Can't connect to MySQL server on '192.168.100.11' (111)

    这个不是IP的问题,应该是端口号的问题,去掉端口号是可以正常打开MySQL的。

    然后查看Mycat的状态却是断开的,应该是Mycat的问题

    server.xml的配置的问题

    5、往mycat插入数据

    ①选择数据库

    ②创建表t_student(表名要和配置文件中的一样)

    mysql> CREATE TABLE `t_student` ( -> `id` int(11) NOT NULL, -> `s_name` varchar(255) DEFAULT NULL, -> PRIMARY KEY (`id`) -> ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

    然后出现bug:

    ERROR 3009 (HY000): java.lang.IllegalArgumentException: Invalid DataSource:0

    解决方法:

    回到mysql添加权限

    GRANT ALL PRIVILEGES ON *.* TO 'root'@'192.168.100.11' IDENTIFIED BY '123456' WITH GRANT OPTION;

    刷新权限

    flush privileges;

    创建成功!

    ③插入数据

    insert into `t_student`(id, name) values ('0', '110'); insert into `t_student`(id, name) values ('1', 'sartin'); insert into `t_student`(id, name) values ('10000', 'broad'); insert into `t_student`(id, name) values ('10001', 'ljc'); insert into `t_student`(id, name) values ('20000', '20000');

    ④查看逻辑表t_student

    数据插入成功!

    6、查看数据是否分片成功

    ①进入mysql数据库

    mysql -uroot -p123456 -P8066

    ②查看数据库db1,db3

    数据库db1:

    数据库db3:

    Mycat读写分离


    读写分离基本的原理是让主数据库处理事务性增、改、删操作,而从数据库处理查询操作。数据库复制被用来把事务性操作导致的变更同步到集群中的从数据库。

    Mycat读写分离和自动切换机制,需要mysql的主从复制机制配合。

    MySQL主从复制


    主从复制,即当主数据库进行数据的增删改操作时,从数据库也要进行一个同样的操作,以

    确保和主数据库的数据保持一致。

    主从配置需要注意的地方

    1、主DB server和从DB server数据库的版本一致

    2、主DB server和从DB server数据库数据名称一致

    3、主DB server开启二进制日志,主DB server和从DB server的server_id都必须唯一

    参考:https://blog.csdn.net/qq_35992900/article/details/80599976

    操作实现

    准备工作

    mysql 均为5.6(版本最好还是一样)

    主数据库 192.168.100.11

    从数据库 192.168.100.12

    MySQL主服务器配置

    1、修改my.conf配置文件

    主从复制的本质思想就是,从数据库通过监听主数据库的一个二进制文件,当主数据库进行数据变化时,会将变化记录在这个二进制文件中,此时从数据库因为对此文件进行了监听,所以进行了同样的同步操作。

    主服务器:

    开启二进制日志 配置唯一的server-id 获得master二进制日志文件名及位置

    ①确定my.cnfw文件的位置

    find / -name my.cnf

    ②vi 修改

    [root@master ~]# vi /etc/my.cnf

    在mysqld中添加

    log-bin=mysql-bin(开启二进制日志)

    #服务器唯一ID,一般取IP最后一段

    server-id=11(设置server-id)

    #设置不开启复制的数据库,此数据库的数据库将不同步到从MySQL中

    binlog-ignore-db=mysql

    [mysqld] #二进制日志文件在datadir目录下可以找到 datadir=/var/lib/mysql socket=/var/lib/mysql/mysql.sock #设置不开启复制的数据库,此数据库的数据库将不同步到从MySQL中 binlog-ignore-db=mysql #启用二进制日志 log-bin=mysql-bin symbolic-links=0 #服务器唯一id,一般取ip地址最后一段 server-id=11 [mysqld_safe] #错误日志文件 log-error=/var/log/mysqld.log pid-file=/var/run/mysqld/mysqld.pid

    master mysql配置完毕,我们来登录master mysql查看我们具体的二进制文件名和位置

    3、重启mysql服务

    service mysqld restart

    4、连接mysql

    mysql -uroot -p123456

    ①查看二进制日志是否开启

    SHOW GLOBAL VARIABLES LIKE '%log%';

    可以看到log_bin是ON(开启)状态 ②查看mysql的二进制日志列表

    show master logs;

    ③创建账户sartin并授予权限

    这一步是赋予root全部权限,已操作可跳过

    grant all privileges on *.* to root@'%' identified by "123456"; GRANT FILE ON *.* TO 'sartin'@'%' IDENTIFIED BY '123456'; GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* to 'sartin'@'%' identified by '123456';

    刷新权限

    flush privileges;

    ④查看mysql现有哪些用户

    select user,host,password from mysql.user;

    ⑤查看mysql的server_id

    show global variables like '%server%';

    ⑥查看master状态

    show master status;

    MySQL主服务器的配置就完成了

    MySQL从服务器配置

    1、修改my.cnf配置文件

    vi /etc/my.cnf

    从服务器只需要添加

    server-id=11(设置server-id)

    server-id=12

    2、重启mysql服务

    service mysqld restart

    3、登录到mysql

    mysql -uroot -p123456

    ①赋予root全部权限

    grant all privileges on *.* to root@'%' identified by "123456";

    ②配置从服务器,进行mysql主数据库的绑定

    master_host是主MySQL的ip地址

    master_user和master_password均是刚刚在主MySQL上创建的那个账户

    master_log_file和master_log_pos是我们在主MySQL上执行show master status命令看到的file和position的信息

    CHANGE MASTER TO MASTER_HOST='192.168.100.11', MASTER_USER='sartin', MASTER_PASSWORD='123456', MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=606;

    ③启动从服务器的复制功能(同步进程)

    start slave;

    ④检查从服务器复制功能状态

    show slave status\G;

    注:Slave_IO及Slave_SQL进程必须正常运行,即YES状态,否则都是错误的状态(如:其中一个NO均属错误)。

    当Slave_IO_Running和Slave_SQL_Running都为YES的时候就表示主从同步设置成功了。

    4、关闭slave同步或者更换master

    stop slave;

    从服务器配置完成!

    最后我们在主数据库中创建一个数据库,你会发现当你在master中创建表或者是在表中插入数据时,我们的slave都会跟着同步进行这些操作,此时你的主从复制就算是大功告成了。

    Mycat配置


    1、配置文件

    ①schema.xml

    在dataHost为master的标签中添加了一个readHost,readHost指定了之前搭建的从MySQL,并且balance属性值从0变为1,表示所有读操作都随机的发送到readHost上。

    <?xml version="1.0"?> <!DOCTYPE mycat:schema SYSTEM "schema.dtd"> <mycat:schema xmlns:mycat="http://io.mycat/"> <schema name="TESTDB" checkSQLschema="true" sqlMaxLimit="100"> <table name="t_student" primaryKey="id" dataNode="dn1,dn3" rule="student_id" /> <table name="t_teacher" dataNode="dn5,dn6" primaryKey="id" rule="student_id" /> </schema> <dataNode name="dn1" dataHost="master" database="db1" /> <dataNode name="dn2" dataHost="slave1" database="db2" /> <dataNode name="dn3" dataHost="master" database="db3" /> <dataNode name="dn6" dataHost="master" database="db6" /> <dataNode name="dn5" dataHost="master" database="db5" /> <dataHost name="master" maxCon="1000" minCon="10" balance="1" writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100"> <heartbeat>select user()</heartbeat> <writeHost host="master" url="192.168.100.11:3306" user="root" password="123456"> <readHost host="slave1" url="192.168.100.12:3306" user="root" password="123456" /> </writeHost> </dataHost> <dataHost name="slave1" maxCon="1000" minCon="10" balance="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100"> <heartbeat>select user()</heartbeat> <writeHost host="slave1" url="192.168.100.12:3306" user="root" password="123456"></writeHost> </dataHost> </mycat:schema>

    2、登录mysql

    mysql -uroot -p123456

    创建db5,db6数据库

    mysql> create database db5; Query OK, 1 row affected (0.03 sec) mysql> create database db6; Query OK, 1 row affected (0.01 sec) mysql> show databases;

    4、启动Mycat

    ./mycat start

    5、登录到mycat

    mysql -uroot -p123456 -P8066 -h 192.168.100.11

    ①创建配置中的表格t_teacher

    CREATE TABLE `t_teacher` ( `id` int(11) NOT NULL, `name` varchar(255) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

    若查看数据,表显示为空,说明表创建成功!

    ②插入数据

    INSERT INTO `t_teacher` (id,name) VALUES ('0', 'You'); INSERT INTO `t_teacher` (id,name) VALUES ('1314', 'Love'); INSERT INTO `t_teacher` (id,name) VALUES ('10001', 'Hello'); INSERT INTO `t_teacher` (id,name) VALUES ('10991', 'Me');

    ③查看数据是否插入成功

    select * from t_teacher;

    5、回到mysql查看数据

    ①登录mysql

    mysql -uroot -p123456

    ②查看数据库

    show databases;

    ③查看db5,db6数据库的表t_teacher

    db5:

    db6:

    6、查看从服务器slave1中的mysql

    mysql -uroot -p123456

    ①查看数据库可以看到我们在master的db5,db6被同步到了slave1的数据库上

    ②查看数据库中的表格数据是否也存在

    mysql> select * from db5.t_teacher; mysql> select * from db6.t_teacher;

    MySQL的主从以及Mycat的读写到这里就成功了!

    Processed: 0.008, SQL: 9