1. 如果项目组中使用的redis是单机版的,如何处理QPS在10万+的场景?
首先讨论这个问题的前提是java应用层的性能要大于redis性能,不然请求无法到达redis。那假如当前QPS是15万+,redis可以处理10万,那么另外5万,何应用可以处理呢?
方案1:
java本地缓存,我们还需在思考一个问题,何种数据存java本地缓存,何种数据存redis?这就需要根据缓存的特性进行分析。
当前的java应用都是集群式,分布式的应用,那么本地缓存也将是多份的。除此之外,java本地缓存相对redis缓存来说是更为有限的。所以,java本地缓存适合存放一些静态的,占用空间不大的,访问量大的数据。Redis作为集中式缓存可以存放会动态变化的,占用空间相对较多的数据。
方案2:
redis读写分离,redis主机复制处理写请求和同步数据给从机,redis从机负责处理读请求,假设从机使用其50%的性能,每个从机每秒处理5万的请求,构建3台从机即可。
2. 单条数据的高并发场景,如何在应用层进行排队?
可以设计一个线程池,处理高并发场景下的写请求
3. 淘宝系统设计秒杀系统的思路
淘宝系统的秒杀方案,主要基于下面2个方面去考虑:热点隔离,数据分层校验
热点隔离的出发点是不想让1%的请求影响到99%的请求,而隔离方案的实施可以从下面3个方面进行处理:
业务隔离: 秒杀时,参与活动的产品和商家可以提前知道,对于这些数据可以提前做好预热。
系统隔离:独立系统处理秒杀请求。
数据隔离:独立的缓存系统和数据库系统,存放热点数据。
数据分层校验:思想如果数据可以满足用户的需求,就不用将请求向下传递
前端缓存,对于静态信息,前端可以进行缓存处理。
动静分离,出发点是要尽可能的将静态资源放到客户端或者CDN, 对静态资源的请求不用到达应用端。
基于时间分片削峰,前端增加个答题功能,用户在下单时需要完成个答题任务,才能下单,使下单流程变长,由之前的1秒内变到2~10秒,并且起到了防止秒杀器的作用。
服务端缓存,应用本地缓存和缓存中间件的集中式缓存
单一商品高并发读问题,秒杀时商品的信息定然会放在缓存当中,如果使用的是redis集群,那么单个商品必然存在redis集群中的某个节点上,缓存节点的性能将成为系统的瓶颈。这个问题可以从两个方面来解决,1是将单个商品的信息分为静态信息和动态信息,静态信息放本地缓存,动态信息放redis缓存;2. redis 集群做读写分离,通过扩张从机来提高集群的请求处理能力。
单一商品高并发更新问题,单一商品高并发会引发什么问题呢?一个数据库线程更新某条记录的时候,其他的线程都要处于等待当中,这样的等待占用的数据库的线程和连接数,也占应用的线程数,这样的话应用将无法处理其他请求,如果不做隔离处理的话,还会影响到连接该数据库的其他请求,使得功能大面积瘫痪。解决方案:下单请求异步返回减少用户等待,在应用层进行排队处理(可以考虑使用线程池来处理下单任务)这样可降低数据层面的高并发,减少数据库的压力
需关注问题:是否有新的热点数据生成,如果有,也需要进行上面的处理