达达平台的物流场景

业务场景

达达是全国领先的最后三公里物流配送平台。 达达的业务模式与滴滴以及Uber很相似,以众包的方式利用社会闲散人力资源,解决O2O最后三公里即时性配送难题。 达达业务主要包含两部分:商家发单,配送员接单配送,如下图所示。

达达的业务规模增长极大,在1年左右的时间从零增长到每天近百万单,给后端带来极大的访问压力。压力主要分为两类:读压力、写压力。读压力来源于配送员在APP中抢单,高频刷新查询周围的订单,每天访问量几亿次,高峰期QPS高达数千次/秒。写压力来源于商家发单、达达接单、取货、完成等操作。达达业务读的压力远大于写压力,读请求量约是写请求量的30倍以上。

下图是达达过去6个月,每天的访问量变化趋图,可见增长极快

下图是达达过去6个月,高峰期请求QPS的变化趋势图,可见增长极快

极速增长的业务,对技术的要求越来越高,我们必须在架构上做好充分的准备,才能迎接业务的挑战。接下来,我们一起看看达达的后台架构是如何演化的。

最初的技术选型

作为创业公司,最重要的一点是敏捷,快速实现产品,对外提供服务,于是我们选择了公有云服务,保证快速实施和可扩展性,节省了自建机房等时间。在技术选型上,为快速的响应业务需求,业务系统使用python做为开发语言,数据库使用Mysql。如下图所示,应用层的几大系统都访问一个数据库。

读写分离

随着业务的发展,访问量的极速增长,上述的方案很快不能满足性能需求。每次请求的响应时间越来越长,比如配送员在app中刷新周围订单,响应时间从最初的500毫秒增加到了2秒以上。业务高峰期,系统甚至出现过宕机,一些商家和配送员甚至因此而怀疑我们的服务质量。在这生死存亡的关键时刻,通过监控,我们发现高期峰Mysql CPU使用率已接近80%,磁盘IO使用率接近90%,Slow query从每天1百条上升到1万条,而且一天比一天严重。数据库俨然已成为瓶颈,我们必须得快速做架构升级。

如下是数据库一周的qps变化图,可见数据库压力的增长极快。

(点击放大图像)

当Web应用服务出现性能瓶颈的时候,由于服务本身无状态(stateless),我们可以通过加机器的水平扩展方式来解决。 而数据库显然无法通过简单的添加机器来实现扩展,因此我们采取了Mysql主从同步和应用服务端读写分离的方案。

Mysql支持主从同步,实时将主库的数据增量复制到从库,而且一个主库可以连接多个从库同步(细节参考Replication)。利用此特性,我们在应用服务端对每次请求做读写判断,若是写请求,则把这次请求内的所有DB操作发向主库;若是读请求,则把这次请求内的所有DB操作发向从库,如下图所示。

实现读写分离后,数据库的压力减少了许多,CPU使用率和IO使用率都降到了5%内,Slow Query也趋近于0。主从同步、读写分离给我们主要带来如下两个好处:

  • 减轻了主库(写)压力:达达的业务主要来源于读操作,做读写分离后,读压力转移到了从库,主库的压力减小了数十倍。
  • 从库(读)可水平扩展(加从库机器):因系统压力主要是读请求,而从库又可水平扩展,当从库压力太时,可直接添加从库机器,缓解读请求压力

如下是优化后数据库qps的变化图:

读写分离前主库的select qps

(点击放大图像)

  读写分离后主库的select qps

当然,没有一个方案是万能的。读写分离,暂时解决了Mysql压力问题,同时也带来了新的挑战。业务高峰期,商家发完订单,在我的订单列表中却看不到当发的订单(典型的read after write);系统内部偶尔也会出现一些查询不到数据的异常。通过监控,我们发现,业务高峰期Mysql可能会出现主从延迟,极端情况,主从延迟高达10秒。

那如何监控主从同步状态?在从库机器上,执行show slave status,查看Seconds_Behind_Master值,代表主从同步从库落后主库的时间,单位为秒,若同从同步无延迟,这个值为0。Mysql主从延迟一个重要的原因之一是主从复制是单线程串行执行。

那如何为避免或解决主从延迟?我们做了如下一些优化:

  • 优化Mysql参数,比如增大innodb_buffer_pool_size,让更多操作在Mysql内存中完成,减少磁盘操作。
  • 使用高性能CPU主机
  • 数据库使用物理主机,避免使用虚拟云主机,提升IO性能
  • 使用SSD磁盘,提升IO性能。SSD的随机IO性能约是SATA硬盘的10倍。
  • 业务代码优化,将实时性要求高的某些操作,使用主库做读操作

垂直分库

读写分离很好的解决读压力问题,每次读压力增加,可以通过加从库的方式水平扩展。但是写操作的压力随着业务爆发式的增长没有很有效的缓解办法,比如商家发单起来越慢,严重影响了商家的使用体验。我们监控发现,数据库写操作越来越慢,一次普通的insert操作,甚至可能会执行1秒以上。

下图是数据库主库的压力, 可见磁盘IO使用率已经非常高,高峰期IO响应时间最大达到636毫秒,IO使用率最高达到100%。

(点击放大图像)

同时,业务越来越复杂,多个应用系统使用同一个数据库,其中一个很小的非核心功能出现Slow query,常常影响主库上的其它核心业务功能。我们有一个应用系统在MySql中记录日志,日志量非常大,近1亿行记录,而这张表的ID是UUID,某一天高峰期,整个系统突然变慢,进而引发了宕机。监控发现,这张表insert极慢,拖慢了整个MySql Master,进而拖跨了整个系统。(当然在mysql中记日志不是一种好的设计,因此我们开发了大数据日志系统。另一方面,UUID做主键是个糟糕的选择,在下文的水平分库中,针对ID的生成,有更深入的讲述)。

这时,主库成为了性能瓶颈,我们意识到,必需得再一次做架构升级,将主库做拆分,一方面以提升性能,另一方面减少系统间的相互影响,以提升系统稳定性。这一次,我们将系统按业务进行了垂直拆分。如下图所示,将最初庞大的数据库按业务拆分成不同的业务数据库,每个系统仅访问对应业务的数据库,避免或减少跨库访问。

下图是垂直拆分后,数据库主库的压力,可见磁盘IO使用率已降低了许多,高峰期IO响应时间在2.33毫秒内,IO使用率最高只到22.8%。

(点击放大图像)

未来是美好的,道路是曲折的。垂直分库过程,也遇到不少挑战,最大的挑战是:不能跨库join,同时需要对现有代码重构。单库时,可以简单的使用join关联表查询;拆库后,拆分后的数据库在不同的实例上,就不能跨库使用join了。比如在CRM系统中,需要通过商家名查询某个商家的所有订单,在垂直分库前,可以join商家和订单表做查询,如下如示:

select * from tb_order where supplier_id in (select id from supplier where name=‘上海海底捞’);

分库后,则要重构代码,先通过商家名查询商家id,再通过商家Id查询订单表,如下所示:

supplier_ids  =   select id from supplier where name=‘上海海底捞’
select * from tb_order where supplier_id in (supplier_ids )

垂直分库过程中的经验教训,使我们制定了SQL最佳实践,其中一条便是程序中禁用或少用join,而应该在程序中组装数据,让SQL更简单。一方面为以后进一步垂直拆分业务做准备,另一方面也避免了Mysql中join的性能较低的问题。

经过一个星期紧锣密鼓的底层架构调整,以及业务代码重构,终于完成了数据库的垂直拆分。拆分之后,每个应用程序只访问对应的数据库,一方面将单点数据库拆分成了多个,分摊了主库写压力;另一方面,拆分后的数据库各自独立,实现了业务隔离,不再互相影响。

水平分库(sharding)

读写分离,通过从库水平扩展,解决了读压力;垂直分库通过按业务拆分主库,缓存了写压力,但系统依然存在以下隐患:

  • 单表数据量越来越大。如订单表,单表记录数很快将过亿,超出MySql的极限,影响读写性能。
  • 核心业务库的写压力越来越大,已不能再进一次垂直拆分,Mysql 主库不具备水平扩展的能力

以前,系统压力逼迫我们架构升级,这一次,我们需提前做好架构升级,实现数据库的水平扩展(sharding)。我们的业务类似于Uber,而Uber在公司成立的5年后(2014)年才实施了水平分库(mezzanine-migration),但我们的业务发展要求我们在成立18月就要开始实施水平分库。逻辑架构图如下图所示:

水平分库面临的第一个问题是,按什么逻辑进行拆分。一种方案是按城市拆分,一个城市的所有数据在一个数据库中;另一种方案是按订单ID平均拆分数据。按城市拆分的优点是数据聚合度比较高,做聚合查询比较简单,实现也相对简单,缺点是数据分布不均匀,某些城市的数据量极大,产生热点,而这些热点以后可能还要被迫再次拆分。按订单ID拆分则正相反,优点是数据分布均匀,不会出现一个数据库数据极大或极小的情况,缺点是数据太分散,不利于做聚合查询。比如,按订单ID拆分后,一个商家的订单可能分布在不同的数据库中,查询一个商家的所有订单,可能需要查询多个数据库。针对这种情况,一种解决方案是将需要聚合查询的数据做冗余表,冗余的表不做拆分,同时在业务开发过程中,减少聚合查询。

反复权衡利弊,并参考了Uber等公司的分库方案后,我们最后决定按订单ID做水平分库。从架构上,我们将系统分为三层:

  • 应用层:即各类业务应用系统
  • 数据访问层:统一的数据访问接口,对上层应用层屏蔽读写分库、分库、缓存等技术细节。
  • 数据层:对DB数据进行分片,并可动态的添加shard分片。

水平分库的技术关键点在于数据访问层的设计,数据访问层主要包含三部分:

  • ID生成器:生成每张表的主键
  • 数据源路由:将每次DB操作路由到不同的shard数据源上
  • 缓存: 采用Redis实现数据的缓存,提升性能

ID生成器是整个水平分库的核心,它决定了如何拆分数据,以及查询存储-检索数据。ID需要跨库全局唯一,否则会引发业务层的冲突。此外,ID必须是数字且升序,这主要是考虑到升序的ID能保证Mysql的性能(若是UUID等随机字符串,在高并发和大数据量情况下,性能极差。对比性能测试数据可供参考uuid-vs-int-insert-performance)。同时,ID生成器必须非常稳定,因为任何故障都会影响所有的数据库操作。

我们的ID的生成策略借鉴了Instagram的ID生成算法(sharding-ids-at-instagram)。具体方案如下: 

(点击放大图像)

  • 整个ID的二进制长度为64位
  • 前36位使用时间戳,以保证ID是升序增加
  • 中间13位是分库标识,用来标识当前这个ID对应的记录在哪个数据库中
  • 后15位为自增序列,以保证在同一秒内并发时,ID不会重复。每个shard库都有一个自增序列表,生成自增序列时,从自增序列表中获取当前自增序列值,并加1,做为当前ID的后15位

总结

创业是与时间赛跑的过程,前期为了快速满足业务需求,我们采用简单高效的方案,如使用云服务、应用服务直接访问单点DB;后期随着系统压力增大,性能和稳定性逐渐纳入考虑范围,而DB最容易出现性能瓶颈,我们采用读写分离、垂直分库、水平分库等方案。面对高性能和高稳定性,架构升级需要尽可能超前完成,否则,系统随时可能出现系统响应变慢甚至宕机的情况。

参考:

http://www.infoq.com/cn/articles/imdada-high-performance-server-optimization


第二部分:

从2014年起,外卖、水果、生鲜这些到家的O2O服务正在快速兴起,从各公司的关注点来看,大量都是从消费者端进行流量切入——通过大量资金快速获取用户,然后将用户需求导入到商户手中。

但大量“O2O”们没有解决好的问题是“最后三公里”的物流。很多平台的物流模式是把大量订单导入到商家那里,由商家自己来进行配送,商家一般通过自建的小时工模式来解决物流的问题。自建小时工模式最大的问题在于低效——如果商家很小,无法让小时工开足马力运转,同时也可能出现在不同的时间段的运力分配的问题,比如在午餐时间段配送力不足,而其它时间运力过剩。

这就是达达切入配送市场的初衷——用当下流行的“共享经济”模式,通过社会化的物流去解决即时性的最后三公里的物流问题。

如果做一个类比,可以用滴滴进行比较,不同点在于滴滴送人,达达送货。在商户端,安装了商户APP后就能够在平台上发送配送的需求。同时,任何一个配送员,甚至之前从未做过配送员的人,只要安装了达达配送APP,有一辆电动车,在通过达达非常严格的审核和线上线下培训之后,就可以看到周围商户的需求,就可以开始进行配送赚钱。

对此,达达配送CTO杨骏认为,这其实是一个需求端(商家端)和供给端(配送员端)对实时并具有地域性需求的匹配过程。这种模式的最大优势是精准匹配,其次是可扩展性——当配送员数量达到一定规模后,几乎可以通过口口相传来达到快速的自增长,这也是达达仅用了一年多时间就将配送员积累到了几十万的原因。

很难想象有哪个企业拥有几十万的配送员,即便是京东也只有几万人的规模。而众包物流除了解决人力需求的问题外还提升了效率——这是一个非常有弹性的运力,只有需求出现的时候,运力才会去满足它,获得的收入是完全按照订单数来决定的,当没有需求的时候,就不需要有这样一个配送员。

“达达在国内最早采用了众包物流的模式,它的飞速发展也证明了这个模式对于’最后三公里’配送的市场是非常合适的。我们在很短的时间内就将配送量从零开始做到每天近百万单的规模,这说明我们当时切的这个痛点也是非常正确的”,杨骏表示。

趋同商业模式背后的技术比拼

1、数据驱动

达达发展到今天,其研发人员的数量也不到一百,达达用什么跟同行去竞争、跟更大的互联网公司去竞争?

杨骏认为,良好的技术氛围是塑造工程师文化的关键。在达达内部有很多技术分享会,也会定期请Uber或Facebook的技术同行来内部做技术交流。但最重要的还是人的质量问题。在达达的招聘中有一条原则——只招在当前团队平均水平以上的人,这样才能保证公司研发人员的整体能力越来越强。目前达达的技术团队中,有来自阿里、百度、京东、腾讯的技术骨干。虽然达达的研发目前还是一支相对不是那么大的团队,但团队中技术骨干的简历让人印象深刻。

另一个关键点在于技术的创新。在技术投入上,达达很早就开展了围绕配送效率的项目研究,比如订单合并。这意味着通过技术手段,把起始地和目的地比较接近的订单合并在一起,让配送员进行同时配送,极大提升了配送效率。

“在订单合并的背后,是大量的算法研究,达达专门有一个专职的BI团队,这支团队建立了后台的一套很完整的数据仓库,每天处理大量的数据,生成各种各样的报表。”杨骏认为,数据才是产品和运营优化的动力,包括配送员配送路线的优化、动态的定价策略等等。

比如,达达对所有的送货地址数据处理中,都必须保证送货地址是非常精准的。实际情况往往是,商家在输入地址时有可能输得比较含糊,有可能地址解析时出现各种各样的错误。所以达达很早就在后台创建了“云地址库”——记录了所有商家每一次输入的收货人电话号码和他的地址的关联关系。这样任何商家如果输入了云地址库中某个已知收货人的电话号码,达达的系统就会自动提示该收货人的地址信息,避免了商家手动输入地址。这个用户体验大大节省了商家发单的时间。而在有了云地址库后,系统在背后可以做大量的数据优化、精准分析的工作,去修正所有的地址数据,这样在做订单合并的时候才能确保最大化的提升效率。

据了解,目前达达每天产生的数据量大概在100G上下,而且对实时数据处理的需求很大,目前传统的数据库已经很难处理日常数据,所以达达目前正在讨论的一件事是如何利用新的数据架构来处理新的需求。

杨骏谈到:“达达配送整个API的使用都是实时的:有单子发出来的时候,我们需要配送员能够实时看到;另外,订单合并也要求做实时的合并。目前后台离线的分析以及需要用的数据量已经超过数据库的存储范围,所以达达正在考虑把整体架构迁移到Hadoop上。此外,达达在过去的一年中也对系统的底层架构做了很多升级,包括数据库的主从分离,读写分离,垂直拆分,缓存系统的上线,保证在单量激增的同时系统一直稳定可用。”

2、货品安全

物流的货品安全问题是一个老生常谈的问题。过去无数的实例证明,所有的物流企业都需要一套行之有效的货品安全体系。

为了保证货品的配送安全,达达建立了一套非常严格的注册和审核的流程,所有的达达配送员必须是实名身份证认证,平台对身份文件进行审核,同时调用第三方服务做背景调查。如果发现有一些有问题的人,会从审核环节就把他排除在外面。此外,在通过审核后配送员必须进行一次新手线上培训及考试,通过以后才能接单。而当配送员接了少量的单子后,必须再接受一次线下的培训,这是和培训师面对面的培训,并且再次通过考试他才能长久的接单。所以达达在审核、线上培训、线下培训这几个环节就已经做了大量的筛选,保证相对质量较高的、真实可靠的配送员才会进入达达的配送员体系中去。

而支付保证金模式则是保证货品安全的另一个保障——如果用户选择当面付款,达达平台会要求配送员到商家那儿取货时,自己出现金把货买下来,配送完成后用户再把货品钱交给配送员。也就是说在配送的过程中,配送员其实是拥有了货品的,这大大降低了配送员把货拿走的概率。而如果是线上支付,用户已经在线上付过钱,平台会将配送员的账户进行对应金额的冻结,直到配送完成。再有,对于每一个订单,平台都跟踪取货和送达的时间以及送货的轨迹。这就保证了所有订单都是真实的,同时也保证了我们对于每一个订单的服务质量都有跟踪。而所有的订单背后对配送员都有一套评分体系,以此对配送员进行评价,优胜劣汰,将接单较多、服务质量较好的配送员留在平台上。

用技术打造众包模式的行业壁垒

自从总理提出互联网+计划后,用互联网对传统行业进行优化,让传统行业变得更有效率就是互联网届的主旋律。甭管是否互联网企业,大家都在积极投身这场“互联网+”的大革命,O2O、跨界等沙龙主题每天都在进行,资本、商业模式等关键词成了每天各大媒体最活跃的关键词。但冷静下来后,我们发现,其实技术才是决定谁能够走得更远,更能接近目标的关键。

尽管众包模式或者共享经济在当前的大环境下被所有人一致看好,但不得不说的是,竞争依旧是残酷的。如何在雷同的商业模式里迅速树立行业壁垒,这是杨骏所关心的问题。

“其实是两个壁垒的问题,首先是规模的壁垒。当用户规模达到一定程度时,会出现这样的情况,如果你是任何一个商户,当你打开你的APP时会发现,就在你的门口不远处就有一个配送员等着接你的单子。而同样作为配送员来说,当你打开你的APP,你会发现周围有很多商户需要你配送,这就是规模效应。对双边市场来说,规模本身就是一个巨大的壁垒,这也是Uber、滴滴们花了大钱去拓展,去迅速增加规模的根本原因。拿滴滴举例,现在它已经大到一定程度,至少在国内不会有人再想做第二个滴滴了,这就是规模效应。达达对于最后三公里是首创的众包模式,有非常好的领跑效应。现在达达平台比市场上其他用这个模式的平台规模都大很多倍。”

第二个壁垒则是效率的壁垒。如何让配送员在相同的时间内配送更多的单子,这其实是用户体验和成本的壁垒。配送员在一个小时内多送单就意味着每一单的成本有所下降。也就是说可以给到商家更优惠的价格,同时也会给到配送员更高的报酬,因为整个效益都提升了。

杨骏表示,“这两个壁垒的形成需要以强大的技术实力来保障系统稳定性和高效性。我们的团队从只有几个人开始发展到现在,在这两个方面都做了大量的工作,保证了我们在这个行业的领跑地位。”

达达配送在很早的时候就开放了配送的API,允许所有做O2O的电商通过API接入使用达达的物流配送体系。此外,在支付模式上,达达目前已经支持第三方的当面付场景,商家支付运费和达达配送员提取运费已经完全线上化,运费方面已经不存在线下的现金交易,未来也还会有各种各样不同的支付手段来方便用户付款。

从更长远的发展来看,达达依然会继续深耕物流行业,在商业和技术模式上创新解决最后三公里中的复杂问题。比如驻店模式——在短期内派几个配送员在某些高峰的时段,驻店帮商户做配送。而平台上的配送员每天接单量总和达百万,这也意味着配送员跟用户见面的机会都是很好的流量入口,未来甚至可以依托配送员进行产品推广。这也是很有意思的战略方向。“从金融角度来考虑,达达已经有数十万非常优质的商户在平台上,一定程度上知道每个商户的发展情况。未来可以相应开展金融服务和供应链服务,这是另外一个非常有想象空间的方向。”杨骏最后说道。

参考:

http://www.csdn.net/article/2015-10-26/2826039





第三部分:


[ 导读 ]  资本寒冬下的物流O2O生机,物流玩家需要即把握好即时性、区域性和离散性的市场需求,搭建自建或众包运力的物流系统,运用好社区和商圈资源,加强服务质量的管控,应运去铺设一张张深入“毛细血管”的小物流网络,形成壁垒。
达达平台的物流场景_第1张图片

研究结论

1、O2O服务对物流服务提出了新的需求,可概括为即时性、区域性和离散性。因此,一张张深入“毛细血管”的小物流网络将取代电商时代的网状物流系统。


2、物流系统的搭建多由自建运力和众包运力组成,社区和商圈成为战略资源,对人员和订单的管控成为线下服务质量控制的两个关键。


3、一个物流网络的壁垒就在于规模与效率的加成效应。


4、目前参与这场物流重建的有两类玩家:第三方物流平台和O2O业务平台,前者想做所有O2O服务的基础设施,后者则希望在服务好自身业务的基础上做更多业务延伸。


本地生活服务,寒冬下的“资本宠儿”


近一个月来,本地生活服务领域的投资非常活跃。9月8日,本地生活服务平台“生活半径”获得来自阿里口碑网的C轮融资;9月18日,外卖平台“点我吧”也确认完成来自口碑网的C轮战略投资。虽目前的业务重心不同,但两者都要发力做“本地生活服务平台”,而其实质就是即时物流配送业务。另外,9月23日宣布获得7000万美元C轮融资的社区电商“爱鲜蜂”也表示,下一步将发力物流领域的投资布局。


无独有偶,“京东到家”和“饿了么”这两个本地生活服务的“流量巨头”早已经开始搭建自己的众包物流体系。同样是基于众包的第三方物流平台“达达”在6月则完成了来自DST领投的1亿美元C轮,这已经是达达成立一年内的第三轮融资。在7月独立并拿到2.5亿美元融资的百度外卖也表示要建成一个同城物流网络。


可以说,无论是O2O领域的创业者还是投资人,都开始逐渐看到物流的价值。物流之于大部分O2O服务就像物流之于电商一样,是基础设施的角色。不过,相比于电商时代,O2O业态的繁荣带来的是一次物流体系的重建,是一场从主干道到毛细血管的创新。



一、问题:O2O业态下的物流新需求


1、O2O生态中的“黄金地”


在O2O生态中,业务形态繁多、边界几乎可以无限延伸。但若对各类O2O服务进行业务逻辑上的拆解,几乎所有的O2O业务都可以按照 “做信息还是做交易”、“到店服务还是不到店服务”两大维度放入以下四个象限中(如下图):

达达平台的物流场景_第2张图片

其中,信息服务对传统行业的改造能力有限,也不足以承载更多商业模式创新的红利。因此,随着互联网对实体经济的渗透越来越深入,停留在信息层的服务价值正在衰减,大家都不约而同的转向交易层的服务。例如,大众点评推出“闪惠”、58同城力推58到家等,都是它们由信息服务向交易服务转型的重要布局。


而同样聚焦在交易层,大家关于“是否到店”的选择也在发生变化,定位于家庭及办公场景的O2O服务正在迅速崛起。一方面,“懒人经济”盛行,选择足不出户进行服务消费的用户在一二线城市正变得越来越多;另一方面,相对某一个经营门店来说,“到家”是一个多元化业务承载能力更强的消费场景,这给了O2O公司在一个场景中更大限度开发用户消费需求的机会。


因此,上图中几乎所有的O2O服务都在往第四象限移动,与用户在家庭、办公、出行等日常生活场景中建立接触点。而这其中,即时配送服务在需求刚性、消费频次、用户黏性等方面都比上门服务更胜一筹,也是目前创业者和资本都最活跃的O2O细分领域。因此,本文所讨论的O2O服务也都分布在这个细分领域之内。


2、O2O服务的痛点


对于聚焦“送货上门”的O2O服务来说有两大痛点:物流和支付。其中,物流不仅是业务模式的核心所在,也是在整体市场规模不断扩大过程中所日益凸显出来的行业短板。


物流的问题又分为两类:一类是商家自身物流能力日渐无法满足需求;另一类则是商家本身就不具备物流能力。


前者的代表是饿了么等外卖平台。当平台起步时,单量较小,餐馆自己的配送员可以满足订单需求。但随着单量增长以及用户对服务体验的要求越来越高,餐馆自身运力已经无法满足需求。这时候平台为了保障服务体验,必须在物流配送方面给出解决方案。


后者的代表则是各类商超、便利店、药店、花店等零售商。他们本身并没有物流能力,但线下零售与线上融合的趋势不可逆,在面对用户配送到家的需求时,这些线下商家或依赖京东、饿了么等平台,或与达达等第三方物流公司合作。


可以说,最后一公里的物流配送若不能达标,基于本地生活的各类O2O服务也无法快速扩张、实现规模化。


3、O2O业态下的物流新需求


现有的电商物流体系能解决O2O即时配送服务的物流需求吗?我们来看看传统电商物流体系的运营方式。


无论是京东的自建物流,还是淘宝所依赖的以“三通一达”为代表的第三方物流,都需要建立一个全国性的网络,由干线、支线、仓储中心、分拨中心、落地配送等环节构成,货品在这个物流网络中逐层传递。如此搭建系统结构的原因在于,传统电商有海量SKU、时效性较低、区域性弱等特点,因此传统电商在物流环节考虑的是如何降低成本并实现集约化。


然而O2O商品和服务的配送却与电商的要求截然不同,集中呈现为即时性、区域性、离散性等特点。


即时性:这是 O2O 区别于电商最大的特点,其订单的配送时间基本都以“小时”计量,外卖订单则需要精确到“分钟”。传统电商物流的网状结构显然无法满足O2O订单对时效性的需求。


区域性:用户在下即时配送的订单时,会根据自己所处的位置就近消费,因此这类订单天然的具有区域性特点。传统电商覆盖全国范围的一张大网解决不了区域性配送的效率问题,普遍的解决方案是以三公里为半径搭建区域型的配送网络。


离散性:人们基于便利性而产生的配送需求往往是突发性的、碎片化的,例如一个用户同时通过饿了么叫外卖、在京东到家上购买生鲜和零食,却无法实现统一配货和配送。因此,传统电商物流的连续型大规模配送系统不起作用,相应的,需建立一个点对点的、离散型的物流模型。这个物流模型最典型的特点就是不集货入库、没有中转环节。


因此,“干线+集中式仓储+支线”的一张物流大网在O2O业务中已经不再适用,取而代之的,是一张张深入“毛细血管”的小物流网络散落在城市的各个角落,并通过一定的管理和运营规则将这些小物流网络连接起来。



二、解决方案:一场深入“毛细血管”的物流系统重建


1、运力供给


物流是一个劳动密集型的生意,足够的运力是基础。在这场深入毛细血管的物流系统大重建中,各家公司在运力组建方面呈现出了不同的思路。


自建


自建物流最大的优势无疑是对服务的品控能力更强。因此,最早一批自建物流的O2O公司便是那些定位中高端餐饮品牌和用户的外卖平台,如到家美食会、点我吧、趣活美食送等。


随着外卖市场规模的迅速扩大,饿了么、美团、百度外卖等“流量大户”也纷纷开始自建物流。一方面,餐馆的自有运力已经不足以承担日益增长的单量;另一方面,外卖行业的竞争已经从流量端转移到了线下服务端,自建物流以保证服务质量也是必经之路。


自建运力的第三方物流平台则不多,典型的有风先生。


但自建物流的弊端也很明显,过重的运营方式使得整个物流系统难以快速实现规模化。因此,无论是第三方物流平台还是以外卖为代表的O2O业务平台,都有一部分运力采用众包的方式,其中众包的比例正在逐渐增大,而达达更是完全采用众包的方式组建运力。


众包


众包模式的物流系统在逻辑上与Uber一脉相承。众包物流平台的配送员通常自备交通工具、自付邮费,平台按照中心调度的方式给他们就近派单(或是让配送员抢单),配送员接单后直接去到商户处取货,完成配送后与平台按单完成结算。


在达达的创始人蒯佳祺看来,众包物流平台的精髓就是“规则的制定”,通过合理的产品机制和运营规则来管理数十万游走在大街上的兼职配送员,而非通过公司的制度管理。这与自建物流的管理方式在思路上完全不同。所以,以B2C物流起家的京东在O2O业务上转变思路做众包物流还要面临自身基因带来的阻碍。


运力延伸


所谓运力延伸,就是将其它共享经济模式中的闲置劳动力延伸到配送服务中来,其本质仍是一种众包模式。


Uber从2014年开始便依次推出送餐、本地配送等业务,今年4月Uber也开始与400多家零售商合作,为它们提供当日送达服务。Uber 创始人Travis Kalanick对公司的定位是——做一家按需物流公司。


再看国内,Uber的模式和思路正在被实践。据企鹅智酷了解,虽否认了资本层面的合作,但饿了么正在与滴滴出行确实在进行业务层面的接触,双方近期将开始合作测试,滴滴出行将用旗下车辆帮助饿了么送餐。先期的合作会从北京开始,主要针对特色餐厅和中高档消费用户。未来,双方的合作会扩展到快递、商超、生鲜等领域。


2、社区和商圈的价值


新的物流体系犹如在已有的物流干线基础上,又生长出来了很多 “毛细血管”。这些毛细血管深入到社区、商圈,使得以社区和商圈成为了这个物流体系中重要的单位。


一方面,社区或商圈内的零售店、便利店等可以作为仓储节点。即时配送的离散型、突发性等特点使得社会化库存将全面取代大规模集货入库的仓储方式。尤其对于“代跑腿”的业务来说,这些零售店就是一个个自带SKU的小仓库。


另一方面,这些零售店、便利店、夫妻小店还可以作为物流配送节点,贡献运力。例如,社区电商“爱鲜蜂”就是依靠社区里夫妻店的经营者来进行最后一公里配送;拥有几十万小店资源的拉卡拉在布局社区电商业务时,也发动小店店主为用户提供送货上门服务。同时,这些社区和商圈商户中的劳动力还可以利用自己的闲置时段为众包物流平台提供配送服务,这是一个庞大的闲置劳动力资源集。


3、线下服务控制


京东商城的B2C模式之所以在体验上可以与淘宝拉开距离,主要就是因为用自营的方式做仓储和物流可以实现各环节服务可预期、各环节时间成本可控。那么众包的物流平台该怎样做线下服务控制?如前文所说,这需要依靠产品和运营规则的制定,具体则可以细化为两大方面:对人员的管控;对订单的管控。


对人员的管控


首先是对快递员审核培训。例如,达达的做法是所有的配送员都需要通过实名身份认证,并且达达将配送员数据库与政府数据库进行对接,确保每个配送员“没有前科”,尽量做好反欺诈。


其次,用培训规范配送员的服务。大部分平台都需要配送员在上岗前通过基础考试,有的平台还会定期召集配送员进行培训。


再次,用合理的奖惩机制规范和激励配送员。仍以达达为例,它为每个配送员建立了一个评分体系,并根据配送员的配送效率和服务质量为其打分。配送员的信用评分将直接影响他的接单权限和奖惩。


对订单的管控


配送过程的信息化是各物流平台都在做的事情。化实现程度很低,而当平台自己承担配送之后,物流过程信息化成为首当其冲的任务。例如饿了么的“开放配送平台”(也就是“蜂鸟系统”)所承接的所有订单都是完全信息化的,为的就是实现订单的实时监控:配送员从商户发出订单到订单完成这个过程中的每个环节和所处的地理位置都可以通过手机被实时追踪。理论上,订单若在配送过程中出现问题,可以准确定位到配送员及其位置,及时解决或事后反馈。


达达还对订单做了平台担保。对于货到付款的订单,达达的配送员需要先垫付相应金额,完成配送后再从用户端收钱;对于在线支付的订单,平台则会冻结配送员相应金额的信用值,完成配送后在予以解冻。


饿了么的物流研发负责人高伟认为,目前众包物流在品控方面与自营还有一定的差距,除了不断完善产品机制和运营机制,还需要经历一个不断市场化的过程,通过商户的选择来不断优化整个体系,这也是行业演化的必经之路。


4、规模与效率


在蒯佳祺看来,一个物流网络的壁垒就在于规模与效率的加成效应。物流是一个典型的双边交易市场,需求与供给的平衡和匹配是双边市场的关键。良好的匹配能提升效率,效率将促成规模,而规模的不断增大又能进一步优化效率。规模与效率的加成将为双边市场带来网络效应,这与Uber和滴滴的发展路径非常相似。除此之外,效率也将带来成本的降低和优化,饿了么和达达都表示这是平台实现盈利的必经之路。


一些物流平台正通过“无分区”运营模式来提高物流网络的整体效率。


目前大部分物流平台都是采用 “分区”运营,即以类似“区域分公司”的概念为管理单位来承担订单对接、调度派单及配送等在职能,各分区之间互不影响。而“无分区”运营即以用户订单为中心,通过一个总调度中心进行订单任务派发。对于配送员来说,一单的终点就是下一单的起点,与Uber司机的状态更为接近。当然,由于订单自身的区域性属性,每一个配送员的活动范围也并不会太大。


当一个区域内订单密度和配送员密度不匹配的时候,无分区运营能实现更灵活的运力调度,从而提高整个配送网络的效率,同时半径范围内的用户也更有可能得到有保障的服务。达达、点我吧都是采用无分区运营。


除了匹配度之外,衡量一个物流网络的效率还有一些基础指标,包括:容量,也就是这个物流网络能同时承载多大的单量规模,其各个区域分别能承载多少商户;人均配送效率,即是一个配送员一天配送单量的均值和峰值;时效性,即完成一次配送的平均时长;订单满足率,即下单后完成订单的比率;事故率,即订单是否完好无损的送到用户手中,期间损坏或丢失的比率。


三、玩家们:做O2O生态中的基础设施


1、第三方物流平台:做线下商户和O2O平台的基础设施


随着餐厅、超市、便利店等传统线下餐饮和零售都开始向线上融合,即时配送类的O2O业务渐成生态。想在这个生态中的做出规模的玩家都必须是一个“交易平台+物流平台”,而第三方物流平台想做的就是帮那些没有足够物流能力的商户或O2O平台补齐物流这块短板,做这个生态中的基础设施。它们只提供针对B端商户或O2O平台的服务,帮助商户或O2O平台更顺利的完成订单。目前,第三方物流平台包括达达、风先生、生活半径、我快到等。


第三方物流平台包括自建和众包两种搭建方式。2010年便开始以“本地生活服务配送”切入第三方物流领域的生活半径做的是自营模式,但规模化速度相对较慢。同样采用自建模式的风先生在运营模式上与其它平台存在一些差异,其本质更像向线下商户提供劳务外包服务。而2014年才成立的达达则采用众包模式,目前已成为第三方物流平台中规模最大的一家。据达达公布的数据,其目前已扩展到27个城市,拥有40万实名注册的配送员,日单量约70万。


由于不具备来自C端的流量入口,第三方物流平台拼的都是对商户的服务能力,集中体现为自身物流网络的效率和规模。规模可以通过线下的推广运营来达成,而效率则必须通过产品技术来实现。团队的强物流基因决定了达达的技术优势,这也是达达能在一年时间里迅速建立起规模优势的关键。


订单合并和路程规划


订单合并是提高效率最重要的手段。当单量密度足够大时,在某个半径区域内会同时产生很多订单,合理的订单合并和经过算法优化的路程规划可以帮配送员省去不少在路上反复来回的时间。


订单合并有两种情况:一是同店合并,二是沿路合并。


第一种情况很好理解,也就是配送员到店后这家店又产生了新的顺路的订单,便可以直接合并给这个配送员。第二种情况则是给配送员同时推送一组订单,这些订单都位于A点到B点之间,并且系统还为配送员推荐经过优化之后的最佳行程。合并订单的比例越高,订单的完成效率就越高,这将带来的结果是:整个物流网络效率的提升和成本的下降。这与UberPool的原理非常类似。


价格模型制定


除此之外,达达还有一套比较复杂的定价模型。这个模型中包含城市、区域、天气、商户类型等多个计算维度,因此每一单的价格都有可能不同。这样做的目的一方面是更好的激励配送员,另一方面也是让市场调节发挥更大的作用。除了达达之外,点我吧的定价模型也比较有意思,它参考出租车的定价方式,在一定距离内采用固定收费,超出后每公里加收一定费用。


在合作方式上,达达为线下商户和配送员分别开发了app,用于发单和抢单。而对于有互联网能力的饿了么、京东、百度外卖、美团等O2O平台,达达则向它们提供API接口,平台自主接入后可直接向达达的配送员派单。


在蒯佳祺看来,解决了物流,支付问题也将水到渠成。对于那些尚没有接入线上支付的商家,达达通过自身的平台担保先行支付给商家,随后再从用户端收取相应款项,为商家的线下支付提供了一个解决方案。除此之外,O2O服务普遍都面临推广难题,而物流是商户与用户之间的高频接触点。


第三方物流平台若能提供合格的基础设施型服务,则会有越来越多的公司选择基于它们来创业:抛开物流,专注做好面向用户端的服务和产品以及上游供应链。目前,达达的合作伙伴包括饿了么、京东、百度外卖、淘点点、美团、一米鲜、爱鲜蜂、回家吃饭、觅食、沱沱工社等各个细分领域内的领跑者。用蒯佳祺的话来说:“第三方物流平台的本质是服务性和包容性的,而非侵略性。”


2、以O2O业务为入口做一个“同城物流网”


虽然有第三方物流平台的支持,拥有大流量的O2O平台却并没有放弃自己做物流的打算。近期,外卖平台频频获得融资。8月底,饿了么宣布获得6.3亿美元F轮系列融资;9月,点我吧获得来自阿里口碑网的C轮融资。但这背后资本所争夺的绝不仅仅是外卖市场。


用高频和规模构建入口


一方面,外卖是所有O2O业务中集刚需、高频、高黏性于一身的入口级业务,饿了么等外卖平台也由此具备了入口级的资源优势和规模优势。另一方面,外卖对配送在时效性上的要求几乎是最高的,这也使得在构建和优化自身物流系统这件事上,外卖平台有着最强烈的需求。可以说,外卖业务就像是即时物流的 “试金石”。


可以看到,一些外卖平台已经开始做业务延伸,希望搭建一张能够承载多品类配送业务的同城物流网。今年4月,饿了么开始研发“蜂鸟配送系统”,于6月上线,并于8月开始正式对接第三方物流平台和以由闲散劳动力组成的众包物流(目前以第三方为主),推出“开放配送平台”的概念。截至9月,饿了么开放配送平台已覆盖全国 260 多个城市,日峰值配送订单达到 80 万单,已接入约500家第三方配送团队。而在9月刚宣布获得口碑网C轮融资的外卖平台点我吧也借势推出面向商户的配送服务“点我达”,目前覆盖十几个城市,日单约10万单。


可以说,外卖配送本质上做的就是短距离即时物流这件事。对于饿了么等平台来说,一旦这一模式在外卖领域获得大范围验证,下一步顺理成章可以将服务对象扩展到更多品类的本地生活服务。张旭豪也公开表示,饿了么将凭借开放配送平台把物流和配送打造成新的核心竞争力,在前端(流量端)从外卖拓展到生鲜、蛋糕、超市、药品等品类,线下商家通过入驻饿了么获取订单,同时在后端由饿了么的开发配送平台来完成配送。


同时拥有流量优势和物流基因的京东也为其O2O品牌“京东到家”规划了一条与饿了么相似的路径。不同的是,京东到家选择从生鲜、商超、便利店等品类入手,这是仅次于外卖的高频、高黏性的业务,继而形成一个“不到店”服务的综合型平台。在京东到家看来,他们和合作商户的协同效应不只是产生在前端流量或是现金上,还要产生在后端的用户对接上,具体的也就是指物流配送。根据京东到家公布的数据,截至9月,上线四个月的京东众包物流已覆盖21个城市,拥有10万配送员。


分级式的物流体系


以目前配送体量最大的外卖平台饿了么来看,其开放配送平台中的运力分为三个部分:自建、第三方配送接入、基于闲散劳动力的众包。


在看到依靠商家自配已经无法满足用户需求的问题时,饿了么率先开始尝试的是自建物流。即使做了开放平台后,自建也被认为是饿了么“旗舰级”的配送服务,是饿了么所有配送服务中价格最高的。目前,饿了么自建物流团队的规模约为5000人。


但自建物流的问题在于扩张速度慢,5000人的规模显然无法消化平台上200万的峰值订单。并且外卖配送集中在午餐和晚餐两个高峰,其它时段的人员闲置也将拉高运营成本。


随后,饿了么推出了“蜂鸟系统”,开始整合闲散的劳动力资源做众包物流,其中也包括餐厅自己的配送员。据称目前已经拥有超过 20 万这样的社会化配送人员。在饿了么物流研发负责人高伟看来,目前众包物流与自建物流在品控上还有一定的差距,因此众包物流主要用于解决长尾订单。


8月,饿了么开始大规模接入第三方配送团队,并将其作为其开放配送平台的主力。第三方配送团队除了承担饿了么平台上入驻商户的订单配送,还可以自行拓展商户、扩充配送品类来实现多元化经营。据饿了么给出的数据,目前全国约有1000多个团队正在与配送平台意向接触或接入运营中,其中到9月中旬已经有超过半数的团队完成接入并开始运营,包括达达、顺丰、趣送、蜂窝微服、晟邦物流等。


合作与竞争


虽然越来越多的O2O平台开始发力物流服务,但无论是O2O平台之间,还是O2O平台与第三方物流配送平台之间,目前合作的意愿远大于竞争的剑拔弩张。


例如,饿了么与京东到家正在实践运力共享。在订餐高峰时段,京东到家的配送团队将调度给饿了么使用,而在非订餐高峰时段,饿了么的运力又可以支持京东到家平台上的生鲜和商超配送,后者是全天候的业务。


第三方物流平台与O2O平台之间的关系则更像上下游关系:O2O平台主要面对消费者,它们从C端获取流量,帮线下商户带去订单,而物流平台则帮助这些商户完成订单。完全自建物流的O2O平台很少。


虽然O2O服务提供商都开始意识到物流的重要性并相继进入,但“最后三公里物流”这个市场的集中度已经相对较高,包括用户、商户和资本的聚集度。这时候,已经拥有规模优势的平台将加速前行,后进入者或规模尚小的平台或难再成事。


参考:

http://www.szuem.com/Home/Details/1279



第四部分:



 

网站性能优化-数据库及服务器架构篇
 


 

1、Web Server 与 DB Server 分离

小型网站或 B/S 项目,因同时在线人数不多,尚可让同一台物理主机,既做 Web Server,又做 DB Server。但此二者皆会占用大量的 CPU、内存、磁盘 I/O,最好让二者分别用不同的服务器主机来提供服务,以分散压力、提高负载承受能力。此外,二者若在同一网段,应尽量用内网 Private IP 进行访问,而不要用 Public IP 或主机名称。

基本上跑 Web 上的应用程序,不管用什么软、硬件,同时处理多个用户的 request,通常都比较消耗 CPU;但对数据库而言,CPU 就不见得会大量消耗,而是内存和磁盘 I/O 用得比 Web Server 多。因此一般建议 Web Server 用普通的 PC 即可,但要用好一点的 CPU;而 DB Server 就不能草率,应尽量买高级的服务器,并要有 RAID 5 或 6 的磁盘阵列 (硬件的 RAID,性能远比操作系统或软件做的 RAID 要好),并有 4 GB 以上的内存。当然如果操作系统、数据库都用 64 位版本的最好,例如升级到 64 位的 SQL Server 和 64 位的 Windows Server,这样内存都可配置到 64 GB;不过要记得,太旧的 PC,一些周边硬件的 driver 可能不支持 64 位的操作系统和软件。

如果在线人数持续增加,则可增加多台 Web Server 和 DB Server,用「服务器集群 (cluster)」、「负载均衡 (Load balancing) 集群」、「高可用性集群 High-availability (HA)」、数据库集群,以实现更大规模的分布式布署。

Deployment Plan(部署规划):

http://msdn.microsoft.com/zh-cn/library/ms978676.aspx

Three-Tiered Distribution(三级分布)(硬件、不同主机的物理级分层):

http://msdn.microsoft.com/zh-cn/library/ms978694.aspx

Three-Layered Services Application(三层服务应用程序)(软件、代码上的分层):

http://msdn.microsoft.com/zh-cn/library/ms978689.aspx

Tiered Distribution(分级分布):

http://msdn.microsoft.com/en-gb/library/ms978701(zh-cn).aspx

Deployment Patterns:

http://msdn.microsoft.com/zh-cn/library/ms998478.aspx

http://msdn.microsoft.com/en-us/library/ms998478.aspx


2、负载均衡 (Load Balance)

负载均衡技术发展了多年,有很多专业的服务提供商和产品可选择,基本上又可分为「软件」和「硬件」的解决方案:

(1) 硬件:

硬件的解决方案称作 Layer 4 Switch (第 4 层交换),可将业务流分配到合适的 AP Server 进行处理,知名产品如 Alteon、F5 等。这些硬件产品虽比软件的解决方案要贵得多,但是物有所值,通常能提供远比软件优秀的性能,和方便、易于管理的 UI 界面,供管理人员快速配置。据说 Yahoo 中国当初接近 2000 台服务器时,只用三台 Alteon 就搞定了 [1]。

(2) 软件:

Apache 这一款众所皆知的 HTTP Server,其双向 Proxy / Reverse Proxy 功能,亦可达成 HTTP 负载均衡功能,但其效率算不上特别好。而另一款 HAProxy 就是纯粹用来处理负载均衡的,且具有简单的缓存功能。

以操作系统内置的负载均衡功能来讲,Unix 如 Sun 的 Solaris 有支持,Linux 上则有常用的 LVS (Linux Virtual Server),而微软的 Windows Server 2003 / 2008 则有 NLB (Network LoadBalance)。

LVS 是利用 ipvsadm 这一个以 IP 为主的负载均衡程序,来达到让所有 TCP/IP 的通讯协议都可以进行负载均衡。由于它是 Linux Kernel 所支持,因此效率相当好,占用的 CPU 资源相当低,但缺点是 ipvsadm 无法针对 Layer 4 以上的网络 packet 数据进行分析。

至于 Windows Server 的 NLB,其原理是不论有多少台服务器,都全部共用一个「集群的 IP」,如下图 1 的 Active Load balancer,和下图 2 的 Virtual Server 1 (Web Server),以及 Virtual DB Server,依照负载均衡的类型来做分配 (Active/Active、Active/Standby、...),而用户在外面只会看到单一个 IP,至于背后有多少台服务器,用户并不需要知道 (如同 Cluster 集群和云计算的概念)。


达达平台的物流场景_第3张图片

图 1 分布式用户 vs 服务器农场 (Web Server farm)

达达平台的物流场景_第4张图片


图 2 红色箭头为 Failover 架构 (HA),其功能与 Load Balance 不同

上图 2 中,有四台 Real Server (Web Server),以及三台 Real DB Server,形成 Web 及 DB 的服务器集群 (Cluster)。我们看到最上方的 Virtual Server 1 本身不具备任何的数据服务 (如:.NET 代码、图片...等),只有一个功能,就是将用户的连线 request 请求,重新导向下方的四台 Real Server。这种利用重新导向 (director) 的方式,将服务负载分布给 Real Server 的方式,就称作 Load Balance。

现在似乎还没有一种做法,能自动计算主机的「负载」情形,例如计算 CPU 已使用多少百分比,以决定要把 request 丢向哪一台 Real Server;现在一般都还是按照轮替 (Round-robin) 的方式,或加上一些权重的设置而已。

若我们在 Server 上设置 Load Balance,且要执行 ASP.NET 程序,就要注意一个问题,就是 Session 的存储位置是在哪一台 Web Server 的内存上,以避免发生有用户表单填写得比较久,等到他提交时,已经被 Windows Server 的 NLB 将工作阶段切换到另一台 Web Server 主机上了。此时就可考虑将 Session State,改存储在 SQL Server 里。

至于用软件做的 Load Balance 其性能如何呢?基本上用软件做的,性能一定不会是 1 + 1 = 2,但通常能提高 Availability,亦即常听到的 HA (高可用性集群 High-availability),即 Failover 方式,如上图 2 的最上方,红色箭头左侧的 Virtual Server 2,是能够侦测 Virtual Server 1 宕机或无法提供服务时,自动将自己的 IP address 取代 Virtual Server1。因此 HA 是指提供「不会中断的服务」,而本帖讨论的 Load Balance 是指提供「能承受高度负载的服务」,两者指的不是同一件事。MIS 人员应视公司的硬件资源、成本和预算,考量是否两者都要做。

Load-Balanced Cluster(负载平衡群集):

http://msdn.microsoft.com/zh-cn/library/ms978730.aspx

http://msdn.microsoft.com/en-us/library/ms978730.aspx

Server Clustering(服务器群集):

http://msdn.microsoft.com/en-gb/library/ms998414(zh-cn).aspx

Installing Network Load Balancing (NLB) on Windows Server 2008:

http://blogs.msdn.com/clustering/archive/2008/01/08/7024154.aspx

Linux load balancing support & consulting:

http://www.netdigix.com/linux-loadbalancing.php

Load Balancing (WCF, 与本文无直接关系):

http://msdn.microsoft.com/zh-cn/library/ms730128.aspx

http://msdn.microsoft.com/en-us/library/ms730128.aspx


3、展示和功能的分层

大型网站中,常会为了将来的可扩展性、源代码维护方便,而将前台的展示 (HTML、Script),和后台的商业逻辑、数据库访问 (.NET/C#、SQL),切成多层。

根据 Martin Fowler 在 P of EAA 里的說法:Layer 是指「逻辑」上的分层 (logical separation),Tier 是指「物理」上的分层 (physical separation)。若我们的 ASP.NET 站台,是用「虚拟」的分层 (N-Layer),来切开 UI - BLL - DAL,通常不会有性能上的问题;但若是用「物理」的分层 (N-Tier),亦即如上图 2 和下图 3,可能每一台 AP Server 都负责不同的商业逻辑 (销售、库存、物流、制造、会计、...),各自的源代码都存放在不同的物理主机上,且可各自独立运作,此时就要考虑到每一台 AP Server 在彼此协调合作,以及调用 Web Service (XML 的性能不佳)、执行分布式事务上的性能问题。

达达平台的物流场景_第5张图片


图 3 「物理」上的分层,各种商业逻辑可能存在多台物理主机上

谈到「物理」分层上的分布式事务 (Distributed Transaction),微软的 Enterprise Services、COM+、WCF、WF 用到操作系统上的 MS DTC 来协调事务,由于 MS DTC 和这些应用程序各自处于不同的 Process,在沟通上会遇到序列化、反序列化的动作,还要整合事务中所有的 AppDomain 和不同主机上的资源,无可避免地一定会拖累性能。

Web Applications: N-Tier vs. N-Layer :

http://codebetter.com/blogs/david.hayden/archive/2005/07/23/129745.aspx


4、数据大表拆分

对比较大的数据表,或历史数据比较多的数据表,可根据一定的逻辑进行拆分。若每天的数据量非常大,则可采用按日存放,再用一个「汇总表」来记录当天的一个汇总值;也可先将比较大的表拆分成多个表,再通过「索引表」进行关联处理,以避免查询大表造成的性能问题 [1]。

另也可用「表分区」的方式,将数据存储在不同的文件上,然后再部署到独立的物理服务器,以增加 I/O 吞吐,改善读写的性能。

此外,在本文的系列作「30 分钟快快乐乐学 SQL Performance Tuning」曾提过,若一个数据表的字段过多 (与刚才提的记录量过多不同),应垂直切割成两个以上的数据表,并可用同名的 Primary Key 一对多连结起来,如:Northwind 的 Orders、Order Details 数据表。以避免在访问数据时,以「集簇引 (clustered index)」扫描时会加载过多的数据,或修改数据时造成互相锁定或锁定过久。


5、图片服务器分离

对于 Web Server 来说,用户对图片的请求是最消耗系统资源的,因此可视网站的规模和项目的特性,部署独立的图片服务器,甚至多台图片服务器。


6、读写分离

同时对数据库进行「读」和「写」的操作,是非常没效率的一种访问方式。比较好的做法,是根据读、写的压力和需求,分别建立两台结构完全相同的数据库服务器,将负责「写」的那台服务器的数据,定时复制给负责「读」的服务器。


7、扩容性应对突增流量

大型网站在设计架构的时候,必须考虑到以后的容量扩充 [1]。对于活动类的网站来说,不定时的突增流量是巨大的。在网站主存储服务器上,采用配置文件形式,指定每一个存储盘柜上存储的数据文件的 ID 范围。当前台服务器需要读取一个数据的时候,首先通过询问主存储服务器上的接口,获得该数据所在的盘柜及目录地址,然后再去该盘柜读取实际的数据文件。如果需要增加盘柜,则只要修改配置文件即可,前台程序完全不受影响。


8、缓存

缓存 (Cache) 是数据库或对象在内存中的临时容器,使用缓存可大幅减少数据库的读取,改由内存来提供数据。例如我们可以在 Web Server、DB Server 之间增加一层「数据缓存层」,在内存中建立被频繁请求对象的副本,如此一来,不访问数据库也可供给数据。例如,有 100 个用户请求同一份资料,以前需要查询数据库 100 次,现在则只需要 1 次,其余都可从缓存数据中获得,而且读取速度、网页反应速度会大幅提升。

提供缓存的产品有很多种,还可分为用硬件或软件所做的缓存,如:ASP.NET 内置的缓存功能、第三方厂商的缓存套件、Hibernate 和 NHibernate 里也有 Session 和 SessionFactory 的缓存机制、Oracle 的 cache group 技术,还有我先前在「用 IIS 7、ARR 與 Velocity 建设高性能的大型网站」这篇文章介绍的,微软官方新一代的分布式缓存技术 Velocity,另外像 Proxy Server (代理服务器) 也可以作为网页的缓存:


客户端<---->代理服务器<---->目的服务器

在 .NET 的类库中,有提供 CacheDependency 和 AggregateCacheDependency 这两个类,可用来将 ASP.NET 中缓存的对象 (如:DataSet),和一或多个物理文件 (如:XML 文件) 或数据库中的表,去建立一种关联。当其中任一个 XML 文件被修改或移除时,与其关联的 DataSet 也会一并从内存里移除;当然,也可透过您程序中设定的时间自动移除。


ASP.NET 2.0 以后的缓存,最大的改变在于 CacheDependency 类已经被微软重新改写过,我们也可透过自定义类去继承它后再改写,以达成以下功能:

  • 从 Active Directory 中的请求,让缓存失效 (缓存被自动移除)
  • 从 MSMQ 或 MQSeries 中的请求,让缓存失效
  • 从 Web Service 中的请求,让缓存失效
  • 创建用于 Oracle 的 CacheDependency
  • 其他

此外,SQL Server 中还有一种 SqlCacheDependency (缓存相依性),可监听数据表中的数据是否曾经改变,亦即避免用户在缓存期间查到的数据是旧的,达到如果数据不变化,用户就一直从缓存中取得数据;一旦数据有变化,就自动更新缓存中的数据。启用 SqlCacheDependency 的方式,只要透过 aspnet_regsql.exe 这个工具,搭配参数输入命令,就会在 SQL Server 中产生一个新的 AspNet_SqlCacheTablesForChangeNotification 表,如下图 4 所示,这张表的的每一条记录,都代表您要监听的其中一个表;最右侧的 changeId 字段,其值为供系统判断,用户对 ASP.NET 中的请求,应由内存中的缓存来提供,抑或要至数据库重新做查询。

达达平台的物流场景_第6张图片


图 4 启用 SqlCacheDependency 后,自动添加用来监听的表

另外再谈到,我在「网站性能越来越差怎么办?」这篇文章,也有提过下面的内容:


(4) 用程序或软件做缓存

用程序做缓存,如 ASP.NET 从 1.x 时代,就已内建的 Cache (缓存) 机制;或用一些第三方的辅助软件、Framework。


(5) 用硬件做快取或缓冲、砸钱加装 AP Server

他还在原本的网页服务器,与数据库服务器的架构中,加入一组应用程序服务器,作为网页服务器 cache 数据的来源。

改版之后的新网站,搜寻速度提升许多,先前每日的统计数据中,处理速度超过 3 秒的数据超过 50 万笔;而改版后,每星期超过 3 秒的查询不到 10 笔。


(6) 用硬件做缓存 (cache)

全盛时期,来自美国 blog 的流量每天达 80 万次。这个数字其实不高,对程序高手来说是小菜一碟,但笔者是半吊子工程师,知识有限也因此可能程序写得不好,频频被主机供货商发信警告,要求改善网站系统性能。最后,我决定开发 cache system。cache system 缓存系统上线后,将数据库读写,从每天 80 万次降低到每天 16 万次。

回复:

Peter.z.lu

中间件可以有很多选择:

Ncache, Coherence, Velocity, MemCache...

另外,还有像是 Memcached、Cacheman 这种分布式缓存的系统。前者可基于 Linux 和 Win32 平台使用,通过在内存里维护一个巨大的 hash 表,可存储图像、视频、文件及数据库检索的结果,并且支持多服务器,可解决 ASP.NET 内置的缓存机制仅适用于单独的服务器;后者据说是微软旗下 Popfly 项目组成员 Sriram Krishnan 的作品,将来也有可能成为微软的正式产品。


9、分布式系统数据结构 - 以 MySpace 为例

在网络上流传一篇很火红的文章「从 MySpace 数据库看分布式系统数据结构变迁」,内容提到 MySpace 这个大型的社区网站,使用微软平台的 Windows Server、SQL Server、ASP.NET 技术,如今每个月的用户访问量高达 500 亿,且已有 2 亿个以上的用户注册。以下仅节录该文的重点:

第一代架构 - 添置更多的 Web 服务器

在 MySpace 有 50 万个注册用户的时候,网站只用了两台 Dell 双 CPU、4 GB 内存的 Web Server (分散用户的请求)、一台 DB Server (所有数据都存储在这)。


第二代架构 - 增加数据库服务器

运行在三台数据库服务器上,一台用于更新数据 (由它复制到其他两个)、另两台用于读取数据,因为看网页的人多,而需要写入的人少。等到用户数和访问量增加了,就再加装硬盘。

后来数据库服务器的 I/O 成了瓶颈,就按照垂直分割模式设计,把网站里的不同功能,如:登录、用户资料和博客,搬移到不同的数据库服务器中,以分担访问压力;若要增加新功能,就再投入新的数据库服务器。

当注册用户达到 200 万后,还从存储设备与数据库服务器直接交互的方式,切换到 SAN (存储区域网络),一种高带宽、专门设计的网络系统,可将大量磁盘存储设备连接在一起。MySpace 让数据库连接到 SAN。但是当用户增加到 300 万人后,垂直分割策略也变得难以维持下去,后来架构师后来将主机升级成 34 个 CPU 的昂贵服务器,却也无法负荷。


第三代架构 - 转到分布式计算架构

架构师将 MySpace 移到分布式计算架构,它在物理上分布的众多服务器,整体必须逻辑上等同于单台机器。拿数据库来说,就不能再像过去那样将应用拆分,再以不同数据库分别支持,而必须将整个站点看作一个应用。这次,不再按站点功能和应用分割数据库,MySpace 开始将它的用户按每 100 万一组分割,然后将各组的全部数据分别存入独立的 SQL Server 实例。后来 MySpace 的每台数据库服务器实际运行两个 SQL Server 实例,也就是说每台服务器会服务大约 200 万用户。


第四代架构 - 增加数据缓存层

当用户达到 900-1000 万时,MySpace再次遭遇存储瓶颈问题,后来引用了新的 SAN 产品,但站点目前的要求,已经超越 SAN 的 I/O 磁盘存储系统、及其读写数据的极限速度。

当用户达到 1700 万时,增加了一个数据缓存层,其位于 Web 服务器和数据库服务器之间,其唯一职能是在内存中建立被频繁请求数据对象的副本。以前每一位用户查询一个信息,就请求一次数据库;现在当任一个用户请求数据库后,缓存层就会保留一个副本,当其他用户再访问时就不需要再请求数据库了,如此一来,不访问数据库也可以供给数据。


第五代架构 - 转到支持 64 位处理器的操作系统和数据库软件

当用户数达到 2600 万时,转到了还处于 Beta 版、但支持 64 位处理器的 SQL Server 2005。在升级到 64 位的 SQL Server 2005 和 Windows Server 2003 后,MySpace 每台服务器配备了 32 GB 内存,后来又提升到了 64 GB。

从 MySpace 数据库看分布式系统数据结构变迁:

http://www.cnblogs.com/cxccbv/archive/2009/07/15/1524387.html

http://www.javaeye.com/topic/152766

http://smb.pconline.com.cn/database/0808/1403100.html

http://idai.blogbus.com/logs/14736411.html




你可能感兴趣的:(项目经验)