注:本文首发于CSDN,转载请标明出处。
由于海外购物是最近一两年的另一个风口热点,已经有不少团队进入了市场,竞争已然白热化;HIGO是美丽说旗下的创新产品,目前仍在快速发展,鉴于当前特殊时期,本次分享为了避免透露公司敏感信息,关于系统架构的细节部分,不会是确数,代以倍数来强化说明架构演变带来的性能提升。
众所周知,电商发展到今天,获取用户的成本越来越高,为此已经形成一条不成文的共识:无促不销。HIGO在运营层面上也大致每月一大促、每周一小促、每天一专题的节奏来开展,复杂多变的业务场景对系统架构而言是非常大的挑战和考验,也验证了互联网系统架构铁律:架构不是一成不变的,而是随着业务需求不断演变的。HIGO的架构从诞生至今,其中以2015.08为时间节点,发生过一次非常重大变化。但总体保持一致,都是基于Linux操作系统,采用成熟的LNMP架构和开源的高性能服务组件来实现,涉及具体使用场景的变化也很清晰,完全是为了适应业务而发生的,其中开源软件功不可没。
简单说明,服务端提供标准HTTP接口,响应客户端请求,返回结构化的JSON;业务端主要使用PHP开发,使用了公司自主研发的一套基于PHP5 Namespace的轻量MVC框架。客户端iOS、Android App的请求首先到达4层负载均衡器LVS,LVS将请求转发到一组高可用nginx应用负载均衡器“nginx配置了fastcgi缓存”,再根据不同的业务,转发到后端的php-fpm集群,响应具体的业务,将结果返还给客户端。在具体的业务层,PHP会根据实际情况来会和缓存(Redis)和存储(MySQL)做交互。1.0版中缓存使用单台Redis “master + slaver”,采用VRRP协议实现高可用;数据库交于美丽说主站维护,一主一从。App中的IM模块采用开源的node.js框架meteor,图片服务简单的使用了NFS文件共享,挂载到php-fpm节点。这套成熟的架构在很长的时间段内,扛住了用户快速增长和业务快速迭代需求带来的压力。
v1.0版的架构有个明显的单点,那就是基于NFS的图片服务。但是由于架构够使,而且公司为其购买了商业CDN服务,一直没有报过重大问题,所以直到改版,都没有花精力在上面。在此不得不说个插曲,由于海外买手不断反馈App响应速度慢,IM聊天消息常常不能正常收发,当时的架构团队决定将机房迁到了香港,虽然当时减少了买手的投诉,但后来的实践证明之前的决策是个错误,8月份架构升级的时候,机器又迁回了北京。
图1 HIGO架构图
下面分享几个实际遇到的问题和应对之策:
6月份上旬的一天大促预热,突然报上线服务巨慢,人工在预上线环境检查确认,发现接口基本上都超时。通过商业和自有监控系统发现是MySQL链接数过高,已然超过DBA设定的阈值,php-fpm单节点进程数已经飙到了近2K,系统处于HANG住的状态。多方排查,确定由于Redis配置问题,加上香港机房网络抖动,导致Redis出现了两个master,等于缓存层完全失效,所有的请求都直接穿透到MySQL;雪上加霜的是,由于业务工期紧张的缘故,PHP的业务层存在大量慢查询,表结构没有适当索引、不当的索引,子查询以及联合查询等,将问题进一步扩大化,最终导致服务无法正响应。整个技术团队也以此为契机,开启了漫长的数据库优化之路。
由于公司战略层的缘故,DBA没有对HIGO业务给予足够的重视,MySQL的一主一从却一直存在从库同步延迟超出可接受范围,逼迫技术团队在存储上做了妥协,放弃从库,只用主库,导致主库的压力一直下不来,读写无法分离,性能瓶颈点始终在存储层“使用xhproy做过性能分析,此结论成立”。
Redis 缓存与持久化混合使用,导致缓存系统部署无法分布式,内存使用率不高,而且出现问题不易排查。
这一阶段主要面临的压力并非来自线上流量,而是产品和业务的需求压力;主要目标是快速迭代,实现产品功能。我们上线的频率非常之高,随之不可避免的在线上生产环境引入了一些bug。由此可见,团队的主要矛盾随着公司的业务发展在不断的发生着变化。
美丽说大手笔购买了跑男冠名权,HIGO将会迎来一波流量爆涨期,预计的增长率10倍不止,v1.0的架构显示不足以支撑,所以架构升级,势在必行。
从8月份开始,我们面临的主要问题是暴涨的流量,而且是有明显波峰的流量,需要我们全面升级系统架构,解决各种单点和系统性能瓶颈点,以应对外部流量对我们的压力。v2.0架构主体继承v1.0,着眼小处优化改进,具体的一些做法如下:
借鉴淘宝,在LVS与nginx之间加了层流量控制,采用nginx + lua“openresty”实现,可以针对不同规则来进行服务降级,减少对核心业务的冲击,保证服务可用性。
将Redis的使用按业务场景分开:对于KV缓存的采用twemproxy代理分布式部署,以便水平扩展;对于需要持久存储的计数器、队列、集合等数据,单独部署高可用Redis持久化存储。升级后一来将请求分散,减少单节点的压力;二来业务层依不同需求,选择不同方案,也会更加清晰。
php-fpm集群架构保持不变,随时跟据业务增减节点即可,完全可伸缩,自不用多做介绍。
DB层使用公司自主研发的一套dbproxy,能够自动实现读写分离、分库分表,SQL审计等。与此同时,业务层根据具体情况实现了拆库分库,例如拆分为用户、商品、订单、优惠券等系统,不同的业务调用对应的数据库,跨业务通过公共lib库调用,不容许相互之间直接访问数据库,尽可能高内聚低耦合,减少系统之间的耦合度。这样做的好处显而易见,但也引入不和谐因素,最直接受影响的就是统计,数据分散到各个不同库,汇总统计无异恶梦。对此我们采取一个中庸的解决方案,DBA每12个小时将各库全量导出,再全量汇总到线下统计库,以牺牲统计实时性来降低线上服务的实现复杂度。
曾经的单点图片服务,则利用曲线救国思路,调用了主站现成的服务。IM亦是,交由主站专业的团队来维护。
目前v2.0的大部分功能已经上线,目前来看,效果达到预期,也让我们跑男扛流量有一份自信。
随着人员的不断扩充,业务的不断增涨,系统模块服务化的需求越来越明确。我们之前小尝试了服务化,但由于种种原因并没有推广开来,但我坚定的认为未来服务化终归还是会被提上日程。
未来我们系统还会不断引入其他模块和服务,但我们会尽可能保持架构的简单性、清晰性,降低系统间的耦合度,打造高可用、可扩展、高性能的系统。
如你所见,HIGO的架构一点也不高大上,完全是一个务实型的以业务为导向的架构,这正应了互联网一句老话:没有最好的架构,只有更适应业务的架构。是的,这不是美丽说HIGO系统架构演变的终点,而是才刚刚开始。
由于后端接口复杂度不一致,单纯看某个接口的QPS意义不大,我参考QA同学的接口压力测试报告,给出单个节点平均的升级前后的性能对比表:
表1:单个节点平均的升级前后的性能对比
注:单个php-fpm节点,非精确值,仅供参考。
作者简介: 杨永杰,美丽说HIGO部公司的高级架构师,专注于基于LNMP架构的互联网技术,全栈架构师。
(责编/钱曙光,关注架构和算法领域,寻求报道或者投稿请发邮件qianshg@csdn.net,交流探讨可加微信qshuguang2008,备注姓名+公司+职位)
「CSDN 高级架构师群」,内有SDCC 2015架构专场的讲师等诸多知名互联网公司的大牛架构师,如果你想进群交流,请加微信qshuguang2008申请入群,备注姓名+公司+职位。