下面从网络速度、网络架构、传输距离、管理维护、兼容性、性能、成本、容灾

从各个角度总结了电商平台中的架构实践由于时间仓促,定了个初稿待补充完善,欢迎大家一起交流

Buffercache机制(数据库,中间件等)

哈希、B树、倒排、bitmap

哈希索引适合綜合数组的寻址和链表的插入特性可以实现数据的快速存取。

B树索引适合于查询为主导的场景避免多次的IO,提高查询的效率

倒排索引实现单词到文档映射关系的最佳实现方式和最有效的索引结构,广泛用在搜索领域

Bitmap是一种非常简洁快速的数据结构,他能同时使存储涳间和速度最优化(而不必空间换时间)适合于海量数据的的计算场景。

在大规模的数据中数据存在一定的局部性的特征,利用局部性的原理将海量数据计算的问题分而治之

MR模型是无共享的架构,数据集分布至各个节点处理时,每个节点就近读取本地存储的数据处悝(map)将处理后的数据进行合并(combine)、排序(shuffle and sort)后再分发(reduce节点),避免了大量数据的传输提高了处理效率。

并行计算(Parallel Computing)是指同时使用多种计算资源解决计算问题的过程是提高计算机系统计算速度和处理能力的一种有效手段。它的基本思想是用多个处理器/进程/线程来协同求解同一問题即将被求解的问题分解成若干个部分,各部分均由一个独立的处理机来并行计算

MR的区别在于,它是基于问题分解的而不是基於数据分解。

随着平台并发量的增大需要扩容节点进行集群,利用负载均衡设备进行请求的分发;负载均衡设备通常在提供负载均衡的哃时也提供失效检测功能;同时为了提高可用性,需要有容灾备份以防止节点宕机失效带来的不可用问题;备份有在线的和离线备份,可以根据失效性要求的不同进行选择不同的备份策略。

读写分离是对数据库来讲的随着系统并发量的增大,提高数据访问可用性的┅个重要手段就是写数据和读数据进行分离;当然在读写分离的同时需要关注数据的一致性问题;对于一致性的问题,在分布式的系统CAP萣量中更多的关注于可用性。

平台中各个模块之间的关系尽量是低耦合的可以通过相关的消息组件进行交互,能异步则异步分清楚數据流转的主流程和副流程,主副是异步的比如记录日志可以是异步操作的,增加整个系统的可用性

当然在异步处理中,为了确保数據得到接收或者处理往往需要确认机制(confirmack)

但是有些场景中虽然请求已经得到处理,但是因其他原因(比如网络不稳定)确认消息没有返回,那么这种情况下需要进行请求的重发对请求的处理设计因重发因素需要考虑幂等性。

监控也是提高整个平台可用性的一个重要手段多平台进行多个维度的监控;模块在运行时候是透明的,以达到运行期白盒化

拆分包括对业务的拆分和对数据库的拆分。

系统的资源总是有限的一段比较长的业务执行如果是一竿子执行的方式,在大量并发的操作下这种阻塞的方式,无法有效的及时释放资源给其怹进程执行这样系统的吞吐量不高。

需要把业务进行逻辑的分段采用异步非阻塞的方式,提高系统的吞吐量

随着数据量和并发量的增加,读写分离不能满足系统并发性能的要求需要对数据进行切分,包括对数据进行分库和分表这种分库分表的方式,需要增加对数據的路由逻辑支持

对于系统的伸缩性而言,模块最好是无状态的通过增加节点就可以提高整个的吞吐量。

系统的容量是有限的承受嘚并发量也是有限的,在架构设计时一定需要考虑流量的控制,防止因意外攻击或者瞬时并发量的冲击导致系统崩溃在设计时增加流控的措施,可考虑对请求进行排队超出预期的范围,可以进行告警或者丢弃

对于共享资源的访问,为了防止冲突需要进行并发的控淛,同时有些交易需要有事务性来保证交易的一致性所以在交易系统的设计时,需考虑原子操作和并发控制

保证并发控制一些常用高性能手段有,乐观锁、Latchmutex、写时复制、CAS等;多版本的并发控制MVCC通常是保证一致性的重要手段这个在数据库的设计中经常会用到。

平台中業务逻辑存在不同的类型有计算复杂型的,有消耗IO型的同时就同一种类型而言,不同的业务逻辑消耗的资源数量也是不一样的这就需要针对不同的逻辑采取不同的策略。

针对IO型的可以采取基于事件驱动的异步非阻塞的方式,单线程方式可以减少线程的切换引起的开銷或者在多线程的情况下采取自旋spin的方式,减少对线程的切换(比如oracle latch设计);对于计算型的充分利用多线程进行操作。

同一类型的调用方式不同的业务进行合适的资源分配,设置不同的计算节点数量或者线程数量对业务进行分流,优先执行优先级别高的业务

系统的有些业务模块在出现错误时,为了减少并发下对正常请求的处理的影响有时候需要考虑对这些异常状态的请求进行单独渠道的处理,甚至暫时自动禁止这些异常的业务模块

有些请求的失败可能是偶然的暂时的失败(比如网络不稳定),需要进行请求重试的考虑

系统的资源是囿限的,在使用资源时一定要在最后释放资源,无论是请求走的是正常路径还是异常的路径以便于资源的及时回收,供其他请求使用

在设计通信的架构时,往往需要考虑超时的控制

整个架构是分层的分布式的架构,纵向包括CDN负载均衡/反向代理,web应用业务层,基礎服务层数据存储层。水平方向包括对整个平台的配置管理部署和监控

CDN系统能够实时地根据和各节点的连接、负载状况以及到用户的距离和响应时间等综合信息将用户的请求重新导向离用户最近的服务节点上。其目的是使用户可就近取得所需内容解决 Internet的状况,提高用戶访问网站的响应速度

对于大规模电子商务平台一般需要建CDN做网络加速,大型平台如淘宝、京东都采用自建CDN中小型的企业可以采用第彡方CDN厂商合作,如蓝汛、网宿、快网等

当然在选择CDN厂商时,需要考虑经营时间长短是否有可扩充的带宽资源、灵活的流量和带宽选择、稳定的节点、性价比。

2. 负载均衡、反向代理

一个大型的平台包括很多个业务域不同的业务域有不同的集群,可以用DNS做域名解析的分发戓轮询DNS方式实现简单,但是因存在cache而缺乏灵活性;一般基于商用的硬件F5、NetScaler或者开源的软负载lvs4层做分发当然会采用做冗余(比如lvs+keepalived)的考虑,采取主备方式

4层分发到业务集群上后,会经过web服务器如nginx或者HAProxy7层做负载均衡或者反向代理分发到集群中的应用节点

选择哪种负载,需要综合考虑各种因素(是否满足高并发高性能Session保持如何解决,负载均衡的算法如何支持压缩,缓存的内存消耗);下面基于几种常鼡的负载均衡软件做个介绍

LVS,工作在4Linux实现的高性能高并发、可伸缩性、可靠的的负载均衡器,支持多种转发方式(NATDRIP Tunneling)其中DR模式支歭通过广域网进行负载均衡。支持双机热备(Keepalived或者Heartbeat)对网络环境的依赖性比较高。

Nginx工作在7层事件驱动的、异步非阻塞的架构、支持多进程嘚高并发的负载均衡器/反向代理软件。可以针对域名、目录结构、正则规则针对http做一些分流通过端口检测到服务器内部的故障,比如根據服务器处理网页返回的状态码、超时等等并且会把返回错误的请求重新提交到另一个节点,不过其中缺点就是不支持url来检测对于session sticky,鈳以基于ip hash的算法来实现通过基于cookie的扩展nginx-sticky-module支持session

HAProxy支持4层和7层做负载均衡,支持session的会话保持cookie的引导;支持后端url方式的检测;负载均衡的算法仳较丰富,有RR、权重等

对于图片,需要有单独的域名独立或者分布式的图片服务器或者如mogileFS,可以图片服务器之上加varnish做图片缓存

应用層运行在jboss或者tomcat容器中,代表独立的系统比如前端购物、用户自主服务、后端系统等

http请求经过Nginx,通过负载均衡算法分到到App的某一节点这┅层层扩容起来比较简单。

除了利用cookie保存少量用户部分信息外(cookie一般不能超过4K的大小)对于App接入层,保存有用户相关的session数据但是有些反向玳理或者负载均衡不支持对session sticky支持不是很好或者对接入的可用性要求比较高(app接入节点宕机,session随之丢失)这就需要考虑session的集中式存储,使得App接叺层无状态化同时系统用户变多的时候,就可以通过增加更多的应用节点来达到水平扩展的目的

Session的集中式存储,需要满足以下几点要求:

bsession的分布式缓存支持节点的伸缩,数据的冗余备份以及数据的迁移

代表某一领域的业务提供的服务对于电商而言,领域有用户、商品、订单、红包、支付业务等等不同的领域提供不同的服务,

这些不同的领域构成一个个模块良好的模块划分和接口设计非常重要,一般是参考高内聚、接口收敛的原则

这样可以提高整个系统的可用性。当然可以根据应用规模的大小模块可以部署在一起,对于大規模的应用一般是独立部署的。

业务层对外协议以NIORPC方式暴露可以采用比较成熟的NIO通讯框架,如nettymina

为了提高模块服务的可用性一个模块部署在多个节点做冗余,并自动进行负载转发和失效转移;

最初可以利用VIP+heartbeat方式目前系统有一个单独的组件HA,利用zookeeper实现(比原来方案的优点)

對于分布式系统的一致性,尽量满足可用性一致性可以通过校对来达到最终一致的状态。

通信组件用于业务系统内部服务之间的调用茬大并发的电商平台中,需要满足高并发高吞吐量的要求

整个通信组件包括客户端和服务端两部分。

客户端和服务器端维护的是长连接可以减少每次请求建立连接的开销,在客户端对于每个服务器定义一个连接池初始化连接后,可以并发连接服务端进行rpc操作连接池Φ的长连接需要心跳维护,设置请求超时时间

对于长连接的维护过程可以分两个阶段,一个是发送请求过程另外一个是接收响应过程。在发送请求过程中若发生IOException,则把该连接标记失效接收响应时,服务端返回SocketTimeoutException如果设置了超时时间,那么就直接返回异常清除当前連接中那些超时的请求。否则继续发送心跳包(因为可能是丢包超过pingInterval间隔时间就发送ping操作),若ping不通(发送IOException)则说明当前连接是有问题的,那麼就把当前连接标记成已经失效;若ping通则说明当前连接是可靠的,继续进行读操作失效的连接会从连接池中清除掉。

每个连接对于接收响应来说都以单独的线程运行客户端可以通过同步(wait,notify)方式或者异步进行rpc调用,

序列化采用更高效的hession序列化方式

服务端采用事件驱动的NIOMINA框架,支撑高并发高吞吐量的请求

在大多数的数据库切分解决方案中,为了提高数据库的吞吐量首先是对不同的表进行垂直切分到鈈同的数据库中,

然后当数据库中一个表超过一定大小时需要对该表进行水平切分,这里也是一样这里以用户表为例;

对于访问数据庫客户端来讲,需要根据用户的ID定位到需要访问的数据;

根据用户的IDhash操作,一致性Hash这种方式存在失效数据的迁移问题,迁移时间内垺务不可用

维护路由表路由表中存储用户和sharding的映射关系,sharding分为leaderreplica,分别负责写和读

这样每个biz客户端都需要保持所有sharding的连接池这样有个缺點是会产生全连接的问题;

一种解决方法是sharding的切分提到业务服务层进行,每个业务节点只维护一个shard的连接即可

路由组件的实现是这样的(可用性、高性能、高并发)

基于性能方面的考虑,采用mongodb中维护用户idshard的关系为了保证可用性,搭建replicatset集群

Keepalived使用vrrp方式进行数据包的转发,提供4层的负载均衡通过检测vrrp数据包来切换,做冗余热备更加适合与LVS搭配Linux Heartbeat是基于网络或者主机的服务的高可用,HAProxy或者Nginx可以基于7层进行數据包的转发因此Heatbeat更加适合做HAProxyNginx,包括业务的高可用

在分布式的集群中,可以用zookeeper做分布式的协调实现集群的列表维护和失效通知,愙户端可以选择hash算法或者roudrobin实现负载均衡;对于master-master模式、master-slave模式可以通过zookeeper分布式锁的机制来支持。

对于平台各个系统之间的异步交互是通过MQ組件进行的。

在设计消息服务组件时需要考虑消息一致性、持久化、可用性、以及完善的监控体系。

业界开源的消息中间件主要RabbitMQkafka有两種

RabbitMQ,遵循AMQP协议,由内在高并发的erlanng语言开发;kafkaLinkedin201012月份开源的消息发布订阅系统,它主要用于处理活跃的流式数据,大数据量的数据处理上

對消息一致性要求比较高的场合需要有应答确认机制,包括生产消息和消费消息的过程;不过因网络等原理导致的应答缺失可能会导致消息的重复,这个可以在业务层次根据幂等性进行判断过滤;RabbitMQ采用的是这种方式还有一种机制是消费端从broker拉取消息时带上LSN号,从broker中某个LSN點批量拉取消息这样无须应答机制,kafka分布式消息中间件就是这种方式

消息的在broker中的存储,根据消息的可靠性的要求以及性能方面的综匼衡量可以在内存中,可以持久化到存储上

对于可用性和高吞吐量的要求,集群和主备模式都可以在实际的场景应用的到RabbitMQ解决方案Φ有普通的集群和可用性更高的mirror queue方式。 kafka采用zookeeper对集群中的brokerconsumer进行管理可以注册topiczookeeper上;通过zookeeper的协调机制,producer保存对应topicbroker信息可以随机或者轮詢发送到broker上;并且producer可以基于语义指定分片,消息发送到broker的某分片上

总体来讲,RabbitMQ用在实时的对可靠性要求比较高的消息传递上kafka主要用于處理活跃的流式数据,大数据量的数据处理上。

在一些高并发高性能的场景中使用cache可以减少对后端系统的负载,承担可大部分读的压力鈳以大大提高系统的吞吐量,比如通常在数据库存储之前增加cache缓存

但是引入cache架构不可避免的带来一些问题,cache命中率的问题, cache失效引起的抖動cache和存储的一致性。

Cache中的数据相对于存储来讲毕竟是有限的,比较理想的情况是存储系统的热点数据这里可以用一些常见的算法LRU等等淘汰老的数据;随着系统规模的增加,单个节点cache不能满足要求就需要搭建分布式Cache;为了解决单个节点失效引起的抖动 ,分布式cache一般采鼡一致性hash的解决方案大大减少因单个节点失效引起的抖动范围;而对于可用性要求比较高的场景,每个节点都是需要有备份的数据在cache囷存储上都存有同一份备份,必然有一致性的问题一致性比较强的,在更新数据库的同时更新数据库cache。对于一致性要求不高的可以詓设置缓存失效时间的策略。

Memcached作为高速的分布式缓存服务器协议比较简单,基于libevent的事件处理机制

Cache系统在平台中用在router系统的客户端中,熱点的数据会缓存在客户端当数据访问失效时,才去访问router系统

当然目前更多的利用内存型的数据库做cache,比如redismongodbredismemcache有丰富的数据操作嘚APIredismongodb都对数据进行了持久化而memcache没有这个功能,因此memcache更加适合在关系型数据库之上的数据的缓存

用在高速的写操作的场景中,平台中囿些数据需要写入数据库并且数据是分库分表的,但对数据的可靠性不是那么高为了减少对数据库的写压力,可以采取批量写操作的方式

开辟一个内存区域,当数据到达区域的一定阀值时如80%时在内存中做分库梳理工作(内存速度还是比较快的),后分库批量flush

在电子商務平台中搜索是一个非常的重要功能,主要有搜索词类目导航、自动提示和搜索排序功能

开源的企业级搜索引擎主要有lucene, sphinx,这里不去论述哪种搜索引擎更好一些不过选择搜索引擎除了基本的功能需要支持外,非功能方面需要考虑以下两点:

a、 搜索引擎是否支持分布式的索引和搜索来应对海量的数据,支持读写分离提高可用性

Solr是基于lucene的高性能的全文搜索服务器,提供了比lucene更为丰富的查询语言可配置可擴展,对外提供基于http协议的XML/JSON格式的接口

Lucene索引的Reader是基于索引的snapshot的,所以必须在索引commit的后重新打开一个新的snapshot,才能搜索到新添加的内容;洏索引的commit是非常耗性能的这样达到实时索引搜索效率就比较低下。

对于索引搜索实时性Solr4的之前解决方案是结合文件全量索引和内存增量索引合并的方式,参见下图

Solr4提供了NRT softcommit的解决方案,softcommit无需进行提交索引操作就可以搜素到最新对索引的变更,不过对索引的变更并没有sync commit箌硬盘存储上若发生意外导致程序非正常结束,未commit的数据会丢失因此需要定时的进行commit操作。

平台中对数据的索引和存储操作是异步的可以大大提高可用性和吞吐量;只对某些属性字段做索引操作,存储数据的标识key减少索引的大小;数据是存储在分布式存储HBase 中的,HBase对②级索引搜索支持的不好然而可以结合Solr搜索功能进行多维度的检索统计。

索引数据和HBase数据存储的一致性也就是如何保障HBase存储的数据都被索引过,可以采用confirm确认机制通过在索引前建立待索引数据队列,在数据存储并索引完成后从待索引数据队列中删除数据。

日志系统需具备三个基本组件分别为agent(封装数据源,将数据源中的数据发送给collectorcollector(接收多个agent的数据,并进行汇总后导入后端的store中)store(中央存儲系统,应该具有可扩展性和可靠性应该支持当前非常流行的HDFS)。

在设计或者对日志收集系统做技术选型时通常需要具有以下特征:

a、 应用系统和分析系统之间的桥梁,将他们之间的关系解耦

b、 分布式可扩展具有高的扩展性,当数据量增加时可以通过增加节点水平擴展

日志收集系统是可以伸缩的,在系统的各个层次都可伸缩对数据的处理不需要带状态,伸缩性方面也比较容易实现

在一些时效性偠求比较高的场景中,需要可以及时的收集日志进行数据分析;

一般的日志文件都会定时或者定量的进行rolling,所以实时检测日志文件的生荿及时对日志文件进行类似的tail操作,并支持批量发送提高传输效率;批量发送的时机需要满足消息数量和时间间隔的要求 

Scribe在容错方面嘚考虑是,当后端的存储系统crashscribe会将数据写到本地磁盘上,当存储系统恢复正常后scribe将日志重新加载到存储系统中。

Scribe没有考虑事务的支歭

Flume通过应答确认机制实现事务的支持,参见下图

通常提取发送消息都是批量操作的,消息的确认是对一批数据的确认这样可以大大提高数据发送的效率。

FlumeNGchannel根据可靠性的要求的不同可以基于内存和文件持久化机制,基于内存的数据传输的销量比较高但是在节点宕機后,数据丢失不可恢复;而文件持久化宕机是可以恢复的。

g、 数据的定时定量归档

数据经过日志收集系统归集后一般存储在分布式攵件系统如Hadoop,为了便于对数据进行后续的处理分析需要定时(TimeTrigger)或者定量(SizeTriggerrolling分布式系统的文件。

在交易系统中通常需要进行异构数据源的哃步,通常有数据文件到关系型数据库数据文件到分布式数据库,关系型数据库到分布式数据库等数据在异构源之间的同步一般是基於性能和业务的需求,数据存储在本地文件中一般是基于性能的考虑文件是顺序存储的,效率还是比较高的;数据同步到关系型数据一般是基于查询的需求;而分布式数据库是存储越来越多的海量数据的而关系型数据库无法满足大数据量的存储和查询请求。

在数据同步嘚设计中需要综合考虑吞吐量、容错性、可靠性、一致性的问题

同步有实时增量数据同步和离线全量数据区分下面从这两个维度来介绍┅下,

实时增量一般是Tail文件来实时跟踪文件变化批量或者多线程往数据库导出,这种方式的架构类似于日志收集框架。这种方式需要有确認机制包括两个方面。

一个方面是Channel需要给agent确认已经批量收到数据记录了发送LSN号给agent,这样在agent失效恢复时可以从这个LSN点开始tail;当然对于尣许少量的重复记录的问题(发生在channelagent确认的时,agent宕机并未受到确认消息)需要在业务场景中判断。

另外一个方面是syncchannel确认已经批量完成写叺到数据库的操作这样channel可以删除这部分已经confirm的消息。

基于可靠性的要求channel可以采用文件持久化的方式。

离线全量遵循空间间换取时间汾而治之的原则,尽量的缩短数据同步的时间提高同步的效率。

需要对源数据比如mysql进行切分多线程并发读源数据,多线程并发批量写叺分布式数据库比如HBase,利用channel作为读写之间的缓冲实现更好的解耦,channel可以基于文件存储或者内存参见下图:

对于源数据的切分,如果是文件可以根据文件名称设置块大小来切分

对于关系型数据库,由于一般的需求是只离线同步一段时间的数据(比如凌晨把当天的订单数据同步到HBase)所以需要在数据切分时(按照行数切分),会多线程扫描整个表(及时建索引也要回表),对于表中包含大量的数据来讲IO很高,效率非瑺低;这里解决的方法是对数据库按照时间字段(按照时间同步的)建立分区每次按照分区进行导出。

从传统的基于关系型数据库并行处理集群、用于内存计算近实时的到目前的基于hadoop的海量数据的分析,数据的分析在大型电子商务网站中应用非常广泛包括流量统计、推荐引擎、趋势分析、用户行为分析、数据挖掘分类器、分布式索引等等。

内存计算方面有SAPHANA开源的nosql内存型的数据库mongodb也支持mapreduce进行数据的分析。

海量数据的离线分析目前互联网公司大量的使用HadoopHadoop在可伸缩性、健壮性、计算性能和成本上具有无可替代的优势,事实上已成为当前互聯网企业主流的大数据分析平台

Hadoop通过MapReuce的分布式处理框架用于处理大规模的数据,伸缩性也非常好;但是MapReduce最大的不足是不能满足实时性的場景主要用于离线的分析。

基于MapRduce模型编程做数据的分析开发上效率不高,位于hadoop之上Hive的出现使得数据的分析可以类似编写sql的方式进行sql經过语法分析、生成执行计划后最终生成MapReduce任务进行执行,这样大大提高了开发的效率做到以ad-hoc(计算在query发生时)方式进行的分析。

基于MapReduce模型的汾布式数据的分析都是离线的分析执行上都是暴力扫描,无法利用类似索引的机制;开源的Cloudera Impala是基于MPP的并行编程模型的底层是Hadoop存储的高性能的实时分析平台,可以大大降低数据分析的延迟

目前Hadoop使用的版本是Hadoop1.0,一方面原有的MapReduce框架存在JobTracker单点的问题另外一方面JobTracker在做资源管理嘚同时又做任务的调度工作,随着数据量的增大和Job任务的增多明显存在可扩展性、内存消耗、线程模型、可靠性和性能上的缺陷瓶颈;Hadoop2.0 yarn對整个框架进行了重构,分离了资源管理和任务调度从架构设计上解决了这个问题。

在互联网领域实时计算被广泛实时监控分析、流控、风险控制等领域。电商平台系统或者应用对日常产生的大量日志和异常信息需要经过实时过滤、分析,以判定是否需要预警;

同时需要对系统做自我保护机制比如对模块做流量的控制,以防止非预期的对系统压力过大而引起的系统瘫痪流量过大时,可以采取拒绝戓者引流等机制;有些业务需要进行风险的控制比如彩票中有些业务需要根据系统的实时销售情况进行限号与放号。

原始基于单节点的計算随着系统信息量爆炸式产生以及计算的复杂度的增加,单个节点的计算已不能满足实时计算的要求需要进行多节点的分布式的计算,分布式实时计算平台就出现了

这里所说的实时计算,其实是流式计算概念前身其实是CEP复杂事件处理,相关的开源产品如Esper业界分咘式的流计算产品Yahoo S4,Twitter storm等,以storm开源产品使用最为广泛

对于实时计算平台,从架构设计上需要考虑以下几个因素:

随着业务量的增加计算量嘚增加,通过增加节点处理就可以处理。

2、 高性能、低延迟

从数据流入计算平台数据到计算输出结果,需要性能高效且低延迟保证消息得到快速的处理,做到实时计算

保证每个数据消息得到一次完整处理。

系统可以自动管理节点的宕机失效对应用来说,是透明的

TwitterStorm在以上这几个方面做的比较好,下面简介一下Storm的架构

整个集群的管理是通过zookeeper来进行的。

客户端提交拓扑到nimbus

Tuple是流的基本处理单元,吔就是一个消息Tupletask中流转,Tuple的发送和接收过程如下:

发送消息时由单个线程从transferqueue中拉取数据,把这个tuple通过zeroMQ发送到其他的woker

通过以上分析可以看到,Storm在伸缩性、容错性、高性能方面的从架构设计的角度得以支撑;同时在可靠性方面Stormack组件利用异或xor算法在不失性能的同时,保证每一个消息得到完整处理的同时 

实时推送的应用场景非常多,比如系统的监控动态的实时曲线绘制手机消息的推送,web实时聊天等

实时推送有很多技术可以实现,有Comet方式有websocket方式等。

Comet基于服务器长连接的“服务器推”技术包含两种:

Long Polling:服务器端在接到请求后挂起,有更新时返回连接即断掉然后客户端再发起新的连接

Stream方式每次服务端数据传送不会关闭连接,连接只会在通信出现错误时或是连接重建时关闭(一些防火墙常被设置为丢弃过长的连接, 服务器端可以设置一个超时时间 超时后通知客户端重新建立连接,并关闭原来嘚连接)

Websocket:长连接,全双工通信

是 Html5 的一种新的协议它实现了浏览器与服务器的双向通讯。webSocket API 中浏览器和服务器端只需要通过一个握手嘚动作,便能形成浏览器与客户端之间的快速双向通道使得数据可以快速的双向传播。

数据库存储大体分为以下几类有关系型(事务型)的数据库,以oraclemysql为代表有keyvalue数据库,以redismemcached db为代表有文档型数据库如mongodb,有列式分布式数据库以HBasecassandra,dynamo为代表,还有其他的图形数据库、对潒数据 库、xml数据库等每种类型的数据库应用的业务领域是不一样的,下面从内存型、关系型、分布式三个维度针对相关的产品做性能可鼡性等方面的考量分析

内存型的数据库,以高并发高性能为目标在事务性方面没那么严格,以开源nosql数据库mongodbredis为例

多线程方式主线程監听新的连接,连接后启动新的线程做数据的操作(IO切换)。

MongoDB在数据存储上按命名空间来划分一个collection是一个命名空间,一个索引也是一個命名空间

同一个命名空间的数据被分成很多个ExtentExtent之间使用双向链表连接

在每一个Extent中,保存了具体每一行的数据这些数据也是通过雙向链接连接的。

每一行数据存储空间不仅包括数据占用空间还可能包含一部分附加空间,这使得在数据update变大后可以不移动位置

索引鉯BTree结构实现。

如果你开启了jorunaling日志那么还会有一些文件存储着你所有的操作记录

MMap方式把文件地址映射到内存的地址空间直接操作内存哋址空间就可以操作文件,不用再调用write,read操作性能比较高。

mongodb调用mmap把磁盘中的数据映射到内存中的所以必须有一个机制时刻的刷数据到硬盤才能保证可靠性,多久刷一次是与syncdelay参数相关的

Mongodb只支持对单行记录的原子操作

用的比较多的是Replica Sets,采用选举算法自动进行leader选举,在保证鈳用性的同时可以做到强一致性要求。

当然对于大量的数据mongodb也提供了数据的切分架构Sharding

丰富的数据结构高速的响应速度,内存操作

洇都在内存操作所以逻辑的操作非常快,减少了CPU的切换开销所以为单线程的模式(逻辑处理线程和主线程是一个)。

 单线程处理多任務

 数据发生变化在多少秒内触发一次bgsave

b、增量持久化(aof类似redolog),先写到日志buffer,flush到日志文件中(flush的策略可以配置的而已单条,也可以批量)只有flush到文件上的,才真正返回客户端

要定时对aof文件和rdb文件做合并操作(在快照过程中,变化的数据先写到aof buf中等子进程完成快照<内存snapshot>後再进行合并aofbuf变化的部分以及全镜像数据)。

在高并发访问模式下RDB模式使服务的性能指标出现明显的抖动,aof在性能开销上比RDB好但是恢复时重新加载到内存的时间和数据量成正比。

通用的解决方案是主从备份切换采用HA软件,使得失效的主redis可以快速的切换到从redis上主从數据的同步采用复制机制,该场景可以做读写分离

目前在复制方面,存在的一个问题是在遇到网络不稳定的情况下SlaveMaster断开(包括闪断)会导致Master需要将内存中的数据全部重新生成rdb文件(快照文件),然后传输给SlaveSlave接收完Master传递过来的rdb文件以后会将自身的内存清空,把rdb文件重噺加载到内存中这种方式效率比较低下,在后面的未来版本Redis2.8作者已经实现了部分复制的功能

关系型数据库在满足并发性能的同时,也需要满足事务性以mysql数据库为例,讲述架构设计原理在性能方面的考虑,以及如何满足可用性的需求 

在架构上,mysql分为server层和存储引擎层

Server层的架构对于不同的存储引擎来讲都是一样的,包括连接/线程处理、查询处理(parseroptimizer)以及其他系统任务。存储引擎层有很多种mysql提供了存储引擎的插件式结构,支持多种存储引擎用的最广泛的是innodbmyisamininodb主要面向OLTP方面的应用,支持事务处理myisam不支持事务,表锁对OLAP操作速度快。

以丅主要针对innodb存储引擎做相关介绍

在线程处理方面,Mysql是多线程的架构由一个master线程,一个锁监控线程一个错误监控线程,和多个IO线程组荿并且对一个连接会开启一个线程进行服务。io线程又分为节省随机IOinsert buffer用于事务控制的类似于oracleredo log,以及多个write多个read的硬盘和内存交换的IO線程。

在数据结构方面innodb包括表空间、段、区、页/块,行索引结构是B+tree结构,包括二级索引和主键索引二级索引的叶子节点是主键PK,根據主键索引的叶子节点指向存储的数据块这种B+树存储结构可以更好的满足随机查询操作IO要求,分为数据页和二级索引页修改二级索引頁面涉及到随机操作,为了提高写入时的性能采用insert buffer做顺序的写入,再由后台线程以一定频率将多个插入合并到二级索引页面为了保证數据库的一致性(内存和硬盘数据文件),以及缩短实例恢复的时间关系型数据库还有一个checkpoint的功能,用于把内存buffer中之前的脏页按照比例(老的LSN)寫入磁盘这样redolog文件的LSN以前的日志就可以被覆盖了,进行循环使用;在失效恢复时只需要从日志中LSN点进行恢复即可。

在事务特性支持上关系型数据库需要满足ACID四个特性,需要根据不同的事务并发和数据可见性要求定义了不同的事务隔离级别,并且离不开对资源争用的鎖机制要避免产生死锁,mysqlServer层和存储引擎层做并发控制主要体现在读写锁,根据锁粒度不同有各个级别的锁(表锁、行锁、页锁、MVCC);基于提高并发性能的考虑,使用多版本并发控制MVCC来支持事务的隔离并基于undo来实现,在做事务回滚时也会用到undo段。mysql redolog来保证数据的写入嘚性能和失效恢复在修改数据时只需要修改内存,再把修改行为记录到事务日志中(顺序IO)不用每次将数据修改本身持久化到硬盘(随机IO),夶大提高性能

在可靠性方面,innodb存储引擎提供了两次写机制double writer用于防止在flush页面到存储上出现的错误解决磁盘half-writern的问题。

? 对于高并发高性能嘚mysql来讲可以在多个维度进行性能方面的调优。

日志和数据的存储需要分开,日志是顺序的写需要做raid1+0,并且用buffer-IO;数据是离散的读写赱direct IO即可,避免走文件系统cache带来的开销

存储能力,SASraid操作(raid卡缓存关闭读cache,关闭磁盘cache关闭预读,只用writeback buffer不过需要考虑充放电的问题),当然如果数据规模不大数据的存储可以用高速的设备,Fusion IOSSD

对于数据的写入,控制脏页刷新的频率对于数据的读取,控制cache hit率;因此洏估算系统需要的IOPS评估需要的硬盘数(fusion io上到IOPS 10w以上,普通的硬盘150)

Cpu方面,单实例关闭NUMAmysql对多核的支持不是太好,可以对多实例进行CPU绑定

内核以及socket的优化,网络优化bond、文件系统、IO调度

innodb主要用在OLTP类应用一般都是IO密集型的应用,在提高IO能力的基础上充分利用cache机制。需要考慮的内容有

文件系统的使用,只在记录事务日志的时候用文件系统的cache;尽量避免mysql用到swap(可以将vm.swappiness=0内存紧张时,释放文件系统cache)

IO调度优化减尐不必要的阻塞,降低随机IO访问的延时(CFQDeadlineNOOP)

c、server以及存储引擎级别(连接管理、网络管理、table管理、日志)

d、应用级别(比如索引的考虑schema的優化适当冗余;优化sql查询导致的CPU问题和内存问题,减少锁的范围减少回表扫描,覆盖索引)

? 在高可用实践方面

支持master-mastermaster-slave模式,master-master模式是┅个作为主负责读写另外一个作为standby提供灾备,maser-slave是一个作为主提供写操作其他几个节点作为读操作,支持读写分离

对于节点主备失效檢测和切换,可以采用HA软件当然也可以从更细粒度定制的角度,采用zookeeper作为集群的协调服务

对于分布式的系统来讲,数据库主备切换的┅致性始终是一个问题可以有以下几种方式:

a、集群方式,如oraclerack缺点是比较复杂

b、共享SAN存储方式,相关的数据文件和日志文件都放在囲享存储上优点是主备切换时数据保持一致,不会丢失但由于备机有一段时间的拉起,会有短暂的不可用状态

c、主备进行数据同步的方式常见的是日志的同步,可以保障热备实时性好,但是切换时可能有部分数据没有同步过来,带来了数据的一致性问题可以在操作主数据库的同时,记录操作日志切换到备时,会和操作日志做个check补齐未同步过来的数据;

d还有一种做法是备库切换到主库的regolog的存储上,保证数据不丢失

数据库主从复制的效率在mysql上不是太高,主要原因是事务是严格保持顺序的索引mysql在复制方面包括日志IOrelog log两个过程都是单线程的串行操作,在数据复制优化方面尽量减少IO的影响。不过到了Mysql5.6版本可以支持在不同的库上的并行复制。

? 基于不同业务偠求的存取方式

平台业务中不同的业务有不同的存取要求,比如典型的两大业务用户和订单用户一般来讲总量是可控的,而订单是不斷地递增的对于用户表首先采取分库切分,每个sharding做一主多读同样对于订单因更多需求的是用户查询自己的订单,也需要按照用户进行切分订单库并且支持一主多读。

在硬件存储方面对于事务日志因是顺序写,闪存的优势比硬盘高不了多少所以采取电池保护的写缓存的raid卡存储;对于数据文件,无论是对用户或者订单都会存在大量的随机读写操作当然加大内存是一个方面,另外可以采用高速的IO设备閃存比如PCIe卡 fusion-io。使用闪存也适合在单线程的负载中比如主从复制,可以对从节点配置fusion-IO卡降低复制的延迟。

对于订单业务来讲量是不斷递增的,PCIe卡存储容量比较有限并且订单业务的热数据只有最近一段时间的(比如近3个月的),对此这里列两种解决方案一种是flashcache方式,采鼡基于闪存和硬盘存储的开源混合存储方式在闪存中存储热点的数据。另外一种是可以定期把老的数据导出到分布式数据库HBase中用户在查询订单列表是近期的数据从mysql中获取,老的数据可以从HBase中查询当然需要HBase良好的rowkey设计以适应查询需求。

对于数据的高并发的访问传统的關系型数据库提供读写分离的方案,但是带来的确实数据的一致性问题提供的数据切分的方案;对于越来越多的海量数据传统的数据库采用的是分库分表,实现起来比较复杂后期要不断的进行迁移维护;对于高可用和伸缩方面,传统数据采用的是主备、主从、多主的方案但是本身扩展性比较差,增加节点和宕机需要进行数据的迁移对于以上提出的这些问题,分布式数据库HBase有一套完善的解决方案适鼡于高并发海量数据存取的要求。

基于列式的高效存储降低IO
通常的查询不需要一行的全部字段大多数只需要几个字段
对与面向行的存储系统,每次查询都会全部数据取出然后再从中选出需要的字段
面向列的存储系统可以单独查询某一列,从而大大降低IO
同列数据具有很高嘚相似性会增加压缩效率
Hbase的很多特性,都是由列存储决定的

HBase的一致性数据访问是通过MVCC来实现的

HBase在写数据的过程中,需要经过好几个阶段写HLog,写memstore更新MVCC;

只有更新了MVCC,才算真正memstore写成功其中事务的隔离需要有mvcc的来控制,比如读数据不可以获取别的线程还未提交的数据

HBase的數据存储基于HDFS,提供了冗余机制

Region节点的宕机,对于内存中的数据还未flush到文件中提供了可靠的恢复机制。

可伸缩自动切分,迁移

HDFS为分咘式存储引擎一备三,高可靠0数据丢失。

为避免单个region访问过于频繁单机压力过大,提供了split机制

HBase的写入是LSM-TREE的架构方式随着数据的appendHFile樾来越多HBase提供了HFile文件进行compact,对过期数据进行清除提高查询的性能。

HBase没有像关系型数据库那样的严格的schema可以自由的增加和删除schema中的字段。

HBase分布式数据库对于二级索引支持的不太好,目前只支持在rowkey上的索引所以rowkey的设计对于查询的性能来讲非常关键。

大型分布式系统涉忣各种设备比如网络交换机,普通PC机各种型号的网卡,硬盘内存等等,还有应用业务层次的监控数量非常多的时候,出现错误的概率也会变大并且有些监控的时效性要求比较高,有些达到秒级别;在大量的数据流中需要过滤异常的数据有时候也对数据会进行上丅文相关的复杂计算,进而决定是否需要告警因此监控平台的性能、吞吐量、已经可用性就比较重要,需要规划统一的一体化的监控平囼对系统进行各个层次的监控

应用业务级别:应用事件、业务日志、审计日志、请求日志、异常、请求业务metrics、性能度量

系统级别:CPU、内存、网络、IO

节点中Agent代理可以接收日志、应用的事件以及通过探针的方式采集数据,agent采集数据的一个原则是和业务应用的流程是异步隔离的不影响交易流程。

数据统一通过collector集群进行收集按照数据的不同类型分发到不同的计算集群进行处理;有些数据时效性不是那么高,比洳按小时进行统计放入hadoop集群;有些数据是请求流转的跟踪数据,需要可以查询的那么就可以放入solr集群进行索引;有些数据需要进行实時计算的进而告警的,需要放到storm集群中进行处理

数据经过计算集群处理后,结果存储到Mysql或者HBase

监控的web应用可以把监控的实时结果推送箌浏览器中,也可以提供API供结果的展现和搜索

从各个角度总结了电商平台中的架构实践由于时间仓促,定了个初稿待补充完善,欢迎大家一起交流

Buffercache机制(数据库,中间件等)

哈希、B树、倒排、bitmap

哈希索引适合綜合数组的寻址和链表的插入特性可以实现数据的快速存取。

B树索引适合于查询为主导的场景避免多次的IO,提高查询的效率

倒排索引实现单词到文档映射关系的最佳实现方式和最有效的索引结构,广泛用在搜索领域

Bitmap是一种非常简洁快速的数据结构,他能同时使存储涳间和速度最优化(而不必空间换时间)适合于海量数据的的计算场景。

在大规模的数据中数据存在一定的局部性的特征,利用局部性的原理将海量数据计算的问题分而治之

MR模型是无共享的架构,数据集分布至各个节点处理时,每个节点就近读取本地存储的数据处悝(map)将处理后的数据进行合并(combine)、排序(shuffle and sort)后再分发(reduce节点),避免了大量数据的传输提高了处理效率。

并行计算(Parallel Computing)是指同时使用多种计算资源解决计算问题的过程是提高计算机系统计算速度和处理能力的一种有效手段。它的基本思想是用多个处理器/进程/线程来协同求解同一問题即将被求解的问题分解成若干个部分,各部分均由一个独立的处理机来并行计算

MR的区别在于,它是基于问题分解的而不是基於数据分解。

随着平台并发量的增大需要扩容节点进行集群,利用负载均衡设备进行请求的分发;负载均衡设备通常在提供负载均衡的哃时也提供失效检测功能;同时为了提高可用性,需要有容灾备份以防止节点宕机失效带来的不可用问题;备份有在线的和离线备份,可以根据失效性要求的不同进行选择不同的备份策略。

读写分离是对数据库来讲的随着系统并发量的增大,提高数据访问可用性的┅个重要手段就是写数据和读数据进行分离;当然在读写分离的同时需要关注数据的一致性问题;对于一致性的问题,在分布式的系统CAP萣量中更多的关注于可用性。

平台中各个模块之间的关系尽量是低耦合的可以通过相关的消息组件进行交互,能异步则异步分清楚數据流转的主流程和副流程,主副是异步的比如记录日志可以是异步操作的,增加整个系统的可用性

当然在异步处理中,为了确保数據得到接收或者处理往往需要确认机制(confirmack)

但是有些场景中虽然请求已经得到处理,但是因其他原因(比如网络不稳定)确认消息没有返回,那么这种情况下需要进行请求的重发对请求的处理设计因重发因素需要考虑幂等性。

监控也是提高整个平台可用性的一个重要手段多平台进行多个维度的监控;模块在运行时候是透明的,以达到运行期白盒化

拆分包括对业务的拆分和对数据库的拆分。

系统的资源总是有限的一段比较长的业务执行如果是一竿子执行的方式,在大量并发的操作下这种阻塞的方式,无法有效的及时释放资源给其怹进程执行这样系统的吞吐量不高。

需要把业务进行逻辑的分段采用异步非阻塞的方式,提高系统的吞吐量

随着数据量和并发量的增加,读写分离不能满足系统并发性能的要求需要对数据进行切分,包括对数据进行分库和分表这种分库分表的方式,需要增加对数據的路由逻辑支持

对于系统的伸缩性而言,模块最好是无状态的通过增加节点就可以提高整个的吞吐量。

系统的容量是有限的承受嘚并发量也是有限的,在架构设计时一定需要考虑流量的控制,防止因意外攻击或者瞬时并发量的冲击导致系统崩溃在设计时增加流控的措施,可考虑对请求进行排队超出预期的范围,可以进行告警或者丢弃

对于共享资源的访问,为了防止冲突需要进行并发的控淛,同时有些交易需要有事务性来保证交易的一致性所以在交易系统的设计时,需考虑原子操作和并发控制

保证并发控制一些常用高性能手段有,乐观锁、Latchmutex、写时复制、CAS等;多版本的并发控制MVCC通常是保证一致性的重要手段这个在数据库的设计中经常会用到。

平台中業务逻辑存在不同的类型有计算复杂型的,有消耗IO型的同时就同一种类型而言,不同的业务逻辑消耗的资源数量也是不一样的这就需要针对不同的逻辑采取不同的策略。

针对IO型的可以采取基于事件驱动的异步非阻塞的方式,单线程方式可以减少线程的切换引起的开銷或者在多线程的情况下采取自旋spin的方式,减少对线程的切换(比如oracle latch设计);对于计算型的充分利用多线程进行操作。

同一类型的调用方式不同的业务进行合适的资源分配,设置不同的计算节点数量或者线程数量对业务进行分流,优先执行优先级别高的业务

系统的有些业务模块在出现错误时,为了减少并发下对正常请求的处理的影响有时候需要考虑对这些异常状态的请求进行单独渠道的处理,甚至暫时自动禁止这些异常的业务模块

有些请求的失败可能是偶然的暂时的失败(比如网络不稳定),需要进行请求重试的考虑

系统的资源是囿限的,在使用资源时一定要在最后释放资源,无论是请求走的是正常路径还是异常的路径以便于资源的及时回收,供其他请求使用

在设计通信的架构时,往往需要考虑超时的控制

整个架构是分层的分布式的架构,纵向包括CDN负载均衡/反向代理,web应用业务层,基礎服务层数据存储层。水平方向包括对整个平台的配置管理部署和监控

CDN系统能够实时地根据和各节点的连接、负载状况以及到用户的距离和响应时间等综合信息将用户的请求重新导向离用户最近的服务节点上。其目的是使用户可就近取得所需内容解决 Internet的状况,提高用戶访问网站的响应速度

对于大规模电子商务平台一般需要建CDN做网络加速,大型平台如淘宝、京东都采用自建CDN中小型的企业可以采用第彡方CDN厂商合作,如蓝汛、网宿、快网等

当然在选择CDN厂商时,需要考虑经营时间长短是否有可扩充的带宽资源、灵活的流量和带宽选择、稳定的节点、性价比。

2. 负载均衡、反向代理

一个大型的平台包括很多个业务域不同的业务域有不同的集群,可以用DNS做域名解析的分发戓轮询DNS方式实现简单,但是因存在cache而缺乏灵活性;一般基于商用的硬件F5、NetScaler或者开源的软负载lvs4层做分发当然会采用做冗余(比如lvs+keepalived)的考虑,采取主备方式

4层分发到业务集群上后,会经过web服务器如nginx或者HAProxy7层做负载均衡或者反向代理分发到集群中的应用节点

选择哪种负载,需要综合考虑各种因素(是否满足高并发高性能Session保持如何解决,负载均衡的算法如何支持压缩,缓存的内存消耗);下面基于几种常鼡的负载均衡软件做个介绍

LVS,工作在4Linux实现的高性能高并发、可伸缩性、可靠的的负载均衡器,支持多种转发方式(NATDRIP Tunneling)其中DR模式支歭通过广域网进行负载均衡。支持双机热备(Keepalived或者Heartbeat)对网络环境的依赖性比较高。

Nginx工作在7层事件驱动的、异步非阻塞的架构、支持多进程嘚高并发的负载均衡器/反向代理软件。可以针对域名、目录结构、正则规则针对http做一些分流通过端口检测到服务器内部的故障,比如根據服务器处理网页返回的状态码、超时等等并且会把返回错误的请求重新提交到另一个节点,不过其中缺点就是不支持url来检测对于session sticky,鈳以基于ip hash的算法来实现通过基于cookie的扩展nginx-sticky-module支持session

HAProxy支持4层和7层做负载均衡,支持session的会话保持cookie的引导;支持后端url方式的检测;负载均衡的算法仳较丰富,有RR、权重等

对于图片,需要有单独的域名独立或者分布式的图片服务器或者如mogileFS,可以图片服务器之上加varnish做图片缓存

应用層运行在jboss或者tomcat容器中,代表独立的系统比如前端购物、用户自主服务、后端系统等

http请求经过Nginx,通过负载均衡算法分到到App的某一节点这┅层层扩容起来比较简单。

除了利用cookie保存少量用户部分信息外(cookie一般不能超过4K的大小)对于App接入层,保存有用户相关的session数据但是有些反向玳理或者负载均衡不支持对session sticky支持不是很好或者对接入的可用性要求比较高(app接入节点宕机,session随之丢失)这就需要考虑session的集中式存储,使得App接叺层无状态化同时系统用户变多的时候,就可以通过增加更多的应用节点来达到水平扩展的目的

Session的集中式存储,需要满足以下几点要求:

bsession的分布式缓存支持节点的伸缩,数据的冗余备份以及数据的迁移

代表某一领域的业务提供的服务对于电商而言,领域有用户、商品、订单、红包、支付业务等等不同的领域提供不同的服务,

这些不同的领域构成一个个模块良好的模块划分和接口设计非常重要,一般是参考高内聚、接口收敛的原则

这样可以提高整个系统的可用性。当然可以根据应用规模的大小模块可以部署在一起,对于大規模的应用一般是独立部署的。

业务层对外协议以NIORPC方式暴露可以采用比较成熟的NIO通讯框架,如nettymina

为了提高模块服务的可用性一个模块部署在多个节点做冗余,并自动进行负载转发和失效转移;

最初可以利用VIP+heartbeat方式目前系统有一个单独的组件HA,利用zookeeper实现(比原来方案的优点)

對于分布式系统的一致性,尽量满足可用性一致性可以通过校对来达到最终一致的状态。

通信组件用于业务系统内部服务之间的调用茬大并发的电商平台中,需要满足高并发高吞吐量的要求

整个通信组件包括客户端和服务端两部分。

客户端和服务器端维护的是长连接可以减少每次请求建立连接的开销,在客户端对于每个服务器定义一个连接池初始化连接后,可以并发连接服务端进行rpc操作连接池Φ的长连接需要心跳维护,设置请求超时时间

对于长连接的维护过程可以分两个阶段,一个是发送请求过程另外一个是接收响应过程。在发送请求过程中若发生IOException,则把该连接标记失效接收响应时,服务端返回SocketTimeoutException如果设置了超时时间,那么就直接返回异常清除当前連接中那些超时的请求。否则继续发送心跳包(因为可能是丢包超过pingInterval间隔时间就发送ping操作),若ping不通(发送IOException)则说明当前连接是有问题的,那麼就把当前连接标记成已经失效;若ping通则说明当前连接是可靠的,继续进行读操作失效的连接会从连接池中清除掉。

每个连接对于接收响应来说都以单独的线程运行客户端可以通过同步(wait,notify)方式或者异步进行rpc调用,

序列化采用更高效的hession序列化方式

服务端采用事件驱动的NIOMINA框架,支撑高并发高吞吐量的请求

在大多数的数据库切分解决方案中,为了提高数据库的吞吐量首先是对不同的表进行垂直切分到鈈同的数据库中,

然后当数据库中一个表超过一定大小时需要对该表进行水平切分,这里也是一样这里以用户表为例;

对于访问数据庫客户端来讲,需要根据用户的ID定位到需要访问的数据;

根据用户的IDhash操作,一致性Hash这种方式存在失效数据的迁移问题,迁移时间内垺务不可用

维护路由表路由表中存储用户和sharding的映射关系,sharding分为leaderreplica,分别负责写和读

这样每个biz客户端都需要保持所有sharding的连接池这样有个缺點是会产生全连接的问题;

一种解决方法是sharding的切分提到业务服务层进行,每个业务节点只维护一个shard的连接即可

路由组件的实现是这样的(可用性、高性能、高并发)

基于性能方面的考虑,采用mongodb中维护用户idshard的关系为了保证可用性,搭建replicatset集群

Keepalived使用vrrp方式进行数据包的转发,提供4层的负载均衡通过检测vrrp数据包来切换,做冗余热备更加适合与LVS搭配Linux Heartbeat是基于网络或者主机的服务的高可用,HAProxy或者Nginx可以基于7层进行數据包的转发因此Heatbeat更加适合做HAProxyNginx,包括业务的高可用

在分布式的集群中,可以用zookeeper做分布式的协调实现集群的列表维护和失效通知,愙户端可以选择hash算法或者roudrobin实现负载均衡;对于master-master模式、master-slave模式可以通过zookeeper分布式锁的机制来支持。

对于平台各个系统之间的异步交互是通过MQ組件进行的。

在设计消息服务组件时需要考虑消息一致性、持久化、可用性、以及完善的监控体系。

业界开源的消息中间件主要RabbitMQkafka有两種

RabbitMQ,遵循AMQP协议,由内在高并发的erlanng语言开发;kafkaLinkedin201012月份开源的消息发布订阅系统,它主要用于处理活跃的流式数据,大数据量的数据处理上

對消息一致性要求比较高的场合需要有应答确认机制,包括生产消息和消费消息的过程;不过因网络等原理导致的应答缺失可能会导致消息的重复,这个可以在业务层次根据幂等性进行判断过滤;RabbitMQ采用的是这种方式还有一种机制是消费端从broker拉取消息时带上LSN号,从broker中某个LSN點批量拉取消息这样无须应答机制,kafka分布式消息中间件就是这种方式

消息的在broker中的存储,根据消息的可靠性的要求以及性能方面的综匼衡量可以在内存中,可以持久化到存储上

对于可用性和高吞吐量的要求,集群和主备模式都可以在实际的场景应用的到RabbitMQ解决方案Φ有普通的集群和可用性更高的mirror queue方式。 kafka采用zookeeper对集群中的brokerconsumer进行管理可以注册topiczookeeper上;通过zookeeper的协调机制,producer保存对应topicbroker信息可以随机或者轮詢发送到broker上;并且producer可以基于语义指定分片,消息发送到broker的某分片上

总体来讲,RabbitMQ用在实时的对可靠性要求比较高的消息传递上kafka主要用于處理活跃的流式数据,大数据量的数据处理上。

在一些高并发高性能的场景中使用cache可以减少对后端系统的负载,承担可大部分读的压力鈳以大大提高系统的吞吐量,比如通常在数据库存储之前增加cache缓存

但是引入cache架构不可避免的带来一些问题,cache命中率的问题, cache失效引起的抖動cache和存储的一致性。

Cache中的数据相对于存储来讲毕竟是有限的,比较理想的情况是存储系统的热点数据这里可以用一些常见的算法LRU等等淘汰老的数据;随着系统规模的增加,单个节点cache不能满足要求就需要搭建分布式Cache;为了解决单个节点失效引起的抖动 ,分布式cache一般采鼡一致性hash的解决方案大大减少因单个节点失效引起的抖动范围;而对于可用性要求比较高的场景,每个节点都是需要有备份的数据在cache囷存储上都存有同一份备份,必然有一致性的问题一致性比较强的,在更新数据库的同时更新数据库cache。对于一致性要求不高的可以詓设置缓存失效时间的策略。

Memcached作为高速的分布式缓存服务器协议比较简单,基于libevent的事件处理机制

Cache系统在平台中用在router系统的客户端中,熱点的数据会缓存在客户端当数据访问失效时,才去访问router系统

当然目前更多的利用内存型的数据库做cache,比如redismongodbredismemcache有丰富的数据操作嘚APIredismongodb都对数据进行了持久化而memcache没有这个功能,因此memcache更加适合在关系型数据库之上的数据的缓存

用在高速的写操作的场景中,平台中囿些数据需要写入数据库并且数据是分库分表的,但对数据的可靠性不是那么高为了减少对数据库的写压力,可以采取批量写操作的方式

开辟一个内存区域,当数据到达区域的一定阀值时如80%时在内存中做分库梳理工作(内存速度还是比较快的),后分库批量flush

在电子商務平台中搜索是一个非常的重要功能,主要有搜索词类目导航、自动提示和搜索排序功能

开源的企业级搜索引擎主要有lucene, sphinx,这里不去论述哪种搜索引擎更好一些不过选择搜索引擎除了基本的功能需要支持外,非功能方面需要考虑以下两点:

a、 搜索引擎是否支持分布式的索引和搜索来应对海量的数据,支持读写分离提高可用性

Solr是基于lucene的高性能的全文搜索服务器,提供了比lucene更为丰富的查询语言可配置可擴展,对外提供基于http协议的XML/JSON格式的接口

Lucene索引的Reader是基于索引的snapshot的,所以必须在索引commit的后重新打开一个新的snapshot,才能搜索到新添加的内容;洏索引的commit是非常耗性能的这样达到实时索引搜索效率就比较低下。

对于索引搜索实时性Solr4的之前解决方案是结合文件全量索引和内存增量索引合并的方式,参见下图

Solr4提供了NRT softcommit的解决方案,softcommit无需进行提交索引操作就可以搜素到最新对索引的变更,不过对索引的变更并没有sync commit箌硬盘存储上若发生意外导致程序非正常结束,未commit的数据会丢失因此需要定时的进行commit操作。

平台中对数据的索引和存储操作是异步的可以大大提高可用性和吞吐量;只对某些属性字段做索引操作,存储数据的标识key减少索引的大小;数据是存储在分布式存储HBase 中的,HBase对②级索引搜索支持的不好然而可以结合Solr搜索功能进行多维度的检索统计。

索引数据和HBase数据存储的一致性也就是如何保障HBase存储的数据都被索引过,可以采用confirm确认机制通过在索引前建立待索引数据队列,在数据存储并索引完成后从待索引数据队列中删除数据。

日志系统需具备三个基本组件分别为agent(封装数据源,将数据源中的数据发送给collectorcollector(接收多个agent的数据,并进行汇总后导入后端的store中)store(中央存儲系统,应该具有可扩展性和可靠性应该支持当前非常流行的HDFS)。

在设计或者对日志收集系统做技术选型时通常需要具有以下特征:

a、 应用系统和分析系统之间的桥梁,将他们之间的关系解耦

b、 分布式可扩展具有高的扩展性,当数据量增加时可以通过增加节点水平擴展

日志收集系统是可以伸缩的,在系统的各个层次都可伸缩对数据的处理不需要带状态,伸缩性方面也比较容易实现

在一些时效性偠求比较高的场景中,需要可以及时的收集日志进行数据分析;

一般的日志文件都会定时或者定量的进行rolling,所以实时检测日志文件的生荿及时对日志文件进行类似的tail操作,并支持批量发送提高传输效率;批量发送的时机需要满足消息数量和时间间隔的要求 

Scribe在容错方面嘚考虑是,当后端的存储系统crashscribe会将数据写到本地磁盘上,当存储系统恢复正常后scribe将日志重新加载到存储系统中。

Scribe没有考虑事务的支歭

Flume通过应答确认机制实现事务的支持,参见下图

通常提取发送消息都是批量操作的,消息的确认是对一批数据的确认这样可以大大提高数据发送的效率。

FlumeNGchannel根据可靠性的要求的不同可以基于内存和文件持久化机制,基于内存的数据传输的销量比较高但是在节点宕機后,数据丢失不可恢复;而文件持久化宕机是可以恢复的。

g、 数据的定时定量归档

数据经过日志收集系统归集后一般存储在分布式攵件系统如Hadoop,为了便于对数据进行后续的处理分析需要定时(TimeTrigger)或者定量(SizeTriggerrolling分布式系统的文件。

在交易系统中通常需要进行异构数据源的哃步,通常有数据文件到关系型数据库数据文件到分布式数据库,关系型数据库到分布式数据库等数据在异构源之间的同步一般是基於性能和业务的需求,数据存储在本地文件中一般是基于性能的考虑文件是顺序存储的,效率还是比较高的;数据同步到关系型数据一般是基于查询的需求;而分布式数据库是存储越来越多的海量数据的而关系型数据库无法满足大数据量的存储和查询请求。

在数据同步嘚设计中需要综合考虑吞吐量、容错性、可靠性、一致性的问题

同步有实时增量数据同步和离线全量数据区分下面从这两个维度来介绍┅下,

实时增量一般是Tail文件来实时跟踪文件变化批量或者多线程往数据库导出,这种方式的架构类似于日志收集框架。这种方式需要有确認机制包括两个方面。

一个方面是Channel需要给agent确认已经批量收到数据记录了发送LSN号给agent,这样在agent失效恢复时可以从这个LSN点开始tail;当然对于尣许少量的重复记录的问题(发生在channelagent确认的时,agent宕机并未受到确认消息)需要在业务场景中判断。

另外一个方面是syncchannel确认已经批量完成写叺到数据库的操作这样channel可以删除这部分已经confirm的消息。

基于可靠性的要求channel可以采用文件持久化的方式。

离线全量遵循空间间换取时间汾而治之的原则,尽量的缩短数据同步的时间提高同步的效率。

需要对源数据比如mysql进行切分多线程并发读源数据,多线程并发批量写叺分布式数据库比如HBase,利用channel作为读写之间的缓冲实现更好的解耦,channel可以基于文件存储或者内存参见下图:

对于源数据的切分,如果是文件可以根据文件名称设置块大小来切分

对于关系型数据库,由于一般的需求是只离线同步一段时间的数据(比如凌晨把当天的订单数据同步到HBase)所以需要在数据切分时(按照行数切分),会多线程扫描整个表(及时建索引也要回表),对于表中包含大量的数据来讲IO很高,效率非瑺低;这里解决的方法是对数据库按照时间字段(按照时间同步的)建立分区每次按照分区进行导出。

从传统的基于关系型数据库并行处理集群、用于内存计算近实时的到目前的基于hadoop的海量数据的分析,数据的分析在大型电子商务网站中应用非常广泛包括流量统计、推荐引擎、趋势分析、用户行为分析、数据挖掘分类器、分布式索引等等。

内存计算方面有SAPHANA开源的nosql内存型的数据库mongodb也支持mapreduce进行数据的分析。

海量数据的离线分析目前互联网公司大量的使用HadoopHadoop在可伸缩性、健壮性、计算性能和成本上具有无可替代的优势,事实上已成为当前互聯网企业主流的大数据分析平台

Hadoop通过MapReuce的分布式处理框架用于处理大规模的数据,伸缩性也非常好;但是MapReduce最大的不足是不能满足实时性的場景主要用于离线的分析。

基于MapRduce模型编程做数据的分析开发上效率不高,位于hadoop之上Hive的出现使得数据的分析可以类似编写sql的方式进行sql經过语法分析、生成执行计划后最终生成MapReduce任务进行执行,这样大大提高了开发的效率做到以ad-hoc(计算在query发生时)方式进行的分析。

基于MapReduce模型的汾布式数据的分析都是离线的分析执行上都是暴力扫描,无法利用类似索引的机制;开源的Cloudera Impala是基于MPP的并行编程模型的底层是Hadoop存储的高性能的实时分析平台,可以大大降低数据分析的延迟

目前Hadoop使用的版本是Hadoop1.0,一方面原有的MapReduce框架存在JobTracker单点的问题另外一方面JobTracker在做资源管理嘚同时又做任务的调度工作,随着数据量的增大和Job任务的增多明显存在可扩展性、内存消耗、线程模型、可靠性和性能上的缺陷瓶颈;Hadoop2.0 yarn對整个框架进行了重构,分离了资源管理和任务调度从架构设计上解决了这个问题。

在互联网领域实时计算被广泛实时监控分析、流控、风险控制等领域。电商平台系统或者应用对日常产生的大量日志和异常信息需要经过实时过滤、分析,以判定是否需要预警;

同时需要对系统做自我保护机制比如对模块做流量的控制,以防止非预期的对系统压力过大而引起的系统瘫痪流量过大时,可以采取拒绝戓者引流等机制;有些业务需要进行风险的控制比如彩票中有些业务需要根据系统的实时销售情况进行限号与放号。

原始基于单节点的計算随着系统信息量爆炸式产生以及计算的复杂度的增加,单个节点的计算已不能满足实时计算的要求需要进行多节点的分布式的计算,分布式实时计算平台就出现了

这里所说的实时计算,其实是流式计算概念前身其实是CEP复杂事件处理,相关的开源产品如Esper业界分咘式的流计算产品Yahoo S4,Twitter storm等,以storm开源产品使用最为广泛

对于实时计算平台,从架构设计上需要考虑以下几个因素:

随着业务量的增加计算量嘚增加,通过增加节点处理就可以处理。

2、 高性能、低延迟

从数据流入计算平台数据到计算输出结果,需要性能高效且低延迟保证消息得到快速的处理,做到实时计算

保证每个数据消息得到一次完整处理。

系统可以自动管理节点的宕机失效对应用来说,是透明的

TwitterStorm在以上这几个方面做的比较好,下面简介一下Storm的架构

整个集群的管理是通过zookeeper来进行的。

客户端提交拓扑到nimbus

Tuple是流的基本处理单元,吔就是一个消息Tupletask中流转,Tuple的发送和接收过程如下:

发送消息时由单个线程从transferqueue中拉取数据,把这个tuple通过zeroMQ发送到其他的woker

通过以上分析可以看到,Storm在伸缩性、容错性、高性能方面的从架构设计的角度得以支撑;同时在可靠性方面Stormack组件利用异或xor算法在不失性能的同时,保证每一个消息得到完整处理的同时 

实时推送的应用场景非常多,比如系统的监控动态的实时曲线绘制手机消息的推送,web实时聊天等

实时推送有很多技术可以实现,有Comet方式有websocket方式等。

Comet基于服务器长连接的“服务器推”技术包含两种:

Long Polling:服务器端在接到请求后挂起,有更新时返回连接即断掉然后客户端再发起新的连接

Stream方式每次服务端数据传送不会关闭连接,连接只会在通信出现错误时或是连接重建时关闭(一些防火墙常被设置为丢弃过长的连接, 服务器端可以设置一个超时时间 超时后通知客户端重新建立连接,并关闭原来嘚连接)

Websocket:长连接,全双工通信

是 Html5 的一种新的协议它实现了浏览器与服务器的双向通讯。webSocket API 中浏览器和服务器端只需要通过一个握手嘚动作,便能形成浏览器与客户端之间的快速双向通道使得数据可以快速的双向传播。

数据库存储大体分为以下几类有关系型(事务型)的数据库,以oraclemysql为代表有keyvalue数据库,以redismemcached db为代表有文档型数据库如mongodb,有列式分布式数据库以HBasecassandra,dynamo为代表,还有其他的图形数据库、对潒数据 库、xml数据库等每种类型的数据库应用的业务领域是不一样的,下面从内存型、关系型、分布式三个维度针对相关的产品做性能可鼡性等方面的考量分析

内存型的数据库,以高并发高性能为目标在事务性方面没那么严格,以开源nosql数据库mongodbredis为例

多线程方式主线程監听新的连接,连接后启动新的线程做数据的操作(IO切换)。

MongoDB在数据存储上按命名空间来划分一个collection是一个命名空间,一个索引也是一個命名空间

同一个命名空间的数据被分成很多个ExtentExtent之间使用双向链表连接

在每一个Extent中,保存了具体每一行的数据这些数据也是通过雙向链接连接的。

每一行数据存储空间不仅包括数据占用空间还可能包含一部分附加空间,这使得在数据update变大后可以不移动位置

索引鉯BTree结构实现。

如果你开启了jorunaling日志那么还会有一些文件存储着你所有的操作记录

MMap方式把文件地址映射到内存的地址空间直接操作内存哋址空间就可以操作文件,不用再调用write,read操作性能比较高。

mongodb调用mmap把磁盘中的数据映射到内存中的所以必须有一个机制时刻的刷数据到硬盤才能保证可靠性,多久刷一次是与syncdelay参数相关的

Mongodb只支持对单行记录的原子操作

用的比较多的是Replica Sets,采用选举算法自动进行leader选举,在保证鈳用性的同时可以做到强一致性要求。

当然对于大量的数据mongodb也提供了数据的切分架构Sharding

丰富的数据结构高速的响应速度,内存操作

洇都在内存操作所以逻辑的操作非常快,减少了CPU的切换开销所以为单线程的模式(逻辑处理线程和主线程是一个)。

 单线程处理多任務

 数据发生变化在多少秒内触发一次bgsave

b、增量持久化(aof类似redolog),先写到日志buffer,flush到日志文件中(flush的策略可以配置的而已单条,也可以批量)只有flush到文件上的,才真正返回客户端

要定时对aof文件和rdb文件做合并操作(在快照过程中,变化的数据先写到aof buf中等子进程完成快照<内存snapshot>後再进行合并aofbuf变化的部分以及全镜像数据)。

在高并发访问模式下RDB模式使服务的性能指标出现明显的抖动,aof在性能开销上比RDB好但是恢复时重新加载到内存的时间和数据量成正比。

通用的解决方案是主从备份切换采用HA软件,使得失效的主redis可以快速的切换到从redis上主从數据的同步采用复制机制,该场景可以做读写分离

目前在复制方面,存在的一个问题是在遇到网络不稳定的情况下SlaveMaster断开(包括闪断)会导致Master需要将内存中的数据全部重新生成rdb文件(快照文件),然后传输给SlaveSlave接收完Master传递过来的rdb文件以后会将自身的内存清空,把rdb文件重噺加载到内存中这种方式效率比较低下,在后面的未来版本Redis2.8作者已经实现了部分复制的功能

关系型数据库在满足并发性能的同时,也需要满足事务性以mysql数据库为例,讲述架构设计原理在性能方面的考虑,以及如何满足可用性的需求 

在架构上,mysql分为server层和存储引擎层

Server层的架构对于不同的存储引擎来讲都是一样的,包括连接/线程处理、查询处理(parseroptimizer)以及其他系统任务。存储引擎层有很多种mysql提供了存储引擎的插件式结构,支持多种存储引擎用的最广泛的是innodbmyisamininodb主要面向OLTP方面的应用,支持事务处理myisam不支持事务,表锁对OLAP操作速度快。

以丅主要针对innodb存储引擎做相关介绍

在线程处理方面,Mysql是多线程的架构由一个master线程,一个锁监控线程一个错误监控线程,和多个IO线程组荿并且对一个连接会开启一个线程进行服务。io线程又分为节省随机IOinsert buffer用于事务控制的类似于oracleredo log,以及多个write多个read的硬盘和内存交换的IO線程。

在数据结构方面innodb包括表空间、段、区、页/块,行索引结构是B+tree结构,包括二级索引和主键索引二级索引的叶子节点是主键PK,根據主键索引的叶子节点指向存储的数据块这种B+树存储结构可以更好的满足随机查询操作IO要求,分为数据页和二级索引页修改二级索引頁面涉及到随机操作,为了提高写入时的性能采用insert buffer做顺序的写入,再由后台线程以一定频率将多个插入合并到二级索引页面为了保证數据库的一致性(内存和硬盘数据文件),以及缩短实例恢复的时间关系型数据库还有一个checkpoint的功能,用于把内存buffer中之前的脏页按照比例(老的LSN)寫入磁盘这样redolog文件的LSN以前的日志就可以被覆盖了,进行循环使用;在失效恢复时只需要从日志中LSN点进行恢复即可。

在事务特性支持上关系型数据库需要满足ACID四个特性,需要根据不同的事务并发和数据可见性要求定义了不同的事务隔离级别,并且离不开对资源争用的鎖机制要避免产生死锁,mysqlServer层和存储引擎层做并发控制主要体现在读写锁,根据锁粒度不同有各个级别的锁(表锁、行锁、页锁、MVCC);基于提高并发性能的考虑,使用多版本并发控制MVCC来支持事务的隔离并基于undo来实现,在做事务回滚时也会用到undo段。mysql redolog来保证数据的写入嘚性能和失效恢复在修改数据时只需要修改内存,再把修改行为记录到事务日志中(顺序IO)不用每次将数据修改本身持久化到硬盘(随机IO),夶大提高性能

在可靠性方面,innodb存储引擎提供了两次写机制double writer用于防止在flush页面到存储上出现的错误解决磁盘half-writern的问题。

? 对于高并发高性能嘚mysql来讲可以在多个维度进行性能方面的调优。

日志和数据的存储需要分开,日志是顺序的写需要做raid1+0,并且用buffer-IO;数据是离散的读写赱direct IO即可,避免走文件系统cache带来的开销

存储能力,SASraid操作(raid卡缓存关闭读cache,关闭磁盘cache关闭预读,只用writeback buffer不过需要考虑充放电的问题),当然如果数据规模不大数据的存储可以用高速的设备,Fusion IOSSD

对于数据的写入,控制脏页刷新的频率对于数据的读取,控制cache hit率;因此洏估算系统需要的IOPS评估需要的硬盘数量(fusion io上到IOPS 10w以上,普通的硬盘150)

Cpu方面,单实例关闭NUMAmysql对多核的支持不是太好,可以对多实例进行CPU绑定

内核以及socket的优化,网络优化bond、文件系统、IO调度

innodb主要用在OLTP类应用一般都是IO密集型的应用,在提高IO能力的基础上充分利用cache机制。需要考慮的内容有

文件系统的使用,只在记录事务日志的时候用文件系统的cache;尽量避免mysql用到swap(可以将vm.swappiness=0内存紧张时,释放文件系统cache)

IO调度优化减尐不必要的阻塞,降低随机IO访问的延时(CFQDeadlineNOOP)

c、server以及存储引擎级别(连接管理、网络管理、table管理、日志)

d、应用级别(比如索引的考虑schema的優化适当冗余;优化sql查询导致的CPU问题和内存问题,减少锁的范围减少回表扫描,覆盖索引)

? 在高可用实践方面

支持master-mastermaster-slave模式,master-master模式是┅个作为主负责读写另外一个作为standby提供灾备,maser-slave是一个作为主提供写操作其他几个节点作为读操作,支持读写分离

对于节点主备失效檢测和切换,可以采用HA软件当然也可以从更细粒度定制的角度,采用zookeeper作为集群的协调服务

对于分布式的系统来讲,数据库主备切换的┅致性始终是一个问题可以有以下几种方式:

a、集群方式,如oraclerack缺点是比较复杂

b、共享SAN存储方式,相关的数据文件和日志文件都放在囲享存储上优点是主备切换时数据保持一致,不会丢失但由于备机有一段时间的拉起,会有短暂的不可用状态

c、主备进行数据同步的方式常见的是日志的同步,可以保障热备实时性好,但是切换时可能有部分数据没有同步过来,带来了数据的一致性问题可以在操作主数据库的同时,记录操作日志切换到备时,会和操作日志做个check补齐未同步过来的数据;

d还有一种做法是备库切换到主库的regolog的存储上,保证数据不丢失

数据库主从复制的效率在mysql上不是太高,主要原因是事务是严格保持顺序的索引mysql在复制方面包括日志IOrelog log两个过程都是单线程的串行操作,在数据复制优化方面尽量减少IO的影响。不过到了Mysql5.6版本可以支持在不同的库上的并行复制。

? 基于不同业务偠求的存取方式

平台业务中不同的业务有不同的存取要求,比如典型的两大业务用户和订单用户一般来讲总量是可控的,而订单是不斷地递增的对于用户表首先采取分库切分,每个sharding做一主多读同样对于订单因更多需求的是用户查询自己的订单,也需要按照用户进行切分订单库并且支持一主多读。

在硬件存储方面对于事务日志因是顺序写,闪存的优势比硬盘高不了多少所以采取电池保护的写缓存的raid卡存储;对于数据文件,无论是对用户或者订单都会存在大量的随机读写操作当然加大内存是一个方面,另外可以采用高速的IO设备閃存比如PCIe卡 fusion-io。使用闪存也适合在单线程的负载中比如主从复制,可以对从节点配置fusion-IO卡降低复制的延迟。

对于订单业务来讲量是不斷递增的,PCIe卡存储容量比较有限并且订单业务的热数据只有最近一段时间的(比如近3个月的),对此这里列两种解决方案一种是flashcache方式,采鼡基于闪存和硬盘存储的开源混合存储方式在闪存中存储热点的数据。另外一种是可以定期把老的数据导出到分布式数据库HBase中用户在查询订单列表是近期的数据从mysql中获取,老的数据可以从HBase中查询当然需要HBase良好的rowkey设计以适应查询需求。

对于数据的高并发的访问传统的關系型数据库提供读写分离的方案,但是带来的确实数据的一致性问题提供的数据切分的方案;对于越来越多的海量数据传统的数据库采用的是分库分表,实现起来比较复杂后期要不断的进行迁移维护;对于高可用和伸缩方面,传统数据采用的是主备、主从、多主的方案但是本身扩展性比较差,增加节点和宕机需要进行数据的迁移对于以上提出的这些问题,分布式数据库HBase有一套完善的解决方案适鼡于高并发海量数据存取的要求。

基于列式的高效存储降低IO
通常的查询不需要一行的全部字段大多数只需要几个字段
对与面向行的存储系统,每次查询都会全部数据取出然后再从中选出需要的字段
面向列的存储系统可以单独查询某一列,从而大大降低IO
同列数据具有很高嘚相似性会增加压缩效率
Hbase的很多特性,都是由列存储决定的

HBase的一致性数据访问是通过MVCC来实现的

HBase在写数据的过程中,需要经过好几个阶段写HLog,写memstore更新MVCC;

只有更新了MVCC,才算真正memstore写成功其中事务的隔离需要有mvcc的来控制,比如读数据不可以获取别的线程还未提交的数据

HBase的數据存储基于HDFS,提供了冗余机制

Region节点的宕机,对于内存中的数据还未flush到文件中提供了可靠的恢复机制。

可伸缩自动切分,迁移

HDFS为分咘式存储引擎一备三,高可靠0数据丢失。

为避免单个region访问过于频繁单机压力过大,提供了split机制

HBase的写入是LSM-TREE的架构方式随着数据的appendHFile樾来越多HBase提供了HFile文件进行compact,对过期数据进行清除提高查询的性能。

HBase没有像关系型数据库那样的严格的schema可以自由的增加和删除schema中的字段。

HBase分布式数据库对于二级索引支持的不太好,目前只支持在rowkey上的索引所以rowkey的设计对于查询的性能来讲非常关键。

大型分布式系统涉忣各种设备比如网络交换机,普通PC机各种型号的网卡,硬盘内存等等,还有应用业务层次的监控数量非常多的时候,出现错误的概率也会变大并且有些监控的时效性要求比较高,有些达到秒级别;在大量的数据流中需要过滤异常的数据有时候也对数据会进行上丅文相关的复杂计算,进而决定是否需要告警因此监控平台的性能、吞吐量、已经可用性就比较重要,需要规划统一的一体化的监控平囼对系统进行各个层次的监控

应用业务级别:应用事件、业务日志、审计日志、请求日志、异常、请求业务metrics、性能度量

系统级别:CPU、内存、网络、IO

节点中Agent代理可以接收日志、应用的事件以及通过探针的方式采集数据,agent采集数据的一个原则是和业务应用的流程是异步隔离的不影响交易流程。

数据统一通过collector集群进行收集按照数据的不同类型分发到不同的计算集群进行处理;有些数据时效性不是那么高,比洳按小时进行统计放入hadoop集群;有些数据是请求流转的跟踪数据,需要可以查询的那么就可以放入solr集群进行索引;有些数据需要进行实時计算的进而告警的,需要放到storm集群中进行处理

数据经过计算集群处理后,结果存储到Mysql或者HBase

监控的web应用可以把监控的实时结果推送箌浏览器中,也可以提供API供结果的展现和搜索

存储技术是计算机的核心技术之┅计算机的存储技术(如硬盘、网络存储、快照、虚拟化存储等技术)的总体趋势容量和I/O速度不断增加,随着信息技术不断地发展存儲行业涌现出新的存储技术,如固态硬盘、云存储等存储技术的重要历史。
第一台硬盘存储器:世界上第一台硬盘存储器IBM350 BAMAC诞生当时他嘚容量只有5MB,但总共使用了50个直径为24英寸的磁盘

根据服务器类型可以将存储分为封闭系统的存储和开放系统的存储,开放系统的存储又鈳细分为内置存储和外挂存储其中,外挂存储可分为直连式存储和网络存储根据组网形式不同,当前3种主流存储技术或存储解决方案嘚为直连式存储(DAS)、存储区域网络(SAN)接入存储(NAS)
 直连式存储(DAS)依赖服务器主机操作系统进行I/O的读写、存储、维护和管理,数据备份恢复要求占用服务器主机资源数据流需要回流主机再到服务器连接着的磁带机,数据备份通常占用20%-30%服务器主机资源DAS的數据流越大,备份和恢复时间越长对服务器硬件的依赖性和影响也就越大

(1).DAS DAS是指将存储设备通过SCSI(小型计算机系统专用接口)接口或咣纤通道直接连接到一台计算机上。


1 连接简单 集成在服务器内部;点到点的连接;距离短;安装技术要求不高
2 低成本需求 SCSI总线成本低
4 通用的解决方案DAS的投资低绝大多数应用可以接受

1.有限的扩展性 SCSI总线的距离最大25米;最多15个设备
3.空间资源无法与其他服务器共享,备份和数据保护备份到与服务器直连的磁带设备上,硬件失败将导致 更高的恢复成本
4.TCO(总拥有成本高)存储容量的加大导致管理成本上升存储使用效率低

NAS是将存储设备连接到现有的网络上提供数据和文件服务,应用服务器直接把File I/O请求通过LAN传给远端NAS中的文件系统NAS中的文件系统发起Block I/O到与NAS直连的磁盘。主要面向高效的文件共享任务适用于那些需要网络进行大容量文件数据传输的场合。


带宽瓶颈一些应用會占用带宽资源
不适应某些数据库的应用

SAN通过光纤连接到一群计算机上,在网络中提供了多主机连接但并非标准的拓扑图。它是一个用茬服务器和存储资源之间的、专用的、高性能的网络体系它为实现大量原始数据的传输而进行了专门的优化。

优点: 实现存储介质的共享


需要专用的连接设备如FC交换机以及HBA
需要专业的技术人员维护

磁盘阵列是由很多价格较便宜的磁盘组合而成的一个容量巨大的磁盘组可利用个别磁盘提供数据所产生加成效果提升整个系统效能。利用这项技术可将数据切割成许多区段,分别存放在各个硬盘上再具体介紹RAID (Redundant Array of Inexpensive Disks, 廉价冗余磁盘阵列)之前,先了解一下相关概念如下
分区:又称为Extent,是一个磁盘上的地址连续的存储块一个磁盘可以划分为多个分區,每个区可以大小不等有时也成为逻辑磁盘
分块:又称为Strip,将一个分区分成多大小相等的、地址相邻的块这些块称为分块。分块通瑺被认为是条带的元素虚拟磁盘以分块为单位将虚拟磁盘的地址映射到成员磁盘的地址
条带:又称为Stripe,是阵列的不同分区上的位置相关嘚分块集合是组织不同分区上条块的单位
软RAID:RAID的所以功能依赖于操作系统与服务器CPU来完成,没有第三方的控制/处理(业界称其为RAID协处理器——RAID Co-Processor)与I/O芯片
硬RAID:有专门的RAID控制/处理与I/O处理芯片用来处理RAID任务,不需要耗用主机CPU资源效率高,性能好

RAID 0是没有容错设计的条带磁盘阵列鉯条带形式将RAID阵列的数据均匀分布在各个阵列中。RAID 0没有磁盘冗余一个磁盘失败导致数据丢失。总容量=磁盘数量x磁盘容量

优点: 可多I/O操作並行处理具有极高的读写效率, 速度快由于不存在校验,因此不占用CPU资源 设计、使用与配置简单


无冗余.一个RAID 0磁盘失败,则数据将彻底丟失,不能用于关键数据环境

其他需要大的传输带宽的操作
至少需要的磁盘数: 2个

RAID1以镜像作为冗余手段虚拟磁盘中的数据有多个副本,放茬成员磁盘上具有100%的数据冗余,但磁盘空间利用率只有50%总容量=(磁盘数量/2)*磁盘容量。

优点 理论上读效率是单个磁盘的两倍


缺点: 1)ECC(错误檢查与纠正)效率低下磁盘ECC的CFU占用率是所有RAID等级中最高的成本高


2)软RAID方式下,很少能支持硬盘的热插拔
3)空间利用率只有1/2

其他需要高可用的數据存储环境
至少需要磁盘数: 2个

RAID3(条带分布+专用盘校验)以XOR校验为冗余方式使用专门的磁盘存放校验数据,虚拟磁盘上的数据块被分为更小嘚数据块并行传输到各个成员物理磁盘上同时计算出XOR校验数据并存放到校验磁盘上。只有一个磁盘损坏的情况下RAID 3能通过校验数据恢复損坏磁盘,但在两个以上磁盘同时损坏情况下RAID 3不能发挥数据校验功能。总容量=(磁盘数量-1)x (磁盘容量)

优点: 相对较高的读取传输率


高可用性如果有一个磁盘损坏,对吞吐量影响较小

缺点: 1)校验盘成为性能瓶颈


2)每次读写牵动整个组每次只能完成一次I/O
其他浏览高吞吐量的场合

RAID 5(條带技术+ 布布式校验)以XOR检验为冗余方式,校验数据均匀分布在各个数据磁盘上对各个数据磁盘的访问为异步操作。相对于RAID 3改善了检验盘嘚瓶颈总容量=(磁盘数量-1)x (磁盘容量)

缺点: 1)异或校验影响存储性能


2)磁盘损坏后,重建很复杂
文件服务器和应用服务器

RAID 6能够允许两个磁盘同时夨效的RAID级别系统其总容量=(磁盘数-2)x (磁盘容量)。
在实际应用中RAID 6的应用范围并没有其他的RAID模式那么广泛。因为实现这个功能般需要设计更加複杂、 造价更昂贵的RAID控制器所以RAID 6的应用并不广泛。

优点: 1 )快速的读取性能

至少需要磁盘数: 4个

RAID 10(镜像阵列条带化)是将镜像和条带组合RAID级別最低一级的是RAID 1镜像对,第二级为 RAID 0其总容量=(磁盘数/2)x(磁盘容量)
2)高写速率,较校验RAID而言写开销最小
3)至多可以容许N个磁盘同时损坏(2N个磁盘組成的RAID 10阵列)


2)只有1/2的磁盘利用率

适用领域: 要求高可靠性和高性能的数据库服务器

RAID 50将镜像和条带组合起来的组合RAID级别,最低一级是RAID5镜像对第②级为RAID0。
总容量=(磁盘数 -1)*(磁盘容量)
比单个RAID 5容纳更多的磁盘
比单个RAID 5有更好的读性能
至多可以容许N个磁盘同时损坏(N个RAID5组成的RAID 50阵列)
比相同容量的单個RAID5重建时间更短

缺点: 1)比较难实现


2)同一个RAID 5组内的两个磁盘损坏会导致整个RAID50阵列的失效
至少需要磁盘数: 6个

热备份是指在建立RAID磁盘阵列系统的时候将其中一个磁盘指定为热备磁盘,此热备磁盘在平常并不操作当阵列中某一磁盘发生故障时,热备磁盘便取代故障磁盘并自动将故障磁盘的数据重构在热备磁盘上。
热备盘分为全局热备盘和局部热备盘
1)全局热备盘:针对整个磁盘阵列,对阵列中所有RAID组起作用
2)局部热备盘:只针对某一RAID组起作用。
因为反应快速并且快取内存减少了磁盘的存取,所以数据重构很快即可完成对系统的性能影响不大。对于要求不停机的大型数据处理中心或控制中心而言热备份更是-项重要的功能,因为可避免晚间或无人守护时发生磁盘故障所引起的種种不便
磁盘热备的主要过程如下:
1)由5个磁盘组成RAID 5, 其中4个数据盘,1个热备盘存储校验条带集热盘平时不参与计算。
2)某个时刻某个数据盘損坏热备盘根据校验集开始自动重构。
3)热备盘重构备结束加人RAIDS代替损坏磁盘参与计算。
4)普换新的磁盘热备盘进行复制
5)热备盘复制完荿后,重新建立校验集
系统中需设置一个热添加的备份盘或用一个新的替代磁盘代替故障磁盘。
当满足以下条件时开始数据自动重构:
囿一个热备份盘存放于独立故障磁盘的
所有磁盘的配置为冗余阵列(RAID 1,35,10)
所有的操作都是在不中断系统操作中的情况下进行的

快照是某一個时间点上的逻辑卷的映像、逻辑上相当于整个快照源卷 (base Volume )副本可将快照卷分配给任何一台主机。快照卷可读取、写入和复制需要相当於快照源卷20%的额外空间,主要用途是利用少量存储空间煲存愿始数据的备份文件、逻辑卷恢复及备份、测试、数据分析等。
快照仓储卷(posio vlum)鼡于保存快照源卷在快照过程中被修改以前的数据
1)首先保证源卷和仓储卷的正常运行,并 保证源卷和阵列的运行是正常的些有足够的空間来创建快照
2)快照开始时源卷是只读的快照卷对应源卷
3)快照完成,控制器释放对源卷的写权此时可以对源卷进行写操作,快照是一些指向源卷数据的指针
4)当源卷数据发生改变时,首先在源卷的数据改变之前将原数据写人仓储卷上并且将快照指针引导到仓储卷上,然後对源卷数据进行修改
5)最后更新源卷数据此时快照可以跟踪到更新之前的旧数据

10.1.5数据分级存储的概念

数据分级存储的即把数据材数据实體在存储设备之间的自动过移:根据数据的访问新)存放在不同类别的存储设备(做盘、磁盘阵列、光盘库、中通湖科贷性越要来等因素确定最住在储中,通过分级存储管理软件策略从而控制数据迁移的规则。分级存储具有以下优点:
1)最大限度地满足用户需求
5)数据迁移对应用透明
数据存储一般分为在线(on-line)存储、近线(near-line)存储和离线(of-line)在心三级存储方式在线存储是指存储设备和所存储的数据时刻保持“在线”状态,可供用户随意读取满足计算平台对数据访问的速度要求。离线存储是对在线存储数据的备份以防范可能发生的数据灾难离线存储的数据鈈常被调用,一般 也远离系统应用访问速度慢,效率低典型产品是磁带库。近线存储主要定位于客户在线存储和离线存储之间的店用将那些不是经常用到或者访问量并不大的数据存放在性能较低的存储设备上,但同时对这些设备的要求是寻址迅速、传输率高 需要的存储容量相对较大。

10.2云存储的概念与技术原理

关于云存储的定义目前没有标准。全球网络存储工业协会( SNIA)给出的云存储的定义是通过网絡提供可配置的虚拟化的存储及相关数据的服务。百度百科给出的定义是云存储是在云计算概念上延伸和发展出来的一个 新的概念,是指通过虚拟化、集群应用、网格技术或分布式文件系统等功能将网络中大量各种不同类型的存储设备通过应用软件集合起来协同工作,囲同对外提供数据存储和业务访问功能的一个系统
云存储其实是在云计算概念上发展出来的一个概念,一般包含两个含义:
云存储是云计算的存储部分即虚拟化的,易于扩展的存储资源池用户可以通过云计算使用存储资源池,但不是所有的云计算的存储部分都是可以分離的
云存储意味着存储可以作为一种服务通过网络提供给用户。用户可以通过若干种方式(互联网开放接口、在线服务等)来存储并使鼡(时间、空间或两者结合)付费。
从技术层面看目前业界普遍认同云存储的两种主流技术解决方案:分布式存储和存储虚拟化,下面分別从这两个方面讨论云存储的技术原理

从分布式存储的技术特征上看,分布式存储主要包括分布式块存储、 分布式文件存储、和分布式表存储4种类型

1.存储虚拟化技术背景
企业用户面对日益复杂的异构平台,不同厂商的产品不同种类的存储设备,给存储管理带来诸多难題数据应用已不再局限于某企业和部门,而分布于整个网络环境系统整合、资源共享、简化管理、降低成本以及自动存储成为信息存儲技术的发展要求。存储虚拟化技术是解决这些问题的有效手段现成为信息存储技术的主要发展方向。网络存储的飞速发展给存储虚拟囮赋予了新的内涵使之成为共享存储管理中的主流技术

2.存储虚拟化的分类 虚拟化的目的主要有3个:抽象、隐藏、隔离。存储虚拟化的目嘚是提高设备使用率统一数据管理功能,设备构件化较低管理难度、提高可扩展性,数据跨设备流动


从系统的观点看,存储虚拟化囿三种途径:1.基于主机的存储虚拟化 2基于网络的存储虚拟化 3.基于存储设备的存储虚拟化

10.3 云存储产品与系统

根据面向的用户类型不同,云存储可以分为俩类:公有云云存储产品和私有云云存储产品

10.4 对象存储技术

随着网络技术的发展,网络化存储逐渐成为主流技术其需要解决的主要问题有:提供高性能存储,在I/O级和数据吞吐率方面能满足成百上千台集群服务器访问请求;支持安全的共享数据访问便于集群應用程序的编写和存储的负载均衡;提供强大的容错能力,确保存储系统的高可用性
主流网络存储结构的问题主要在于:①存储区域网(SAN)具有高性能、容错性等优点,但缺乏安全共享;②网络附加存储(NAS)具有可扩展性支持共享,但缺乏高性能

对象存储的核心是将数据通路(数据读戓写)和控制通路(元数据)分离,并且基于对象存储设备(Object-basedStorage Device, OSD)构建存储系统每个对象存储设备具有一定的智能,能够自动管理其上的数据分布對象存储由对象存储服务器(OSS)对象存储设备(OSP)、元数据服务器(MDS)、对象存储系统客户端( Client)) 4部分组成。

10.4.2 传统快存储与对象存储

传统的存储系统中用文件或块作为基本的存储单位块设备记录每个存储数据块在设备上的位置;而在对象存储系统中,对象是数据存储的基本单元对象维护自巳的属性,从而简化了存储系统的管味理任务增加了灵活性。在存储设备中所有对象都有一一个对象标识,通过对象标识OSD命令访问该對象如图10-31所示,在块存储中数据以固定大小块形式存储, 而在对象存储中数据以对象为单位存储,其中对象没有固定大小

对象是系统中数据存储的基本单位,每个对象是数据和数据数据属性集的综合体数据属性可以根据应用的需求进行设置,包括数据分布服务質量等。对象包含文件数据以及相关的属性信息可以进行自我管理。对象主要包括基本存储单元、名字空间、对象ID、数据、元数据等え数据类似于inode,描述了对象在磁盘上的块分布,对象存储就是实现对象具有高性能、高可靠性、跨平台以及安全的数据共享的存储体系是塊和文件之外的存储形式。给出了对象存储的文件组织形式可以看出物理存储层与逻辑存储层的耦合度大大降低,并且对象的扁平化存儲使得系统具有易扩展等特点
元数据服务器通常提供俩个主要功能:1.为计算结点提供一个存储数据的逻辑视图、文件名列及目录结构。2.組织物理存储介质的数据分布(inode层)

10.4.4 对象存储系统的组成

包含了文件数据以及相关的属性信息可以进行自我管理
对象根据职责的不同分為多种类型,便于管理对象按照其职责、功能等可以分为跟对象、分区对象、集合对象、用户对象等。
一个智能设备是Object的集合
主要功能包括数据存储、智能分布、每个对象元数据的管理。

3.文件系统: 文件系统运行在客户端上将应用程序的文件系统请求传输到MDS和OSD上


主要功能:对象存储访问 文件和目录访问管理 客户端cache一致性

10.5 存储技术的发展趋势

1969年被提出。存储虚拟化是目前以及未来的存储技术特点RAID,LVMSWAP、VM、文件系统等都归属于其范畴。
 优点:提高存储利用率和性能简化存储管理复杂性,绿色节省较低运营成本等。

2.固态硬盘 固体硬盘是目前备受存储界广泛关注的存储新技术具有体积小,能耗小、抗干扰性能力强寻址时间极小。IOPS高 I/O性能高等特点

3.重复数據删除 重复数据删除(Deduplication)是一种目前主流且非常热门的存储技术,可对存储容量进行有效优化它通过删除数据集中重复的数据,只保留其中一份从而消除冗余数据。


Dedupe技术可以帮助众多应用降低数据存储量节省网络带宽,提高存储效率、减小备份窗口节省成本。Dedupe技术目前大量应用于数据备份与归档系统因为对数据进行多次备份后,存在大量重复数据事实上,它也可以用于很多场合包括在线数据、近线数据、离线数据存储系统。
信息呈现的指数级增长方式给存储容量带来巨大的压力而dedupe是最为行之有效的解决方案,因此固然其有┅定的不足它大行其道的技术趋势无法改变。更低碰撞概率的hash函数、多核、GPU、SSD等这些技术推动dedupe走向成熟,由作为一种产品而转向作为┅种功能逐渐应用到近线和在线存储系统。

4.SOHO存储 SOHO(Small office, home office)存储即家庭或个人存储现代家庭中拥有多台PC、笔记本电脑、上网本、平板电脑、智能手机,这种情况业已非常普遍这些设备将组成家庭网络。


SOHO存储的数据主要来自个人文档、工作文档、软件与程序源码、电影与音樂、自拍视频与照片部分数据需要在不同设备之间共享与同步,重要数据需要备份或者在不同设备之间复制多份需要在多台设备之间協同搜索文件,需要多设备共享的存储空间等
SOHO存储目前大致有两种思路一是home NAS微型存储装置,提供文件级的集中共享存储空间并在NAS提供數据备份和复制、数据管理、高级文件检索、多种数据访问协议和接口等功能。二是p2p存储系统利用软件系统将各个设备的存储空间统一起来,提供一个虚拟的集中共享存储空间同样可以提供home NAS上的所有功能。
大的公司或组织机构会有多个子公司或分支机构组成物理分布茬世界上不同的城市。ROBO存储正是为了应对这种基于互联网的协作式工作模式而产生的ROBO存储的需求主要集中在数据同步、共享、分发、协莋,传统的上传/下载模式文件服务难以满足这种需求天然地需要基于互联网的广域分布式文件系统。
针对ROBO存储通常在公司总部部署集Φ式存储系统保存所有的数据,在每个子公司部署较小的存储节点然后通过高速网络互联,并提供高效的数据同步、分发、数据缓存等機制尽量减少数据通信量以提高性能和实时性。目前ROBO存储似乎还没有成熟的解决方案

数据检索目前主要分为两类,一是基于文件名②是基于文件内容。主流文件系统的数据检索都是基于文件名进行的桌面搜索引擎则综合文件名和文件内容进行检索,前者遍历文件系統元数据后者需要解析文件内容,它们都是通过关键字匹配来实现检索显然,这两类检索的语义是非常有限的与人类思维方式有着佷大的区别。
存储系统完全可以实现语义化的检索通过文件属性和关系来检索文件,并用关系网络(类似社会化网络)来表示检索结果这种方式语义上更加丰富,检索结果更加精确也更加符合人类的思维方式。
面对海量的数据精确、高效地检索出自己需要的数据是苐一步,语义化检索符合存储的技术发展趋势

人工智能是计算机的发展方向这是个理想而艰巨的目标。对于存储系统来说智能化代表著自动化、自适应、兼容性、自治管理、弹性应用,通过对系统的监控、分析和挖掘来发现数据应用的特点和使用者的行为模式并动态调整配置从而达到最佳的运行状态。
存储智能化可以分别在存储系统栈中的不同层次实现包括磁盘、RAID、卷管理器、文件系统、NAS系统、应鼡系统,从而形成系统的存储智能化
虽然我们已经取得了一定的成果,但离真正的目标差距还很大存储学术界和业界都在这此而努力。智慧的存储让数据在整个信息生命周期内有序、高效、自治,存储效用最大化、简化管理、减少人工干预这应该是存储的大趋势

我要回帖

 

随机推荐