此文已由作者张镐薪授权网易云社区发布。

欢迎访问网易云社区,了解更多网易技术产品运营经验。

SQL与NoSQL

目前,对于互联网海量数据的存储以及处理,按使用场景,分为OLTP(联机事务处理,比如即时交易,强调快速响应与处理)与OLAP(联机分析处理,比如BI,强调多维数据分析)。对于这些数据的存储,主要有两种解决方案,即基于SQL的关系型数据库,和NoSQL的非关系型数据库。
非关系型数据库在某些特定场景下有奇效,比如键值存储(redis,ROMA,Memcached)数据库应用在排行更新,会话保存,面向文档的数据库(mongoDB、couchDB)应用在日志记录,面向列的数据库(Cassandra、HBase)在博客中的应用。关系型数据库最大的问题在于速度与可扩展性上,而这些NoSQL数据库一般部署简单,支持扩展,而且速度极高。
但是,NoSQL目前还是只能做为关系型数据库在某些特定应用场景的补充,不能完全替代严谨规范的关系型数据库。

关系型数据库瓶颈

目前商用的数据库以及开源的数据库一般都不支持大规模自动扩展,单库上面存在着性能瓶颈。一般的,MySQL数据库单表超过1000W~2000W条记录时,性能就会有比较明显的下降。为了提升性能以及可以存储数据的量,我们需要分库分表。

分库分表

举个例子,假设我们原来的应用是为了客户完成下单,快递员接受并更新运单状态,客户可以随时查看运单状态的任务。一开始我们的数据库层架构设计(忽略其他部分,比如缓存、CDN等)可能是这样:但是很快地,我们发现,把所有的数据放在同一个库里面,随着业务的增长,数据量太大,响应时间变得越来越慢。业务需求已经承受不住了。我们首先做了垂直分片,按照业务模块,将数据库拆分成了快递员库,运单库和客户库来管理。再之后,我们发现运单单表有效数据量量级已经超过了2000W条,为了不影响TPS与QPS。我们需要把运单表做进一步的水平拆分。但是,水平分片后,像分片表关联这种操作,比如order by,group by还有join就不能通过数据库自己本身去完成了,因为每个分片库的数据都不是完整的。而且,跨分片事务(即分布式事务,分布式XA),比较难以实现。
拆分规则有很多种,需要根据具体业务决定。比如如果我们整体业务TPS小于单库可承受TPS,只是我们每天要产生2000W记录,而且这些记录要保存一周。我们可以按照日期分片,比如周一的数据保存到库1,之后以此类推。但是这样做的缺点很明显,同一天的写压力全都打到一个分片上,其他分片处于写空闲状态。即使整体业务TPS小于单库可承受TPS,这样的架构也不利于以后业务增长进行扩展。
我们还可以按照运单号对某一数字(分片个数)取模,让这些运单平均分布到每个后台分片库上。这样,我们可以保证同一时间所有的分片都是工作状态,没有资源浪费。但是,未来如果分片不够用了,扩容难还是个问题。
还有很多其它分片的规则(比如wang-jeekins哈希取模范围,扩容哈希范围,id字段范围等),在之后的MyCat中间件具体使用篇我会详细介绍,并给出一些原创的可行的分片方案。

谁来分库分表

实现这种分库分表可以有多种思路,看上面的架构图,我们可以:

  • 在数据库层做手脚

  • 在应用层做手脚

  • 在应用层与数据库层添加数据库路由中间件(相当于代理)

    首先,在数据库层做手脚,需要数据库产品为开源的,而且修改MySQL和MariaDB之类的数据库需要相当专业的团队以及较高的成本,所以,一般项目初期不会考虑这种方式。

然后是在应用层做手脚,像Ibatis sharding, shark,TDDL等。他们实现分库分表的思路是很相似的:一般这些框架很轻量级,在应用端放一个jar。他们本身不一定都实现了动态配置,但是他们都可以和Disconf之类的动态配置中心结合,实现动态数据源与动态分片规则。首先,应用会访问附近的配置中心,配置中心会告诉这个应用应该去访问哪个数据库以及分片规则是什么。之后,应用会自己去访问数据库,并作分片和合并结果。
这样做的好处是:

  • 实现分片和结果聚合的压力分摊给了每一个应用

  • 根据应用业务场景开发对应的功能

  • 轻量级,代码少

  • 能最大发挥后台数据库的能力
    但是同时,也有它的局限性:

  • 依赖于额外的配置中心实现动态配置

  • 对应用代码有侵入性

  • 使应用处理变重

  • 应用出问题难以定位是哪里出了问题

  • 将业务开发与后台数据库分库分表管理耦合,难于开发管理

最后,是代理的方式:实现思路大概是,实现mysql协议栈,将自己伪装成一个mysql数据库,自己后台管理所有mysql实例。应用无感知,只当后台只是一个mysql实例。这个代理mysql实例,实现分库分表,结果合并等功能。
这种代理实现的好处在于:

  • 对应用没有侵入性

  • 压力打在中间件上

  • 统一管理后台数据库,能及时定位问题
    但是,他也有自己的缺陷,首先就是压力打在中间件上的话,可能不能发挥后台数据库最大的能力。由此,中间件需要做负载均衡集群,这要求中间件必须是无状态的。但是,这无疑增加了架构的复杂程度。目前,淘宝的高吞吐量业务还是在用TDDL类似的产品也是这个原因。
    这两种实现方式还都有共同的难以解决的问题,比如分布式事务这个问题,目前也没有非常完美的方案。还有,他们对于SQL都有限制(比如有的不支持DDL,大部分都不推荐使用大事务等)
    整体说来,项目初期使用代理这种实现方式还是利大于弊的,网上有很多开源产品,他们基本和淘宝的Amoeba和Cobar一脉相承。实际应用场景众多,较为可靠。本文即将介绍的MyCat也不例外。下一篇我们将更详细地介绍MyCat的背景 :-D

免费体验云安全(易盾)内容安全、验证码等服务

更多网易技术、产品、运营经验分享请点击

相关文章:
【推荐】 知物由学 | AI时代,那些黑客正在如何打磨他们的“利器”?(一)
【推荐】 Hive中文注释乱码解决方案
【推荐】 分布式存储系统可靠性系列三:设计模式

MyCat - 背景篇(1)的更多相关文章

  1. 数据库路由中间件MyCat - 背景篇(2)

    此文已由作者张镐薪授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. MyCat的前世今生 如前文所说,Amoeba.Cobar.MyCat等属于同宗一脉.若Amoeba能继续下 ...

  2. 数据库路由中间件MyCat - 使用篇(1)

    此文已由作者张镐薪授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 基本概念 直接介绍概念太枯燥了,还是拿个和背景篇相似的例子介绍 业务场景:客户完成下单,快递员接受并更新运单 ...

  3. MyCat - 使用篇

    Mycat水平拆分之十种分片规则: http://www.cnblogs.com/756623607-zhang/p/6656022.html 数据库路由中间件MyCat - 使用篇(5) 配置MyC ...

  4. 【C/C++】C语言嵌入式编程修炼·背景篇·软件架构篇·内存操作篇

    C 语言嵌入式系统编程修炼之一:背景篇 不同于一般形式的软件编程,嵌入式系统编程建立在特定的硬件平台上,势必要求其编程语言具备较强的硬件直接操作能力.无疑,汇编语言具备这样的特质.但是,归因于汇编语言 ...

  5. 数据库路由中间件MyCat - 源代码篇(15)

    此文已由作者张镐薪授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. public static void handle(String stmt, ServerConnectio ...

  6. 数据库路由中间件MyCat - 源代码篇(13)

    此文已由作者张镐薪授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 4.配置模块 4.2 schema.xml 接上一篇,接下来载入每个schema的配置(也就是每个MyCat ...

  7. 数据库路由中间件MyCat - 源代码篇(1)

    此文已由作者张镐薪授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 进入了源代码篇,我们先从整体入手,之后拿一个简单流程前端连接建立与认证作为例子,理清代码思路和设计模式.然后 ...

  8. 数据库路由中间件MyCat - 使用篇(4)

    此文已由作者张镐薪授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 配置MyCat 3. 配置conf/rule.xml 1.5GA版本中的规则配置比较笨,2.0中优化了一些, ...

  9. 数据库路由中间件MyCat - 使用篇(3)下篇

    此文已由作者张镐薪授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 2. 配置conf/server.xml server.xml几乎保存了所有mycat需要的系统配置信息.其 ...

随机推荐

  1. 岛屿的个数12 · Number of Islands 12

    [抄题]: [思维问题]: [一句话思路]: [输入量]:空: 正常情况:特大:特小:程序里处理到的特殊情况:异常情况(不合法不合理的输入): [画图]: [一刷]: [二刷]: [三刷]: [四刷] ...

  2. Ugly number丑数2,超级丑数

    [抄题]: [思维问题]: [一句话思路]:Long.valueOf(2)转换为long型再做 [输入量]:空: 正常情况:特大:特小:程序里处理到的特殊情况:异常情况(不合法不合理的输入): [画图 ...

  3. docker搭建nginx

    在Docker下部署Nginx,包括: 部署一个最简单的Nginx,可以通过端口访问默认的网站 设置记录访问和错误日志的路径 以交互模式创建centos容器,如果本地没有镜像,会从仓库获取, 等待即可 ...

  4. Spring框架的事务管理之声明式事务管理的类型

    1. 声明式事务管理又分成两种方式 * 基于AspectJ的XML方式(重点掌握)(具体内容见“https://www.cnblogs.com/wyhluckdog/p/10137712.html”) ...

  5. MVC仓储使用join

    代码: var result = from mpc in this.Context.Set<Domain.S_MENU_PURVIEWCODE>() join menu in this.C ...

  6. .net core webapi 部署windows server 2008 r2 笔记

    WebAPI部署文档 安装dotnet-dev-win-x64.1.0.4 安装DotNetCore.1.1.0-WindowsHosting 安装vc_redist.x64 安装Windows6.1 ...

  7. 复利计算器4.0JUnit

    #因为是用IDEA首次写unit test,所以也是麻烦多多,于是就只写了一个函数的测试.... ##需要测试的代码如下 public class Calculator { // 本金为100万,利率 ...

  8. How to Set Up an Rsync Daemon on Your Linux Server

    Introduction This tutorial will take you through setting up an rsync daemon on your Linux server. Yo ...

  9. Netty 系列目录

    Netty 系列目录 二 Netty 源码分析(4.1.20) 1.1 Netty 源码(一)Netty 组件简介 2.1 Netty 源码(一)服务端启动 2.2 Netty 源码(二)客户端启动 ...

  10. 泛型约束where条件的使用(可以通过类型参数动态反射创建实例)

    定义抽象的人类 using System; using System.Collections.Generic; using System.Linq; using System.Text; using ...