精华内容
下载资源
问答
  • SDCC 2015架构专场札记:一线互联网公司的架构实践 发表于8小时前| 835次阅读| 来源CSDN| 1 条评论| 作者么刚 ...SDCC架构数据库互联网性能...本文是来自搜狗商业平台架构师参加算法专场的听课札记,以飨读者。

    SDCC 2015架构专场札记:一线互联网公司的架构实践

    发表于 8小时前| 835次阅读| 来源 CSDN| 1 条评论| 作者 么刚

    width="22" height="16" src="http://hits.sinajs.cn/A1/weiboshare.html?url=http%3A%2F%2Fwww.csdn.net%2Farticle%2F2015-12-03%2F2826378&type=3&count=&appkey=&title=11%E6%9C%8821%E6%97%A5%EF%BC%8C%E4%B8%BA%E6%9C%9F%E4%B8%89%E5%A4%A9%E7%9A%84SDCC2015%E4%B8%AD%E5%9B%BD%E8%BD%AF%E4%BB%B6%E5%BC%80%E5%8F%91%E8%80%85%E5%A4%A7%E4%BC%9A%E6%88%90%E5%8A%9F%E9%97%AD%E5%B9%95%EF%BC%8C%E6%88%91%E4%BB%AC%E7%89%B9%E9%82%80%E8%AF%B7%E4%BA%86%E4%B8%9A%E5%86%85%E4%B8%93%E5%AE%B6%E3%80%81%E4%B8%8E%E4%BC%9A%E8%80%85%E5%88%86%E4%BA%AB%E4%BB%96%E4%BB%AC%E7%9A%84%E5%90%AC%E8%AF%BE%E6%84%9F%E5%8F%97%E5%8F%8A%E4%BB%96%E4%BB%AC%E7%9C%BC%E4%B8%AD%E7%9A%84%E6%9E%B6%E6%9E%84%E4%B8%93%E5%9C%BA%E3%80%82%E6%9C%AC%E6%96%87%E6%98%AF%E6%9D%A5%E8%87%AA%E6%90%9C%E7%8B%97%E5%95%86%E4%B8%9A%E5%B9%B3%E5%8F%B0%E6%9E%B6%E6%9E%84%E5%B8%88%E5%8F%82%E5%8A%A0%E7%AE%97%E6%B3%95%E4%B8%93%E5%9C%BA%E7%9A%84%E5%90%AC%E8%AF%BE%E6%9C%AD%E8%AE%B0%EF%BC%8C%E4%BB%A5%E9%A3%A8%E8%AF%BB%E8%80%85%E3%80%82&pic=&ralateUid=&language=zh_cn&rnd=1449146485886" frameborder="0" scrolling="no" allowtransparency="true"> 摘要:11月21日,为期三天的SDCC2015中国软件开发者大会成功闭幕,我们特邀请了业内专家、与会者分享他们的听课感受及他们眼中的架构专场。本文是来自搜狗商业平台架构师参加算法专场的听课札记,以飨读者。

    【编者按】11月21日,为期三天的SDCC2015中国软件开发者大会成功闭幕,主办方总计邀请了95余位演讲嘉宾,为参会者奉献了10个主题演讲,9大技术专场论坛(80余场技术演讲),另外还有5场特色活动。另外,据官方统计参会人数高达1067名(不含工作人员)。

    其中20日的架构专场,现场听讲人数一度爆满,而没有机会亲临现场的童鞋们,我们特邀请了业内专家、与会者分享他们的听课感受及他们眼中的架构专场。以下是来自搜狗商业平台架构师么刚参加架构专场的听课札记,以飨读者。

    另外,我们在架构专场举办的当天也做了直播,大家也不妨看一下我们的视角:

    以下为么刚的参会笔记:

    航天信息股份有限公司高级架构师范刚:在互联网+的时代,该如何应对系统变革

    来自航天信息股份有限公司的范刚分享了在多年实践中对于系统改造重构的总结与思考。在互联网+的背景之下,很多架构师们面对的是层出不穷的需求、不断更新迭代的新技术以及满身补丁,让开发运维无比头大的老旧系统。是继续缝缝补补还是推倒重来?何去何从,范刚给出了渐进式改造、优化与维护并行,平台与重构并重的答案。很多老旧系统都面临着体系老旧,业务繁杂,代码耦合度高的问题,所谓的渐进式改造,就是在保持系统功能不变的情况下,将业务领域层和技术支撑平台解耦,并实现业务领域层的模块化,最终”像更换零件一样更新系统”。在实际的生产环境中,在进行系统改造的同时,必须满足新的业务需求,对于这个问题范刚给出的经验总结是优化与维护并行:由改造组进行系统优化,维护组满足业务需求,系统优化跟随业务版本上线,快速迭代小步快跑,便于系统优化阶段性效果的验证,也可以有效避免大版本切换的系统性风险。而平台与重构并重是技术支撑平台和业务领域层的优化同时展开,平台组完成技术架构的调研选型、基础平台、公共组件的设计和开发;业务组根据业务逻辑进行模块划分,结合业务需求制定项目计划,完成渐进式重构改造。最后结合项目实例,总结得到软件重构的七步曲(图1)。


    图1 软件重构七步曲

    搜狗商业平台架构师刘建:搜狗商业平台基础架构演化实践

    刘建以搜狗商业平台基础架构为例,向我们完整的展示了一个系统从ALL-IN-ONE的初始阶段一步步演化成为一个高性能、高可用、高可扩展的成熟系统。搜狗商业平台的架构演化分为初始阶段、水平化、服务化和流式计算4个阶段(图2)。

    • 初始阶段,业务优先,快速迭代,但随着业务规模的迅速扩张,数据库健康度低,访问超时等问题日益凸显。
    • 在水平化阶段,通过计算水平化和存储水平化,成功解决了系统性能和存储问题,计算水平化的难点在于状态的处理,理想的设计是独立存储中间状态,实现计算节点的无状态化;而在进行存储水平化设计时,则需要更多的关注数据源的迁移成本,搜狗商业平台是通过自研的数据库分库分表框架Compass实现平滑迁移。
    • 在服务化阶段,通过优化解耦实现资源私有化,服务接口化和模块独立化,有效降低了团队之间的沟通协作成本。搜狗商业平台的服务化基础框架Polaris,是在Thrift基础之上增加了认证,授权,监控,失效重连和负载均衡等机制自研形成。
    • 为了更好的服务客户,引入了kafka + storm + pump + Binlog Tunnel的流式计算框架,流式系统在设计选型时需要充分考虑消息顺序性,消息重复和消息丢失问题,必要时可以进行双路比对,降低系统风险。

    最后值得一提的是,搜狗商业平台最近开源了嵌入式数据库分库分表框架Compass,遵循标准的DataSource接口,支持分库分表、读写分离和负载均衡,可屏蔽底层数据源差异,支持方便的数据源迁移和扩容缩容,并能够进行有效的数据源健康度监控。


    图2搜狗商业平台基础架构演化

    饿了么创新产品研发部副总监程军: 饿了么整体架构

    饿了么技术体系是典型的业务驱动,业务量的爆发式增长推动整体架构不断向前演化。饿了么经历了单机时代、集群时代、SOA时代(图3)的演进过程。为解决性能问题,核心gateway使用F5代替了HAProxy。在SOA过程中,对于核心服务采用数据库按领域拆分、热数据缓存、异步消息通知和服务降级的策略,有效的应对流量洪峰。在数据库方面,饿了么自研了数据中间件DAL,实现了MySQL的连接池、分库分表、读写分离、查询拒绝等功能。引入Service Orchestrator实现前后端分离,提高系统并发度、缩短响应时间。另外饿了么的核心服务是基于Python 构建,也为我们提供了一个用python架构支持高并发互联网服务的一个范例。


    图3饿了么整体架构

    小米科技的架构师张涛:小米网架构变迁实践

    来自小米科技的张涛,分享了小米网的架构变迁以及架构选型的一些思考。为应对业务的迅猛增长,小米网对系统架构做了如下的演进优化:对DB按系统拆分,做到水平可扩展;系统调用关系由网状结构优化为星状结构,引入MQ,实现系统解耦;纵向来看,把系统划分为调度层、业务层、数据层三层结构,功能明确,接口清晰;引入Cobar解决浪涌导致的高压。如何在架构设计层面提高效率,降低成本,小米网的做法是抽象基础服务和基础组建,节约开发成本,提升服务质量;按照“业务纵切,平台横切”的方案,实现业务的模块化和基础服务的平台化。另外张涛还介绍了小米网的特色技术,包括流量控制架构、通用缓存框架MCC、异步消息推送服务Notify、库存设计和智能调拨算法、虚拟化和云服务、监控和异常、安全策略、SOA等。其中MCC采用的是Twemproxy+redis成熟缓存方案,并考虑了数据热加载,业务隔离,多机房灾备等问题而形成的通用缓存框架;告警量爆炸也是大中型互联网公司的常见问题,对此小米给出的建议是:区分异常和告警,只有满足一定频度或数量的异常才能升级为告警,而所有告警必须处理;小米网的SOA框架如下图4 所示,框架选型是基于Thrift实现RPC核心功能,基于etcd完成服务注册、服务发现、failover、框架支持多语言环境,研发可以用很小的成本快速搭建RPC服务。


    图4小米SOA框架

    途牛旅游网研发总监高健:途牛网站无线架构变迁

    途牛旅游网的高健从服务化的推进、多机房异地部署、性能优化和APP客户端技术4个方面介绍了途牛无线架构的演进。在服务化方面,通过引入MQ实现服务的异步化,通过数据库的分库分表实现高性能的并发计算,通过引入NoSQL、MySQL异构同步机制,Unix域通信机制实现分布式计算(图5),并通过注册中心和监控中心实现整个系统的高可用性和高可维护性。多机房异地部署面临的问题是专线不稳定和数据同步延迟过大,因此对于对实时性要求较高的数据可以采用应用层双写的方案。在性能优化部分,途牛采用Codis进行热数据缓存,并且自研了缓存更新系统BWT和监控系统OSS,保障Codis的易用性和平稳运行。而在APP技术方面,采用插件式开发框架,模块之间相互独立,降低耦合度;使用静态化资源,提升响应速度;引入alibaba的AndFix框架,实现热修复。


    图5途牛分布式计算架构

    快的打车架构师王小雪:快的打车架构实践

    快的架构师王小雪完整的回顾了快的打车架构演化过程,从最开始的功能基本可用,到核心链路优化,再到体系化架构设计。在核心链路优化阶段面临的主要问题是LBS查询性能瓶颈和长连接服务不稳定,直接影响到快的核心业务,问题的原因更多地涉及实现层面的细节:比如MongoDB早期版本全库锁的问题,频繁内存拷贝的问题,超时管理算法效率的问题,考验着架构师问题快速定位的能力。而在体系化架构设计阶段则是更为全局和宏观的设计和优化,包括:系统分布式改造、无线开发平台、日志收集检索系统、实时计算与监控和数据层改造等。其中系统分布式改造的技术选型是dubbo+RocketMQ,实现服务之间的接口化和异步化;日志收集和检索系统主要功能是实现问题的快速定位,技术选型是log4j + flume + elasticsearch的组合,单个请求的链式调用关系通过flag进行串联,实现分布式系统的问题追踪和定位;快的的实时计算系统目标是提供实时准确的运营数据,技术选型是较为通用的RocketMQ+storm+HBase,RocketMQ为storm和HBase提供流量平滑功能,HBase在使用时根据业务场景避免update操作,提升性能;在数据源改造(图6)的基本思路是用HBase查询代替Mysql的SQL查询,其中最核心的技术点是Mock Mysql Slave,从mysql master得到binlog数据通过MQ同步到HBase、HDFS等异构存储介质之上,另外HBase的二级索引也是一个社区比较热门的话题,快的的方法是在客户端插入二级索引,相比Coprocessor的方案可更好的兼容HBase批量插入操作。


    图6 统一数据同步方案

    58同城系统架构师孙玄:58同城高性能移动Push推送平台架构演进之路

    孙玄介绍了58移动Push从单平台、多平台,再到高性能平台的演进过程。58最先提供的是iOS的Push服务,iOS不允许service后台常驻,因此APSN几乎是IOS Push的唯一选择,单平台阶段,58搭建了iOS Provider平台和APSN对接,提供了证书验证、连接池、错误处理等功能。随着移动流量的爆发,多终端,多APPs,多策略的业务需求,推动Push进入多平台阶段。关于Android推送,58采用的是自研Android Provider和第三方Push平台对接的方案;采用抽象公共逻辑,统一封装接口的方式解决需求多样化,逻辑复杂化的问题,提升开发效率。高性能阶段则重点解决的是Push性能和稳定性的问题,在性能优化方面,搭建IOS/Android统一的push平台(图7),并通过Push的并行化,异步化提升整体性能;关于稳定性的讨论主要是集中在Android终端,根据不同机型选择不同的Push通道,也可以根据策略选择失败重试机制。


    图7 58同城移动Push架构

    腾讯高级工程师徐汉彬:QQ会员活动运营平台的架构设计演变

    来自腾讯的徐汉彬以会员活动为背景介绍了AMS的架构演变。QQ活动运营的特点是活动多、周期短、个性化强而且过期作废。人力成本极为有限和层出不穷的业务需求是需要解决的主要矛盾,这里徐汉彬给出答案是构建高效的运营开发模式,整个系统架构从上至下分为前端层、CGI层和服务层,前端层提供基础组件,CGI实现业务逻辑,服务层提供平台支撑,通过活动配置文件实现前端逻辑和后端服务的自由组合(图8),使产品运营同学可以独立完成活动发布。除此之外,系统的性能、可用性和安全性也是架构师需要考虑的问题。性能优化方面,AMS引入NoSQL优化增查改删的性能;并采用了带版本号的CAS乐观锁机制提升高频操作的并发度,从而支撑了5w+/s的秒杀活动。对于可用性从架构设计和多维度运维监控两个方面来保证,架构设计层面充分考虑了水平扩容、failover、过载保护、服务降级等问题;在运维监控角度,建立多通道,多维度的监控告警机制,确保及时发现响应线上问题。关于安全体系,AMS采用了技术手段、产品设计、安全支撑体系多管骑下的思路,最大程度上保障业务安全。

    其实这里有一个可以引申开来的话题——科技公司的工具文化,有种比较激进的观点是用最优秀的人才来开发工具,提升整个团队,整个公司的效率,徐汉彬的分享也从一个侧面展示了技术工具的强大威力。


    图8腾讯AMS自动化运营体系

    总结

    听了上述一线架构大牛的分享,收获良多,同时也颇有感触。

    1. 全栈架构。从本次架构会场的分享涵盖了从基础架构到业务形态,从系统设计到持续交付,从安全、监控到虚拟化技术,从版本迭代到项目投入产出比等诸多领域。本质上,架构师的职责就是充分评估业务,人员,成本等要素在技术层面上保障服务的顺利落地,稳定运行并适时推动平滑升级,期间遇到的所有技术的问题都是架构师需要直面的。既是新业务新技术的探路者,又是扫清线上系统瓶颈的急先锋,架构师的担子,不轻。
    2. 趋同存异。一天的分享中,服务化、分库分表、异步、分布式、安全、监控等这些高频词反复出现,说明架构设计的基本原则和架构师们关注点是趋同的,甚至各自系统架构演化到不同阶段遇到的瓶颈和应对的举措也是惊人的相似。当然也有不同,比如安全,有些场景下关注的业务安全,有些则更关注数据安全;比如数据一致性,有些场景要求强一致性,有些只需关注最终一致性。而其实也正是业务场景的差异给了架构师们展示自己聪明才智的舞台。
    3. 拥抱变化。从分享的主题来看,变化、变迁、演化,主线是一个“变”字。业务量的迅猛增长会倒逼架构的优化和升级,快的和饿了么是典型的例子。而新技术出现也会推动架构的变革,比如服务化可以提升开发效率,降低协作成本;比如流式计算,可以改善用户体验甚至是引导用户需求。无论是业务驱动还是技术驱动,架构师都需要做的就是时刻拥抱变化,成为一个敏锐的观察者,技术航线的引领者和架构的实践者。
    展开全文
  • 互联网支付系统整体架构详解

    万次阅读 2017-12-09 09:27:08
    互联网支付系统整体架构详解 在互联网产品运营中,有很多小伙伴或许会遇到这样的困扰:产品好不容易推出来了,流量成本节节攀升,用户的活跃度、留存度却持续下降。 因此在瞬息万变的互联网产品环境中,需要...

                                     互联网支付系统整体架构详解

    在互联网产品运营中,有很多小伙伴或许会遇到这样的困扰:产品好不容易推出来了,流量成本节节攀升,用户的活跃度、留存度却持续下降。


    因此在瞬息万变的互联网产品环境中,需要研发接入支付系统来加入商业行为的闭环,支付系统能够帮助企业更好地实现商业化,利用那些为用户而生的支付体系产品,实现用户积累、商业变现。


    对于支付系统,有针对不同行业的支付系统,有支付宝,微信支付,paypal的通用网关支付,也有聚合了不同网关的聚合系统。


    不论你是对支付行业感兴趣,亦或自己研发支付系统,本篇内容会对你有价值。


    从产品分类、模块功能和业务流程,了解支付产品服务的设计


    支付产品模块是按照支付场景来为业务方提供支付服务。这个模块一般位于支付网关之后,支付渠道之前。 它根据支付能力将不同的支付渠道封装成统一的接口,通过支付网关来对外提供服务。所以,从微服务的角度,支付产品本身也是一个代理模式的微服务,它透过支付网关响应业务方请求, 进行一些统一处理后,分发到不同的支付渠道去执行,最后将执行结果做处理后,通过支付网关再回传给业务方。


    支付产品在支付系统参考架构图中之位置,请看下图所示:




    产品分类


    在不同的公司由于接入渠道和应用的差异,对支付产品分类略有不同。综合支付场景和流程,支付产品可以分为如下几类:


    支付产品是由支付系统对支付渠道进行封装而对业务方提供的支付能力。整体上来说,可以提供如下支付产品:


    1. 快捷支付

    用户在完成绑卡之后,在支付的时候,不需要再输入卡或者身份信息,仅需要输入支付密码就可以完成支付。对于小额度的支付,甚至可以开通小额免密,直接完成支付。 这种支付方式不会打断用户的体验,是目前主要的在线支付方式。一般快捷支付产品是通过封装银行或者第三方支付平台提供的快捷支付接口或者代付接口来实现的。

    2. 网银支付

    用户在支付的时候,需要跳转到银行网银页面来完成支付。在网银页面,需要输入用户的卡号和身份信息。这种支付方式会中断用户当前的体验,一般仅用于PC Web上的支付。 网银支付是封装银行提供的网银支付来实现。

    3. 协议支付

    协议支付也称代收或者代扣,代收指渠道授权商户可以从用户的银行账户中扣款,一般用于定期扣款,不用于日常消费。比如水电煤气、有线电视费。协议支付是通过封装银行、第三方支付提供的代扣或者快捷接口来实现。

    4. 平台支付

    使用微信、支付宝等第三方支付平台来完成支付。使用时,一般需要用户预先安装支付平台系统(手机上),注册并登录到第三方支付平台,并且已经在该平台上完成绑卡等操作。 由于微信、支付宝已经被大量使用,用户也产生对这些平台的信任,平台支付往往是电商公司的主要支付方式。

    5. 外卡支付

    对于由海外支付的需求,还需要提供外卡支付支持。 国内不少支付渠道都能支持外卡支付,如支付宝全球购等。直接对接Paypal,也是目前用的最多的外卡支付渠道。 关于外卡支付,以后会有专文介绍。

    6. 话费支付

    对于有包月小额类型的支付,手机话费也是一个不错的选择。目前也有一些平台可以支持话费支付,比如虹软、联动优势等。

    7. 虚币支付

    不少公司会有自己的虚拟币,比如京豆、Q币等。这些虚币也可以作为一种支付方式。

    8. 账户支付

    也成为余额支付、零钱支付等。 指为用户建立本地账户, 支持充值,之后可以使用这个账户来完成支付。

    9. 信用支付

    如京东的白条,蚂蚁花呗等,指使用信用账户进行透支,类似信用卡支付。

    10. 代付

    和代扣相反,代付是平台将钱打给用户。

    每一种支付方式的详细功能将在后续的各个章节中介绍。 这里先简要介绍支付产品模块的通用功能。


    模块功能


    支出产品根据其支付能力,对外提供不同的功能。整体上来说,一般支付产品需要提供如下接口:
    1. 签约和解约

    在快捷支付、代扣等产品中,用户在使用前,需要先完成签约。签约可以在渠道侧进行,一般第三方支付采用这种方式,当电商需要接入时,让第三方给授权。 银行和银联的签约一般是在电商侧进行, 电商侧负责收集用户的信息,调用银行和银联的接口进行签约。签约后,后续的支付行为就使用签约号来进行,无需再输入个人信息。 和签约相对应,解约则是取消签约关系。

    2. 支付

    支付是少不了的操作。 不同产品中支付行为不一样。快捷支付是在电商服务器上发起,请求渠道进行支付;网银支付则是跳转到银行支付网关上进行; 而账户支付、虚币支付,则是在本地进行的。

    3. 撤销和退款

    有些渠道区分撤销和退款,比如银联、农行等,撤销指取消当天在渠道侧未结算的交易; 而退款仅针对已经结算的交易。有些渠道则不作区分。

    4. 查询签约状态

    对于需要签约的交易,可以通过这个接口来查询签约状态。

    5. 查询订单状态

    通过这个接口来查询支付清单状态以及退款的订单状态。

    6. 预授权

    预授权交易用于受理方向持卡人的发卡方确认交易许可。受理方将预估的消费金额作为预授权金额,发送给持卡人的发卡方。

    7. 预授权撤销

    对已成功的预授权交易,在结算前使用预授权撤销交易,通知发卡方取消付款承诺。预授权撤销交易必须是对原始预授权交易或追加预授权交易最终承兑金额的全额撤销。

    8. 预授权完成交易

    对已批准的预授权交易,用预授权完成做支付结算。

    9. 预授权完成撤销

    预授权完成撤销交易必须是对原始预授权完成交易的全额撤销。预授权完成撤销后的预授权仍然有效。

    10. 对账

    通过FTP或者HTTP方式提供对账文件供商户侧对账。

    11. 余额查询

    查询商户的交易账户的余额,避免由于余额不足导致交易失败。 注意,不是客户的余额。 当然,不是所有的银行或者第三方支付都提供这个接口。


    业务流程


    上述操作,除了对账、查单外,每个操作实现的主流程,一般会包括参数校验,支付路由,生成订单,风险评估,调用渠道服务,更新订单和发送消息这7步,对于一些比较复杂的服务,还会涉及到异步同通知处理的步骤。


    1. 执行参数校验

    所有的支付操作,都需要对输入执行参数校验,避免接口受到攻击。

    • 验证输入参数中各字段的有效性验证,比如用户ID,商户ID,价格,返回地址等参数。

    • 验证账户状态。交易主体、交易对手等账户的状态是处于可交易的状态。

    • 验证订单:如果涉及到预单,还需要验证订单号的有效性,订单状态是未支付。为了避免用户缓存某个URL地址,还需要校验下单时间和支付时间是否超过预定的间隔。

    • 验证签名。签名也是为了防止支付接口被伪造。 一般签名是使用分发给商户的key来对输入参数拼接成的字符串做MD5 Hash或者RSA加密,然后作为一个参数随其他参数一起提交到服务器端。如支付网关设计所介绍,签名验证也可以在网关中统一完成。

    2. 根据支付路由寻找合适的支付服务

    根据用户选择的支付方式确定用来完成该操作的合适的支付渠道。用户指定的支付方式不一定是最终的执行支付的渠道。比如用户选择通过工行信用卡来执行支付,但是我们没有实现和工行的对接,而是可以通过第三方支付,比如支付宝、微信支付、易宝支付,或者银联来完成。那如何选择合适的支付渠道,就通过支付路由来实现。支付路由会综合考虑收费、渠道的可用性等因素来选择最优方案。

    3. 评估交易风险

    检查本次交易是否有风险。风控接口返回三种结果:阻断交易、增强验证和放行交易。

    1) 阻断交易,说明该交易是高风险的,需要终止,不执行第5个步骤;

    2) 增强验证,说明该交易有一定的风险,需要确认下是不是用户本人在操作。这可以通过发送短信验证码或者其他可以验证用户身份的方式来做校验,验证通过后,可以继续执行该交易。

    3) 放行交易,即本次交易是安全的,可以继续往下走。


    4. 生成交易订单

    将订单信息持久化到数据库中。当访问压力大的时候,数据库写入会成为一个瓶颈。

    5. 调用支付渠道提供的服务

    所有的支付服务都需要第三方通道来完成执行。一般银行渠道的调用比较简单,可以直接返回结果。一些第三方支付,支付宝,微信支付等,会通过异步接口来告知支付结果。

    6. 更新订单

    对于同步返回的结果,需要在主线程中更新订单的状态,标记是支付成功还是失败。对于异步返回的渠道,需要在异步程序中处理。

    7. 发送消息

    通过消息来通知相关系统关于订单的变更。风控,信用BI等,都需要依赖这数据做准实时计算。

    8. 异步通知

    如上述流程,其中涉及到调用远程接口,其延迟不可控。如果调用方一直阻塞等待,很容易超时。引入异步通知机制,可以让调用方在主线程中尽快返回,通过异步线程来得到支付结果。对于通过异步来获取支付结果的渠道接口,也需要对应的在异步通知中将结果返回给调用方。 异步通知需要调用方提供一个回调地址,一般以http或者https的方式。这就有技术风险,如果调用失败,还需要重试。而重试不能过于频繁,需要逐步拉大每一次重试的时间间隔。 在异步处理程序中,订单根据处理结果变更状态后,也要发消息通知相关系统。


    支付系统架构整体设计


    每个公司根据其业务和公司发展的不同阶段,所设计的支付系统也会有所不同。我们先看看互联网公司的一些典型的支付系统架构。

    支付宝

    我们先看看业内最强的支付宝系统。架构图如下:
    这个整体架构上并没有与众不同之处。在模块划分上,这个图显示的是最顶层的划分,也无法告知更多细节。 但支付宝架构文档有两个搞支付平台设计的人必须仔细揣摩的要点。 一个是账务处理。在记账方面,涉及到内外两个子系统,外部子系统是单边账,满足线上性能需求;内部子系统走复式记账,满足财务需求。在清结算这个章节中也是基于这个模型来详细介绍如何记账、对账和平账。

    另一个亮点是柔性事务处理,利用消息机制来实现跨系统的事务处理,避免数据库锁导致的性能问题。

    京东金融

    来自京东支付平台总体架构设计 。如下图:
    京东金融是在网银在线的基础上发展起来的。 网银在线的原班技术人员有不少来自易宝公司,在京东收购之后,又引入了支付宝的人才。

    因而从架构上受这两个公司的影响很大。

    去哪儿

    这是来自去哪儿公司分享的支付产品架构。请看下图:

    美团的支付平台架构

    来自美团的支付平台规划架构 。这是2015年的文档。 2016年美团才拿到支付牌照。 从这个架构,大家也能知道为什么美团必须拿到支付牌照。

    这些架构文档全部来自互联网公开资料。 对于架构是否真实反映实际系统情况,需要大家自行判断。 我们以这些文档为基础,分析支付系统的应有的软件架构。

    参考架构

    一般来说,支付系统典型架构会包含如下模块:

    支付系统从架构上来说,分为三层;

    1. 支撑层: 用来支持核心系统的基础软件包和基础设施, 包括运维监控系统、日志分析系统等。

    2. 核心层: 支付系统的核心模块,内部又分为两个部分: 支付核心模块以及支付服务模块。

    3. 产品层: 通过核心层提供的服务组合起来,对最终用户、商户、运营管理人员提供的系统。

    支撑系统

    支撑系统是一个公司提供给支付系统运行的基础设施。 主要包括如下子系统:

    1. 运维监控: 支付系统在下运行过程中不可避免的会受到各种内部和外部的干扰,光纤被挖断、黑客攻击、数据库被误删、上线系统中有bug等等,运维人员必须在第一时间内对这些意外事件作出响应,又不能够一天24小时盯着。这就需要一个运维监控系统来协助完成。

    2. 日志分析: 日志是支付系统统计分析、运维监控的重要依据。公司需要提供基础设施来支持日志统一收集和分析。

    3. 短信平台: 短信在支付系统中有重要作用: 身份验证、安全登录、找回密码、以及报警监控,都需要短信的支持。

    4. 安全机制: 安全是支付的生命线。 SSL、证书系统、防刷接口等,都是支付的必要设施。

    5. 统计报表: 支付数据的可视化展示,是公司进行决策的基础。

    远程连接管理、分布式计算、消息机制、全文检索、文件传输、数据存储、机器学习等,都是构建大型系统所必须的基础软件,这里不再一一详细介绍。

    支付核心系统

    支付核心系统指用户执行支付的核心流程,包括:

    1. 用户从支付应用启动支付流程。

    2. 支付应用根据应用和用户选择的支付工具来调用对应的支付产品来执行支付。

    3. 支付路由根据支付工具、渠道费率、接口稳定性等因素选择合适的支付渠道来落地支付。

    4. 支付渠道调用银行、第三方支付等渠道提供的接口来执行支付操作,最终落地资金转移。

    支付服务系统

    支持支付核心系统所提供的功能。服务系统又分为基础服务系统、资金系统、风控和信用系统。

    基础服务系统提供支撑线上支付系统运行的基础业务功能:

    1. 客户信息管理:包括对用户、商户的实名身份、基本信息、协议的管理;

    2. 卡券管理: 对优惠券、代金券、折扣券的制作、发放、使用流程的管理;

    3. 支付通道管理: 通道接口、配置参数、费用、限额以及QOS的管理;

    4. 账户和账务系统: 管理账户信息以及交易流水、记账凭证等。这里的账务一般指对接线上系统的账务,采用单边账的记账方式。 内部账记录在会计核算系统中。

    5. 订单系统: 一般订单系统可以独立于业务系统来实现的。这里的订单,主要指支付订单。

    资金系统指围绕财务会计而产生的后台资金核实、调度和管理的系统,包括:

    1. 会计核算: 提供会计科目、内部账务、试算平衡、日切、流水登记、核算和归档的功能。

    2. 资金管理: 管理公司在各个支付渠道的头寸,在余额不足时进行打款。 对第三方支付公司,还需要对备付金进行管理。

    3. 清算分润: 对于有分润需求的业务,还需要提供清分清算、对账处理和计费分润功能。

    风控系统是支付系统必备的基础功能,所有的支付行为必须做风险评估并采取对应的措施;信用系统是在风控基础上发展的高级功能,京东的白条,蚂蚁花呗等,都是成功的案例。

    支付应用

    支撑系统、核心系统和服务系统,在每个互联网公司的架构上都是大同小异的,都是必不可少的模块。而支付应用是每个公司根据自己的业务来构建的,各不相同。

    总体来说,可以按照使用对象分为针对最终用户的应用、针对商户的应用、针对运营人员的运营管理、BI和风控后台。

    总结

    本篇为大家描述支付系统的整体架构。后续我们会将以此为基础,分别介绍各个模块的设计。


    展开全文
  • 大型互联网分布式系统架构技术要点 解决问题的通用思路是将分而治之(divide-and-conquer),将大问题分为若干个小问题,各个击破。在大型互联网架构实践中,无一不体现这种思想。 架构目标 低成本:任何公司...

    大型互联网分布式系统架构技术要点

    解决问题的通用思路是将分而治之(divide-and-conquer),将大问题分为若干个小问题,各个击破。在大型互联网的架构实践中,无一不体现这种思想。

    架构目标

    • 低成本:任何公司存在的价值都是为了获取商业利益。在可能的情况下,希望一切都是低成本的。
    • 高性能:网站性能是客观的指标,可以具体体现到响应时间、吞吐量等技术指标。系统的响应延迟,指系统完成某一功能需要使用的时间;系统的吞吐量,指系统在某一时间可以处理的数据总量,通常可以用系统每秒处理的总的数据量来衡量;系统的并发能力,指系统可以同时完成某一功能的能力,通常也用 QPS(query per second)来衡量。
    • 高可用:系统的可用性(availability)指系统在面对各种异常时可以正确提供服务的能力。系统的可用性可 
      以用系统停服务的时间与正常服务的时间的比例来衡量,也可以用某功能的失败次数与成功次数的比例来衡量。
    • 易伸缩:注重线性扩展,是否可以容易通过加入机器来处理不断上升的用户访问压力。系统的伸缩性(scalability)指分布式系统通过扩展集群机器规模提高系统性能(吞吐、延迟、并发)、存储容量、计算能力的特性。
    • 高安全:现在商业环境中,经常出现被网站被拖库,用户账户被盗等现象。网站的安全性不言而喻。

    典型实现

    下面典型的一次web交互请求示意图。

    DNS

    1. 当用户在浏览器中输入网站地址后,浏览器会检查浏览器缓存中是否存在对应域名的解析结果。如果有,则解析过程结束;否则进入下一个步骤
    2. 浏览器查找操作系统缓存中是否存在这个域名的解析结果。这个缓存的内容来源就是操作系统的hosts文件。如果有,则解析过程结束;否则进入下一个步骤
    3. 前两个步骤都是本地查找,没有发生网络交互。在本步骤中,会使用到在网络配置的中DNS地址。这个地址我们通常称之为LDNS(Local DNS)。操作系统会把域名发送给LDNS解析。如果解析成功,则解析过程结束;否则进入下一个步骤
    4. LDNS将请求返回给GTLD(Global Top Level Domain)服务器,GTLD服务器查找此域名对应的Name Server域名的地址。这个Name Server通常就是你的域名提供商的服务器。Name Server根据客户请求,返回该域名对应的IP地址和TTL(Time To Live)值。
    5. 浏览器根据TTL值,把这个域名对应的IP缓存在本地系统中。域名至此解析结束。

    CDN

    CDN(Content Delivery Network,内容分发网络)部署在网络提供商的机房里面。在用户请求网站服务时,可以从距离自己最近的网络提供商获取数据。比如视频网站和内容网站的热点内容。

    如果需要自己搭建CDN系统,有3种主流方案可以选择:

    • squid是缓存服务器科班出生,自己实现了一套内存页/磁盘页的管理系统
    • varnish是觉得squid性能不行,varnish觉得linux内核已经把虚拟内存管理做得很好了,squid的多此一举反而影响了性能。
    • nginx cache是属于不务正业,得益于nginx强大的插件机制。

    LB

    LB(Load Balance,负载均衡)就是将负载(用户的请求)根据某些策略,将负载分摊给多个操作单元执行。该技术可以提供服务器的响应速度以及利用效率,避免出现单点失效。

    这里回顾下前面介绍的两个小节,其实本质上把数据分类(根据数据更新频率,分为动态文件,静态文件),并把数据放在离距离用户最近的地方。另外一点就是,在DNS和CDN具体实现时,也是大量使用了负载均衡技术。

    常见的负载均衡算法由:RR(Round Robin,轮询),WRR(Weighted RR,加权轮询),Random(随机),LC(Least Connection,最少连接),SH(Source Hash,源址哈希)

    在常见的互联网架构中,通常使用软件负载:LVS+HAproxy+WebServer(Nginx)。在部署时,LVS,HAProxy,WebServer都会部署一个集群,用来进行负载均衡。LVS工作在第4层,在网络层利用IP地址进行转发。 HAProxy工作在第7层,根据用户的HTTP请求(比如根据URL,消息头)来进行转发。

    在上述实现中,通常还会使用Keepalived+VIP(虚IP) 技术。Keepalived 提供健康检查,故障转移,提高系统的可用性。通过VIP(配置DNS 绑定域名)的形式对网站进行访问。

    WEB APP

    前端技术:遵循基本的Web前端优化经验,详见Web前端优化最佳实践及工具集锦 
    介绍。另外还可以使用BigPipe,动态页面静态化,无限滚动的翻页技术等技术提供更好的用户体验。另外一部分就是考虑mobile技术了,这块笔者暂时还没涉足,就不谈了。

    后端技术:

    • HTTP协议:HTTP协议大概分为请求头,请求体,响应头,响应体。无论是WebServer还是ApplicationServer,很多花样都是基于请求头的请求路径来玩的。
    • API接口:使用RESTFUL API,暴露接口。它具有如下好处:1.充分利用 HTTP 协议本身语义。2.面向资源,一目了然,具有自解释性。3.无状态,在调用一个接口(访问、操作资源)的时候,可以不用考虑上下文,极大的降低了复杂度。
    • Application Server:在Java中,为了保证程序能够在各个厂商的AS中兼容运行,Sun公司为制定了J2EE规范。从技术发展路径来看, Serverlet,JSP演变都是为了更好地方便程序员们编程。以典型的Tomcat为例,Connector和Container组成一个 Service,多个Service组成一个Server。Connector主要负责接受外部请求,Container负责处理请求。Server提供了生命周期管理,如启动,停止等。
    • Session Framework:在大型互联网架构中,单台机器已经存放不了用户的登录信息。同时为了支持故障转移等特性,需要一套session管理机制,支持海量用户同时在线。通常可以在遵循J2EE的容器内,使用Filter模式和分布式缓存系统来实现。
    • MVC:即Model,View和Controller。Model代表业务逻辑,View表示页面视图,Controller表示根据用户请求,执行相应的业务逻辑,并选择适当的页面视图返回。用过ROR的同学都知道,里面的router配置了什么样的URL和什么样的action相对应。相应的,MVC的本质就是根据不同的URL选择不同的servlet来执行。只不过,结合了Intercepting Filter提供了强大的功能而已。
    • IOC:至于为什么需要IOC,笔者在这篇文章进行了讨论。究其本质实现,无非是反射+单例模式+Hash算法+字节码增强+ThreadLocal。前3者用来实现对象生命周期的管理,后2者用来支持AOP,声明式事务。
    • ORM:这个词实际上放在这里介绍不太合适,但是笔者目前没想把它单独拉出章节来讲。根据笔者的经验,ORM主要完成了类和表的映射,对象和一条表数据记录的映射。其核心实现是通过jdbc获取数据库的meta信息,然后根据映射关系(这里可以通过COC(Conversion Over Configuration,约定优于配置),注解等技术来简化配置)来动态生成sql和返回数据库的执行结果。

    SOA

    网站架构的演进之路,从单一应用架构到垂直应用架构,分布式服务架构以及流动计算架构,越来越体现SOA框架的重要性。这里以优秀的开源实现dubbo为例,简单介绍下。

    dubbo的功能介绍见服务治理过程,对dubbo架构详细介绍的有如何学习dubbo源代码dubbo源代码阅读

    简而言之,就是使用了spring的schema的扩展机制,进而支持自定义dubbo标签;通过类似serviceload机制配置多个可选服务。通过jdk动态代理和Javassist,使服务调用透明化。结合ZooKeeper实现高可用元数据管理。

    MQ

    MQ(Message Queue,消息队列)使服务调用异步化,可以消除并发访问洪峰,提升网站响应速度。 在MQ实现中,笔者写过一篇介绍Kafka的学习笔记,详细介绍见Kafka/Metaq设计思想学习笔记,不再多言。

    CACHE

    Cache就是将数据放到距离计算最近的地方,用来加快处理速度。通常对一定时间内的热点数据进行缓存。 
    在使用缓存时,需要注意缓存预热和缓存穿透问题。

    一般海量数据的缓存系统不会使用Java来实现,是因为Java有额外的对象大小开销以及GC压力。所以一般是用ANSI C来实现。目前用的比较火的是Redis,更多介绍请查看Redis资料汇总

    STORAGE

    在出现NOSQL之前,一统天下的是MySQL分库分表技术。结合类似TDDL等SQL agent技术,也能够执行类似join的操作。后来,就像忽如一夜春风来,出现了很多NOSQL/分布式存储系统产品。

    分布式存储系统是分布式系统中最复杂的一部分,相比较SOA,CACHE等框架,它需要解决的问题更加复杂。常见的问题如下:

    • 数据分布 在多台服务器之间保证数据分布均匀,跨服务器如何读写
    • 一致性 异常情况下如何保证副本一致性
    • 容错 把发生故障当成常态来设计,做到检测是否发生故障并进行故障迁移
    • 负载均衡 新增、移除服务器时如何负载均衡 数据迁移如何不影响已有服务
    • 事务并发控制 如何实现分布式事务,如何实现多版本并发控制
    • 压缩、解压缩 根据数据特点选择恰当算法,如何平衡时间和空间的关系。


    分布式架构

    1.1. web分布式系统的设计原则

    搭建和运营一个可伸缩的web站点或者应用程序意味着什么?在原始层面上这仅仅是用户通过互联网连接到远程资源-使系统变得可伸缩的部分是将资源、或者访问的资源,分布于多个服务器上。

    像生活中大多数事情一样,当构建一个web服务时花时间提前做好计划从长远看来还是很有帮助的;了解一些注意事项和大网站背后的权衡原则可以在创建小型网站时做出更明智的决定。以下是一些影响大规模web系统设计的关键原则:

    • 可用性:对于很多公司来说一个网站的正常运行时间是非常关键的声誉和功能,像一些大型的在线零售系统,即使一分钟的宕 机都有可能导致数千或者数百万美元的损失,因此设计系统的时时可用性和弹性的错误处理机制既是一个基本业务也是一个技术要求。 高可用分布式系统需要仔细考虑关键组件的冗余,分系统失败后能快速修复,并且当问题出现时优雅型降级。
    • 性能:网站的性能正在变成大多数站点考虑的一个重要的方面,网站的速度影响正常使用和用户的满意度,同样影响搜索的排名,这也是影响网站收益和保留用户的一个因素。因此,创建一个快速响应和低延迟的系统是非常关键的。
    • 可靠性:一个系统需要具备可靠性,比如同一个数据的请求始终返回同样的数据响应 。如果数据改变或者被更新,那么同样的数据将返回一个新的数据。用户需要知道一些东西被写入系统或者被存储到系统后,系统会保持不变并且可以在以后恢复到合适的位置。
    • 可伸缩性:当谈到任何大型的分布式系统时,规模大小只是考虑的其中一个方面,同样重要的是增强处理较大规模的负载性能所做的努力,这通常称为系统的可伸缩性。可伸缩性可以代表系统很多不同的参数:额外流量的处理量,添加存储容量的便意性,甚至事务的处理量。
    • 可管理性: 设计一个系统可以方便操作是另一个重要的考虑方面,系统的可管理性等同于操作的可伸缩性:维护和升级。可管理性需要考虑的事情是当问题发生时方便诊断和了解问题,易于升级和修改,以及系统能简单性的操作(即,例行的操作有没有失败和异常?)
    • 成本: 成本是一个重要的因素。很明显这包含硬件和软件成本,但同样重要需要考虑的其他方面是部署和维护系统的成本。开发者构建系统花费的大量时间,运维部署时间,甚至培训时间都需要考虑,成本是总体成本。

    以上每个原则都为设计分布式web架构提供了基础决策。然而,他们也能彼此互斥,例如要实现某个目标就要以另外的作为代价。一个基本的例子:选择通过单纯 增加更多的服务器(可扩展性)来增加地址容量,是以可管理性(你必须操作增加的服务器)和成本(服务器的价格)为代价的。

    当设计任何的web应用程序时,考虑这些关键原则都是很重要的,即使得承认一个设计可能要牺牲它们之中的一个或者多个。

    1.2. 基础

    当设计一个系统架构时,有一些东西是要考虑的:正确的部分是什么,怎样让这些部分很好地融合在一起,以及好的折中方法是什么。通常在系统架构需要之前就为它的可扩展性投资不是一个聪明的商业抉择;然而,在设计上的深谋远虑能在未来节省大量的时间和资源。

    这部分关注点是几乎所有大型web应用程序中心的一些核心因素:服务、冗余、划分和错误处理。每一个因素都包含了选择和妥协,特别是上部分提到的设计原则。为了详细的解析这些,最好是用一个例子来开始。

    实例:图片托管应用

    有时候你可能会在线上传一张图片。对于那些托管并负责分发大量图片的网站来说,要搭建一个既节省成本又高效还能具备较低的延迟性(你能快速的获图片)的网站架构确实是一种挑战。

    我们来假设一个系统,用户可以上传他们的图片到中心服务器,这些图片又能够让一些web链接或者API获取这些图片,就如同现在的Flickr或者 Picasa。为了简化的需要,我们假设应用程序分为两个主要的部分:一个是上传图片到服务器的能力(通常说的写操作),另一个是查询一个图片的能力。然 而,我们当然想上传功能很高效,但是我们更关心的是能够快速分发能力,也就是说当某个人请求一个图片的时候(比如,一个web页面或者其它应用程序请求图 片)能够快速的满足。这种分发能力很像web服务器或者CDN连接服务器(CDN服务器一般用来在多个位置存储内容一边这些内容能够从地理位置或者物理上 更靠近访问它的用户,已达到高效访问的目的)气的作用。

    系统其他重要方面:

    • 对图片存储的数量没有限制,所以存储需要可扩展,在图像数量方面需要考虑。
    • 图片的下载和请求不需要低延迟。
    • 如果用户上传一个图片,图片应该都在那里(图片数据的可靠性)。
    • 系统应该容易管理(可管理性)。
    • 由于图片主机不会有高利润的空间,所以系统需要具有成本效益。

    Figure 1.1是一个简化的功能图。

     

    Figure 1.1: 图片主机应用的简化架构图

    在这个图片主机的例子里,可遇见系统必需快速,它的数据存储要可靠以及这些所有的属性都应该高度的可扩展。建立这个应用程序的一个小版本不是很重要而且很容易部署在单一的服务器上;然而,这不是这节里的感兴趣部分。假设下我们想建一个会增长到和Flickr痛让规模的东西。

     

    服务

    当要考虑设计一个可扩展的系统时,为功能解耦和考虑下系统每部分的服务都定义一个清晰的接口都是很有帮助的。在实际中,在这种方式下的系统设计被成为面向 服务架构(SOA)。对于这类型的系统,每个服务有自己独立的方法上下文,以及使用抽象接口与上下文的外部任何东西进行交互,典型的是别的服务的公共 API。

    把一个系统解构为一些列互补的服务,能够为这些部分从别的部分的操作解耦。这样的抽象帮助在这些服务服、它的基础环境和服务的消费者之间建立清晰的关系。 建立这种清晰的轮廓能帮助隔离问题,但也允许各模块相对其它部分独立扩展。这类面向服务设计系统是非常类似面向对象设计编程的。

    在我们的例子中,上传和检索图像的请求都是由同一个服务器处理的;然而,因为系统需要具有伸缩性,有理由要将这两个功能分解为各由自己的服务进行处理。

    快速转发(Fast-forward)假定服务处于大量使用中;在这种情况下就很容易看到,读取图像所花的时间中有多少是由于受到了写入操作的影响(因为 这两个功能将竞争使用它们共享的资源)。取决于所采用的体系结构,这种影响可能是巨大的。即使上传和下载的速度完全相同(在绝大多数IP网络中都不是这样 的情况,大部分下载速度和上传速度之比都至少设计为3:1),文件读取操作一般都是从高速缓存中进行的,而写操作却不得不进行最终的磁盘操作(而且可能要 写几次才能达成最后的一致状态)。即使所有内容都已在内存中,或者从磁盘(比如SSD磁盘)中进行读取,数据库写入操作几乎往往都要慢于读取操作。 (Pole Position是一个开源的DB基准测试工具,http://polepos.org/,测试结果参见 http://polepos.sourceforge.net/results/PolePositionClientServer.pdf

    这种设计另一个潜在的问题出在web服务器上,像Apache或者lighttpd通常都有一个能够维持的并发连接数上限(默认情况下在500左右,不过 可以更高)和最高流量数,它们会很快被写操作消耗掉。因为读操作可以异步进行,或者采用其它一些像gizp压缩的性能优化或者块传输编码方式,web服务 器可以通过在多个请求服务之间切换来满足比最大连接数更多的请求(一台Apache的最大连接数设置为500,它每秒钟提供近千次读请求服务也是正常 的)。写操作则不同,它需要在上传过程中保持连接,所以大多数家庭网络环境下,上传一个1MB的文件可能需要超过1秒的时间,所以web服务器只能处理 500个这样并发写操作请求。

     

    对于这种瓶颈,一个好的规划案例是将读取和写入图片分离为两个独立的服务,如图Figure 1.2.所示。这让我们可以单独的扩展其中任意一个(因为有可能我们读操作比写操作要频繁很多),同时也有助于我们理清每个节点在做什么。最后,这也避免 了未来的忧虑,这使得故障诊断和查找问题更简单,像慢读问题。

    这种方法的优点是我们能够单独的解决各个模块的问题-我们不用担心写入和检索新图片在同一个上下文环境中。这两种服务仍然使用全球资料库的图片,但是它们 可通过适当的服务接口自由优化它们自己的性能(比如,请求队列,或者缓存热点图片-在这之上的优化)。从维护和成本角度来看,每个服务按需进行独立规模的 规划,这点非常有用,试想如果它们都组合混杂在一起,其中一个无意间影响到了性能,另外的也会受影响。

    当然,上面的例子在你使用两个不同端点时可以很好的工作(事实上,这非常类似于云存储和内容分发网络)。虽然有很多方式来解决这样的瓶颈,但每个都有各自的取舍。

    比如,Flickr通过分配用户访问不同的分片解决这类读/写问题,每一个分片只可以处理一定数量的用户,随着用户的增加更多的分片被添加到集群上(参看“Flickr缩影”的描述http://mysqldba.blogspot.com/2008/04/mysql-uc-2007-presentation-file.html)。 在第一个例子中,可以根据实际用途更简单的规划硬件资源(在整个系统中读和写的比例),然而,Flickr规划是根据用户基数(假定每个用户拥有相同的资 源空间)。在前者中一个故障或者问题会导致整个系统功能的下降(比如,全部不能写入文件了),然而Flickr一个分片的故障只会影响到相关的那部分用 户。在第一个例子中,更容易操作整个数据集-比如,在所有的图像元数据上更新写入服务用来包含新的元数据或者检索-然而在Flickr架构上每一个分片都 需要执行更新或者检索(或者需要创建个索引服务来核对元数据-找出哪一个才是实际结果)。

    冗余(Redundancy)

    为了优雅的处理故障,web架构必须冗余它的服务和数据。例如,单服务器只拥有单文件的话,文件丢失就意味这永远丢失了。丢失数据是个很糟糕的事情,常见的方法是创建多个或者冗余备份。

    同样的原则也适用于服务。如果应用有一个核心功能,确保它同时运行多个备份或者版本可以安全的应对单点故障。

    在系统中创建冗余可以消除单点故障,可以在紧急时刻提供备用功能。例如,如果在一个产品中同时运行服务的两个实例,当其中一个发生故障或者降级(degrade),系统可以转移(failover)到好的那个备份上。故障转移(Failover)可以自动执行或者人工手动干预。

    服务冗余的另一个关键部分是创建无共享(shared-nothing)架构。采用这种架构,每个接点都可以独立的运作,没有中心”大脑”管理状态或者协调活动。这可以大大提高可伸缩性(scalability)因为新的接点可以随时加入而不需要特殊的条件或者知识。而且更重要的是,系统没有单点故障。所以可以更好的应对故障。

    例如,在我们的图片服务应用,所有的图片应该都冗余备份在另外的一个硬件上(理想的情况下,在不同的地理位置,以防数据中心发生大灾难,例如地震,火 灾),而且访问图片的服务(见Figure 1.3.)-包括所有潜在的服务请求-也应该冗余。(负载均衡器是个很好的方法冗余服务,但是下面的方法不仅仅是负载均衡)

     

    Figure 1.3: 使用冗余的图片存储

     

     

    分区

    我们可能遇见单一服务器无法存放的庞大数据集。也可能遇到一个需要过多计算资源的操作,导致性能下降,急需增添容量。这些情况下,你都有两种选择:横向或纵向扩展。

    纵向扩展意味着对单一服务器增添更多资源。对于一个非常庞大的数据集,这可能意味着为单一服务器增加更多(或更大)的硬盘以存放整个数据集。而对于计算操 作,这可能意味着将操作移到一个拥有更快的 CPU 或 更大的内存的服务器中。无论哪种情况,纵向扩展都是为了使单个服务器能够自己处理更多的方法。

    另一方面,对于横向扩展,则是增加更多的节点。例如庞大的数据集,你可以用第二个服务器来存放部分数据;而对于计算操作,你可以切割计算,或是通过额外的 节点加载。想要充分的利用横向扩展的优势,你应该以内在的系统构架设计原则来实现,否则的话,实现的方法将会变成繁琐的修改和切分操作。

    说道横向分区,更常见的技术是将你的服务分区,或分片。分区可以通过对每个功能逻辑集的分割分配而来;可以通过地域划分,也可以通过类似付费 vs. 未付费用户来区分。这种方式的优势是可以通过增添容量来运行服务或实现数据存储。

    以我们的图像服务器为例,将曾经储存在单一的文件服务器的图片重新保存到多个文件服务器中是可以实现的,每个文件服务器都有自己惟一的图片集。(见图表 1.4。)这种构架允许系统将图片保存到某个文件服务器中,在服务器都即将存满时,像增加硬盘一样增加额外的服务器。这种设计需要一种能够将文件名和存放 服务器绑定的命名规则。一个图像的名称可能是映射全部服务器的完整散列方案的形式。或者可选的,每个图像都被分配给一个递增的 ID,当用户请求图像时,图像检索服务只需要保存映射到每个服务器的 ID 范围(类似索引)就可以了。

     

    图 1.4: 使用冗余和分区实现的图片存储服务

    当然,为多个服务器分配数据或功能是充满挑战的。一个关键的问题就是数据局部性;对于分布式系统,计算或操作的数据越相近,系统的性能越佳。因此,一个潜在的问题就是数据的存放遍布多个服务器,当需要一个数据时,它们并不在一起,迫使服务器不得不为从网络中获取数据而付出昂贵的性能代价。

    另一个潜在的问题是不一致性。当多个不同的服务读取和写入同一共享资源时,有可能会遭遇竞争状态——某些数据应当被更新,但读取操作恰 好发生在更新之前——这种情形下,数据就是不一致的。例如图像托管方案中可能出现的竞争状态,一个客户端发送请求,将其某标题为“狗”的图像改名为”小家 伙“。而同时另一个客户端发送读取此图像的请求。第二个客户端中显示的标题是“狗”还是“小家伙”是不能明确的。

    当然,对于分区还有一些障碍存在,但分区允许将问题——数据、负载、使用模式等——切割成可以管理的数据块。这将极大的提高可扩展性和可管理性,但并非没有风险。有很多可以降低风险,处理故障的方法;不过篇幅有限,不再赘述。若有兴趣,可见于此文,获取更多容错和检测的信息。

    1.3. 构建高效和可伸缩的数据访问模块

    在设计分布式系统时一些核心问题已经考虑到,现在让我们来讨论下比较困难的一部分:可伸缩的数据访问。

    对于大多数简单的web应用程序,比如LAMP系统,类似于图 Figure 1.5.

     

    Figure 1.5: 简单web应用程序

    随着它们的成长,主要发生了两方面的变化:应用服务器和数据库的扩展。在一个高度可伸缩的应用程序中,应用服务器通常最小化并且一般是 shared-nothing架构(译注:shared nothing architecture是一 种分布式计算架构,这种架构中不存在集中存储的状态,整个系统中没有资源竞争,这种架构具有非常强的扩张性,在web应用中广泛使用)方式的体现,这使得 系统的应用服务器层水平可伸缩。由于这种设计,数据库服务器可以支持更多的负载和服务;在这一层真正的扩展和性能改变开始发挥作用了。

    剩下的章节主要集中于通过一些更常用的策略和方法提供快速的数据访问来使这些类型服务变得更加迅捷。

     

    Figure 1.6: Oversimplified web application

    大多数系统简化为如图 Figure 1.6所示,这是一个良好的开始。如果你有大量的数据,你想快捷的访问,就像一堆糖果摆放在你办公室抽屉的最上方。虽然过于简化,前面的声明暗示了两个困难的问题:存储的可伸缩性和数据的快速访问。

    为了这一节内容,我们假设你有很大的数据存储空间(TB),并且你想让用户随机访问一小部分数据(查看Figure 1.7)。这类似于在图像应用的例子里在文件服务器定位一个图片文件。

     

    Figure 1.7: Accessing specific data

    这非常具有挑战性,因为它需要把数TB的数据加载到内存中;并且直接转化为磁盘的IO。要知道从磁盘读取比从内存读取慢很多倍-内存的访问速度如同敏捷的 查克·诺里斯(译注:空手道冠军),而磁盘的访问速度就像笨重的卡车一样。这个速度差异在大数据集上会增加更多;在实数顺序读取上内存访问速度至少是磁盘 的6倍,随机读取速度比磁盘快100,000倍(参考“大数据之殇”http://queue.acm.org/detail.cfm?id=1563874)。另外,即使使用唯一的ID,解决获取少量数据存放位置的问题也是个艰巨的任务。这就如同不用眼睛看在你的糖果存放点取出最后一块Jolly Rancher口味的糖果一样。

    谢天谢地,有很多方式你可以让这样的操作更简单些;其中四个比较重要的是缓存,代理,索引和负载均衡。本章的剩余部分将讨论下如何使用每一个概念来使数据访问加快。

    缓存

    缓存利用局部访问原则:最近请求的数据可能会再次被请求。它们几乎被用于计算机的每一层:硬件,操作系统,web浏览器,web应用程序等等。缓存就像短期存储的内存:它有空间的限制,但是通常访问速度比源数据源快并且包含了大多数最近访问的条目。缓存可以在架构的各个层级存在,但是常常在前端比较常见,在这里通常需要在没有下游层级的负担下快速返回数据。

    在我们的API例子中如何使用缓存来快速访问数据?在这种情况下,有两个地方你可以插入缓存。一个操作是在你的请求层节点添加一个缓存,如图 Figure 1.8.

     

    Figure 1.8: Inserting a cache on your request layer node

    直接在一个请求层节点配置一个缓存可以在本地存储相应数据。每次发送一个请求到服务,如果数据存在节点会快速的返回本地缓存的数据。如果数据不在缓存中,请求节点将在磁盘查找数据。请求层节点缓存可以存放在内存和节点本地磁盘中(比网络存储快些)。

     

    Figure 1.9: Multiple caches

    当你扩展这些节点后会发生什么呢?如图Figure 1.9所示,如果请求层扩展为多个节点,每个主机仍然可能有自己的缓存。然而,如果你的负载均衡器随机分配请求到节点,同样的请求将指向不同的节点,从而 增加了缓存的命中缺失率。有两种选择可以解决这个问题:全局缓存和分布式缓存。

     

     

    全局缓存

    全局缓存顾名思义:所有的节点使用同一个缓存空间,这涉及到添加一个服务器,或者某种文件存储系统,速度比访问源存储和通过所有节点访问要快些。每个请求 节点以同样的方式查询本地的一个缓存,这种缓存方案可能有点复杂,因为在客户端和请求数量增加时它很容易被压倒,但是在有些架构里它还是很有用的(尤其是 那些专门的硬件来使全局缓存变得非常快,或者是固定数据集需要被缓存的)。

    在描述图中有两种常见形式的缓存。在图Figure 1.10中,当一个缓存响应没有在缓存中找到时,缓存自身从底层存储中查找出数据。在 Figure 1.11中,当在缓存中招不到数据时,请求节点会向底层去检索数据。

     

    Figure 1.10: Global cache where cache is responsible for retrieval

     

    Figure 1.11: Global cache where request nodes are responsible for retrieval

    大多数使用全局缓存的应用程序趋向于第一类,这类缓存可以管理数据的读取,防止客户端大量的请求同样的数据。然而,一些情况下,第二类实现方式似乎更有意 义。比如,如果一个缓存被用于非常大的文件,一个低命中比的缓存将会导致缓冲区来填满未命中的缓存;在这种情况下,将使缓存中有一个大比例的总数据集。另 一个例子是架构设计中文件在缓存中存储是静态的并且不会被排除。(这可能是因为应用程序要求周围数据的延迟-某些片段的数据可能需要在大数据集中非常快- 在有些地方应用程序逻辑理清排除策略或者热点 比缓存方案好使些)

    分布式缓存

    在分布式缓存(图1.12)中,每个节点都会缓存一部分数据。如果把冰箱看作食杂店的缓存的话,那么分布式缓存就象是把你的食物分别放到多个地方 —— 你的冰箱、柜橱以及便 当盒 ——放到这些便于随时取用的地方就无需一趟趟跑去食杂店了。缓存一般使用一个具有一致性的哈希函数进行分割,如此便可在某请求节点寻找某数据时,能够迅速 知道要到分布式缓存中的哪个地方去找它,以确定改数据是否从缓存中可得。在这种情况下,每个节点都有一个小型缓存,在直接到原数据所作处找数据之前就可以 向别的节点发出寻找数据的请求。由此可得,分布式缓存的一个优势就是,仅仅通过向请求池中添加新的节点便可以拥有更多的缓存空间。

    分布式缓存的一个缺点是修复缺失的节点。一些分布式缓存系统通过在不同节点做多个备份绕过了这个问题;然而,你可以想象这个逻辑迅速变复杂了,尤其是当你 在请求层添加或者删除节点时。即便是一个节点消失和部分缓存数据丢失了,我们还可以在源数据存储地址获取-因此这不一定是灾难性的!

     

    Figure 1.12: Distributed cache

    缓存的伟大之处在于它们使我们的访问速度更快了(当然前提是正确使用),你选择的方法要在更多请求下更快才行。然而,所有这些缓存的代价是必须有额外的存 储空间,通常在放在昂贵的内存中;从来没有嗟来之食。缓存让事情处理起来更快,而且在高负载情况下提供系统功能,否则将会使服务器出现降级。

    有一个很流行的开源缓存项目Memcached (http://memcached.org/)(它可以当做一个本地缓存,也可以用作分布式缓存);当然,还有一些其他操作的支持(包括语言包和框架的一些特有设置)。

    Memcached 被用作很多大型的web站点,尽管他很强大,但也只是简单的内存key-value存储方式,它优化了任意数据存储和快速检索(o(1))。

    Facebook使用了多种不同的缓存来提高他们站点的性能(查看”Facebook caching and performance”)。在语言层面上(使用PHP内置函数调用)他们使用$GLOBALSand APC缓存,这有助于使中间函数调用和结果返回更快(大多数语言都有这样的类库用来提高web页面的性能)。Facebook使用的全局缓存分布在多个服务器上(查看 ”Scaling memcached at Facebook”),这样一个访问缓存的函数调用可以使用很多并行的请求在不同的Memcached 服务器上获取存储的数据。这使得他们在为用户分配数据空间时有了更高的性能和吞吐量,同时有一个中央服务器做更新(这非常重要,因为当你运行上千服务器 时,缓存失效和一致性将是一个大挑战)。

    现在让我们讨论下当数据不在缓存中时该如何处理···

    代理

    简单来说,代理服务器是一种处于客户端和服务器中间的硬件或软件,它从客户端接收请求,并将它们转交给服务器。代理一般用于过滤请求、记录日志或对请求进行转换(增加/删除头部、加密/解密、压缩,等等)。

     

    图1.13: 代理服务器

    当需要协调来自多个服务器的请求时,代理服务器也十分有用,它允许我们从整个系统的角度出发、对请求流量执行优化。压缩转发(collapsed forwarding)是利用代理加快访问的其中一种方法,将多个相同或相似的请求压缩在同一个请求中,然后将单个结果发送给各个客户端。

    假设,有几个节点都希望请求同一份数据,而且它并不在缓存中。在这些请求经过代理时,代理可以通过压缩转发技术将它们合并成为一个请求,这样一来,数据只 需要从磁盘上读取一次即可(见图1.14)。这种技术也有一些缺点,由于每个请求都会有一些时延,有些请求会由于等待与其它请求合并而有所延迟。不管怎么 样,这种技术在高负载环境中是可以帮助提升性能的,特别是在同一份数据被反复访问的情况下。压缩转发有点类似缓存技术,只不过它并不对数据进行存储,而是 充当客户端的代理人,对它们的请求进行某种程度的优化。

    在一个LAN代理服务器中,客户端不需要通过自己的IP连接到Internet,而代理会将请求相同内容的请求合并起来。这里比较容易搞混,因为许多代理同时也充当缓存(这里也确实是一个很适合放缓存的地方),但缓存却不一定能当代理。

     

    图1.14: 通过代理来合并请求

    另一个使用代理的方式不只是合并相同数据的请求,同时也可以用来合并靠近存储源(一般是磁盘)的数据请求。采用这种策略可以让请求最大化使用本地数据,这 样可以减少请求的数据延迟。比如,一群节点请求B部分信息:partB1,partB2等,我们可以设置代理来识别各个请求的空间区域,然后把它们合并为 一个请求并返回一个bigB,大大减少了读取的数据来源(查看图Figure 1.15)。当你随机访问上TB数据时这个请求时间上的差异就非常明显了!代理在高负载情况下,或者限制使用缓存时特别有用,因为它基本上可以批量的把多 个请求合并为一个。

     

    Figure 1.15: Using a proxy to collapse requests for data that is spatially close together

    值得注意的是,代理和缓存可以放到一起使用,但通常最好把缓存放到代理的前面,放到前面的原因和在参加者众多的马拉松比赛中最好让跑得较快的选手在队首起 跑一样。因为缓存从内存中提取数据,速度飞快,它并不介意存在对同一结果的多个请求。但是如果缓存位于代理服务器的另一边,那么在每个请求到达 cache之前都会增加一段额外的时延,这就会影响性能。

    如果你正想在系统中添加代理,那你可以考虑的选项有很多;SquidVarnish都经过了实践检验,广泛用于很多实际的web站点中。这些代理解决方案针对大部分client-server通信提供了大量的优化措施。将二者之中的某一个安装为web服务器层的反向代理(reverse proxy,下面负载均衡器一节中解释)可以大大提高web服务器的性能,减少处理来自客户端的请求所需的工作量。

    索引

    使用索引快速访问数据是个优化数据访问性能公认的策略;可能我们大多数人都是从数据库了解到的索引。索引用增长的存储空间占用和更慢的写(因为你必须写和更新索引)来换取更快的读取。

    你可以把这个概念应用到大数据集中就像应用在传统的关系数据存储。索引要关注的技巧是你必须仔细考虑用户会怎样访问你的数据。如果数据集有很多 TBs,但是每个数据包(payload)很小(可能只有1KB),这时就必须用索引来优化数据访问。在这么大的数据集找到小的数据包是个很有挑战性的工 作因为你不可能在合理的时间內遍历所有数据。甚至,更有可能的是这么大的数据集分布在几个(甚至很多个)物理设备上-这意味着你要用些方法找到期望数据的 正确物理位置。索引是最适合的方法做这种事情。

     

    Figure 1.16: Indexes

    索引可以作为内容的一个表格-表格的每一项指明你的数据存储的位置。例如,如果你正在查找B的第二部分数据-你如何知道去哪里找?如果你有个根据数据类型 (数据A,B,C)排序的索引,索引会告诉你数据B的起点位置。然后你就可以跳转(seek)到那个位置,读取你想要的数据B的第二部分。 (See Figure 1.16.)

    这些索引常常存储在内存中,或者存储在对于客户端请求来说非常快速的本地位置(somewhere very local)。Berkeley DBs (BDBs)和树状数据结构常常按顺序存储数据,非常理想用来存储索引。

    常常索引有很多层,当作数据地图,把你从一个地方指向另外一个地方,一直到你的得到你想要的那块数据。(See Figure 1.17.)

     

    Figure 1.17: Many layers of indexes

    索引也可以用来创建同样数据的多个不同视图(views)。对于大数据集来说,这是个很棒的方法来定义不同的过滤器(filter)和类别(sort),而不用创建多个额外的数据拷贝。

    例如,想象一下,图片存储系统开始实际上存储的是书的每一页的图像,而且服务允许客户查询这些图片中的文字,搜索每个主题的所有书的内容,就像搜索引擎允 许你搜索HTML内容一样。在这种情况下,所有的书的图片占用了很多很多服务器存储,查找其中的一页给用户显示有点难度。首先,用来查询任意词或者词数组 (tuples)的倒排索引(inverse indexes)需要很容易的访问到;然后,导航到那本书的确切页面和位置并获取准确的图片作为返回结果,也有点挑战性。所以,这种境况下,倒排索引应该 映射到每个位置(例如书B),然后B要包含一个索引每个部分所有单词,位置和出现次数的索引。

    可以表示上图Index1的一个倒排索引,可能看起来像下面的样子-每个词或者词数组对应一个包含他们的书。

    Word(s)Book(s)
    being awesomeBook B, Book C, Book D
    alwaysBook C, Book F
    believeBook B

    这个中间索引可能看起来像上面的样子,但是可能只包含词,位置和书B的信息。这种嵌套的索引架构要使每个子索引占用足够小的空间,以防所有的这些信息必须保存在一个大的倒排索引中。

    这是大型系统的关键点,因为即使压缩,这些索引也太大,太昂贵(expensive)而难以存储。在这个系统,如果我们假设我们世界上的很多书-100,000,000 (see Inside Google Books blog post)-每个书只有10页(只是为了下面好计算),每页有250个词,那就是2500亿(250 billion)个词。如果我们假设每个词有5个字符,每个字符占用8位(或者1个字节,即使某些字符要用2个字节),所以每个词占用5个字节,那么每个 词即使只包含一次,这个索引也要占用超过1000GB存储空间。那么,你可以明白创建包含很多其他信息-词组,数据位置和出现次数-的索引,存储空间增长 多快了吧。

    创建这些中间索引和用更小分段表示数据,使的大数据问题可以得到解决。数据可以分散到多个服务器,访问仍然很快。索引是信息检索 (information retrieval)的奠基石,是现代搜索引擎的基础。当然,我们这段只是浅显的介绍,还有其他很多深入研究没有涉及-例如如何使索引更快,更小,包含更 多信息(例如关联(relevancy)),和无缝的更新(在竞争条件下(race conditions),有一些管理性难题;在海量添加或者修改数据的更新中,尤其还涉及到关联(relevancy)和得分(scoring),也有一 些难题)。

    快速简便的查找到数据是很重要的;索引是可以达到这个目的有效简单工具。

    负载均衡器

    最后还要讲讲所有分布式系统中另一个比较关键的部分,负载均衡器。负载均衡器是各种体系结构中一个不可或缺的部分,因为它们担负着将负载在处理服务请求的 一组节点中进行分配的任务。这样就可以让系统中的多个节点透明地服务于同一个功能(参见图1.18)。它的主要目的就是要处理大量并发的连接并将这些连接 分配给某个请求处理节点,从而可使系统具有伸缩性,仅仅通过添加新节点便能处理更多的请求。

     

    图1.18: 负载均衡器

    用于处理这些请求的算法有很多种,包括随机选取节点、循环式选取,甚至可以按照内存或CPU的利用率等等这样特定的条件进行节点选取。负载均衡器可以用软件或硬件设备来实现。近来得到广泛应用的一个开源的软件负载均衡器叫做 HAProxy)。

    在分布式系统中,负载均衡器往往处于系统的最前端,这样所有发来的请求才能进行相应的分发。在一些比较复杂的分布式系统中,将一个请求分发给多个负载均衡器也是常事,如图1.19所示。

     

    图1.19: 多重负载均衡器

    和代理类似,有些负载均衡器还可以基于请求的类型对不同的请求进行不同的处理(技术上讲,这样的叫做反向代理)。

    负载均衡器面临的一个难题是怎么管理同用户的session相关的数据。在电子商务网站中,如果你只有一个客户端,那么很容易就可以把用户放入购物车里的 东西保存起来,等他下次访问访问时购物车里仍能看到那些东西(这很重要,因为当用户回来发现仍然呆在购物车里的产品时很有可能就会买它)。然而,如果在一 个session中将用户分发到了某个节点,但该用户下次访问时却分发到了另外一个节点,这里就有可能产生不一致性,因为新的节点可能就没有保留下用户购 物车里的东西。(要是你把6盒子子农夫山泉放到购物车里了,可下次回来一看购物车空了,难道你不会发火吗?) 解决该问题的一个方法是可以使session具有保持性,让同一用户总是分发到同一个节点之上,但这样一来就很难利用类似failover这样的可靠性措 施了。如果这样的话,用户的购物车里的东西不会丢,但如果用户保持的那个节点失效,就会出现一种特殊的情况,购物车里的东西不会丢这个假设再也不成立了 (虽然但愿不要把这个假设写到程序里)。当然,这个问题还可以用本章中讲到的其它策略和工具来解决,比如服务以及许多并没有讲到的方法(象服务器缓存、 cookie以及URL重写)。

    如果系统中只有不太多的节点,循环式(round robin)DNS系统这样的方案也许更有意义,因为负载均衡器可能比较贵,而且还额外增加了一层没必要的复杂性。当然,在比较大的系统中会有各种各样的 调度以及负载均衡算法,简单点的有随机选取或循环式选取,复杂点的可以考虑上利用率以及处理能力这些因素。所有这些算法都是对浏览和请求进行分发,并能提 供很有用的可靠性工具,比如自动failover或者自动提出失效节点(比如节点失去响应)。然而,这些高级特性会让问题诊断难以进行。例如,当系统载荷 较大时,负载均衡器可能会移除慢速或者超时的节点(由于节点要处理大量请求),但对其它节点而言,这么做实际上是加剧了情况的恶化程度。在这时进行大量的 监测非常重要,因为系统总体流量和吞吐率可能看上去是在下降(因为节点处理的请求变少了),但个别节点却越来越忙得不可开交。

    负载均衡器是一种能让你扩展系统能力的简单易行的方式,和本文中所讲的其它技术一样,它在分布式系统架构中起着基础性的作用。负载均衡器还要提供一个比较 关键的功能,它必需能够探测出节点的运行状况,比如,如果一个节点失去响应或处于过载状态,负载均衡器可以将其总处理请求的节点池中移除出去,还接着使用 系统中冗余的其它不同节点。

    队列

    目前为止我们已经介绍了许多更快读取数据的方法,但另一个使数据层具伸缩性的重要部分是对写的有效管理。当系统简单的时候,只有最小的处理负载和很小的数 据库,写的有多快可以预知;然而,在更复杂的系统,写可能需要几乎无法决定的长久时间。例如,数据可能必须写到不同数据库或索引中的几个地方,或者系统可 能正好处于高负载。这些情况下,写或者任何那一类任务,有可能需要很长的时间,追求性能和可用性需要在系统中创建异步;一个通常的做到那一点的办法是通过 队列。

     

    Figure 1.20: Synchronous request

    设想一个系统,每个客户端都在发起一个远程服务的任务请求。每一个客户端都向服务器发送它们的请求,服务器尽可能快的完成这些任务,并分别返回结果给各个 客户端。在一个小型系统,一个服务器(或逻辑服务)可以给传入的客户端请求提供迅速服务,就像它们来的一样快,这种情形应该工作的很好。然而,当服务器收 到了超过它所能处理数量的请求时,每个客户端在产生一个响应前,将被迫等待其他客户端的请求结束。这是一个同步请求的例子,示意在图1.20。

    这种同步的行为会严重的降低客户端性能;客户端被迫等待,有效的执行零工作,直到它的请求被应答。添加额外的服务器承担系统负载也不会解决这个问题;即使 是有效的负载均衡,为了最大化客户端性能,保证平等的公平的分发工作也是极其困难的。而且,如果服务器处理请求不可及,或者失败了,客户端上行也会失败。 有效解决这个问题在于,需要在客户端请求与实际的提供服务的被执行工作之间建立抽象。

     

    图 1.21:用队列管理请求

    进入队列。一个队列就像它听起来那么简单:一个任务进入,被加入队列然后工人们只要有能力去处理就会拿起下一个任务。(看图1.21)这些任务可能是代表 了简单的写数据库,或者一些复杂的事情,像为一个文档生成一个缩略预览图一类的。当一个客户端提交一个任务请求到一个队列,它们再也不会被迫等待结果;它 们只需要确认请求被正确的接收了。这个确认之后可能在客户端请求的时候,作为一个工作结果的参考。

    队列使客户端能以异步的方式工作,提供了一个客户端请求与其响应的战略抽象。换句话说,在一个同步系统,没有请求与响应的区别,因此它们不能被单独的管 理。在一个异步的系统,客户端请求一个任务,服务端响应一个任务已收到的确认,然后客户端可以周期性的检查任务的状态,一旦它结束就请求结果。当客户端等 待一个异步的请求完成,它可以自由执行其它工作,甚至异步请求其它的服务。后者是队列与消息在分布式系统如何成为杠杆的例子。

    队列也对服务中断和失败提供了防护。例如,创建一个高度强健的队列,这个队列能够重新尝试由于瞬间服务器故障而失败的服务请求,是非常容易的事。相比直接暴露客户端于间歇性服务中断,需要复杂的而且经常矛盾的客户端错误处理程序,用一个队列去加强服务质量的担保更为可取。

    队列对管理任何大规模分布式系统不同部分之间的分布式通信,是一个基础,而且实现它们有许多的方法。有不少开源的队列如 RabbitMQActiveMQBeanstalkD,但是有些也用像 Zookeeper的服务,或者甚至像Redis的数据存储。

    1.4. 结论

    设计有效的系统来进行快速的大数据访问是有趣的,同时有大量的好工具来帮助各种各样的应用程序进行设计。 这文章只覆盖了一些例子,仅仅是一些表面的东西,但将会越来越多–同时在这个领域里一定会继续有更多创新东西。

    以上根据网络内容整理而成!

    展开全文
  • 大型互联网架构概述

    千次阅读 2015-11-10 00:02:30
    本文旨在简单介绍大型互联网架构和核心组件实现原理。 理论上讲,从安装配置,最佳实践以及源码来剖析各个组件,这个自然是极好的。由于笔者时间以及知识有限,有很多知识没有在工作中亲自实践的机会。所以有些...
     
    

    本文旨在简单介绍大型互联网的架构和核心组件实现原理。 理论上讲,从安装配置,最佳实践以及源码来剖析各个组件,这个自然是极好的。由于笔者时间以及知识有限,有很多知识没有在工作中亲自实践的机会。所以有些地方语焉不详,还请大家多多指教。

    大型互联网架构

    解决问题的通用思路是将分而治之(divide-and-conquer),将大问题分为若干个小问题,各个击破。在大型互联网的架构实践中,无一不体现这种思想。

    架构目标

    • 低成本:任何公司存在的价值都是为了获取商业利益。在可能的情况下,希望一切都是低成本的。
    • 高性能:网站性能是客观的指标,可以具体体现到响应时间、吞吐量等技术指标。系统的响应延迟,指系统完成某一功能需要使用的时间;系统的吞吐量,指系统在某一时间可以处理的数据总量,通常可以用系统每秒处理的总的数据量来衡量;系统的并发能力,指系统可以同时完成某一功能的能力,通常也用 QPS(query per second)来衡量。
    • 高可用:系统的可用性(availability)指系统在面对各种异常时可以正确提供服务的能力。系统的可用性可 
      以用系统停服务的时间与正常服务的时间的比例来衡量,也可以用某功能的失败次数与成功次数的比例来衡量。
    • 易伸缩:注重线性扩展,是否可以容易通过加入机器来处理不断上升的用户访问压力。系统的伸缩性(scalability)指分布式系统通过扩展集群机器规模提高系统性能(吞吐、延迟、并发)、存储容量、计算能力的特性。
    • 高安全:现在商业环境中,经常出现被网站被拖库,用户账户被盗等现象。网站的安全性不言而喻。

    典型实现

    下面典型的一次web交互请求示意图。

    在此输入图片描述

    DNS

    1. 当用户在浏览器中输入网站地址后,浏览器会检查浏览器缓存中是否存在对应域名的解析结果。如果有,则解析过程结束;否则进入下一个步骤
    2. 浏览器查找操作系统缓存中是否存在这个域名的解析结果。这个缓存的内容来源就是操作系统的hosts文件。如果有,则解析过程结束;否则进入下一个步骤
    3. 前两个步骤都是本地查找,没有发生网络交互。在本步骤中,会使用到在网络配置的中DNS地址。这个地址我们通常称之为LDNS(Local DNS)。操作系统会把域名发送给LDNS解析。如果解析成功,则解析过程结束;否则进入下一个步骤
    4. LDNS将请求返回给GTLD(Global Top Level Domain)服务器,GTLD服务器查找此域名对应的Name Server域名的地址。这个Name Server通常就是你的域名提供商的服务器。Name Server根据客户请求,返回该域名对应的IP地址和TTL(Time To Live)值。
    5. 浏览器根据TTL值,把这个域名对应的IP缓存在本地系统中。域名至此解析结束。

    CDN

    CDN(Content Delivery Network,内容分发网络)部署在网络提供商的机房里面。在用户请求网站服务时,可以从距离自己最近的网络提供商获取数据。比如视频网站和内容网站的热点内容。

    如果需要自己搭建CDN系统,有3种主流方案可以选择:

    • squid是缓存服务器科班出生,自己实现了一套内存页/磁盘页的管理系统
    • varnish是觉得squid性能不行,varnish觉得linux内核已经把虚拟内存管理做得很好了,squid的多此一举反而影响了性能。
    • nginx cache是属于不务正业,得益于nginx强大的插件机制。

    LB

    LB(Load Balance,负载均衡)就是将负载(用户的请求)根据某些策略,将负载分摊给多个操作单元执行。该技术可以提供服务器的响应速度以及利用效率,避免出现单点失效。

    这里回顾下前面介绍的两个小节,其实本质上把数据分类(根据数据更新频率,分为动态文件,静态文件),并把数据放在离距离用户最近的地方。另外一点就是,在DNS和CDN具体实现时,也是大量使用了负载均衡技术。

    常见的负载均衡算法由:RR(Round Robin,轮询),WRR(Weighted RR,加权轮询),Random(随机),LC(Least Connection,最少连接),SH(Source Hash,源址哈希)

    在常见的互联网架构中,通常使用软件负载:LVS+HAproxy+WebServer(Nginx)。在部署时,LVS,HAProxy,WebServer都会部署一个集群,用来进行负载均衡。LVS工作在第4层,在网络层利用IP地址进行转发。 HAProxy工作在第7层,根据用户的HTTP请求(比如根据URL,消息头)来进行转发。

    在上述实现中,通常还会使用Keepalived+VIP(虚IP) 技术。Keepalived 提供健康检查,故障转移,提高系统的可用性。通过VIP(配置DNS 绑定域名)的形式对网站进行访问。

    WEB APP

    前端技术:遵循基本的Web前端优化经验,详见Web前端优化最佳实践及工具集锦 
    介绍。另外还可以使用BigPipe,动态页面静态化,无限滚动的翻页技术等技术提供更好的用户体验。另外一部分就是考虑mobile技术了,这块笔者暂时还没涉足,就不谈了。

    后端技术:

    • HTTP协议:HTTP协议大概分为请求头,请求体,响应头,响应体。无论是WebServer还是ApplicationServer,很多花样都是基于请求头的请求路径来玩的。
    • API接口:使用RESTFUL API,暴露接口。它具有如下好处:1.充分利用 HTTP 协议本身语义。2.面向资源,一目了然,具有自解释性。3.无状态,在调用一个接口(访问、操作资源)的时候,可以不用考虑上下文,极大的降低了复杂度。
    • Application Server:在Java中,为了保证程序能够在各个厂商的AS中兼容运行,Sun公司为制定了J2EE规范。从技术发展路径来看, Serverlet,JSP演变都是为了更好地方便程序员们编程。以典型的Tomcat为例,Connector和Container组成一个 Service,多个Service组成一个Server。Connector主要负责接受外部请求,Container负责处理请求。Server提供了生命周期管理,如启动,停止等。
    • Session Framework:在大型互联网架构中,单台机器已经存放不了用户的登录信息。同时为了支持故障转移等特性,需要一套session管理机制,支持海量用户同时在线。通常可以在遵循J2EE的容器内,使用Filter模式和分布式缓存系统来实现。
    • MVC:即Model,View和Controller。Model代表业务逻辑,View表示页面视图,Controller表示根据用户请求,执行相应的业务逻辑,并选择适当的页面视图返回。用过ROR的同学都知道,里面的router配置了什么样的URL和什么样的action相对应。相应的,MVC的本质就是根据不同的URL选择不同的servlet来执行。只不过,结合了Intercepting Filter提供了强大的功能而已。
    • IOC:至于为什么需要IOC,笔者在这篇文章进行了讨论。究其本质实现,无非是反射+单例模式+Hash算法+字节码增强+ThreadLocal。前3者用来实现对象生命周期的管理,后2者用来支持AOP,声明式事务。
    • ORM:这个词实际上放在这里介绍不太合适,但是笔者目前没想把它单独拉出章节来讲。根据笔者的经验,ORM主要完成了类和表的映射,对象和一条表数据记录的映射。其核心实现是通过jdbc获取数据库的meta信息,然后根据映射关系(这里可以通过COC(Conversion Over Configuration,约定优于配置),注解等技术来简化配置)来动态生成sql和返回数据库的执行结果。

    SOA

    网站架构的演进之路,从单一应用架构到垂直应用架构,分布式服务架构以及流动计算架构,越来越体现SOA框架的重要性。这里以优秀的开源实现dubbo为例,简单介绍下。

    dubbo的功能介绍见服务治理过程,对dubbo架构详细介绍的有如何学习dubbo源代码dubbo源代码阅读

    简而言之,就是使用了spring的schema的扩展机制,进而支持自定义dubbo标签;通过类似serviceload机制配置多个可选服务。通过jdk动态代理和Javassist,使服务调用透明化。结合ZooKeeper实现高可用元数据管理。

    MQ

    MQ(Message Queue,消息队列)使服务调用异步化,可以消除并发访问洪峰,提升网站响应速度。 在MQ实现中,笔者写过一篇介绍Kafka的学习笔记,详细介绍见Kafka/Metaq设计思想学习笔记,不再多言。

    CACHE

    Cache就是将数据放到距离计算最近的地方,用来加快处理速度。通常对一定时间内的热点数据进行缓存。 
    在使用缓存时,需要注意缓存预热和缓存穿透问题。

    一般海量数据的缓存系统不会使用Java来实现,是因为Java有额外的对象大小开销以及GC压力。所以一般是用ANSI C来实现。目前用的比较火的是Redis,更多介绍请查看Redis资料汇总

    STORAGE

    在出现NOSQL之前,一统天下的是MySQL分库分表技术。结合类似TDDL等SQL agent技术,也能够执行类似join的操作。后来,就像忽如一夜春风来,出现了很多NOSQL/分布式存储系统产品。

    分布式存储系统是分布式系统中最复杂的一部分,相比较SOA,CACHE等框架,它需要解决的问题更加复杂。常见的问题如下:

    • 数据分布 在多台服务器之间保证数据分布均匀,跨服务器如何读写
    • 一致性 异常情况下如何保证副本一致性
    • 容错 把发生故障当成常态来设计,做到检测是否发生故障并进行故障迁移
    • 负载均衡 新增、移除服务器时如何负载均衡 数据迁移如何不影响已有服务
    • 事务并发控制 如何实现分布式事务,如何实现多版本并发控制
    • 压缩、解压缩 根据数据特点选择恰当算法,如何平衡时间和空间的关系。

    当笔者阅读完《大规模分布式存储系统原理解析与架构实战》和google的两篇存储论文后,感觉里面的实现细节太多了。如果要写的话,还是后面单独列一片把。所以这里暂且略过。

    其他

    还有其他方面的知识,等后面积累再多些,再重点写吧,这里仅仅是索引下,读者可以自行略过。

    • 配置数据、元数据管理系统:可以查看这篇ZooKeeper和Diamond有什么不同
    • 搜索系统:机器学习分析用户行为,结合搜索进行推荐排名。 各种大数据分析工具。
    • 云计算:硬件虚拟化。创业公司可以购买云服务,避免固定资产开销,可能闲置, 购买,管理,安装费用 ,无法迅速购买等问题,属于浮动消费,类似开车和租车的区别,仅是租用服务。 云厂商在能源,制冷,运维成本,量大硬件定制,充分利用闲置资源具有优势。
    • 鹰眼系统:日志规范化+打点+数据分析+树状展现,详细介绍可以参考 鹰眼下的淘宝-分布式调用跟踪系统介绍
    • 系统运维: 目标是自动化运维。
      • 监控各种资源指标:
        • OS:(cpu,memory,disk(空间,读写次数))
        • 网络流量
        • 中间件: tomcat, jvm,
        • MQ:通过监控生产者,broker,消费者之间的队列情况,动态决定增加、减少消费者
        • 服务框架自省(运维监控) 依赖关系统计,前台系统访问路径,
      • 显示各种监控结果:Agent —》 Explorer ,Analyze,Visual,Dashboard,Share。
      • 预警,运维 自动、手工降级,系统问题自动排查甚至问题自动修复,
    • 能源节省:能源消耗(CPU,机柜,水冷)
    • 系统安全:涉及系统的方方面面,各种脚本,sql注入,0day等等。
    • 版本开发、版本发布:开发环境,测试环境,支持开速发布,不用大的cycle,灰色发布,回滚降级流程,周边协调。 大众点评的有个关于开发环境搭建的,感兴趣的可以点击打造高效的单机开发环境
    • 数据中心:在《程序员》2014年第一期介绍里面,提到了阿里使用了ZONE的概念来解决横向扩展的问题。阿里主要是为了解决机房网络瓶颈和超大规模系统的伸缩性问题,把完成某一特定业务需要的系统、核心服务、数据库组合成一个业务单元。

    参考

    • 《深入分析Java Web 技术内幕》
    • 《大规模分布式存储系统原理解析与架构实战》
    • 《大型网站技术架构核心原理与案例分析》
    • 《分布式系统原理介绍》
    • 《大规模Web服务开发技术》
    • 《程序员》2014年第一期
    • google系列论文
    • varnish / squid / nginx cache 有什么不同?
    • RESTful的优点
    展开全文
  • 一线互联网公司的架构实践

    千次阅读 2015-12-07 14:43:31
    航天信息股份有限公司高级架构师范刚:在互联网+的时代,该如何应对系统变革 来自航天信息股份有限公司的范刚分享了在多年实践中对于系统改造重构的总结与思考。在互联网+的背景之下,很多架构师们面对的是层出不穷...
  • 互联网十大商业模式

    千次阅读 2014-09-13 13:46:34
    互联网十大商业模式   第一类 传统门户    [ 观点 ]     门户网站,本质上说就是一个信息管理平台,是一个信息“大杂烩”的入口。随着互联网技术的发展,网络商务活动增多,门户网站越来越多地被用于...
  • 三级等保成标配,互联网医院安全架构报告发布 原创动脉网2020-09-24 10:43:19 互联网医院本身处于互联网环境中,随时面临着未知人员的恶意访问与攻击行为,自身的安全性难以保障。2018年7月国家卫生健康委员会、...
  • 互联网系统架构的演进

    千次阅读 2014-08-31 22:49:15
    多终端接入、开放平台给互联网带来了前所未有...本文将从发展演进的层面探讨互联网的系统架构。 天下武功唯快不破 网站初期的架构一般采用“短平快”的架构思路,架构以简单清晰、容易开发为第一衡量指标。 互
  • 随着智慧城市的发展,互联网云脑与智慧城市的结合,相信会出现更多城市神经反射弧的案例。譬如智能驾驶,共享单车,智能护理,城市安全,智能无人商店,等等很多场景将会实现城市神经反射弧的建设,未来如何增强城市...
  • 各种大数据工具架构

    千次阅读 2017-06-05 14:08:09
    大数据技术应用在互联网营销将产生彭妾的商业价值     MapReduce MapReduce框架会自动处理数据划分、多机并行执行、任务之间的协调,并且能够处理某个任务执行失败或者机器出现故障的情况。 ...
  • 作者:刘锋文章简介:从本质上讲智慧地球和智慧城市还是互联网发展到一定程度,向城市建设蔓延和深入的结果。因此建设智慧城市就不能不忽略互联网的发展趋势和进化规律。本文将重点探讨智慧城市通过与互联网大脑的...
  • 本课程主要是针对如何从无到有搭建中小型互联网公司后台服务架构和运维架构的课程,课程所涉及的内容均是当前应用最广泛的技术和工具。本课程所讲解的技术体系已经在多个中小型互联网公司中实战运行使用,目前运行...
  • [转]互联网系统架构的演进

    千次阅读 2013-09-21 10:42:37
    作者:杨光辉来源:...本文将从发展演进的角度,解读高性能互联网系统架构。多终端接入、开放平台给互联网带来了前所未有的用户量级和访问规模,SNS网站产生了海量的UGC(用户产生内容),而且这些内容依
  • 互联网技术架构给我们的启示

    千次阅读 2015-10-27 09:43:36
    从应对市场的整体效果看,互联网分布式架构明显优于商业银行传统集中式架构,核心差别在于两类不同的应用架构理念,以及两类不同的技术团队管理、支持方式。因此,从应用入手,着手调整商业银行传统的技术架构和供应...
  • 9 月 10 日,在历史上的今天,Microsoft Office 首席架构师 Charles Simonyi 出生;推特(Twitter)首席执行官 Dick Costolo 出生;马云出生;互联网上第一个搜索工具诞生。
  • 这个围绕应用和微服务的 PaaS 平台,将为企业解决IT系统复杂、升级迭代慢、运维扩展性差、海量用户支撑能力薄弱、数据孤岛等一系列难题,帮助传统企业快速构建面向互联网亿万用户的大规模分布式架构,降低企业IT成本...
  • 工业互联网平台基于ICT技术打造的开放式平台,聚焦“联接+云”,提供智能化的边缘层、泛在网络、可信IaaS、工业PaaS,及汇聚生态伙伴的工业SaaS, 助力制造企业数字化转型。工业互联网平台面向制造业数字化、网络化、...
  • ITPUB个人空间 s v7H2]3q,q b X 预购买地址:http://www.china-pub.com/129900【书名】互联网时代的软件革命——SaaS架构设计【作者】叶伟 等编著【ISBN】978-7-121-07736-4【出版社】电子工业出版社【出版日期】...
  • 本文节选自《未来架构:从服务化到云原生》一书,张亮、吴晟、敖小剑、宋净超合著,由电子工业出版社博文视点出版,已获得授权。本书对快速演进中的云原生数据架构、典型分布式数据库...
  • 本文着重介绍在互联网应用服务器端的架构设计中需要关注的设计考量点,提供一个总览性认知。首先我们需要知道:不同类型的应用、不同用户规模和阶段的应用在架构设计的考量点都是有差异的,架构设计的挑战以及侧重点...
  • 工业互联网联盟(IIC)架构任务组联合主席、美国Thingswise公司CEO 林诗万尊敬的刘多院长,尊敬的余秘书长,尊敬的各位领导、嘉宾,大家下午好!今天很荣幸有机会到工业互联网峰会与大家交流,为此我要感谢大会对我...
  • 互联网商业模式

    万次阅读 2012-07-04 08:55:39
    随着互联网技术的发展,网络商务活动增多,门户网站越来越多地被用于商业活动中,对以信息服务为主的门户商业模式的探索也在日益白热化。各种应用系统、数据资源和互联网资源在这里可以快速地完成企业对客户、企业对...
  • 商业智能系统并非一个单独的系统,数据主要来源于ERP、WMS、SCM等业务系统、办公系统或互联网的数据文件,通过ETL(Extraction-Transformation-Loading的缩写)工具提取、转换和加载到数据仓库中,再对数据进行进一步...
  • 从本质上讲智慧地球和智慧城市还是互联网发展到一定程度,向城市建设蔓延和深入的结果。因此建设智慧城市就不能忽略互联网的发展...作为城市与互联网结合的智慧城市建设,其未来的架构也不可避免出现城市大脑化的迹象。
  • java架构必须掌握的几点技术?关于学习架构,必须会的几点技术1. java反射技术2. xml文件处理3. properties属性文件处理4. 线程安全机制5.... gson json工具类大家对于几大框架望而生畏,实际上只要...
  • 本系列文章主要是针对如何从无到有搭建中小型互联网公司后台服务架构和运维架构的课程,系列文章所涉及的内容均是当前应用最广泛的技术和工具。本系列文章的技术及工具如下:后台服务架构:dubbo、spring-boot、...
  • 因此在瞬息万变的互联网产品环境中,需要研发接入支付系统来加入商业行为的闭环,支付系统能够帮助企业更好地实现商业化,利用那些为用户而生的支付体系产品,实现用户积累、商业变现。 对于支付系统,有针对不同...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 47,846
精华内容 19,138
关键字:

互联网工具的商业架构