24小时新闻关注

owl,落寞,回-找软件极客新闻中心

MyCat 是一个数据库分库分表中心件,运用 MyCat 能够十分方便地完结数据库的分库分表查询,并且削减项目中的事务代码。今日咱们将经过数据库架构开展的演变来介绍 MyCat 的诞生布景,以及 MyCat 在其间扮演的人物,然后使得咱们对 MyCat 的诞生及其效果有深化的了解。

1单数据库架构

一个项目在初期的时分,为了尽或许快地验证商场,其对事务系统的最大要求是快速完结。在这个阶段,代码开发人员为了能快速完结事务系统,一般都是将一切层级(MVC)的事务代码都写在同一个项目中,一切的事务数据都存放在同一个数据库中。此刻,项目的全体架构图如下所示:

单数据库架构

从上图能够看到,咱们在一个项目中集中了注册、登陆、购物三个模块的事务代码,并且这三个事务模块都读取同一个事务数据库。

但跟着项目的不断推动,用户量不断添加,单台运用服务器现已无法接受如此巨大的流量了。此刻常见的做法是把项目进行分布式布置,涣散单台服务器的流量,然后能够暂时缓解用户添加带来的运用服务器压力。此刻的项目架构图如下所示:

分布式布置-单数据库架构

但跟着咱们布置的运用服务器越来越多,后端的单台数据库服务器现已无法接受如此巨大的流量了。为了赶快缓解用户拜访压力,咱们一般是在运用服务器与数据库服务器中心加多一个缓存层,经过缓存能够抵消掉一部分的数据库查询操作。此刻的项目架构图如下所示:

分布式布置-缓存-单数据库架构

可是添加数据库缓存层只能缓解数据库拜访压力,阻拦部分数据库拜访恳求。跟着用户拜访量的进一步添加,数据库拜访的瓶颈仍是会进一步凸显。这个时分,咱们不得不对数据层的架构进行改造。

2主从数据库架构

这个时分常用的处理方案便是将本来单台数据库服务器变成主从形式的数据库服务器,即一台数据库作为主库支撑写入数据,一台数据库作为读库支撑查询数据。此刻项目的架构图如下所示:

主从数据库架构

咱们经过数据库主从同步完结了读写别离,将一切读操作都引导到从库进行,将一切写操作都引导到主库进行。

由于咱们对数据库层进行了改造,规矩一切读数据库操作要拜访从库,一切写数据库操作要拜访主库,那么咱们就必须对本来的代码进行改造。

public User selectUser(){

dataTemplate.selectById(...);

}

public User insertUser(){

dataTemplate.insert(user);

}

上面是改造前的代码,无论是读操作仍是写操作,咱们都运用同一个数据源进行操作。但为了习惯新的数据库架构,咱们必须在代码中手动判别应该恳求哪个数据源。

public User selectUser(){

readTemplate.selectById(...);

}

public User insertUser(){

writeTemplate.insert(user);

}

经过修正后的代码,开发依据本身阅历判别应该挑选哪个数据源进行操作。当是读操作的时分,咱们挑选 readTemplate。当是写操作的时分,咱们挑选 writeTemplate。

但作为一个程序员,咱们模模糊糊觉得辨认应该用哪个数据源这个判别不应该人工判别,而应该主动让代码去判别。究竟这个判别的形式很简单 —— 假如是 select 那么就用读的数据源,假如是其他那么就用写的数据源。

其实这个便是 MyCat 的用处之一,即作为一个数据库中心件去处理数据源判别问题。假如咱们运用 MyCat 作为数据库中心件,那么咱们不需求关怀我应该运用哪个数据源。MyCat 帮咱们屏蔽了不同数据源的差异,关于咱们来说就只要一个数据源,这个数据源能处理写操作,也能处理读操作。上面查询和刺进的代码就能够变成下面这样:

public User selectUser(){

dataTemplate.selectById(...);

}

public User insertUser(){

dataTemplate.insert(user);

}

完结了主从数据库架构,再运用 MyCat,你发现咱们并不需求去修正太多的代码,只需求将数据源改为 MyCat 地址即可。MyCat 主动把咱们一切的句子发送给后端的 MySQL 服务器。

当咱们运用了主从数据库架构之后,咱们会发现咱们能支撑更多的用户拜访和恳求了。但跟着事务的进一步开展,其实能够发现会存在一些问题:

  • 当咱们修正了注册模块的时分,咱们需求整个项目都发布一次,这样会影响到登录、购物模块的正常运用。
  • 即便每次改动的代码即便很小,咱们仍是需求发布整个项目包,这使得每次发布的代码包十分巨大。
  • 跟着事务量的不断添加,咱们会发现即便完结了主从的读写别离,数据库的压力也是十分大,好像快要接受不了了。

上面说的这些问题仅仅实战中遇到的一部分问题,事实上遇到的问题只会更多不会更少,并且跟着事务的不断开展会更加凸显。

3笔直切分数据库架构

此刻为了各个事务模块不相互影响,咱们把运用层进行笔直拆分,即把注册模块、登陆模块、购物模块都独自作为一个运用系统,别离读写独立的数据库服务器。此刻,咱们的系统架构图如下图所示:

笔直切分数据库架构

完结了笔直拆分之后,咱们能够成功处理上面提到的三个问题:事务模块相互影响问题、单数据库压力问题。

可是跟着事务的进一步扩展,咱们又添加了许多事务模块:客服模块、钱包模块、个人中心模块、收藏夹模块、订单模块等。依照咱们之前所规划的数据库架构,咱们会存在许多个数据源,这些数据源涣散在各个项目中:

  • 用户数据库 192.168.0.1
  • 产品数据库 192.168.0.2
  • 短信数据库 192.168.0.3
  • 客服数据库 192.168.0.4
  • 钱包数据库 192.168.0.5
  • ……

关于一个项目管理者来说,这么多的数据源涣散在不同项目中,怎样共同管理是一个问题。许多时分咱们都很难记住这个项目衔接的是哪个数据库,那个项目衔接的是哪个数据库。

但假如你运用了 MyCat 作为数据库中心件的话,MyCat 就能够帮你处理这个问题。关于一切项目来说,它们只需求共同衔接 MyCat 对外供给的一个地址,而 MyCat 则帮这些项目联络一切后端的 MySQL 数据库。关于前端的项目俩说,它们只知道 MyCat 这个数据库中心件,而不需求去理睬我究竟衔接哪个数据库,MyCat 经过本身装备能够完结这个使命。

哪个表的冗余代码,然后让开发人员更专心于事务逻辑的开发。

4水平切分数据库架构

当数据库架构阅历了主从架构、笔直拆分架构之后,应对一般的事务读写是没有什么问题了。但关于一些中心的事务数据,或许仍是会有瓶颈问题,例如用户模块。

关于一些用户量高达一个亿的用户系统来说,即便经过主从架构、笔直拆分架构的优化,但其用户数据库的单个表里需求存储的数据仍是高达一个亿的巨细。假如咱们把一切的数据都存放在一个表里,无论是注册时的刺进数据,或者是登陆时的查询数据,势必会变得很慢。

这时分,咱们就不得不对这些高数据量的中心事务表进行水平拆分,行将海量的数据记载拆分到多张表中保存。例如咱们一开始或许只要一张 User 表,咱们将 User 表依照用户 ID 对 1000 取余进行拆分,那么咱们就会有 1000 张表,别离是 User_000 至 User_999。此刻,项目的架构图如下所示:

水平切分数据库架构

当咱们在代码中查询用户数据时,咱们先依据用户 ID 取余判别其应该操作的表,之后再查询对应的表。例如 UserId 为 90749738 的用户就应该查询 User_38 表,UserId 为 74847383 的用户就应该查询 User_83 表。

经过水平拆分,咱们成功处理了海量数据中心事务表的读写瓶颈问题。但此刻在代码层面上有一个问题呈现了,那便是咱们需求在查询数据库之前,依据 UserId 去判别应该查询哪个表,这个操作关于一切事务模块来说都是高度共同的,应该抽离成一个共用的项目。

与判别应该运用读数据源仍是写数据源共同,咱们都觉得这样机械的使命不应该丢给程序员做,应该让机器去做。这其实便是 MyCat 能够帮咱们做的工作:MyCat 经过装备一系列的分库分表规矩,让 MyCat 帮咱们主动判别应该查询哪一个分表。经过运用 MyCat 数据库中心件,咱们能够省去在代码层判别查询哪个表的冗余代码,然后让开发人员更专心于事务逻辑的开发。

5总结

从单一的数据库架构,到主从读写别离的数据库架构,再到笔直拆分、水平拆分的数据库架构。咱们能够看到 MyCat 帮咱们处理了读写数据源判别、冗杂数据源地址、分表判别这三个机械的重复性的问题

但 MyCat 开展至今,其功用现已远远超越上面说的这三个。例如 MyCat 支撑主从切换功用,当数据库主库发作网络问题或其他毛病时,MyCat 能够主动切换到从库,然后确保正常读写功用的进行。MyCat 的定位是一个数据库中心件,凡是一切处于运用层和数据层之间的工作,MyCat 都能够做。

在此我向咱们引荐一个架构沟通群。沟通群号:529722406 里边会共享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码剖析,高并发、高功能、分布式、微服务架构的原理,JVM功能优化、分布式架构等这些成为架构师必备的常识系统。还能收取免费的学习资源,现在获益良多

相关文章