分库分表,读写分离,从理论到实战

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zzti_erlie/article/details/85011216

分库分表,读写分离会带来哪些问题?

前面一篇文章图解分布式系统架构(看推荐阅读)大概讲了一下分库分表,以及读写分离出现的场景,分库分表为了解决高并发和海量数据的问题。

分库后会出现新的问题

  1. 跨库join问题
    如有2个库,订单库,用户库,要查询买了某件商品的所有用户信息
  2. 事务问题
    用户下订单的时候需要扣减商品库存,如果订单数据和商品数据在一个数据库中,我们可以使用事务来保证扣减商品库存和生成订单的操作要么都成功要么都失败,但分库后就无法使用数据库事务了,这时就要用到分布式事务了

分表后也会出现新的问题

  1. join操作
    水平分表后,数据分散在多个表中,如果需要与其他表进行join查询,需要在业务代码或数据库中间件中进行多次join查询,然后将结果合并
  2. count()操作
    业务代码或者数据库中间件对每个表进行count(*)操作,然后将结果相加。或者新建一张表,假如表名为“记录数表”,包含table_name和row_count两个字段,每次插入或删除子表数据成功后,都更新“记录数表”
  3. order by操作
    水平分表后,数据分散到多个字表中,排序操作无法再数据库中完成,只能由业务代码或数据库中间件分别查询每个子表中的数据,然后汇总进行排序

而高并发这个阶段,肯定是需要做读写分离的,啥意思?因为实际上大部分的互联网公司,一些网站,或者是 app,其实都是读多写少。所以针对这个情况,就是写一个主库,但是主库挂多个从库,然后从多个从库来读,那不就可以支撑更高的读并发压力了吗?

那么如何实现 MySQL 的读写分离?
其实很简单,就是基于主从复制架构,简单来说,就搞一个主库,挂多个从库,然后我们就单单只是写主库,然后从库读取bin log进行重放,这样主库和从库数据就一样,只不过并发量比较高时,会有主从同步延时问题

放个图理解一下MySQL主从复制的原理,这块面试经常被问到

在这里插入图片描述

总的来说,MySQL复制有三个步骤

  1. 在主库上把数据更改记录到二进制日志中(Binary Log)中(这些记录被称为二进制日志事件)
  2. 备库将主库上的日志复制到自己的中继日志(Relay Log)中
  3. 备库读取中继日志中的事件,将其重放到备库数据之上

现在理论知识都有了,就剩怎么实现了?本来就是为了实现一个功能,现在好了,单写读写分离,跨库join,分布式事务,排序操作等就够你忙的了。

这时候你就应该想起数据库中间件了,它能帮你进行上述操作,把你从复杂的数据处理中解放出来,专注于开发业务代码。

数据库中间件能帮你做什么?

目前国内用的最多的中间件就是sharding-jdbc,mycat,别的用的很少,不再介绍

而数据库中间件针对数据源管理,目前主要有两种思路

  1. 客户端模式,在每个应用程序模块中配置管理自己需要的一个(或者多个)数据源,直接访问各个数据库,在模块内完成数据的整合,sharding-jdbc的实现方式
  2. 通过中间代理层来统一管理所有的数据源,后端数据库集群对前端应用程序透明,mycat的实现方式

放两张图就能理解区别了
在这里插入图片描述

在这里插入图片描述

一般的建议是小公司用sharding-jdbc,大公司用mycat,因为维护一套mycat集群也需要人力,物力。鉴于篇幅限制,本文就介绍一下mycat的基本使用

以一个最形象的例子,让你明白mycat到底帮你做了什么?
在这里插入图片描述

先介绍一下什么是分片?简单来说,就是通过某种特定的条件,将我们存放在同一个数据库中的数据,分散存放到多个数据库上面,以达到分散单台设备负载的效果

如上图所表示,数据被分到多个分片数据库后,应用如果需要读取数据,就要需要处理多个数据源的数据。如果没有数据库中间件,那么应用将直接面对分片集群,数据源切换、事务处理、数据聚合都需要应用直接处理,原本该是专注于业务的应用,将会花大量的工作来处理分片后的问题,最重要的是每个应用处理将是完全的重复造轮子。

所以有了数据库中间件,应用只需要集中与业务处理,大量的通用的数据聚合,事务,数据源切换都由中间件来处理。

那么数据库中间件是怎么做到的呢?

在这里插入图片描述

绿色的部分为mycat的逻辑节点,蓝色的部分为物理节点(即数据库的部署地址)

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

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

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

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

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

实战Mycat

到官网下一个release包下载即可。为了快速熟悉各种配置,一般直接从git上下载代码,本地用idea打开启动,方便练习一波

mycat的配置其实是蛮简单的,最主要的是熟悉各配置文件的规则。如用户名,密码,如何分库,都是在配置文件中定义的

关于配置文件,conf目录下主要以下三个需要熟悉。
server.xml是Mycat服务器参数调整和用户授权的配置文件
schema.xml是逻辑库定义和表以及分片定义的配置文件
rule.xml是分片规则的配置文件

[1]https://www.cnblogs.com/joylee/p/7513038.html
Mycat-Server的github
[2]https://github.com/MyCATApache/Mycat-Server

猜你喜欢

转载自blog.csdn.net/zzti_erlie/article/details/85011216