石衫的架构笔记之高并发系统相关

这个系列涉及到的文章,我做了一些总结与归纳,主要是以下内容:

涉及到的知识点,具体有以下博文来做详细介绍与分析

1.支撑日活百万用户的高并发系统,应该如何设计其数据库架构?

目录:

1.用多台服务器来分库支撑高并发读写(将数据和请求都分散到不同的服务器上了)

2.大量分表来保证海量数据下查询性能(大量分表可以使得单表数据量降低,提高了查询性能)

3.读写分离来支撑按需扩容及性能提升(读的需求往往都大于写,利用主从架构,从来作为读,可以很容易通过主从的扩容来实现按需扩容;另外读写分离还可以由因为读写同一个表可能带来的锁冲突问题)

高并发下的数据库架构设计总结

2.【高并发优化实践】10倍请求压力来袭,你的系统会被击垮吗?

关于MQ挂掉之后的降级机制的设计

如果说在高峰期并发量比较高的情况下,接收到一条数据立马同步写本地磁盘文件,这个性能绝对是极其差的,会导致系统自身的吞吐量瞬间大幅度下降,这个降级机制是绝对无法在生产环境运行的,因为自己就会被高并发请求压垮。

因此当时设计的时候,对降级机制进行了一番精心的设计。

我们的核心思路是一旦MQ中间件故障,触发降级机制之后,系统接收到一条请求不是立马写本地磁盘,而是采用内存双缓冲 + 批量刷磁盘的机制。curren缓冲区满了之后就和ready缓存区进行交换。

推文中出现的问题:在交换时ready缓冲区还没有结束写入到磁盘的操作,导致所有线程全部陷入等待

解决方案:扩大缓存区

启发:对系统设计和开发的任何较为复杂的机制,都必须要参照线上高峰期的最大流量来压力测试。只有这样,才能确保任何在系统上线的复杂机制可以经得起线上高峰期的流量的考验。

3.微服务、注册中心等高可用相关

3.1、【双11狂欢的背后】微服务注册中心如何承载大型系统的千万级访问?

总结:

    3.1.1.通过上面的分析可以看到,Eureka通过设置适当的请求频率(拉取注册表30秒间隔,发送心跳30秒间隔),可以保证一个大规模的系统每秒请求Eureka Server的次数在几百次。

    3.1.2.同时通过纯内存的注册表,保证了所有的请求都可以在内存处理,确保了极高的性能

    3.1.3.另外,多级缓存机制,确保了不会针对内存数据结构发生频繁的读写并发冲突操作,进一步提升性能。


3.2、【性能优化之道】每秒上万并发下的Spring Cloud参数优化实战

总结:

3.2.1.针对大的负责的多表关联SQL解决方案:对数据库就执行简单的单表查询和更新,然后复杂的业务逻辑全部放在java系统中来执行,比如一些关联,或者是计算之类的工作

3.2.2.系统接口超时时间不要搞成几秒甚至几十秒的超时,一般超时定义在1秒以内,是比较通用以及合理的。因为一个接口,理论的最佳响应速度应该在200ms以内,或者慢点的接口就几百毫秒。如果一个接口响应时间达到1秒+,建议考虑用缓存、索引、NoSQL等各种你能想到的技术手段,优化一下性能。否则你要是胡乱设置超时时间是几秒,甚至几十秒,万一下游服务偶然出了点问题响应时间长了点呢?那你这个线程池里的线程立马全部卡死!

3.2.3.设置合理的接口重试机制

3.2.4.涉及到了重试,那么必须上接口的幂等性保障机制:常见的方案:1、可以在数据库里建一个唯一索引,插入数据的时候如果唯一索引冲突了就不会插入重复数据;2、通过redis里放一个唯一id值,然后每次要插入数据,都通过redis判断一下,那个值如果已经存在了,那么就不要插入重复数据了

3.3、微服务架构如何保障双11狂欢下的99.99%高可用

建议参考方案:

3.3.1、首先你的hystrix资源隔离以及超时这块,必须设置合理的参数,避免高峰期,频繁的hystrix线程卡死

3.3.2、其次,针对个别的服务故障,要设置合理的降级策略,保证各个服务挂了,可以合理的降级,系统整体可用!

           比如,如果你的某个服务挂了,那么你的hystrix会走熔断器,然后就会降级,你需要考虑到各个服务的降级逻辑。

            举一些常见的例子:

            如果查询数据的服务挂了,你可以查本地的缓存

            如果写入数据的服务挂了,你可以先把这个写入操作记录日志到比如mysql里,或者写入MQ里,后面再慢慢恢复

            如果redis挂了,你可以查mysql

            如果mysql挂了,你可以把操作日志记录到es里去,后面再慢慢恢复数据。

            具体用什么降级策略,要根据业务来定,不是一成不变的。
 

4.如果20万用户同时访问一个热点缓存,如何优化你的缓存架构?

解决该类问题主要分为三个点:

(1)基于流式计算技术的缓存热点自动发现

(2)热点缓存自动加载为JVM本地缓存

(3)限流熔断保护

同时,该类问题实际上就是热key的一类问题,那关于热key,大value的解决方案,这里也提一下:热key的解决方案【流程其实就是“发现热key”即监控等,然后解决热key,比如互斥锁,逻辑永不过期,早发现并缓存到本地】(方案1方案2;略复杂的方案3);大key的解决方案【主要是针对:1、单个简单的key存储的value很大(1)对象需要每次都整存整取;(2)该对象每次只需要存取部分数据;2、 hash, set,zset,list 中存储过多的元素;3、一个集群存储了上亿的key这三方面的问题分别给我相应的解决方案即可】(方案1方案2方案3方案四

猜你喜欢

转载自blog.csdn.net/jayxujia123/article/details/106738813