数据密集型系统架构设计

按照使用的资源类型划分,我们可以把系统分为三大类型:IO密集型、计算密集型,数据密集型。系统的类型反映了系统的主要瓶颈。现实情况中,大部分系统在由小变大的过程中,最先出现瓶颈的是IO。IO问题体现在两个方面:高并发,存储介质的读写(例如数据库,磁盘等)。随着业务逻辑的复杂化,接下来出现瓶颈的是计算,也就是常说的CPU
idle不足。出现计算瓶颈的时候,一般会使用水平扩展(加机器)和垂直扩张(服务拆分)两个方法。随着数据量(用户数量,客户数量)的增长,再接下来出现瓶颈的是内存。

如今,内存的合理使用比以往更加重要。一方面,大数据理论已经非常普及,用数据驱动产品也已经被普遍接受并落地,同时数据分析也促使产品设计的更加精细,因此系统承载的数量比以前有了很大的变化,系统遇到内存瓶颈的时间也比以前大大缩短了。另一方面,内存依然是相对昂贵的硬件,不能无限制的使用。即使在Amazon等云服务上,大内存的实例也是很昂贵的,并且大内存的实例往往伴随着高性能型CPU,这对一些数据密集型系统是一个浪费。因此,本文重点探讨数据密集系统如何应对出现的瓶颈。


1. 拆库

任何工程上的问题最基本的思路都是“分而治之”。因此,当内存不够时,很自然的想法是将数据拆分到多台机器中,俗称拆库。沿用数据库拆分的术语,拆库又分为“水平拆分”和“垂直拆分”两个派别。

1.1 水平拆分

水平拆分是指将同一种数据的不同记录进行拆分。

例如我们有一亿条商品数据供查询。如果单机无法存储,可以使用四台机器,每台机器存储2500万条商品数据。其中,每台机器称为一个“分片”,同一个分片的多台机器组成一个“分组”,从四个分组各选出一台机器组成一个完整的服务。当上游服务进行查询时,同时查询四台机器,并对返回结果做合并。

在使用水平拆分的方案时,需要重点考虑以下问题:

  • 索引服务

如前几篇文章所述,任何大数据量系统中,在启动之前都需要加载索引数据。索引数据一般是预先计算好的,并且以二进制格式持久化的文件。因为服务进行了拆分,每一台机器只需要加载一部分数据,因此需要为每个分组的机器单独计算索引数据,这样减少了系统启动时处理的数据量,加快启动速度。

  • 数据更新

同样,由于每台机器只需要加载一部分数据,那么也只需要处理这部分数据的更新。目前主流的更新数据流都是使用 Mesage Queue 作为传输和持久化系统个,在服务端接收 Message Queue 的数据并持久化到本地,供在线服务定期读取。一般同一类的数据使用一个 Topic 传输,同时 Message Queue 一般都支持 Partition 的机制。即在向 MQ 中发送一条数据时,可以指定将该条数据发送到哪个 Partition;在从 MQ 中读取数据时,可以指定只读取哪些 Partition 的数据。例如上文的例子,存储商品数据的服务器分了四个组,因此可以将传输商品更新数据的
Topic 划分为四个 Partition,每个分组的机器只需要订阅其需要的 Partition 即可。在实际操作中,为了保持未来的扩展性,一般 Partition 的数量都会设置为分组数量的若干倍,例如八个或者十六个,这样在未来数据量进一步增长导致分组个数进一步增加时,不需要修改 MQ 的 Partition 配置。

利用 MQ 这个机制,可以使每台机器只订阅自己需要处理的数据,减少带宽,也减少更新时处理的数据量,避免浪费资源。

  • 服务管理的复杂性

在我们管理上下游机器时,一般会使用以 ZooKeeper 为核心的服务管理系统。即每个服务都注册在 ZooKeeper 中,当上游服务需要访问下游服务时,去 ZooKeeper 中查询可用的下游服务列表,并同时考虑负载均衡等因素,选择最合适的一个下游服务实例。

当一个服务出现分组时,管理的难度会增大。服务管理系统需要确保一个服务的每个分组的实例同样多,并且负载基本保持平衡。另外,当任何一台机器出现 故障导致的宕时,需要启动备用机器。这时,需要判断是哪个分组的机器发生了故障,并启动相关分组的机器实例,重新注册到 ZK 中。

  • 无法拆分的数据

有很多数据是无法拆分的。一方面有些数据是天然不可拆分的,例如各种策略使用的词典;另一方面,有些数据即使可以拆分,但和系统中其他数据的拆分规则不同,那么系统也无法保证所有数据都能被拆分,只能优先拆分主要数据。

1.2 垂直拆分

在传统关系型数据库的设计上,垂直拆分是指将一种数据的不同列进行拆分;在对系统架构的设计上,垂直拆分是只将一个服务的不同计算逻辑拆分为多个服务。在使用垂直拆分的方案时,需要重点考虑以下问题:

  • 增加网络请求次数,增加系统响应时间

如果是对响应时间要求很高的系统,一定会尽可能地避免垂直拆分,例如搜索。而有一些对逻辑确实很复杂,对时间又不太敏感的系统,一般都会优先选择垂直拆分,例如支付。

  • 增加系统复杂度

将服务进行了分层,更加了开发成本,对运维的要求也更高。

  • 数据冗余

有一些数据会被拆分过的多个服务使用,会出现在上下游多个服务中,那么数据的分发、更新都会更加复杂,即浪费资源,又进一步增加了系统的复杂度。因此,在垂直拆分的过程中,一定要尽可能将服务的功能做良好的划分,避免一种数据被多个服务使用的情况。

垂直拆分的方案中,有一种情况可以大幅减少机器数量,即:一部分数据的存在并不是在处理请求的时候被直接使用,其存在是为了维护被处理请求的逻辑直接使用的数据。

一个典型的例子是检索服务中的正排索引。检索服务在查询时,直接使用的是倒排索引,而倒排索引是根据正排索引生成的。正排索引往往有多种数据,当一条数据发生更新时,会影响其他类别的数据。因此,一条数据的更新信息无法被单独处理,在系统的内存中往往同时维护正排索引和倒排索引,导致内存翻倍。这种情况下,如果我们把正排索引独立到一台离线机器中,这台机器维护正排索引的全部数据,当正排索引发生更新时,倒排索引的更新信息,并分发给所有在线机器。那么,在线服务就不需要维护正排索引,能够大幅度减少内存的使用。

1.3 综述

实际情况中,大型系统往往同时使用水平拆分和垂直拆分两种方案。一方面,水平拆分虽然服务内部进行了分组,但对外仍然是单一的服务,因此从业务逻辑上来讲更加简单。另一方面,垂直拆分可以将非常复杂、计算资源有不同需求的业务逻辑进行很好的隔离,方便系统中各业务逻辑可以针对自己的特点进行开发和部署。因此,在选择拆分方案时,要结合系统的主要矛盾以及目前团队成员的技术特点,综合考虑做出选择。


2. 多级存储

俗话说,当上帝为你关上了一扇门,必(可)定(能)为你打开了一扇窗。如果说大数据是上帝为架构师关上的一扇门,那么热点数据就是打开的那扇窗。虽然在现实世界中的数据是海量难以估算的,但幸运的是,有价值或者说值得关注的数据总是少数的。在大型系统中,请永远把二八法则的重要性放在第一位。

一般来说,计算机的存储系统分为三级:CPU Cache,内存,磁盘。这三者的访问速度依次降低(并且是数量级的降低),单位存储的成本也依次降低(也是数量级的降低)。多级存储的基本思想是,按照被访问频率的不同给数据分类,访问频率越高的数据应当放在访问速度越快的存储介质中。

三种系统都使用页式存储的结构,页也是其处理数据的最小单位。由于这个特性,我们一般在编写程序时,尽可能地将连续访问的数据放在内存的相邻位置,以提高CPU Cache的命中率,也就是常说的 locality principle。

随着SSD的出现,对磁盘的使用已经出现了新的方法论。机械磁盘的随机读写速度在10ms左右,不太可能供实时系统使用。而SSD磁盘的随机读写速度在100us左右,对于有些秒级响应的系统来说,已经可以作为实时系统的存储介质。一种典型的情况是系统存在相当数量的冷门数据。系统对于热点数据可以快速地反馈,对于很少被访问的冷门数据可以存储在SSD磁盘中。当冷门数据被访问时,只要latency仍然可以控制在秒级,就可以在保证用户体验只有很少的损害的情况下,大幅减少系统成本。

一种典型的场景是电商的商品信息。经常被访问的商品可能不到商品总量的1%。像淘宝这样规模的电商系统,实际可能比1%还低。

另一种典型的场景是用户评论。无论按评论发表的先后顺序,还是按某种规则计算出的评论的质量度排序,总是前100个左右的评论被经常访问,后面的评论几乎不会被访问到。

另外,回想上文提到的检索服务的案例。正排索引除了可以拆分为单独的服务之外,还可以存储在磁盘中。更新正排索引的时候直接从磁盘读取数据,修改后写会磁盘,同时更新内存的倒排索引。如果使用SSD磁盘,虽然更新的延迟会增长,但也会控制在毫秒级,对于系统完全是可以接受的。要知道,在一条数据到达检索服务之前,都会经过若干次网络传输,由磁盘引起的延迟并不是主要因素。

在使用磁盘作为可以提供实时查询功能的存储介质时,很常见的方案是将磁盘作为二级缓存,将最近访问的数据保存在内存中,当访问的数据不在内存中时,从磁盘读取,并放入内存中。这个方案的假设是,最近被访问的数据很可能在接下来仍然被访问。采用这种方案需要重点注意,防止爬虫或者外部的恶意请求短期内访问大量冷门数据,造成实际的热点数据被换出缓存,导致处理真实请求时有大量的缓存失效。



大数据技术对商业效果的提升已经在越来越多的行业中被证明,未来的服务,无论是在线还是离线,处理的数据都会有数量级甚至几个数量级的增长。同时,我们看到内存除了访问速度越来越快,在存储的数据量和成本上并没有太大的变化。因此,未来越来越多的系统的主要瓶颈会从计算、IO转移到数据量上,内存密集型系统会变得越来越重要,相信其架构在未来几年也会有很多新的方式出现。

时间: 2024-11-03 21:11:09

数据密集型系统架构设计的相关文章

IM系统架构设计之浅见

背景:除去大名鼎鼎的QQ这款即时聊天工具,还有许多细分行业的IM,比如淘宝阿里旺旺.网易泡泡.YY语音.......恰巧公司产品也要开发一款基于我们自己行业的类IM系统,很有幸我担当了这个产品的架构师,核心代码编写.实现者.下面我近年来从技术上我对IM系统(即时消息的传输,不包括语音,视频,文件的传输)的理解和设计分享出来,浅薄之见,望大家别见笑,欢迎给出批评意见. 一.网络传输协议的选择 目前我知晓的所有IM系统传输即时消息无外乎使用UDP.TCP.基于TCP的http这几种协议中的一种或几种

petshop4.0 具体解释之中的一个(系统架构设计)

前言:PetShop是一个范例,微软用它来展示.Net企业系统开发的能力.业界有很多.Net与J2EE之争,很多数据是从微软的PetShop和Sun的PetStore而来.这样的争论不可避免带有浓厚的商业色彩,对于我们开发者而言,没有必要过多关注.然而PetShop随着版本号的不断更新,至如今基于.Net 2.0的PetShop4.0为止,整个设计逐渐变得成熟而优雅,却又非常多能够借鉴之处.PetShop是一个小型的项目,系统架构与代码都比較简单,却也凸现了很多颇有价值的设计与开发理念.本系列试

高可用、高扩展、低延迟交易处理系统架构设计

为实现一个高TPS.高可靠性.高扩展性.低响应延迟的交易处理系统,在系统架构设计上,需要有诸多考虑.  1. 交易处理系统的功能 交易系统是用于连接多个不同的交易请求系统(上游系统)与交易受理系统(下游系统),在这些交易上下游系统之间传递不同格式的交易报文.同时一个交易请求可能需要发送多个不同的子交易请求到不同的交易受理系统,交易处理系统还负责子交易的拆分.交易完整性与一致性保证. 一个典型的交易处理系统,往往需要支持多种不同的通信协议(TCP长连接.TCP短链接.CTG.CICS.MQ等),支

NET ERP系统架构设计

解析大型.NET ERP系统架构设计 Framework+ Application 设计模式 我对大型系统的理解,从数量上面来讲,源代码超过百万行以上,系统有超过300个以上的功能,从质量上来讲系统应该具备良好的可扩展性和可维护性,系统中的功能紧密关联.除去业务上的复杂性,如何设计这样的一个协作良好的系统,搭建开发人员基础平台,一直是我研究的方向. SouceCounter(版本3.3.91.79)对源代码的统计信息如下: 下面来详细解析一下这个系统的设计架构,纯.NET技术架构方案,C/S W

电商峰值系统架构设计--转载

1.1 系统架构设计目录 摘要:双11来临之际,<程序员>以“电商峰值系统架构设计”为主题,力邀京东.当当.小米.1号店.海尔商城.唯品会.蘑菇街.麦包包等电商企业,及商派.基调网络等服务公司,分享电商峰值系统架构设计的最佳技术实践. 自2009年11月11日,淘宝商城(现名天猫)拉开网购狂欢节的序幕,各大电商的促销浪潮此起彼伏.此时的电商大战不仅是价格之争,更是技术的较量.如何设计电商峰值系统来更好地满足用户蜂拥而至的访问,如何在海量数据处理中实时发现有效信息并转化为商机,成为众多电商企业密

0. 视频监控系统架构设计

0.视频监控系统架构设计 0.1.功能指标 (1)搭建共享文件夹 (2)实现Ubuntu的NAT上网和桥接上网 (3)搭建局域网 (4)搭建nfs服务器.tftp服务器 (5)将uboot.kernel.rootfs镜像文件下载到开发板中 (6)移植MPP,ORTP库和WiFi库 (7)编写应用程序实现RTP/RTCP传输视频流,实现有线传输和无线传输 0.2.架构搭建 该系统中主控 CPU 采用HI3518EV200作为核心,通过在HI3518E芯片上运行linux,构建嵌入式平台, 接收来自

机票实时搜索系统架构设计

机票实时搜索系统架构设计 ? 不同的业务场景,不同的特征 ? 结合特征去进?设计和优化 ? 通?!=最优 ? 量体裁? 分布式系统的CAP理论 首先把分布式系统中的三个特性进行了如下归纳:    ● 一致性(C):在分布式系统中的所有数据备份,在同一时刻是否同样的值.(等同于所有节点访问同一份最新的数据副本) ● 可用性(A):在集群中一部分节点故障后,集群整体是否还能响应客户端的读写请求.(对数据更新具备高可用性) ● 分区容错性(P):以实际效果而言,分区相当于对通信的时限要求.系统如果不能

京东虚拟业务多维订单系统架构设计读后感

阅读文章:京东虚拟业务多维订单系统架构设计 文章网址:https://mp.weixin.qq.com/s?__biz=MzU1MzE2NzIzMg==&mid=2247486428&idx=1&sn=382f9d307073839f7900df7168916cf1&chksm=fbf7bb33cc80322599a586248c4bf92880374dcb8c48249c91b03170230112492b3ec628206e&scene=21#wechat_re

系统架构设计了解

系统架构设计的关键点 单一应用结构 当网站流量很小时,只需要一个应用,将所有的功能都部署在一块儿,以减少部署节点和成本,当流量增加时,通过搭建集群增加主机的水平扩展方式可以提升整个系统的性能,此时用于简化CRUD工作量的数据访问框架是关键 锤子应用架构 当访问量随着推广不断增大,单一应用的水平扩展所带来的速度提升越来越小时,此时可以将应用拆分为几个互不相干的几个应用( 没有交互 ),以提升效率,这是用于加速前端叶念开发的框架是关键 分布式服务架构 当垂直应用越来越多,应用之间的交互是不可避免的,