第105讲:Mycat垂直分表实战:从规划到解决问题的完整指南

文章目录

    • 1.垂直分表的背景
    • 2.垂直分表案例实战
      • 2.1.垂直分表规划
      • 2.2.配置Mycat实现垂直分表
      • 2.3.重启Mycat
      • 2.4.在Mycat命令行中导入数据结构
      • 2.5.查看由Mycat分表后每个分片上存储的表
      • 2.6.Mycat垂直分表后可能遇到的问题
      • 2.7.垂直分表完成

1.垂直分表的背景

我们的商城系统数据库,目前是单点数据库,随着业务量越来越大,每日产生的数据量越来越多,单台数据库的存储能力和计算能力是有限的,为了保证用户的体验度和满意度,在数据库性能到达瓶颈之前,我们先对数据进行性能优化,目前的优化方案是对商城库进行垂直分表,扩展数据库节点,将不同业务的表存储在多个数据库节点中,提高数据库的性能。

垂直分库指的是将一个库中的多个表,拆分到多个数据库实例中,也就是拆分到了多台不同的数据库服务器上,缓解了单台数据库所承担的压力。

image-20220713204639355

2.垂直分表案例实战

2.1.垂直分表规划

为了保证数据库的高可用性和读写分离,我们在前面准备了2套双主双从的集群,我们按照双主双从集群进行划分,每一套双主双从充当一个数据节点也就是分片,将商品库的这些表分别存放在不同的节点分片中,从而达到分表的目的。

如下图所示,商品库的所有表的划分情况如下:

  • 将tb_goods_base、tb_goods_brand、tb_goods_cat、tb_goods_desc、tb_goods_item、tb_user、tb_user_address这7张表划分到分片1这个双主双从集群中。
  • 将tb_order_item、tb_order_master、tb_order_pay_log、tb_areas_city、tb_areas_region、tb_areas_provinces这6张表划分到分片2这个双主双从集群中。

image-20220713204300489

利用Mycat实现垂直分表的思路:

  • 首先声明一个schema,定义逻辑库,逻辑库就是这个商品库。
  • 然后定义逻辑表table,根据不同的表划分到不同的数据节点dataNode上。
  • 然后定义dataNode关联数据库节点中真实的数据库。
  • 最后定义dataHost也就是分片,一共定义2组分片,分别指向各自的双主双从复制集群。

此架构实现后,我们的商品库就从单点架构升级达到了双主双从高可用+读写分离的架构,并且也从逻辑上进行了分库分表操作,提供数据库性能。

2.2.配置Mycat实现垂直分表

1)在Schema配置文件中配置垂直分表

关于配置参数有几点需要说明一下:

  • 如果在<schema>标签中指定了dataNode数据节点,那么该逻辑库下所有的表都会被存储到指定数据节点的数据库实例上。
  • 如果单独在<table>逻辑表标签中定义了dataNode数据节点,那么该数据节点的优先级将大于schema中的数据节点,会根据逻辑表标签中的定义的dataNode,将该表存放在指定的数据库实例中。
  • 由于我们的分片一共有两个,因此我们要定义两个dataNode数据节点,一个数据节点相当于是一个分片,然后将指定的表、库按照需求划分到对应的分片上。
  • 定义好分片后,就需要去定义dataHost数据主机了,一个分片对应一个dataHost,因此我们需要定义两组dataHost,第一套双主双从集群分片主机为mysqlcluster-1,第二套双主双从集群分片主机为mysqlcluster-2。
  • 然后在dataHost中去指定数据存储的具体数据库实例,也就是我们的双主双从集群,双主双从集群也是两套主从复制集群,我们配置成两组<writeHost>,双主双从集群只有一个主库承担写操作,另一个主库充当备用主库,当主库故障后,备用主库直接切换成主库,形成高可用集群,双从全部承担读操作。

Schema配置文件的逻辑调用关系如下:

<schema>中包含<table>,定义要对那些库和表进行操作,逻辑库和逻辑表都会关联数据节点<dataNode>,在数据节点中关联数据主机<dataHost>和真实数据库名称,在<dataHost>中定义数据库实例信息。

一个逻辑库或者逻辑表的分库分表操作,是根据关联数据节点确定要将库、表分在哪个数据库节点上,然后关联的数据节点找到具体的数据主机,最后库、表就分在了关联的数据主机上。

[root@mysql-1 ~]# vim /data/mycat/conf/schema.xml
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">  
<mycat:schema xmlns:mycat="http://io.mycat/"><!--定义逻辑库 库名叫做db_shopping 该逻辑库关联dn1这个数据节点--> 	<schema name="db_shopping" checkSQLschema="false" sqlMaxLimit="100" dataNode="dn1"><!--定义逻辑表 将部分表划分到dn1这个分片--><table name="tb_goods_base" dataNode="dn1" primaryKey="id"/><table name="tb_goods_brand" dataNode="dn1"/><table name="tb_goods_cat" dataNode="dn1"/><table name="tb_goods_desc" dataNode="dn1"/><table name="tb_goods_item" dataNode="dn1"/><table name="tb_user" dataNode="dn1"/><table name="tb_user_address" dataNode="dn1"/><!--定义逻辑表 将部分表划分到dn2这个分片--><table name="tb_order_item" dataNode="dn2"/><table name="tb_order_master" dataNode="dn2"/><table name="tb_order_pay_log" dataNode="dn2"/><table name="tb_areas_city" dataNode="dn2"/><table name="tb_areas_region" dataNode="dn2"/><table name="tb_areas_provinces" dataNode="dn2"/></schema>  <!--定义数据节点 也就是分片 一个分片会关联一个数据主机组 然后对应真实的数据库名称--><dataNode name="dn1" dataHost="mysqlcluster-1" database= "db_shopping" />          <dataNode name="dn2" dataHost="mysqlcluster-2" database= "db_shopping" />          <!--定义数据主机 在这个标签下定义具体的读写操作路由的数据库实例地址 schema、table划分如何指定的是该数据主机关联的数据节点 那么对应的库、表都会被存储在数据主机定义的数据库实例中--><dataHost name="mysqlcluster-1" maxCon="1000" minCon="10" balance="1"  writeType="0" dbType="mysql"  dbDriver="native" switchType="1">    <heartbeat>select user()</heartbeat>  <!--定义写操作路由的数据库实例--><writeHost host="c1-1-master3306" url="192.168.20.11:3306" user="root" password="123456"><!--定义读操作路由的数据库实例--><readHost host="c1-1-slave3308" url="192.168.20.11:3308" user="root" password="123456" /></writeHost> <!--备用的主库 也是提供写操作的数据库,当主库c1-1-master3306故障后 备用库开始提供写操作--><writeHost host="c1-2-master3306" url="192.168.20.12:3306" user="root" password="123456"><!--备用主库的从库 从始至终 只要备用主库不故障 会一直提供读服务--><readHost host="c1-2-slave3308" url="192.168.20.12:3308" user="root" password="123456" /></writeHost> </dataHost>  <dataHost name="mysqlcluster-2" maxCon="1000" minCon="10" balance="1"  writeType="0" dbType="mysql"  dbDriver="native" switchType="1">    <heartbeat>select user()</heartbeat>  <writeHost host="c2-1-master3307" url="192.168.20.11:3307" user="root" password="123456"><readHost host="c2-1-slave3309" url="192.168.20.11:3309" user="root" password="123456" /></writeHost> <!--备用主库db3 主库db1故障后 开始提供写操作--><writeHost host="c2-2-master3307" url="192.168.20.12:3307" user="root" password="123456"><!--备用主库的从库 从始至终 只要备用主库不故障 会一直提供读服务--><readHost host="c2-2-slave3309" url="192.168.20.12:3309" user="root" password="123456" /></writeHost> </dataHost>  </mycat:schema>

2)在Server配置文件中定义通过Mycat连接后允许访问的逻辑库

[root@mysql-1 ~]# vim /data/mycat/conf/server.xml
······<user name="root" defaultAccount="true"><!--登录用户的密码--><property name="password">123456</property><!--该用户登录后可以显示那些Schema--><property name="schemas">TESTDB</property></user>
······

2.3.重启Mycat

垂直分表策略规则配置完成后,下面就可以重启Mycat了。

[root@mysql-1 ~]# mycat restart
Stopping Mycat-server...
Mycat-server was not running.
Starting Mycat-server...

2.4.在Mycat命令行中导入数据结构

Mycat已经配置完垂直分表了,当有数据要写入到我们分的表时,对应的数据库实例上要保证这个库、表都存在,否则用户的数据将写入失败,无论是生产环境还是测试环境,使用Mycat分库分库后,需要先在分片节点上将数据库创建出来,然后再通过Mycat将不同的表划分存储到不同的分片节点上。

1)在两个分片节点中分别创建出db_shopping数据库

分片节点是双主双从集群,只需要连接上双主双从的任意一个主库上,创建数据库即可,会同步到所有的从库、主库上。

#分片1的主库操作
[root@mysql-1 sql]# mysql -uroot -p123456 -P3306 -h 192.168.20.11
mysql> create database db_shopping character set utf8mb4;#分片2的主库操作
[root@mysql-1 sql]# mysql -uroot -p123456 -P3307 -h 192.168.20.11
mysql> create database db_shopping character set utf8mb4;

image-20220713222407220

2)登陆Mycat导入商品库的所有表以及数据

数据库需要在每个数据库实例上独立创建出来,数据表我们是通过Mycat进行垂直分表的,因此无需在每个实例上创建,只需要登陆Mycat,在Mycat中执行建表语句和插入数据,这时Mycat就会根据配置的分表策略,将不同的表写入到不同的数据库实例上。

当线上生产库要进行分表时,也是按照这种套路,在Mycat上执行多个表备份的数据,Mycat会自动路由到指定的数据库实例分片上。

[root@mysql-1 sql]# mysql -uroot -p123456 -P8066 -h 192.168.20.11
mysql> use db_shopping;
mysql> source /root/sql/shopping-table.sql
mysql> source /root/sql/shopping-insert.sql

2.5.查看由Mycat分表后每个分片上存储的表

我们一共有2个分片,每个分片都是双主双从的集群模式,我们只需要看每个分片的任意一个主库即可,因为从库会同步主库的数据,接下来我们去查看每个分片上所存储的商品库的表有那些,是否是我们规划的样子。

1)分片:mysqlcluster-1

查看该分片节点中的任意一个主库即可看到全部信息。

分片1:mysqlcluster-1包含了tb_goods_base、tb_goods_brand、tb_goods_cat、tb_goods_desc、tb_goods_item、tb_user、tb_user_address这7张表,垂直分表成功。

image-20220713224532691

2)分片:mysqlcluster-2

查看该分片节点中的任意一个主库即可看到全部信息。

分片2:mysqlcluster-2包含了tb_order_item、tb_order_master、tb_order_pay_log、tb_areas_city、tb_areas_region、tb_areas_provinces这6张表,垂直分表成功。

image-20220713224627802

2.6.Mycat垂直分表后可能遇到的问题

程序连接数据库,都是直接配置Mycat的地址,Mycat中的数据库、表都是逻辑性的,对于程序而言、开发同事而言,他们并不知道Mycat后端对应了那些数据库实例,并且当Mycat进行垂直分库、分表后,表与表之间可能都不在一个数据库实例上。

这时如果我们有多表联查的操作,可能联查的表与表并没有分在同一个数据库实例里,此时就会报错了,提示Mycat路由找不到对应的表,如下图所示:

image-20220713230543035

mysql> select ua.user_id, ua.contact, p.province, c.city, r.area , ua.address from tb_user_address ua ,tb_areas_city c , tb_areas_provinces p ,tb_areas_region r where ua.province_id = p.provinceid and ua.city_id = c.cityid and ua.town_id = r.areaid ;

tb_user_address、tb_areas_city这几张表都是在数据库中存在的,但是依旧报错说找不到该表,回想一下,在我们分库分表时,并没有将这两张表放在一个分片中,此时Mycat就不知道这两张表究竟位于哪一个分片中,因此就会报错找不到这张表。

image-20220713225756317

解决办法就是将要进行联查的表在Mycat分表时,设置成全局表,全局表会在指定的分片节点上创建,可以指定多个分片节点,并数据也是一样的,配置如下:

除了tb_user_address这张表以外,联查的其他表都在一个分片里,因此我们只对tb_user_address这张表设置全局表即可。

            <table name="tb_user_address" dataNode="dn1,dn2" type="global"/>

虽然指定了全局表,即使重启Mycat也不会生效,因为涉及到修改数据分布了,就需要将数据库实例上的库全部删除,然后重新备份还原,非常麻烦,因此建议一开始分库分表时,就将有联查动作的表划分到一个分片节点中,避免出错。

配置全局表后,重新删库导入表之后,在每个分片节点上都会存在全局表,全局表很鸡肋,后期设置需要重新刷Mycat配置,很麻烦,不建议使用,前期尽可能规划好。

image-20220713231748047

经过一系列删库还原,生效全局表后,联查成功。

image-20220713231409965

2.7.垂直分表完成

此时垂直分表已经完成了,说一些实战性的经验。

db_shopping库的部分表分在了分片节点1上,部分表分在分片节点2上,以后有新表创建时,如果没有在Mycat中为新表单独进行配置,默认会被分片到逻辑库关联的分片节点上。

如果对于新表就要求说存储在分片节点2上,那么在创建这张新表时,就在Mycat上配置好,然后重启Mycat,最后在Mycat上创建这张新表,字段路由到分片节点2上。

一定要最初就规划好每个分片锁存储的表,尽可能不使用全局表。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/718610.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

javaWebssh水利综合信息管理系统myeclipse开发mysql数据库MVC模式java编程计算机网页设计

一、源码特点 java ssh水利综合信息管理系统是一套完善的web设计系统&#xff08;系统采用ssh框架进行设计开发&#xff09;&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为TOMCA…

MATLAB 实现贝叶斯决策

1. 原理 后验概率&#xff1a; 1.最小错误率决策&#xff08;最大后验概率决策&#xff09;&#xff1a; 2.最小风险决策&#xff1a; 3.正态分布下的贝叶斯决策 2. 过程 2.1 训练集数据可视化 导入两类训练集数据&#xff0c;并绘制其数据分布&#xff0c;如下&#xff1a;…

云时代【5】—— LXC 与 容器

云时代【5】—— LXC 与 容器 三、LXC&#xff08;一&#xff09;基本介绍&#xff08;二&#xff09;相关 Linux 指令实战&#xff1a;使用 LXC 操作容器 四、Docker&#xff08;一&#xff09;删除、安装、配置&#xff08;二&#xff09;镜像仓库1. 分类2. 相关指令&#xf…

JavaSE-09(Java IO精华总结)

Java IO 简单做个总结&#xff1a; 1 .InputStream/OutputStream 字节流的抽象类。2 .Reader/Writer 字符流的抽象类。3 .FileInputStream/FileOutputStream 节点流&#xff1a;以字节为单位直接操作“文件”。4 .ByteArrayInputStream/ByteArrayOutputStream 节点流&#xff…

Running job: job_1709516801756_0003

** yarn运行卡在Running job: job_1709516801756_0003问题解决&#xff1a; ** 在运行wordcount时出现错误&#xff0c;一直卡住 运行命令&#xff1a;hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples-3.1.3.jar wordcount /input /output 出现错误&#xff1a…

经典思路!人参叶际微生物如何发8分文章?

中国中医科学院中药研究所在《Environmental Microbiome》期刊上(IF7.9)发表了关于叶际真菌微生态网络的文章&#xff0c;该研究通过对ITS测序结果和环境因子测定结果以及皂苷含量测定结果进行生信分析&#xff0c;提出了维持微生态网络的稳定性策略和影响皂苷含量的因素。 期刊…

H12-821_113

113.如图所示是路由器现ATE输出的部分信息&#xff0c;以下关于这部分信息的描述&#xff0c;错误的是哪一项&#xff1f; A.display pim rp-info命令用来查看组播组对应的RP信息 B.RP地址是2.2.2.2 C.组地址是225.0.0.0 D.RP的优先级是0 答案&#xff1a;C 注释&#xff1a; …

HCIA-Datacom题库(自己整理分类的)_29_PPP协议判断【6道题】

1.数据链路层采用PPP封装链路两端的IP地址可以不在同一个网段。√ 2.PPP链路两端不在同一网段不能通信。 3.参考以下拓扑及配置&#xff0c;路由器R1与R2通过Serial低速线缆连接&#xff0c;且数据链路层封装使用PPP。当R1和R2的Holdtime不一致时&#xff0c;PPP协商失败&…

爬虫实战——麻省理工学院新闻

文章目录 发现宝藏一、 目标二、 浅析三、获取所有模块四、请求处理模块、版面、文章1. 分析切换页面的参数传递2. 获取共有多少页标签并遍历版面3.解析版面并保存版面信息4. 解析文章列表和文章5. 清洗文章6. 保存文章图片 五、完整代码六、效果展示 发现宝藏 前些天发现了一…

MySQL面试题-日志(答案版)

日志 1、为什么需要 undo log&#xff1f; &#xff08;1&#xff09;实现事务回滚&#xff0c;保障事务的原子性。 事务处理过程中&#xff0c;如果出现了错误或者用户执 行了 ROLLBACK 语句&#xff0c;MySQL 可以利用 undo log 中的历史数据将数据恢复到事务开始之前的状态…

ssh无法直接登入Linux超级用户root(23/3/3更新)

说明&#xff1a;不允许ssh用超级用户的身份登入是为了安全性&#xff0c;如果只是学习使用对安全性没啥要求可以按以下操作解除限制 以普通用户登录到服务器后&#xff0c;执行以下命令以编辑 SSH 服务器配置文件 /etc/ssh/sshd_config sudo nano /etc/ssh/sshd_config 此时会…

【C++练级之路】【Lv.10】【STL】priority_queue类和反向迭代器的模拟实现

快乐的流畅&#xff1a;个人主页 个人专栏&#xff1a;《C语言》《数据结构世界》《进击的C》 远方有一堆篝火&#xff0c;在为久候之人燃烧&#xff01; 文章目录 一、仿函数1.1 仿函数的介绍1.2 仿函数的优势 二、priority_queue2.1 push2.2 pop2.3 top2.4 size2.5 empty 三、…

【3D Slicer】心脏CT图像分割操作保姆级教程 Cardiac CT image segmentation

心脏CT图像分割操作流程指南 1 安装3D Slicer软件2 打开文件2.1 从File->Add Data->Choose File2.2 直接拖入 3 进行分割操作4 切片填充 Fill between slices5 第二个例子6 数据保存7 打开保存后的文件 1 安装3D Slicer软件 方式二选一 1.官网&#xff1a;3D Slicer 2.百…

无字母数字rce总结(自增、取反、异或、或、临时文件上传)

目录 自增 取反 异或 或 临时文件上传 自增 自 PHP 8.3.0 起&#xff0c;此功能已软弃用 在 PHP 中&#xff0c;可以递增非数字字符串。该字符串必须是字母数字 ASCII 字符串。当到达字母 Z 且递增到下个字母时&#xff0c;将进位到左侧值。例如&#xff0c;$a Z; $a;将…

Java中的Object类详解

Java中的Object类详解 1. equals(Object obj)2. hashCode()3. toString()4.getClass()5.notify() 和 notifyAll()6. wait() 和 wait(long timeout)7. clone()8.finalize() Java中的 Object 类是所有类的父类&#xff0c;可以被所有Java类继承并使用。下面先看下源码&#xff1a…

google最新大语言模型gemma本地化部署

Gemma是google推出的新一代大语言模型&#xff0c;构建目标是本地化、开源、高性能。 与同类大语言模型对比&#xff0c;它不仅对硬件的依赖更小&#xff0c;性能却更高。关键是完全开源&#xff0c;使得对模型在具有行业特性的场景中&#xff0c;有了高度定制的能力。 Gemma模…

面试数据库篇(mysql)- 12分库分表

拆分策略 垂直分库 垂直分库:以表为依据,根据业务将不同表拆分到不同库中。 特点: 按业务对数据分级管理、维护、监控、扩展在高并发下,提高磁盘IO和数据量连接数垂直分表:以字段为依据,根据字段属性将不同字段拆分到不同表中。 特点: 1,冷热数据分离 2,减少IO过渡争…

【Micropython基础】TCP客户端与服务器

文章目录 前言一、连接Wifi1.1 创建STA接口1.2 激活wifi接口1.3 连接WIFI1.4 判断WIFI是否连接1.5 连接WIFI总体代码 二、创建TCP 客户端2.1 创建套接字2.2 设置TCP服务器的ip地址和端口2.3 连接TCP服务器2.3 发送数据2.4 接收数据2.5 断开连接2.6 示例代码 三、TCP服务器的创建…

批量二维码的教程和优势:拓宽应用领域,提升效率与创新

随着二维码技术的不断发展&#xff0c;批量二维码在多个领域展现出了显著的优势&#xff0c;为商业和行业带来了更多便捷和创新。以下是批量二维码的一些显著优势&#xff1a; 1. 高效快速生成&#xff1a; 批量二维码一次性生成多个二维码&#xff0c;相较于逐个生成的方式&…

Linux之进程信号

目录 一、概念引入 1、生活中的信号 2、Linux中的信号 二、信号处理常见方式 三、信号的产生 1、键盘产生信号 2、系统调用接口产生信号 3、软件条件产生信号 4、硬件异常产生信号 四、信号的保存 相关概念 信号保存——三个数据结构 信号集——sigset_t 信号集操…