你好,我是利奥。
前段时间介绍了MySQL和Redis的相关技术。大概告一段落,只能说对这两个技术调音原理有了初步的了解,等整个technology stack学的差不多了再回来做第二版的修改。
前言任何技术的总结都有商业背景。简单的介绍会帮助你更好的理解,顺便输出自己的学习思路。
已经满足了之前一个跨境电商项目的基本需求。如购买需求、积分、会员、购物车、用户、广告、消息通知等。
我们开始考虑特价、秒杀、限时、推荐的一些功能吧。让我无缘无故写,从0到1,肯定不会。一点一点去研究淘宝10年前的技术发展过程当然不会划算。问题是,如何开发设计一个秒杀系统?
有这个想法的时候,我也是疯了。要点如下
我仍然没有钱来支持我的想法。毕竟花点时间写代码还是可以的。所以,综上所述,购买秒杀相关的课程,学习前人的思路,再考虑自己的系统规模进行开发是我接下来的任务
学习思想说起学习,相信很多人都会处于以下状态。
现在信息化太爆炸,很多app和系统很容易被他按照个人喜好影响。我一直觉得应该鞭策自己,给自己一些动力。做时间的主人,做生活的主人。
至于学习的顺序,建议一点一点学习适合自己能力的技术。很多人基础还没学会,天天嚷嚷着要学微服务、分发、并发。然后在群里,我问他为什么,他说要拿阿里20K。
20K没那么容易。技术没有捷径。循序渐进才是王道。C#转Java快半年了,刚学微服务。我学微服是因为我领导在会上说我以后可能要学微服。不然吃饱了就没事干了。我要端上这块大骨头。
关闭!回到正题!
数据尽量要少数据要尽量少主要有两点:用户请求中附加的数据要尽量少服务器返回给客户端的数据要尽量少千万不要传输无关的字段。
因为数据在网络上传输是需要时间的,其次,无论是请求数据还是返回数据,都需要服务器做处理,在网络上写的时候服务器通常要做压缩和字符编码,这些都是非常消耗CPU的,所以减少传输的数据量可以显著减少CPU的使用。
第二层意思是完成一些业务。我们从数据库中读取校验值和保存的数据,这涉及到与数据库的交互。调用其他服务会涉及数据序列化和反序列化,这也是CPU的一大杀手,也会增加延迟。而且数据库本身很容易成为瓶颈,所以越少和数据库打交道越好,数据越简单越小越好。
这里有一些例子。比如下单的时候,需要根据成交量做出选择,是要用前端到后端的对应值进行实体类拼接,还是前端只传输ID。根据用户ID找到用户的等级,然后根据等级找到这个用户对应的商品价格?
还有下面的积分ID,是前端传输,还是只是用户ID,查一下积分ID?
是否有必要将用户的信息保存到缓存中,直接进行Redis incr、decr或反向检查?如果给了缓存,如何保证一致性?(请参考我之前Redis的第七篇文章)
以上只是一些想法,并不是最好的解决方案。代码还没有优化,只是开发的一个阶段。
请求数尽量要少看的时候第一时间没有回应要求。这里我就以图文并茂的形式介绍一下。
用户请求的页面返回后,浏览器会用其他额外的请求来渲染这个页面,例如,这个页面所依赖的CSS/JavaScript、图片、Ajax请求都被定义为“额外请求”,这些额外请求要尽量少。因为浏览器发出的每个请求都会有一些消耗,比如建立连接需要三次握手,有时候会有页面依赖或者连接限制,有些请求(比如JavaScript)需要串行加载等等。
如果不同请求的域名不一样,还涉及到这些域名的DNS解析,可能需要更长的时间。所以我们要记住,减少请求的数量可以显著减少这些因素造成的资源消耗。
路径尽量要短这里的路径主要是关于节点的数量。这些节点可以表示为一个系统或一个新的套接字连接(例如,代理服务器只是创建一个新的套接字连接来转发请求)。在每个节点之后,通常会生成一个新的套接字连接。缩短请求路径不仅可以增加可用性,还可以有效提高性能(减少中间节点的数量可以减少数据的序列化和反序列化),减少延迟(可以减少网络传输时间)。
这里的依赖主要是秒杀系统和业务系统的区别在于,业务系统追求稳定,秒杀系统追求那一刻的效率。这也类似于CP和AP之间的选择。
如下图所示,我们可以把它想象成一个尖峰场景。如果某项服务出现故障,是否会影响整个系统?肯定不行,所以这里要注意强依赖和弱依赖的问题。
这个没什么好说的。一旦发生事故或停机,不仅会影响使用,还可能影响数据,所以我们必须用多服务、分布式和集群的思想来设计系统。
学习淘宝淘宝早期秒杀系统架构要快速搭建一个简单的秒杀系统,只需要在你的产品购买页面添加一个“定时上架”功能,让用户只在秒杀开始时看到购买按钮,当产品库存售完时就会结束。这是当时钉钉系统实现的第一个版本。
音量增加10w/s随着体量的增加,遇到了很多瓶颈。因此,将道钉模块分离成道钉系统。这样就可以对秒杀系统做一些针对性的优化。
在部署方面,秒杀系统也可以独立部署在一个集群中,使得秒杀模块在不影响正常商品购买的机器负载的情况下,可以大流量枯竭。
为了提高读取性能,减少与数据库的交互,将库存数量等热点数据单独放在一个缓存系统中。
安全性方面,可以增加秒杀滑块,防止秒杀抢单,影响正常用户体验需求。
音量的增加是100w/s在界面上做一些静态和动态的分离,让用户在杀的时候不需要刷新整个页面。
秒杀产品在服务器端的本地缓存不需要调用依赖系统获取数据的后台服务,甚至不需要查询公共缓存集群中的数据,既可以减少系统调用,又可以避免碾压公共缓存集群。
安全性方面,增加系统限流保护,防止最坏情况的发生。
结尾建筑是一门平衡的艺术,一旦最好的建筑脱离了它所适应的场景,一切都将空谈。这里说的几点只是一个方向,你要尽量往这些方向努力,但也要考虑平衡其他因素。动静分离什么是动静数据动静分离不是真正的活数据,死数据。所谓“动静分离”,实际上是将用户请求的数据(如HTML页面)分为“动态数据”和“静态数据”。
简单来说,
“动态数据”与“静态数据”的主要区别在于页面中的输出数据是否与URL、查看者、时间、地域相关,是否包含Cookie等私有数据动态和静态不是指数据本身是动态还是静态,而是数据中是否包含与访问者相关的个性化数据。
静态数据优化在了解了动态数据和静态数据之后,我猜你脑子里已经有了一个优化方案。
我估计很多人不理解直接缓存HTTP连接。下面介绍一下。静态转换是直接缓存HTTP,而不是缓存数据。Web代理服务器根据请求URL直接取出对应的HTTP响应头和响应体然后直接返回。这个响应过程非常简单,甚至连HTTP协议都不需要重新组装,甚至连HTTP请求头都不需要解析。
动静分离改造以电子商务为例(淘宝,JD.COM)
下面两张参考图可以理解商品细节部分分离的思路。
分离出动态内容后,我们可以对信息进行JSON(以JSON格式组织数据),方便前端采集。
动态数据优化ESI scheme(或SSI):在Web代理服务器上发出动态内容请求,并将请求插入到静态页面中。当用户得到页面时,它已经是一个完整的页面了。这种方式对服务器性能有一定影响,但用户体验更好。CSI方案。也就是单独发起一个异步JavaScript请求,从服务器获取动态内容。这样服务器端性能更好,但用户端页面可能会延迟,体验稍差。动静分离的架构方案该方案将虚拟机改为物理机增加缓存容量,并采用一致哈希分组方法提高命中率。这里把缓存分成几组,希望达到命中率和访问热点的平衡。哈希包越少,缓存的命中率肯定越高。但短板也会把单一商品集中在一个包里,容易导致缓存崩溃。因此,我们应该适当地添加多个相同的数据包,以平衡访问热点和命中率的问题。
优势缺点
如下图所示,单机部署的架构图
统一缓存层
所谓统一缓存层,是指将单机缓存统一分离,形成单个缓存集群。统一缓存层是比较理想的方案,可以推广。该方案的结构图如下
优势
缺点
要解决以上问题,可以对缓存进行哈希,即一组缓存的缓存内容相同,这样可以避免热点数据过于集中带来的新的瓶颈。
在CDN上
整个系统动静分离后,我们自然会想到更进一步的方案,就是把缓存进一步转发到CDN,因为CDN离用户最近,效果会更好。
采用这种方案,有三个主要问题需要解决。
失效有点类似Redis。如果缓存没有及时更新,用户看到的值可能会在此期间放错位置。如果及时更新,就要保证CDN能够在几秒内同时使分布在全国各地的缓存失效。这个要求还是比较高的。
命中率是缓存的生命线。有缓存系统的命中率太低,和没有缓存系统没什么区别。相反,它消耗自己的性能来查询缓存系统。
综上所述,放产品详情,博客详情等不太现实。在中国所有的CDN节点上。我们可以采用以下解决方案来解决这一不足。
综合以上因素,选择CDN的二级缓存更合适,因为二级缓存数量更少,容量更大,这样用户的请求会先返回到源CDN的二级缓存,如果没有命中,会返回到源站获取数据。部署模式如下图所示:
使用CDN的二级缓存作为缓存,可以达到类似当前服务器静态缓存的命中率,因为节点数量少,缓存不是很分散,访问相对集中,从而解决了命中率问题,给用户最好的访问体验,是目前比较理想的CDN解决方案。
此外,CDN部署方案具有以下特点:
这样,90%的静态数据都缓存在客户端或CDN中。当秒杀真的发生时,用户只需要点击专门的“刷新夺宝”按钮,而不需要刷新整个页面。这样,系统只向服务器请求少量的有效数据,而不是重复请求大量的静态数据。相比普通详情页的动态数据,秒杀动态数据更少,性能提升3倍以上。所以“抢宝”的设计思路让我们可以在不刷新页面的情况下,向服务器请求最新的动态数据。
二八原则什么是二八原则世界上80%的财富掌握在20%的人手中,火热的数据也是如此。几千万的商品,几百万的商品,每天都有几十万的用户访问。这类数据就是
热点数据。在信息时代,并不是所有的数据都是热门的,所以在处理系统的热门时间时,我们可以分为两种情况。
从不是热点到成为热点最典型的例子就是今日头条,微博这样的app。如果一个新闻事件慢慢发酵,而系统中没有这个事件的缓存,那么系统可能很快就要宕机了。
所以我们需要先找到热点。热点分为热点操作和热点数据。
热点操作当用户在下拉模式下刷新时,他/她希望看到他/她正在关注的事件是否被热搜过。带热搜的热点数据事件应该是用户经常访问的。对于系统,是
读请求和写请求。这两种处理方法差别很大,但读取更容易处理,因为它可以减少与数据库的交互。写请求的瓶颈通常在存储层。后面会介绍。热点数据又分为
动态热点数据(外界因素导致的热点商品)和静态热点数据(商家推荐的商品)如何发现动态热点数据?这是一个更大的系统,对于一个小系统来说。ELK scheme可以收集用户搜索商品的次数来判断是否是热点数据。
如何处理动态热点数据?主要有三个思路。
最简单的优化方法是直接缓存数据。如果把热点数据和静态数据分开,静态数据可以缓存很长时间。然而,热数据的缓存更多的是“临时”缓存,即静态数据和动态数据都在队列中缓存几秒钟。由于队列长度有限,可以用LRU消去算法来代替。
限值,电流限值限制,目前的限制更多的是一种保护机制,限制的方式有很多种,比如对被访问的商品的ID做一致的Hash,然后根据Hash做桶,为每个桶设置一个处理队列,从而将热门商品限制在一个请求队列中,防止其他请求因为某些热门商品占用过多的服务器资源而一直获得服务器的处理资源。
隔离spike系统设计的首要原则是隔离这些热数据,不要让1%的请求影响到其他99%。隔离之后,优化这1%的请求就更方便了。
结尾[/s2/]大概总结了一下
作者:桓韶的成长之路
链接:https://juejin.cn/post/7050760579480305701
最新评论