如何构建日均千万PV Web站点 (三) Sharding

      
 其实国内许多大型网站为了应对日益复杂的业务场景,通过使用分而治之的手段将整个网站业务分成不同的产品线,比如说国内那些大型购物交易网站它们都将自己的网站首页、商铺、订单、买家、卖家等拆分不同的产品线,分归不同的业务团队负责;

    集体到技术,也会根据产品线划分,将一个网站拆分成许多不同的应用,每个应用用独立部署维护。应用之间可以通过一个超链接建立关系(在首页上的导航链接每个都指向不同的应用地址),也可以通过消息队列进行数据分发,当然最多的还是通过访问同一个数据库存储系统来构成一个关联的完整系统
此时的架构如下图所示:

  分布式服务,随着业务拆分越来越小,存储系统越来越庞大,应用系统的整体复杂度呈指数级增加,部署维护越来越困难,由于所有应用要和所有数据库系统连接,在数万台服务器规模的网站中,这些连接的数目是服务器规模的平方,导致数据库连接资源不足,拒绝服务。

  既然每一个应用系统都需要执行许多相同的业务操作,比如用户管理、商品管理等,那么可以将这些共用的业务提取出来,独立部署。由这些可复用的业务连接数据库,提供共用服务,而应用系统只需要管理用户界面,通过分布式服务调用共用业务服务完成具体业务操作

数据库如何sharding?

数据的切分(Sharding)根据其切分规则的类型,可以分为两种切分模式。一种是按照
不同的表(或者 Schema)来切分到不同的数据库(主机)之上,这种切可以称之为数据的
垂直(纵向)切分;另外一种则是根据表中的数据的逻辑关系,将同一个表中的数据按照某 种条件拆分到多台数据库(主机)上面,这种切分称之为数据的水平(横向)切分。
垂直切分的最大特点就是规则简单,实施也更为方便,尤其适合各业务之间的耦合度非 常低,相互影响很小,业务逻辑非常清晰的系统。在这种系统中,可以很容易做到将不同业
务模块所使用的表分拆到不同的数据库中。根据不同的表来进行拆分,对应用程序的影响也 更小,拆分规则也会比较简单清晰。
水平切分于垂直切分相比,相对来说稍微复杂一些。因为要将同一个表中的不同数据拆 分到不同的数据库中,对于应用程序来说,拆分规则本身就较根据表名来拆分更为复杂, 后
期的数据维护也会更为复杂一些。 当我们某个(或者某些)表的数据量和访问量特别的大,通过垂直切分将其放在独立的
设备上后仍然无法满足性能要求,这时候我们就必须将垂直切分和水平切分相结合,先垂直 切分,然后再水平切分,才能解决这种超大型表的性能问题。
下面我们就针对垂直、水平以及组合切分这三种数据切分方式的架构实现及切分后数据 的整合进行相应的分析。 14.2 数据的垂直切分
我们先来看一下,数据的垂直切分到底是如何一个切分法的。数据的垂直切分,也可以 称之为纵向切分。将数据库想象成为由很多个一大块一大块的“数据块”(表)组成,我们
垂直的将这些 “数据块”切开,然后将他们分散到多台数据库主机上面。这样的切分方法就 是一个垂直(纵向)的数据切分。
一个架构设计较好的应用系统,其总体功能肯定是由很多个功能模块所组成的,而每一 个功能模块所需要的数据对应到数据库中就是一个或者多个表。而在架构设计中,各个功能
模块相互之间的交互点越统一越少,系统的耦合度就越低,系统各个模块的维护性以及扩展 性也就越好。这样的系统,实现数据的垂直切分也就越容易。
当我们的功能模块越清晰,耦合度越低,数据垂直切分的规则定义也就越容易。完全可 以根据功能模块来进行数据的切分,不同功能模块的数据存放于不同的数据库主机中,可以
很容易就避免掉跨数据库的 Join 存在,同时系统架构也非常的清晰.

当然,很难有系统能够做到所有功能模块所使用的表完全独立,完全不需要访问对方的
表或者需要两个模块的表进行 Join 操作。这种情况下,我们就必须根据实际的应用场景进 行评估权衡。决定是迁就应用程序将需要 Join
的表的相关某快都存放在同一个数据库中, 还是让应用程序做更多的事情,也就是程序完全通过模块接口取得不同数据库中的数据, 然 后在程序中完成 Join 操作。
一般来说,如果是一个负载相对不是很大的系统,而且表关联又非常的频繁,那可能数 据库让步,将几个相关模块合并在一起减少应用程序的工作的方案可以减少较多的工作量,
是一个可行的方案。 当然,通过数据库的让步,让多个模块集中共用数据源,实际上也是简介的默许了各模
块架构耦合度增大的发展,可能会让以后的架构越来越恶化。尤其是当发展到一定阶段之后 ,
发现数据库实在无法承担这些表所带来的压力,不得不面临再次切分的时候,所带来的架构 改造成本可能会远远大于最初的时候。
所以,在数据库进行垂直切分的时候,如何切分,切分到什么样的程度,是一个比较考 验人的难题。只能在实际的应用场景中通过平衡各方面的成本和收益,才能分析出一个真正
适合自己的拆分方案。 比如在本书所使用示例系统的 example 数据库,我们简单的分析一下,然后再设计一 个简单的切分规则,进行一次垂直垂直拆分。
系统功能可以基本分为四个功能模块:用户,群组消息,相册以及事件,


分别对应为如 下这些表:

1. 用户模块表:user,user_profile,user_group,user_photo_album

2. 群组讨论表:groups,group_message,group_message_content,top_message

3. 相册相关表:photo,photo_album,photo_album_relation,photo_comment

4. 事件信息表:event
初略一看,没有哪一个模块可以脱离其他模块独立存在,模块与模块之间都存在着关系 , 莫非无法切分?
当然不是,我们再稍微深入分析一下,可以发现,虽然各个模块所使用的表之间都有关 联,但是关联关系还算比较清晰,也比较简单。
群组讨论模块和用户模块之间主要存在通过用户或者是群组关系来进行关联。一般 关联的时候都会是通过用户的 id 或者 nick_name 以及 group 的 id
来进行关 联,通过模块之间的接口实现不会带来太多麻烦; 相册模块仅仅与用户模块存在通过用户的关联。这两个模块之间的关联基本就有通 过用户 id
关联的内容,简单清晰,接口明确; 事件模块与各个模块可能都有关联,但是都只关注其各个模块中对象的 ID 信 息 , 同样可以做到很容易分拆。
所以,我们第一步可以将数据库按照功能模块相关的表进行一次垂直拆分,每个模块所 涉及的表单独到一个数据库中,模块与模块之间的表关联都在应用系统端通过藉口来处理。
如下图所示: 通过这样的垂直切分之后,之前只能通过一个数据库来提供的服务,就被分拆成四个数 据库来提供服务,服务能力自然是增加几倍了。 垂直切分的优点
数据库的拆分简单明了,拆分规则明确; 应用程序模块清晰明确,整合容易; 数据维护方便易行,容易定位; 垂直切分的缺点
部分表关联无法在数据库级别完成,需要在程序中完成; 对于访问极其频繁且数据量超大的表仍然存在性能平静,不一定能满足要求; 事务处理相对更为复杂;
切分达到一定程度之后,扩展性会遇到限制; 过读切分可能会带来系统过渡复杂而难以维护。
针对于垂直切分可能遇到数据切分及事务问题,在数据库层面实在是很难找到一个较好 的处理方案。实际应用案例中,数据库的垂直切分大多是与应用系统的模块相对应,同一个
模块的数据源存放于同一个数据库中,可以解决模块内部的数据关联问题。而模块与模块之间,则通过应用程序以服务接口方式来相互提供所需要的数据。虽然这样做在数据库的总体
操作次数方面确实会有所增加,但是在系统整体扩展性以及架构模块化方面,都是有益的。
可能在某些操作的单次响应时间会稍有增加,但是系统的整体性能很可能反而会有一定的提 升。而扩展瓶颈问题,就只能依靠下一节将要介绍的数据水平切分架构来解决了。

14.3 数据的水平切分
上面一节分析介绍了数据的垂直切分,这一节再分析一下数据的水平切分。数据的垂直 切分基本上可以简单的理解为按照表按照模块来切分数据,而水平切分就不再是按照表或者
是功能模块来切分了。一般来说,简单的水平切分主要是将某个访问极其平凡的表再按照某 个字段的某种规则来分散到多个表之中,每个表中包含一部分数据。
简单来说,我们可以将数据的水平切分理解为是按照数据行的切分,就是将表中的某些
行切分到一个数据库,而另外的某些行又切分到其他的数据库中。当然,为了能够比较容易的判定各行数据被切分到哪个数据库中了,切分总是都需要按照某种特定的规则来进行的。
如根据某个数字类型字段基于特定数目取模,某个时间类型字段的范围,或者是某个字符类 型字段的 hash
值。如果整个系统中大部分核心表都可以通过某个字段来进行关联,那这个 字段自然是一个进行水平分区的上上之选了,当然,非常特殊无法使用就只能另选其他了。
一般来说,像现在互联网非常火爆的 Web2.0 类型的网站,基本上大部分数据都能够通 过会员用户信息关联上,可能很多核心表都非常适合通过会员 ID
来进行数据的水平切分。 而像论坛社区讨论系统,就更容易切分了,非常容易按照论坛编号来进行数据的水平切分。 切分之后基本上不会出现各个库之间的交互。
如我们的示例系统,所有数据都是和用户关联的,那么我们就可以根据用户来进行水平 拆分,将不同用户的数据切分到不同的数据库中。当然,唯一有点区别的是用户模块中的
groups 表和用户没有直接关系,所以 groups 不能根据用户来进行水平拆分。对于这种特
殊情况下的表,我们完全可以独立出来,单独放在一个独立的数据库中。其实这个做法可以 说是利用了前面一节所介绍的
“数据的垂直切分”方法,我将在下一节中更为详细的介绍这 种垂直切分与水平切分同时使用的联合切分方法。 所以,对于我们的示例数据库来说,大部分的表都可以根据用户
ID 来进行水平的切分 。 不同用户相关的数据进行切分之后存放在不同的数据库中。如将所有用户 ID 通过 2 取模 然后分别存放于两个不同的数据库中。每个和用户
ID 关联上的表都可以这样切分。这样, 基本上每个用户相关的数据,都在同一个数据库中,即使是需要关联,也可以非常简单的关 联上。
我们可以通过下图来更为直观的展示水平切分相关信息: 水平切分的优点 表关联基本能够在数据库端全部完成; 不会存在某些超大型数据量和高负载的表遇到瓶颈的问题;
应用程序端整体架构改动相对较少; 事务处理相对简单; 只要切分规则能够定义好,基本上较难遇到扩展性限制; 水平切分的缺点
切分规则相对更为复杂,很难抽象出一个能够满足整个数据库的切分规则; 后期数据的维护难度有所增加,人为手工定位数据更困难;
应用系统各模块耦合度较高,可能会对后面数据的迁移拆分造成一定的困难。

14.4 垂直与水平联合切分的使用
上面两节内容中,我们分别,了解了“垂直”和“水平”这两种切分方式的实现以及切 分之后的架构信息,同时也分析了两种架构各自的优缺点。但是在实际的应用场景中,除了
那些负载并不是太大,业务逻辑也相对较简单的系统可以通过上面两种切分方法之一来解决
扩展性问题之外,恐怕其他大部分业务逻辑稍微复杂一点,系统负载大一些的系统,都无法
通过上面任何一种数据的切分方法来实现较好的扩展性,而需要将上述两种切分方法结合使 用,不同的场景使用不同的切分方法。
在这一节中,我将结合垂直切分和水平切分各自的优缺点,进一步完善我们的整体架构 , 让系统的扩展性进一步提高。
一般来说,我们数据库中的所有表很难通过某一个(或少数几个)字段全部关联起来, 所以很难简单的仅仅通过数据的水平切分来解决所有问题。而垂直切分也只能解决部分问
题,对于那些负载非常高的系统,即使仅仅只是单个表都无法通过单台数据库主机来承担其
负载。我们必须结合“垂直”和“水平”两种切分方式同时使用,充分利用两者的优点,避 开其缺点。
每一个应用系统的负载都是一步一步增长上来的,在开始遇到性能瓶颈的时候,大多数 架构师和 DBA
都会选择先进行数据的垂直拆分,因为这样的成本最先,最符合这个时期所追 求的最大投入产出比。然而,随着业务的不断扩张,系统负载的持续增长,在系统稳定一段
时期之后,经过了垂直拆分之后的数据库集群可能又再一次不堪重负,遇到了性能瓶颈。 这时候我们该如何抉择?是再次进一步细分模块呢,还是寻求其他的办法来解决?如果
我们再一次像最开始那样继续细分模块,进行数据的垂直切分,那我们可能在不久的将来,
又会遇到现在所面对的同样的问题。而且随着模块的不断的细化,应用系统的架构也会越来 越复杂,整个系统很可能会出现失控的局面。
这时候我们就必须要通过数据的水平切分的优势,来解决这里所遇到的问题。而且, 我 们完全不必要在使用数据水平切分的时候,推倒之前进行数据垂直切分的成果,而是在其基
础上利用水平切分的优势来避开垂直切分的弊端,解决系统复杂性不断扩大的问题。而水平
拆分的弊端(规则难以统一)也已经被之前的垂直切分解决掉了,让水平拆分可以进行的得 心应手。
对于我们的示例数据库,假设在最开始,我们进行了数据的垂直切分,然而随着业务的 不断增长,数据库系统遇到了瓶颈,我们选择重构数据库集群的架构。如何重构?考虑到之
前已经做好了数据的垂直切分,而且模块结构清晰明确。而业务增长的势头越来越猛,即使
现在进一步再次拆分模块,也坚持不了太久。我们选择了在垂直切分的基础上再进行水平拆 分。
在经历过垂直拆分后的各个数据库集群中的每一个都只有一个功能模块,而每个功能模 块中的所有表基本上都会与某个字段进行关联。如用户模块全部都可以通过用户 ID
进行切 分,群组讨论模块则都通过群组 ID 来切分,相册模块则根据相册 ID 来进切分,最后的事
件通知信息表考虑到数据的时限性(仅仅只会访问最近某个事件段的信息),则考虑按时间 来切分。 下图展示了切分后的整个架构:
实际上,在很多大型的应用系统中,垂直切分和水平切这两种数据的切分方法基本上都 是并存的,而且经常在不断的交替进行,以不断的增加系统的扩展能力。我们在应对不同的
应用场景的时候,也需要充分考虑到这两种切分方法各自的局限,以及各自的优势,在不同 的时期(负载压力)使用不同的结合方式。 联合切分的优点
可以充分利用垂直切分和水平切分各自的优势而避免各自的缺陷; 让系统扩展性得到最大化提升; 联合切分的缺点
数据库系统架构比较复杂,维护难度更大;应用程序架构也相对更复杂。

关于数据库如何sharding详情请参考<<MySQL性能调优与架构设计>>

如何构建日均千万PV Web站点 (三) Sharding,布布扣,bubuko.com

时间: 2024-12-20 08:03:16

如何构建日均千万PV Web站点 (三) Sharding的相关文章

如何构建日均千万PV Web站点(二) 之~缓存为王~

随着网站业务的不断发展,用户的规模越来越大:介于中国无比蹩脚复杂的网路环境:南电信:北联通:中间竟然只用一条链路进行互联通信!有研究表明,网站访问延迟和用户流失率正相关,网站访问速度越慢,用户越容易失去耐心而离开.为了提高更好的用户体验,留住用户,网站需要加速网站访问速度.如今主要的手段只有使用CDN和反向代理了:此时网站的架构应该是这样的: 1.使用CDN和缓存服务器:CDN和反向代理的基本原理都是缓存数据,区别就在于CDN部署在网络提供商的机房,使用户在请求网站服务时,可以从距离自己最近的网

如何构建日均千万PV Web站点 (一)

 其实大多数互联网网站起初的网站架构都是(Linux+Apache+MySQL+PHP). 不过随着时代的发展,科技的进步.互联网进入寻常百姓家的生活.所谓的用户的需求,铸就了一个个互联网大牛: http://www.trueland.net/IndustryNews/gjszl.shtml 近日研究机构we are social发布了<2014年全球社会化媒体.数字和移动业务数据洞察>,公布了其对全球互联网.关键社交.数字化业务和移动应用的统计数据.报告指出全球数字化业务正以惊人的趋势保持高

日均百万PV架构第三弹(分布内容为王)

接续接上篇 缓存时代来临 为蓝本,继续改造我们的百万级站点架构,这次我们 拿之前存储静态内容的 nfs 开刀,众所周知 nfs 的多台集群节点下可能由于多重 原因(磁盘io , 网络带宽, 并发场景),不适合做文件共享系统的基础结构. 互联网站点中,存在大量图片或其他静态内容,并且这些内容一般在1M之内,对于 海量小文件,我们将采用mogilefs分布式文件系统来完成.其中概念自行google. # mogilefs分布式文件系统工作流程 架构已经愈发复杂,我们需要从新梳理一下.从下表中应该很容

在Linux上设置web站点(三)——在httpd2.2中设置https服务

https是以安全为目标的http通道,在http下加入了SSL层,https的安全基础是ssl,因此加密的详细内容就需要ssl. 下面简介在https2.2下设置https服务的步骤 1.创建私有CA: 使用openssl命令,详细介绍:http://blog.51cto.com/papapa213/2096589 1)创建CA的私钥: (umask 077;openssl genrsa -out /etc/pki/CA/private/cakey.pem 2048) 2)生成自签证书: op

详解CentOS7.4搭建Tomcat构建Java Web站点(内附源码包)

Java简介 Java是一门面向对象编程语言,不仅吸收了C++语言的各种优点,还摒弃了C++里难以理解的多继承.指针等概念,因此Java语言具有功能强大和简单易用两个特征.Java语言作为静态面向对象编程语言的代表,极好地实现了面向对象理论.Java具有简单性.面向对象.分布式.健壮性.安全性.平台独立与可移植性.多线程.动态性等特点.Java可以编写桌面应用程序.Web应用程序.分布式系统和嵌入式系统应用程序等. Tomcat简介 Tomcat是Apache软件基金会的Jakarta项目中的一

《构建高性能 Web站点》笔记

书名:构建高性能Web站点 出版社: 电子工业出版社 ISBN:9787121170935 一  绪论 等待的时间: (1) 数据在网络上的传输时间 (2) 站点服务器处理请求并生成回应数据的时间 (3) 浏览器本地计算和渲染的时间 二  数据的网络传输 数据如何发送 (1) 应用程序通过系统函数库接口(如send)向内核发出系统调用 (2) 系统内核将数据从用户态内存区复制到由内核维护的内核缓冲区(这块地址空间的大小有限,需要发送的数据以队列的形式进入) (3) 内核通知网卡来取数据,网卡将数

构建高可用web站点学习--前言

前言:本人对于提高web站点的访问量等的有很浓厚的兴趣,也学习了将近一年的时间,希望能总结点东西,虽然很多东西都是从书籍和资料中学习的,而不是原创,但是这是我总结的一点感悟和进行的分类吧. 本系列文章大多为谈论一些基本思想.至于代码实现和服务器的搭建和配置,可能不会涉及到,不过其中会涉及到一些基本的参数配置,所以要求对服务器的搭建和配置有基本的了解.因为搭建和配置的资料网上和书本都 很多,我在这里就能不说就不说了.免得影响文章的长度和关注的焦点. 目录结构: (一)单个服务器如何处理请求 (二)

学习笔记大型《构建高性能web站点》

吞吐率 ab -n1000 -c 100 http://new.dangdang.com/ 测试结果重点关注:1个Requests per second,2个Time per request 影响吞吐率的因素: 并发策略.I/O模型.I/O性能.CPU核数.程序本身逻辑复杂度 1.CPU并发计算 系统负载: cat proc/loadavg 结果:0.00 0.00 0.00 1/130 12041 左边三个数字代表1.5.15分钟的系统负载,数字越小,系统响应速度越快 学习笔记大型<构建高性能

大前端应用开发与架构设计-使用HTML构建Web站点

大前端应用开发与架构设计-使用HTML构建Web站点 大前端应用开发与架构设计 2.1 Web基础介绍 2.1.1 了解互联网应用程序的架构 什么叫做互联网? 互联网:通过网络(有线.无线,4G)将世界各地的计算机(手机.平板.PC.服务器)连接起来的结构. 随着互联网及其相关技术的不断发展,目前基于互联网的程序有B/S(Broswer/Server)架构和C/S(Client/Server)架构两种组成. B/S也就是浏览器/服务器,用户只需要在浏览器中进行相关操作(通常是输入访问地址,或者提