大家好,我是Leo,前段时间介绍了MySQL和Redis的相关技术。大概告一段落了,我只能说对这两个技术优化的原理有了初步的了解,等我了解了整个技术栈后再回来修改第二版。推荐阅读3万字讲什么是Redis(下)3万字讲什么是MySQL(上)福利每1-2周我们会选出前3名分发一些书籍,每逢节日都会选出前10名发点书麻烦这三个人在我右下角点了联系我,加了微信,发了博客。最近不是在学习MySQL和Redis吗?找几本经典的书送给你,比如:高性能MySQL,Redis设计与实现,Redis深度探险,或者数据结构类剑指offer,代码随意记录前言任何技术总结都有商业背景,简单介绍有助于更好的理解,顺便输出一下自己的学习心得。之前一个跨境电商项目的基本要求已经满足。比如购买需求,积分,会员,购物车,用户,广告,消息通知等。下面开始考虑一些特价,闪杀,限时,推荐功能。无缘无故写一下,从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解析,可能耗时更长。所以我们要记住的是,减少请求的数量可以显着减少上述因素造成的资源消耗。路径应尽可能短。这里的路径主要是关于节点的个数。这些节点可以表示为一个系统或一个新的Socket连接(例如,代理服务器只是创建一个新的Socket连接来转发请求)。每经过一个节点,一般都会产生一个新的Socket连接。缩短请求路径不仅可以提高可用性,还可以有效提高性能(减少中间节点可以减少数据序列化和反序列化),减少延迟(减少网络传输时间)。尽量少依赖。这里主要是因为秒杀系统不同于业务系统,业务系统追求的是稳定,而秒杀系统追求的是效率。这也类似于CP和AP的选择。如下图所示,我们可以认为是秒杀场景。如果某个服务宕机了,会不会影响到整个系统?肯定是不行的,所以这里要注意强弱依赖的问题。结束单点没什么好说的。一旦发生事故或停机,不仅会影响使用,还会影响数据。因此,我们必须采用多服务、分布式、集群的思想来设计系统。学习淘宝淘宝早期秒杀系统架构,快速搭建一个简单的秒杀系统。你只需要在你的商品购买页面增加一个“预定上架”的功能,让用户只有在秒杀启动的时候才能看到购买按钮。当产品库存售完即止。当时第一版秒杀系统就是这样实现的。音量增加10w/s随着音量的增加,也遇到了很多瓶颈。因此,秒杀模块独立成一个秒杀系统。这样就可以专门针对秒杀系统做一些有针对性的优化。在部署方面,秒杀系统也可以集群独立部署,让秒杀模块在不影响正常购买产品的机器负载的情况下,被大量流量冲垮。库存数量等热点数据放在单独的缓存系统中,提高读取性能,减少与数据库的交互。在安全性方面,可以添加秒杀滑块,防止秒杀脚本抢单影响正常的用户体验需求。100w/s的音量提升,将界面上的动静分离,让用户秒杀时无需刷新整个页面。闪购商品在服务器端本地缓存,不需要调用依赖系统的后台服务获取数据,甚至不需要在公共缓存集群中查询数据,既可以减少系统调用,又可以避免压倒大众缓存集群。在安全方面,增加了系统限流保护,防止最坏情况的发生。封闭取景是一门平衡的艺术,脱离了适合的场景,再好的取景也无济于事。这里说的几点只是一个方向。你应该努力往这些方向努力,但你也必须考虑平衡其他因素。什么是动静分离?动静数据分离不是真正的活数据、死数据。所谓“动静分离”,其实就是将用户请求的数据(如HTML页面)分为“动态数据”和“静态数据”。简单来说,“动态数据”和“静态数据”的主要区别在于看页面输出的数据是否与URL、查看者、时间、区域相关,是否包含cookie等隐私数据,比如百度前11的热搜那么,不管是谁访问,他都是一样的。它是典型的静态数据,但是是动态接口。淘宝首页的商品会根据每个人的特点推送相关的、感兴趣的商品。这是动态的数据,动态的界面(但是有推荐算法的APP没有多少有这样的功能)。动静不是指数据本身是否动态,而是指数据中是否包含与访问者相关的个性化数据。静态数据优化了解了动态数据和静态数据之后,我猜你心里已经有了一个优化方案,可以把用户的静态数据缓存在Redis中,或者缓存到离用户最近的地方。比如用户浏览器,CDN。HTTP连接的直接缓存利用Web服务器来处理大量并发静态文件请求。比如我们常用的nginx和apache直接缓存HTTP连接。估计很多人不理解。我在这里介绍一下。静态转换是直接缓存HTTP,而不是缓存数据。Web代理服务器根据请求URL直接取出对应的HTTP响应头和响应体直接返回。这个响应过程非常简单,连HTTP协议都不用重新组装,连HTTP请求头都不用解析。动静分离以电子商务(淘宝、京东)和博客(掘金、CSDN)为例。我们可以缓存URL,使URL唯一。大家可以看看上面提到的天猫、京东、CSDN、掘金。缓存的键是每个唯一的数字id。产品/文章是动态的,但是每个用户登录的信息验证是静态的,所以我们可以把这部分服务分离出来。异步地理因素。详情页区域相关因素是异步获取的。当然你也可以通过动态请求的方式获取,不过这里异步获取更合适。(无关紧要的数据)隔离时间因素。服务器输出的时间也是通过动态请求获取的。下面两张参考图可以理解产品细节分离的思路。将动态内容分离后,我们可以将信息JSON化(将数据组织成JSON格式),方便前端获取。动态数据优化ESI方案(或SSI):即在Web代理服务器上进行动态内容请求,并将该请求插入到静态页面中。当用户拿到页面时,它已经是一个完整的页面了。这种方式对服务器性能有一定影响,但用户体验较好。CSI计划。即发起一个单独的异步JavaScript请求,从服务器获取动态内容。这种方式服务器端性能较好,但用户端页面可能会出现延迟,体验稍差。单台物理机部署动静分离架构方案;统一缓存层;上传到CDN。物理单机部署的解决方案是将虚拟机改为物理机来增加Cache的容量,并采用一致性Hash分组的方式来提高命中率。这里将Cache分成几组,希望在命中率和访问热点之间取得平衡。Hashgroups越少,cache的命中率越高,但缺点是单个产品会集中在一组中,容易导致Cache崩溃,所以要适当加入多个相同的groups来平衡关于访问热点和点击的问题。优点没有网络瓶颈,可以使用大内存;既可以提高命中率,又可以减少Gzip压缩;减轻Cache失效的压力,因为它采用了定时失效的方式,比如只缓存3秒,过期了会自动失效。缺点也在一定程度上造成了CPU的浪费,因为单个Java进程很难使用整个物理机的CPU。Java应用部署在物理机上,作为Cache使用,运维复杂度高,如下图所示。单机部署的架构图是一个统一的Cache层。所谓统一Cache层,就是将单台机器的Cache分开。形成一个单独的缓存集群。统一的Cache层是一种更理想的可扩展方案。该方案的结构图如下。优点单个Cache层可以降低访问多个应用程序时使用Cache的成本。这样连接起来的应用只需要维护自己的Java系统,不需要单独维护Cache,只关心如何使用。统一的Cache方案更易于维护。比如以后要加强监控和配置的自动化,只需要一个方案,统一起来更方便维护和升级。内存可以共享,最大限度地利用内存,不同系统之间的内存可以动态切换,从而有效应对各种攻击。缺点Cache层内部交换网络成为瓶颈;缓存服务器的网卡也会成为瓶颈;机器越少风险越大,其中一台机器挂掉会影响很大一部分缓存数据。针对以上问题,可以对Cache进行Hash分组,即一组Cache缓存内容相同,可以避免热点数据过度集中造成新的瓶颈。CDN将整个系统的动静分离之后,我们自然而然地想到了更进一步的解决方案,就是将缓存进一步向CDN移动,因为CDN离用户最近,效果会更好。使用该方案,主要需要解决三个问题:故障问题、命中率问题、版本更新问题,故障有点类似于Redis。如果缓存没有及时更新,那段时间用户看到的值可能会错位。如果及时更新的话,需要保证CDN能够在秒级内同时失效分布在全国各地的缓存。这个要求还是比较高的。命中率是缓存的生命线。如果一个缓存系统的命中率太低,那和没有缓存系统没什么区别。相反,它会消耗自己的性能来查询缓存系统。综上所述,把产品详情、博客详情等放到全国所有的CDN节点上是不现实的。我们可以使用以下解决方案来解决这个问题。人流量相对集中的区域距离主站点相对较远;nodestothemainsiteCDNs之间的网络相对较好和稳定;节点容量比较大,不会过多占用其他CDN的资源。不要有太多的节点。综合以上因素,选择CDN的二级缓存是比较合适的,因为二级缓存的数量比较少,容量比较大,这样用户的请求先返回给二级缓存——原CDN的二级缓存,如果没有命中,则返回源站获取数据,部署方式如下图所示:使用CDN的二级缓存作为缓存,可以达到与目前的服务端静态缓存,由于节点数量少,缓存不是很分散,流量比较集中。这样既解决了命中率的问题,同时又能给用户最好的访问体验,是目前比较理想的CDN解决方案。此外,基于CDN的部署方案具有以下特点:整个页面缓存在用户的浏览器中;如果强制刷新整个页面,也会请求CDN;实际有效请求只是用户点击“刷新抢宝”按钮点击。这样90%的静态数据都缓存在客户端或者CDN上。当真正的秒杀发生时,用户只需要点击特殊的“刷新抢宝”按钮,而不用刷新整个页面。这样,系统只向服务器请求少量的有效数据,而不是重复请求大量的静态数据。相比普通详情页的动态数据,秒杀的动态数据更少,性能提升3倍以上。所以,“抢宝”的设计思路让我们可以在不刷新页面的情况下向服务器请求最新的动态数据。什么是28原则?世界上80%的财富掌握在20%的人手中。热数据也是如此。有数千万种产品,每天有数十万用户访问数百万种产品。这种类型的数据是热点数据。在信息时代,并不是所有的数据都是热门的,所以在处理系统热点时,我们可以分为两种情况:特定的热点数据(比如推荐商品)不是推荐数据,但是后来最典型的例子就是今日头条,微博等应用。如果一个新闻事件慢慢发酵,系统中没有这个事件的缓存,过一段时间系统可能会崩溃。所以我们首先要找到热点。热点分为热点操作和热点数据热点操作。用户下拉刷新的时候,想看看自己关注的事件有没有上热搜。热点数据热搜事件必须被用户持续访问。对于系统来说,就是读请求和写请求。这两种类型的处理有很大不同,但是读取处理得更好,因为它们减少了与数据库的交互。写请求的瓶颈往往在存储层。后续会介绍热点数据,分为动态热点数据(外部因素触发的热门商品)、静态热点数据(商家推荐的商品),如何找到动态热点数据?搭建一个异步系统,可以收集交易链路上各个环节的中间件产品的热点key,比如Nginx、缓存、RPC服务框架等中间件(部分中间件产品已经有热点统计模块)。将上游系统采集的热点数据发送给热点服务台,下游系统(如交易系统)就会知道哪些商品被频繁调用,进而做热点保护。这是一个更大的系统,适用于一个小系统。通过ELK解决方案可以收集用户搜索商品的次数,判断是否为热点数据。如何处理动态热点数据?主要有三个思路:优化、限制、隔离、优化、优化。最简单的优化方法是直接缓存数据。如果热数据与静态和动态数据分离,静态数据可以长期缓存。但是,缓存热点数据更多的是一种“临时”缓存,即不管是静态数据还是动态数据,都会在队列中临时缓存几秒。由于队列长度有限,可以用LRU淘汰算法代替。limit,流量限制,流量限制更多的是一种保护机制,限制的方式有很多种,比如对访问的商品id做一个一致的Hash,然后根据这个Hash做buckets,设置一个processingqueue为每个bucket,这样就可以将热门商品限制在一个请求队列中,防止其他请求因为某些热门商品占用过多的服务器资源而无法从服务器接收处理资源。隔离秒杀系统设计的第一个原则就是隔离这个热点数据,不让1%的请求影响另外99%的请求。隔离之后,更方便优化那1%的请求。最后粗略总结了秒杀系统的设计五原则、动静分离方案、二十八原则、冷热数据处理方案。和大家一样,我也在学习这类系统的设计思路,接下来准备做一些代码。具体效果可以通过【公众号】=>【项目体验】=>【跨境电商】非常欢迎大家关注公众号【欢少的成长之路】后台有疑问,我们在群里一起讨论!下次见!