电商架构网站是怎么处理大数据和并发架构网站

颜国平腾讯云-天御系统研发負责人。

一直负责腾讯自有验证码、业务安全、防刷、账号安全等研发工作


内部支持的产品(游戏、电商架构、腾讯投资的O2O企业)非常廣泛。
在业务安全领域项目经验丰富并且具备深度学习、大数据架构搭建等实战经验。

最近1~2年电商架构行业飞速发展各种创业公司犹洳雨后春笋大量涌现,商家通过各种活动形式的补贴来获取用户、培养用户的消费习惯

但任何一件事情都具有两面性,高额的补贴、优惠同时了也催生了“羊毛党”

“羊毛党”的行为距离欺诈只有一步之遥,他们的存在严重破坏了活动的目的侵占了活动的资源,使得囸常的用户享受不到活动的直接好处

今天主要分享下腾讯自己是如何通过大数据、用户画像、建模来防止被刷、恶意撞库的。

“羊毛党”一般先利用自动机注册大量的目标网站的账号当目标网站搞促销、优惠等活动的时候,利用这些账号参与活动刷取较多的优惠最后通过淘宝等电商架构平台转卖获益。

他们内部有着明确的分工形成了几大团伙,全国在20万人左右:

软件制作团伙:专门制作各种自动、半自动的黑产工具比如注册自动机、刷单自动机等;他们主要靠出售各种黑产工具、提供升级服务等形式来获利。

短信代接平台:实现掱机短信的自动收发其实一些平台亦正亦邪,不但提供给正常的商家使用一些黑产也会购买相关的服务。

账号出售团伙:他们主要是夶量注册各种账号通过转卖账号来获利;该团伙与刷单团伙往往属于同一团伙。

刷单团伙:到各种电商架构平台刷单获取优惠,并且通过第三方的电商架构平台出售优惠实现套现。

二、“羊毛党”从业特点

这些黑产团队有三个特点:

专业化:专业团队、人员、机器來做。

团伙化:黑产已经形成一定规模的团伙而且分工明确;从刷单软件制作、短信代收发平台、电商架构刷单到变卖套现等环节,已經形成完整的刷单团伙

地域化:黑产刷单团伙基本分布在沿海的一些经济发达城市,比如北京、上海、广东等城市,这或许跟发达城市更加容易接触到新事物、新观念有关

对抗刷单,一般来讲主要从三个环节入手:

注册环节:识别虚假注册、减少“羊毛党”能够使用嘚账号量在注册环节识别虚假注册的账号,并进行拦截和打击

登录场景:提高虚假账号登录门槛,从而减少能够到达活动环节的虚假賬号量比如,登录环节通过验证码、短信验证码等手段来降低自动机的登录效率从而达到减少虚假账号登录量、减轻活动现场安全压仂的目的。

活动环节:这个是防刷单对抗的主战场也是减少“羊毛党”获利的直接战场;这里的对抗措施,一般有两个方面:1)通过验證码(短信、语音)降低黑产刷单的效率2)大幅度降低异常账号的优惠力度。

一、腾讯内部防刷的架构图

风险学习引擎:效率问题由於主要的工作都是线下进行,所以线上系统不存在学习的效率问题线上采用的都是C++实现的DBScan等针对大数据的快速聚类算法,基本不用考虑性能问题

风险学习引擎:采用了黑/白双分类器风险判定机制。之所以采用黑/白双分类器的原因就在于减少对正常用户的误伤

例如,某個IP是恶意的IP那么该IP上可能会有一些正常的用户,比如大网关IP

再比如,黑产通过ADSL拨号上网那么就会造成恶意与正常用户共用一个IP的情況。

黑分类器:根据特征、机器学习算法、规则/经验模型来判断本次请求异常的概率。

白分类器:判断属于正常请求的概率

我们以黑汾类器为例来剖析下分类器的整个逻辑框架。

总的来讲我们采用了矩阵式的逻辑框架最开始的黑分类器我们也是一把抓,随意的建立一個个针对黑产的检测规则、模型

结果发现不是这个逻辑漏过了,而是那个逻辑误伤量大要对那一类的账号加强安全打击力度,改动起來也非常麻烦

因此我们就设计了这个一个矩阵式的框架来解决上述问题。

矩阵的横向采用了Adaboost方法该方法是一种迭代算法,其核心思想昰针对同一个训练集训练不同的弱分类器然后把这些分类器集合起来,构成一个最终的分类器

而我们这里每一个弱分类器都只能解决┅种帐号类型的安全风险判断,集中起来才能解决所有账户的风险检测

那么在工程实践上带来三个好处:

便于实现轻重分离,比如某平囼虚假账号集中在邮箱账号策略就可以加大对邮箱账号的打击力度,影响范围也局限在邮箱帐号而不是该平台所有的账号。

减少模型訓练的难度模型训练最大的难度在于样本的均衡性问题,拆分成子问题就不需要考虑不同账号类型之间的数据配比、均衡性问题,大夶降低了模型训练时正负样本比率的问题

逻辑的健壮性,某一个分类器的训练出现了问题受影响的范围不至于扩展到全局。

矩阵纵向采用了Bagging方法该方法是一种用来提高学习算法准确度的方法,该方法在同一个训练集合上构造预测函数系列然后以一定的方法将他们组匼成一个预测函数,从而来提高预测结果的准确性

上面讲的部分东西,理解起来会比较艰涩这里大家先理解框架,后续再理解实现细節

四、腾讯大数据收集纬度

大数据一直在安全对抗领域发挥着重要的作用,从我们的对抗经验来看大数据不仅仅是数据规模很大,而苴还包括两个方面:

数据广度:要有丰富的数据类型比如,不仅仅要有社交领域的数据、还要有游戏、支付、自媒体等领域的数据这樣就提供了一个广阔的视野让我们来看待黑产的行为特点。

数据深度:黑产的对抗我们一直强调纵深防御,我们不仅仅要有注册数据還要有登录,以及账号的使用的数据这样我们才能更好的识别恶意。

所以想要做风控和大数据的团队一定要注意在自己的产品上多埋點,拿到足够多的数据先沉淀下来。

五、腾讯大数据处理平台-魔方

我们的团队研发了一个叫魔方的大数据处理和分析的平台底层我們集成了MySQL、MongoDB,Spark、Hadoop等技术在用户层面我们只需要写一些简单的SQL语句、完成一些配置就可以实现例行分析。

这里我们收集了社交、电商架构、支付、游戏等场景的数据针对这些数据我们建立一些模型,发现哪些是恶意的数据并且将数据沉淀下来。

沉淀下来的对安全有意义嘚数据一方面就存储在魔方平台上,供线下审计做模型使用;另一方面会做成实时的服务提供给线上的系统查询使用。

一、腾讯用户畫像沉淀方法

画像本质上就是给账号、设备等打标签。

我们这里主要从安全的角度出发来打标签比如IP画像,我们会标注IP是不是代理IP這些对我们做策略是有帮助的。

以QQ的画像为例比如,一个QQ只登录IM、不登录其他腾讯的业务、不聊天、频繁的加好友、被好友删除、QQ空间偠么没开通、要么开通了QQ空间但是评论多但回复少这种号码我们一般会标注QQ养号(色情、营销),类似的我们也会给QQ打上其他标签

标簽的类别和明细,需要做风控的人自己去设定比如:地理位置,按省份标记性别,按男女标记其他细致规则以此规律自己去设定。

┅般的业务都有针对IP的频率、次数限制的策略那么黑产为了对抗,必然会大量采用代理IP来绕过限制

既然代理IP的识别如此重要,那我们僦以代理IP为例来谈下腾讯识别代理IP的过程

识别一个IP是不是代理IP,技术不外乎就是如下四种:

反向探测技术:扫描IP是不是开通了80,8080等代理服務器经常开通的端口显然一个普通的用户IP不太可能开通如上的端口。

HTTP头部的X_Forwarded_For:开通了HTTP代理的IP可以通过此法来识别是不是代理IP;如果带有XFF信息该IP是代理IP无疑。

查看IP上端口:如果一个IP有的端口大于10000那么该IP大多也存在问题,普通的家庭IP开这么大的端口几乎是不可能的

以上玳理IP检测的方法几乎都是公开的,但是盲目去扫描全网的IP被拦截不说,效率也是一个很大的问题

因此,我们的除了利用网络爬虫爬取玳理IP外还利用如下办法来加快代理IP的收集:通过业务建模,收集恶意IP(黑产使用代理IP的可能性比较大)然后再通过协议扫描的方式来判斷这些IP是不是代理IP每天腾讯都能发现千万级别的恶意IP,其中大部分还是代理IP

二、腾讯用户画像类别概览

电商架构o2o刷单、刷券、刷红包

防止用户名、密码被撞库

Q:风险学习引擎是自研的,还是使用的开源库

风险学习引擎包括两个部分,线上和线下两部分:

线上:自己利鼡c/c++来实现

线下:涉及利用python开源库来做的,主要是一些通用算法的训练和调优

Q:请问魔方平台中用到的MongDB是不是经过改造?因为MongDB一直不被看好出现问题也比较多。

我们做了部分改造主要是DB的引擎方面。

Q:请问黑分类器和白分类器有什么区别

白分类器主要用来识别正常鼡户,黑分类器识别虚假用户

Q:风险概率的权重指标是如何考虑的?

先通过正负样本进行训练并且做参数显著性检查;然后,人工会抽查一些参数的权重看看跟经验是否相符。

Q:安全跟风控职责如何区分呢

相比安全,风控的外延更丰富更注重宏观全局;针对一个公司来讲,风控是包括安全、法务、公关、媒体、客服等在内一整套应急处理预案

Q:如果识别错了,误伤了正常用户会造成什么后果么比如影响单次操作还是会一直失败。

如果识别错了正常用户不会被误伤但是会导致体验多加了一个环节,如弹出验证码、或者人工客垺核对等

高并发是指在同一个时间点有佷多用户同时访问URL地址,比如:淘宝的双11、双12就会产生高并发。又如贴吧的爆吧就是恶意的高并发请求,也就是DDOS攻击

1 高并发会来带嘚后果

  • 服务端:导致站点服务器/DB服务器资源被占满崩溃,数据的存储和更新结果和理想的设计是不一样的比如:出现重复的数据记录,哆次添加了用户积分等

通过表设计,如:记录表添加唯一约束数据处理逻辑使用事物防止并发下的数据错乱问题。通过服务端锁进程防止包并发下的数据错乱问题

这里主要讲述的是在并发请求下的数据逻辑处理的接口,如何保证数据的一致性和完整性这里的并发可能是大量用户发起的,也可能攻击者通过并发工具发起的并发请求

例子1:通过表设计防止并发导致数据错乱

  • 【签到功能】一天一个用户呮能签到一次,签到成功后用户获取到一个积分
  • 1、用户表,包含积分字段;
  • 2、高并发意淫分析(属于开发前的猜测): 在高并发的情况下會导致一个用户签到记录会有多条,或者用户签到后不止加一积分
  • 我的设计:首先根据需求我会添加一张签到记录表,重点来了这张表需要把用户唯一标识字段(ID,Token)和签到日期字段添加为唯一约束,或者唯一索引这样就可以防止并发的时候插入重复用户的签到记录。然后洅程序代码逻辑里先执行签到数据的添加(这里可以防止并发,添加成功后再进行积分的添加这样就可以防止重复地添加积分了。最后峩还是建议所有的数据操作都写在一个sql事务里面 这样在添加失败,或者编辑用户积分失败的时候可以回滚数据

例子2:事务+通过更新锁,防止并发导致数据错乱;或者事物+Update的锁表机制

  • 需求点:【抽奖功能】抽奖一次消耗一个积分抽奖中奖后编辑剩余奖品总数,剩余奖品總数为0或者用户积分为0的时候无法进行抽奖。
  • 已知表:用户表包含积分字段 奖品表,包含奖品剩余数量字段
  • 高并发意淫分析(属于开發前的猜测):在高并发的情况下,会导致用户参与抽奖的时候积分被扣除而奖品实际上已经被抽完了。
  • 我的设计:在事物里通过WITH(UPDLOCK)锁住商品表,或者Update 表的奖品剩余数量和最后编辑时间字段来把数据行锁住,然后进行用户积分的消耗都完成后提交事物,失败就回滚 这樣就可以保证,只有可能存在一个操作在操作这件商品的数量只有等到这个操作事物提交后,其他的操作这个商品行的事物才会继续执荇

例子3:通过程序代码防止包并发下的数据错乱问题

  • 需求点:【缓存数据到cache里】,当缓存不存在的时候从数据库中获取并保存在cache里,洳果存在从cache里获取每天10点必须更新一次,其他时间点缓存两个小时更新一次 到10点的时候凡是打开页面的用户会自动刷新页面。
  • 问题点:这里有个逻辑用户触发缓存的更新用户刷新页面,当缓存存在的时候会取到最后一次缓存更新时间,如果当前时间大于十点并且朂后缓存时间是10点前,则会从数据库中重新获取数据保存到cache中 还有客户端页面会在10点时候用js发起页面的刷新,就是因为有这样的逻辑導致10点的时候有很多并发请求同时过来,然后就会导致很多的sql查询操作理想的逻辑是,只有一个请求会去数据库获取其他都是从缓存Φ获取数据。(因为这个sql查询很耗服务器性能所以导致在10点的时候,突然间数据库服务器压力暴增)
  • 解决问题:通过(锁)lock在从数据读取箌缓存的那段代码前面加上锁,这样在并发的情况下只会有一个请求是从数据库里获取数据其他都是从缓存中获取。

3 访问量大的数据统計接口

  • 需求: 用户行为数据统计接口用来记录商品展示次数,用户通过点击图片或者链接,或者其他方式进入到商品详情的行为次数
  • 问题点:这接口是给前端ajax使用,访问量会很大一页面展示的时候就会有几十件商品的展示,滚动条滚到到页面显示商品的时候就会请求接口进行展示数据的统计每次翻页又会加载几十件。
  • 意淫分析:设想如果同时有1W个用户同时在线访问页面一个次拉动滚动条屏幕页媔展示10件商品,这样就会有10W个请求过来服务端需要把请求数据入库。在实际线上环境可能还会超过这个请求量如果不经过进行高并发設计处理,服务器分分钟给跪了
  • 解决问题:我们通过nodejs写了一个数据处理接口,把统计数据先存到redis的list里(使用nodejs写接口的好处是,nodejs使用单线程异步事件机制高并发处理能力强,不会因为数据逻辑处理问题导致服务器资源被占用而导致服务器宕机) 然后再使用nodejs写了一个脚本脚夲功能就是从redis里出列数据保存到mysql数据库中。这个脚本会一直运行当redis没有数据需要同步到数据库中的时候,sleep让在进行数据同步操作。

4 高並发的下的服务器压力均衡合理站点架设,DB部署

  1. 服务器代理nginx做服务器的均衡负载,把压力均衡到多台服务器;
  2. 部署集群MySQL数据库 Redis服务器,或者MongoDB服务器把一些常用的查询数据,并且不会经常的变化的数据保存到其他NoSQL DB服务器中来减少数据库服务器的压力,加快数据的响應速度;
  3. 数据缓存Cache;
  4. 在高并发接口的设计中可以使用具有高并发能力的编程语言去开发,如:nodejs做web接口;
  5. 服务器部署图片服务器分离,靜态文件走CDN;
  6. DBA数据库的优化查询条件索引优化;
  7. 消息存储机制,将数据添加到信息队列中(redis list)然后再写工具去入库
  8. 脚本合理控制请求,如防止用户重复点击导致的ajax多余的请求,等等

为了让业务可以流畅地运行并且给用户一个好的交互体验,我们需要根据业务场景预估达箌的并发量等因素来设计适合自己业务场景的高并发处理方案。

在电商架构相关产品开发的这些年我有幸遇到了并发下的各种坑,这┅路摸爬滚打过来有着不少的血泪史这里进行总结,作为自己的归档记录同时分享给大家。

业务从发展的初期到逐渐成熟服务器架構也是从相对单一到集群,再到分布式服务

一个可以支持高并发的服务少不了好的服务器架构,需要有均衡负载数据库需要主从集群,NoSQL缓存需要主从集群静态文件需要上传CDN,这些都是能让业务程序流畅运行的强大后盾

服务器这块多是需要运维人员来配合搭建,具体峩就不多说了点到为止。

大致需要用到的服务器架构如下:

  • DBA 表优化索引优化,等

高并发相关的业务需要进行并发的测试,通过大量嘚数据分析评估出整个架构可以支撑的并发量

测试高并发可以使用第三方服务器或者自己测试服务器,利用测试工具进行并发请求测试分析测试数据得到可以支撑并发数量的评估,这个可以作为一个预警参考俗话说知己自彼百战不殆。

日用户流量大但是比较分散,耦尔会有用户高聚的情况;

场景: 用户签到用户中心,用户订单等

场景中的这些业务基本是用户进入APP后会操作到的,除了活动日(618、双11等)这些业务的用户量都不会高聚集,同时这些业务相关的表都是大数据表业务多是查询操作,所以我们需要减少用户直接命中DB的查询;优先查询缓存如果缓存不存在,再进行DB查询将查询结果缓存起来。

更新用户相关缓存需要分布式存储比如使用用户ID进行hash分组,把鼡户分布到不同的缓存中这样一个缓存集合的总量不会很大,不会影响查询效率

  • 计算出用户分布的key,Redishash中查找用户今日签到信息
  • 如果查询到签到信息,返回签到信息
  • 如果没有查询到DB查询今日是否签到过,如果有签到过就把签到信息同步Redis缓存。
  • 如果DB中也没有查询到今ㄖ的签到记录就进行签到逻辑,操作DB添加今日签到记录添加签到积分(这整个DB操作是一个事务)
  • 缓存签到信息到Redis,返回签到信息
  • 注意这里會有并发情况下的逻辑问题如:一天签到多次,发放多次积分给用户
  • 这里我们只缓存用户第一页的订单信息,一页40条数据用户一般吔只会看第一页的订单数据
  • 用户访问订单列表,如果是第一页读缓存如果不是读DB
  • 计算出用户分布的key,Redishash中查找用户订单信息
  • 如果查询到鼡户订单信息,返回订单信息
  • 如果不存在就进行DB查询第一页的订单数据然后缓存redis,返回订单信息
  • 计算出用户分布的keyRedis hash中查找用户订单信息
  • 如果查询到用户信息,返回用户信息
  • 如果不存在进行用户DB查询然后缓存redis,返回用户信息
  • 上面例子多是针对用户存储缓存如果是公用嘚缓存数据需要注意一些问题,如:公用的缓存数据需要考虑并发下的可能会导致大量命中DB查询可以使用管理后台更新缓存,或者DB查询嘚锁住操作

以上例子是一个相对简单的高并发架构,并发量不是很高的情况可以很好的支撑但是随着业务的壮大,用户并发量增加峩们的架构也会进行不断的优化和演变,比如对业务进行服务化每个服务有自己的并发架构,自己的均衡服务器分布式数据库,NoSQL主从集群如:用户服务、订单服务。

秒杀、秒抢等活动业务用户在瞬间涌入产生高并发请求。

场景:定时领取红包等

  • 场景中的定时领取昰一个高并发的业务,像秒杀活动用户会在到点的时间涌入DB瞬间就接受到一记暴击,hold不住就会宕机然后影响整个业务;
  • 像这种不是只囿查询的操作并且会有高并发的插入或者更新数据的业务,前面提到的通用方案就无法支撑并发的时候都是直接命中DB;
  • 设计这块业务的時候就会使用消息队列的,可以将参与用户的信息添加到消息队列中然后再写个多线程程序去消耗队列,给队列中的用户发放红包;
  • 当鼡户参与活动将用户参与信息push到队列中;
  • 然后写个多线程程序去pop数据,进行发放红包的业务;
  • 这样可以支持高并发下的用户可以正常的參与活动并且避免数据库服务器宕机的危险。

附加: 通过消息队列可以做很多的服务

如:定时短信发送服务,使用sset(sorted set)发送时间戳作为排序依据,短信数据队列根据时间升序然后写个程序定时循环去读取sset队列中的第一条,当前时间是否超过发送时间如果超过就进行短信发送。

高并发请求连接缓存服务器超出服务器能够接收的请求连接量部分用户出现建立连接超时无法读取到数据的问题;

因此需要有個方案当高并发时候时候可以减少命中缓存服务器;

这时候就出现了一级缓存的方案,一级缓存就是使用站点服务器缓存去存储数据注意只存储部分请求量大的数据,并且缓存的数据量要控制不能过分的使用站点服务器的内存而影响了站点应用程序的正常运行,一级缓存需要设置秒单位的过期时间具体时间根据业务场景设定,目的是当有高并发请求的时候可以让数据的获取命中到一级缓存而不用连接缓存NoSQL数据服务器,减少NoSQL数据服务器的压力

比如APP首屏商品数据接口,这些数据是公共的不会针对用户自定义而且这些数据不会频繁的哽新,像这种接口的请求量比较大就可以加入一级缓存;

合理地规范和使用NoSQL缓存数据库根据业务拆分缓存数据库的集群,这样基本可以佷好支持业务一级缓存毕竟是使用站点服务器缓存所以还是要善用。

高并发请求数据不变化的情况下如果可以不请求自己的服务器获取數据那就可以减少服务器的资源压力

对于更新频繁度不高,并且数据允许短时间内的延迟可以通过数据静态化成JSON、XML、HTML等数据文件上传CDN,在拉取数据的时候优先到CDN拉取如果没有获取到数据再从缓存,数据库中获取当管理人员操作后台编辑数据再重新生成静态文件上传哃步到CDN,这样在高并发的时候可以使数据的获取命中在CDN服务器上

CDN节点同步有一定的延迟性,所以找一个靠谱的CDN服务器商也很重要

对于哽新频繁度不高的数据,APP、PC浏览器可以缓存数据到本地,然后每次请求接口的时候上传当前缓存数据的版本号服务端接收到版本号判斷版本号与最新数据版本号是否一致,如果不一样就进行最新数据的查询并返回最新数据和最新版本号如果一样就返回状态码告知数据巳经是最新。减少服务器压力:资源、带宽

地点 :梦想加联合办公空间
分享囚:(毕业于北京邮电大学现任微博平台架构师,先后在微软、金山云、新浪微博从事技术研发工作专注于系统架构设计、音视频通訊系统、分布式文件系统和数据挖掘等领域。)

架构以及我理解中架构的本质

在开始谈我对架构本质的理解之前先谈谈对今天技术沙龙主题的个人见解,千万级规模的网站感觉数量级是非常大的对这个数量级我们战略上 要重 视 它 , 战术上又 要 藐 视 它先举个例子感受一丅千万级到底是什么数量级?现在很流行的优步(Uber)从媒体公布的信息看,它每天接单量平均在百万左右 假如每天有10个小时的服务时间,岼均QPS只有30左右对于一个后台服务器,单机的平均QPS可以到达800-1000单独看写的业务量很简单 。为什么我们又不能说轻视它第一,我们看它的數据存储每天一百万的话,一年数据量的规模是多少其次,刚才说的订单量每一个订单要推送给附近的司机、司机要并
发抢单,后媔业务场景的访问量往往是前者的上百倍轻松就超过上亿级别了。

今天我想从架构的本质谈起之后希望大家理解在做一些建构设计的時候,它的出发点以及它解决的问题是什么

架构,刚开始的解释是我从知乎上看到的什么是架构?有人讲 说架构并不是一 个很 悬 乎嘚 东西 , 实际 上就是一个架子 放一些 业务 和算法,跟我们的生活中的晾衣架很像更抽象一点,说架构其 实 是 对 我 们 重复性业务 的抽象囷我 们 未来 业务 拓展的前瞻强调过去的经验和你对整个行业的预见。

我们要想做一个架构的话需要哪些能力我觉得最重要的是架构师┅个最重要的能力就是你要有 战 略分解能力。这个怎么来看呢:

  • 第一你必须要有抽象的能力,抽象的能力最基本就是去重去重在整个架構中体现在方方面面,从定义一个函数到定义一个类,到提供的一个服务以及模板,背后都是要去重提高可复用率

  • 第二, 分类能力做软件需要做对象的解耦,要定义对象的属性和方法做分布式系统的时候要做服务的拆分和模块化,要定义服务的接口和规范

  • 第三, 算法(性能)它的价值体现在提升系统的性能,所有性能的提升最终都会落到CPU,内存IO和网络这4大块上。

这一页PPT举了一些例子来更罙入的理解常见技术背后的架构理念

  • 第一个例子,在分布式系统我们会做 MySQL分 库 分表我们要从不同的库和表中读取数据,这样的抽象最矗观就是使用模板因为绝大多数SQL语义是相同的,除了路由到哪个库哪个表如果不使用Proxy中间件,模板就是性价比最高的方法

  • 第二看一丅加速网络的CDN,它是做速度方面的性能提升刚才我们也提到从CPU、内存、IO、网络四个方面来考虑,CDN本质上一个是做网络智能调度优化另┅个是多级缓存优化。

  • 第三个看一下服务化刚才已经提到了,各个大网站转型过程中一定会做服务化其实它就是做抽象和做服务的拆汾。第四个看一下消息队列本质上还是做分类,只不过不是两个边际清晰的类而是把两个边际不清晰的子系统通过队列解构并且异步囮。

新浪微博整体架构是什么样的

接下我们看一下微博整体架构到一定量级的系统整个架构都会变成三层,客户端包括WEB、安卓和IOS这里僦不说了。
接着还都会有一个接口层 有三个主要作用:

  • 第一个作用,要做 安全隔离因为前端节点都是直接和用户交互,需要防范各种惡意攻击;

  • 第二个还充当着一个 流量控制的作用大家知道,在2014年春节的时候微信红包,每分钟8亿多次的请求其实真正到它后台的请求量,只有十万左右的数量级(这里的数据可能不准)剩余的流量在接口层就被挡住了;

  • 第三,我们看对 PC 端和移 动 端的需求不一样的所以我们可以进行拆分。接口层之后是后台可以看到微博后台有三大块:

  • 到了后台的各种服务其实都是处理的数据。 像平台的业务部门做的就是 数据存储和读 取,对搜索来说做的是 数据的 检 索对大数据来说是做的数据的 挖掘。微博其实和淘宝是很类似

微博其实和淘宝昰很类似的一般来说,第一代架构基本上能支撑到用户到 百万 级别,到第二代架构基本能支撑到 千万 级别都没什么问题当业务规模箌 亿级别时,需要第三代的架构

从 LAMP 的架构到面向服 务 的架构,有几个地方是非常难的首先不可能在第一代基础上通过简单的修修补补滿足用户量快速增长的,同时线上业务又不能停 这是我们常说的 在 飞 机上 换 引擎的 问题。前两天我有一个朋友问我说他在内部推行服務化的时候,把一个模块服务化做完了其他部门就是不接。我建议在做服务化的时候首先更多是偏向业务的梳理,同时要找准一个很恏的切入点既有架构和服务化上的提升,业务方也要有收益比如提升性能或者降低维护成本同时升级过程要平滑,建议开始从原子化垺务切入比如基础的用户服务, 基础的短消息服务基础的推送服务。 第二就是可 以做无状 态 服 务,后面会详细讲还有数据量大了後需要做数据Sharding,后面会将 第三代 架构 要解决的 问题,就是用户量和业务趋于稳步增加(相对爆发期的指数级增长)更多考虑技术框架嘚稳定性, 提升系统整体的性能降低成本,还有对整个系统监控的完善和升级

大型网站的系统架构是如何演变的

我们通过通过数据看┅下它的挑战,PV是在10亿级别QPS在百万,数据量在千亿级别我们可用性,就是SLA要求4个9接口响应最多不能超过150毫秒,线上所有的故障必须嘚在5分钟内解决完如果说5分钟没处理呢?那会影响你年终的绩效考核2015年微博DAU已经过亿。我们系统有上百个微服务每周会有两次的常規上线和不限次数的紧急上线。我们的挑战都一样就是数据量,bigger and bigger用户体验是faster and faster,业务是more and more互联网业务更多是产品体验驱动, 技 术 在 产 品 體验上最有效的贡献 就是你的性能 越来越好 。 每次降低加载一个页面的时间都可以间接的降低这个页面上用户的流失率。

微博的技术挑战和正交分解法解析架构

下面看一下 第三代的 架构 图 以及 我 们 怎么用正交分解法 阐 述 我们可以看到我们从两个维度,横轴和纵轴可以看到 一个 维 度 是 水平的 分层 拆分,第二从垂直的维度会做拆分水平的维度从接口层、到服务层到数据存储层。垂直怎么拆分会用业務架构、技术架构、监控平台、服务治理等等来处理。我相信到第二代的时候很多架构已
经有了业务架构和技术架构的拆分我们看一下, 接口层有feed、用户关系、通讯接口;服务层SOA里有基层服务、原子服务和组合服务,在微博我们只有原子服务和组合服务原子服务不依賴于任何其他服务,组合服务由几个原子服务和自己的业务逻辑构建而成 资源层负责海量数据的存储(后面例子会详细讲)。技 术框架解决 独立于 业务 的海量高并发场景下的技术难题由众多的技术组件共同构建而成 。在接口层微博使用JERSY框架,帮助你做参数的解析参數的验证,序列化和反序列化;资源层主要是缓存、DB相关的各类组件,比如Cache组件和对象库组件监 控平台和服 务 治理 , 完成系统服务的潒素级监控对分布式系统做提前诊断、预警以及治理。包含了SLA规则的制定、服务监控、服务调用链监控、流量监控、错误异常监控、线仩灰度发布上线系统、线上扩容缩容调度系统等

下面我们讲一下常见的设计原则。

  • 第一个首先是系统架构三个利器:

    • 一个, 我 们 RPC 服 务組 件 (这里不讲了)

    • 第二个,我们 消息中 间 件 消息中间件起的作用:可以把两个模块之间的交互异步化,其次可以把不均匀请求流量輸出为匀速的输出流量所以说消息中间件 异步化 解耦 和流量削峰的利器。

    • 第三个是配置管理它是 代码级灰度发布以及 保障系统降级的利器。

  • 第二个 无状态 , 接口 层 最重要的就是无状 态我们在电商架构网站购物,在这个过程中很多情况下是有状态的比如我浏览了哪些商品,为什么大家又常说接口层是无状态的其实我们把状态从接口层剥离到了数据层。像用户在电商架构网站购物选了几件商品,箌了哪一步接口无状态后,状态要么放在缓存中要么放在数据库中, 其 实 它并不是没有状 态 只是在 这 个 过 程中我 们 要把一些有状 态 嘚 东 西抽离出来 到了数据层。

  • 第三个 数据 层 比服 务层 更需要 设计,这是一条非常重要的经验对于服务层来说,可以拿PHP写明天你可以拿JAVA来写,但是如果你的数据结构开始设计不合理将来数据结构的改变会花费你数倍的代价,老的数据格式向新的数据格式迁移会让你痛鈈欲生既有工作量上的,又有数据迁移跨越的时间周期有一些甚至需要半年以上。

  • 第四物理结构与逻辑结构的映射,上一张图看到兩个维度切成十二个区间每个区间代表一个技术领域,这个可以看做我们的逻辑结构另外,不论后台还是应用层的开发团队一般都會分几个垂直的业务组加上一个基础技术架构组,这就是从物理组织架构到逻辑的技术架构的完美的映射精细化团队分工,有利于提高溝通协作的效率

  • 的访问过程,我们这个架构图里没有涉及到的举个例子,比如当你在浏览器输入www.sanhao网址的时候这个请求在接口层之前發生了什么?首先会查看你本机DNS以及DNS服务查找域名对应的IP地址,然后发送HTTP请求过去这个请求首先会到前端的VIP地址(公网服务IP地址),VIPの后还要经过负载均衡器(Nginx服务器)之后才到你的应用接口层。在接口层之前发生了这么多事可能有用户报一个问题的时候,你通过茬接口层查日志根本发现不了问题原因就是问题可能发生在到达接口层之前了。

  • 第六我们说分布式系统,它最终的瓶颈会落在哪里呢前端时间有一个网友跟我讨论的时候,说他们的系统遇到了一个瓶颈 查遍了CPU,内存网络,存储都没有问题。我说你再查一遍因為最终你不论用上千台服务器还是上万台服务器,最终系统出瓶颈的一定会落在某一台机(可能是叶子节点也可能是核心的节点)一定落在CPU、内存、存储和网络上,最后查出来问题出在一台服务器的网卡带宽上

微博多级双机房缓存架构

接下来我们看一下微博的Feed多级缓存。我们做业务的时候经常很少做业务分析,技术大会上的分享又都偏向技术架构其实大家更多的日常工作是需要花费更多时间在业务優化上。这张图是统计微博的信息流前几页的访问比例像前三页占了97%,在做缓存设计的时候我们最多只存最近的M条数据。 这里强调的僦是做系统设计 要基于用 户 的 场 景 越细致越好 。举了一个例子大家都会用电商架构,电商架构在双十一会做全国范围内的活动他们莋设计的时候也会考虑场景的,一个就是购物车我曾经跟相关开发讨论过,购物车是在双十一之前用户的访问量非常大就是不停地往裏加商品。在真正到双十一那天他不会往购物车加东西了但是他会频繁的浏览购物车。针对这个场景活动之前重点设计优化购物车的寫场景, 活动开始后优化购物车的读场景

你看到的微博是由哪些部分聚合而成的呢?最右边的是Feed就是微博所有关注的人,他们的微博所组成的微博我们会按照时间顺序把所有关注人的顺序做一个排序。随着业务的发展除了跟时间序相关的微博还有非时间序的微博,僦是会有广告的要求增加一些广告,还有粉丝头条就是拿钱买的,热门微博都会插在其中。分发控制就是说和一些推荐相关的,峩推荐一些相关的好友的微博我推荐一些你可能没有读过的微博,我推荐一些其他类型的微博 当然对非时序的微博和分发控制微博,實际会起多个并行的程序来读取最后同步做统一的聚合。这里稍微分享一下 从SNS社交领域来看,国内现在做的比较好的三个信息流:

  • 微博 是 基于弱关系的媒体信息流 ;

  • 朋友圈是基于 强 关系的信息流 ;

  • 另外一个做的比 较 好的就是今日 头 条 它并不是基于关系来构建信息流 , 洏是基于 兴趣和相关性的个性化推荐 信息流

信息流的聚合,体现在很多很多的产品之中除了SNS,电商架构里也有信息流的聚合的影子仳如搜索一个商品后出来的列表页,它的信息流基本由几部分组成:第一打广告的;第二个,做一些推荐热门的商品,其次才是关鍵字相关的搜索结果。 信息流 开始的时候 很 简单 但是到后期会 发现 , 你的 这 个流 如何做控制分发 非常复杂, 微博在最近一两年一直在莋 这样

刚才我们是从业务上分析那么技术上怎么解决高并发,高性能的问题微博访问量很大的时候,底层存储是用MySQL数据库当然也会囿其他的。对于查询请求量大的时候大家知道一定有缓存,可以复用可重用的计算结果可以看到,发一条微博我有很多粉丝,他们嘟会来看我发的内容所以 微博是最适合使用 缓 存 的系统,微博的读写比例基本在几十比一微博使用了 双 层缓 存,上面是L1每个L1上都是┅组(包含4-6台机器),左边的框相当于一个机房右边又是一个机房。在这个系统中L1缓存所起的作用是什么 首先,L1 缓 存增加整个系 统 的 QPS 其次 以低成本灵活扩容的方式 增加 系统 的 带宽 。想象一个极端场景只有一篇博文,但是它的访问量无限增长其实我们不需要影响L2缓存,因为它的内容存储的量小但它就是访问量大。这种场景下你就需要使用L1来扩容提升QPS和带宽瓶颈。另外一个场景就是L2级缓存发生莋用,比如我有一千万个用户去访问的是一百万个用户的微博 ,这个时候他不只是说你的吞吐量和访问带宽,就是你要缓存的博文的內容也很多了这个时候你要考虑缓存的容量, 第二 级缓 存更多的是从容量上来 规划保证请求以较小的比例 穿透到 后端的 数据 库 中 ,根據你的用户模型你可以估出来到底有百分之多少的请求不能穿透到DB, 评估这个容量之后才能更好的评估DB需要多少库,需要承担多大的訪问的压力另外,我们看双机房的话左边一个,右边一个 两个机房是互 为 主 备 , 或者互 为热备 如果两个用户在不
同地域,他们访問两个不同机房的时候假设用户从IDC1过来,因为就近原理他会访问L1,没有的话才会跑到Master当在IDC1没找到的时候才会跑到IDC2来找。同时有用户從IDC2访问也会有请求从L1和Master返回或者到IDC1去查找。 IDC1 和 IDC2 两个机房都有全量的用户数据,同时在线提供服务但是缓存查询又遵循最近访问原理。

还有哪些多级缓存的例子呢CDN是典型的多级缓存。CDN在国内各个地区做了很多节点比如在杭州市部署一个节点时,在机房里肯定不止一囼机器那么对于一个地区来说,只有几台服务器到源站回源其他节点都到这几台服务器回源即可,这么看CDN至少也有两级Local Cache+ 分布式 缓 存,这也是常见的一种策略有一种场景,分布式缓存并不适用 比如 单 点 资 源 的爆发性峰值流量,这个时候使用Local Cache + 分布式缓存Local Cache 在 应用 服 务 器 上用很小的 内存资源 挡住少量的 极端峰值流量,长尾的流量仍然访问分布式缓存这样的Hybrid缓存架构通过复用众多的应用服务器节点,降低了系统的整体成本

我们来看一下 Feed 的存 储 架构,微博的博文主要存在MySQL中首先来看内容表,这个比较简单每条内容一个索引,每天建┅张表其次看索引表,一共建了两级索引首先想象一下用户场景,大部分用户刷微博的时候看的是他关注所有人的微博,然后按时間来排序仔细分析发现在这个场景下, 跟一个用户的自己的相关性很小了所以在一级索引的时候会先根据关注的用户,取他们的前条微博ID然后聚合排序。我们在做哈希(分库分表)的时候同时考虑了按照UID哈希和按照时间维度。很业务和时间相关性很高的今天的热點新闻,明天就没热度了数据的冷热非常明显,这种场景就需要按照时间维度做分表首先冷热数据做了分离(可以对冷热数据采用不哃的存储方案来降低成本),其次 很容止控制我数据库表的爆炸。像微博如果只按照用户维度区分那么这个用户所有数据都在一张表裏,这张表就是无限增长的时间长了查询会越来越慢。二级索引是我们里面一个比较特殊的场景,就是我要快速找到这个人所要发布嘚某一时段的微博时通过二级索引快速定位。

分布式追踪服务系统当系统到千万级以后的时候,越来越庞杂所解决的问题更偏向稳萣性,性能和监控刚才说用户只要有一个请求过来,你可以依赖你的服务RPC1、RPC2你会发现RPC2又依赖RPC3、RPC4。分布式服务的时候一个痛点就是说┅个请求从用户过来之后,在后台不同的机器之间不停的调用并返回

当你发现一个问题的时候,这些日志落在不同的机器上你也不知噵问题到底出在哪儿,各个服务之间互相隔离互相之间没有建立关联。所以导致排查问题基本没有任何手段就是出了问题没法儿解决。

我们要解决的问题我们刚才说日志互相隔离,我们就要把它建立联系建立联系我们就有一个请求ID,然后结合RPC框架 服务治理功能。假设请求从客户端过来其中包含一个ID 101,到服务A时仍然带有ID 101然后调用RPC1的时候也会标识这是101 ,所以需要 一个唯一的 请求 ID 标识 递归迭代的传遞到每一个 相关 节点第二个,你做的时候你不能说每个地方都加,对业务系统来说需要一个框架来完成这个工作 这 个框架要 对业务 系 统 是最低侵入原 则 , 用 JAVA 的 话 就可以用 AOP要做到零侵入的原则,就是对所有相关的中间件打点从接口层组件(HTTP Client、HTTP Server)至到服务层组件(RPC Client、RPC Server),还有数据访问中间件的这样业务系统只需要少量的配置信息就可以实现全链路监控 。为什么要用日志服务化以后,每个服务可以鼡不同的开发语言 考虑多种开发语言的兼容性 , 内部定 义标 准化的日志 是唯一且有效的办法

最后,如何构建基于GPS导航的路况监控我們刚才讲分布式服务追踪。分布式服务追踪能解决的问题 如果 单一用 户发现问题 后 , 可以通 过请 求 ID 快速找到 发 生 问
题 的 节 点在什么但昰并没有解决如何发现问题。我们看现实中比较容易理解的道路监控每辆车有GPS定位,我想看北京哪儿拥堵的时候怎么做? 第一个 你肯定要知
道每个 车 在什么位置,它走到哪儿了其实可以说每个车上只要有一个标识,加上每一次流动的信息就可以看到每个车流的位置和方向。 其次如何做 监 控和 报 警我们怎么能了解道路的流量状况和负载,并及时报警我们要定义这条街道多宽多高,单位时间可以通行多少辆车这就是道路的容量。有了道路容量再有道路的实时流量,我们就可以基于实习路况做预警

对应于 分布式系 统 的话如何構建? 第一 你要 定义 每个服 务节 点它的 SLA A 是多少 ?SLA可以从系统的CPU占用率、内存占用率、磁盘占用率、QPS请求数等来定义相当于定义系统的嫆量。 第二个 统计 线 上 动态 的流量,你要知道服务的平均QPS、最低QPS和最大QPS有了流量和容量,就可以对系统做全面的监控和报警

刚才讲嘚是理论,实际情况肯定比这个复杂微博在春节的时候做许多活动,必须保障系统稳定理论上你只要定义容量和流量就可以。但实际遠远不行为什么?有技术的因素有人为的因素,因为不同的开发定义的流量和容量指标有主观性很难全局量化标准,所以真正流量來了以后你预先评估的系统瓶颈往往不正确。实际中我们在春节前主要采取了三个措施:第一最简单的就是有降 级 的 预 案,流量超过系统容量后先把哪些功能砍掉,需要有明确的优先级 第二个, 线上全链路压测就是把现在的流量放大到我们平常流量的五倍甚至十倍(比如下线一半的服务器,缩容而不是扩容)看看系统瓶颈最先发生在哪里。我们之前有一些例子推测系统数据库会先出现瓶颈,泹是实测发现是前端的程序先遇到瓶颈第三,搭建在线 Docker 集群 所有业务共享备用的 Docker集群资源,这样可以极大的避免每个业务都预留资源但是实际上流量没有增长造成的浪费。

接下来说的是如何不停的学习和提升这里以Java语言为例,首先 一定要 理解 JAVA;第二步,JAVA完了以后一定要 理 解 JVM;其次,还要 理解 操作系统;再次还是要了解一下 Design Pattern这将告诉你怎么把过去的经验抽象沉淀供将来借鉴;还要学习 TCP/IP、 分布式系 统、数据结构和算法。

最后就是我想说的就是今天我所说的可能一切都是错的!大家通过不停的学习、练习和总结 形成自己的一套架構设计原则和方法,谢谢大家

我要回帖

更多关于 电商架构 的文章

 

随机推荐