高并发系统设计三层面
高并发系统设计要点:
提高吞吐量(并发数):在拆分应用时,在水平方向拆应用,拆的层越多,吞吐量就会越高,但相应延时也会越高。同步架构:三层;异步架构:四层。在架构设计时,无状态设计最重要。
响应延迟
性能优化层次有三个层面。
架构设计层次:如何拆分系统,如何使各个部分系统负载更加均衡,充分发挥硬件设施的性能优势,减少系统内部开销等。
算法逻辑层次:关注算法选择是否高效、算法逻辑优化,空间时间优化任务并行处理,使用无锁数据结构等;使用ThreadLocal;采用压缩算法压缩数据,更复杂的逻辑减少数据传输。
代码优化层次:关注代码细节优化,代码实现是否合理,是否创建了过多的对象,循环遍历是否高效,cache使用是否高效、合理,是否重用计算结果。
代码优化层次
代码优化层次包括:
循环遍历是否合理高效,不要在循环里调用RPC接口、查询分布式缓存、执行SQL等。要先调批量接口组装好数据,再循环处理。
代码逻辑避免生成过多的对象或无效对象:输出Log的时候的log级别判断,避免new无效对象。
ArrayList、HashMap初始容量设置是否合理:扩容代价。
对数据对象是否合理重用,比如通过RPC查到的数据能复用则必须复用。
根据数据访问特性选择合适的数据结构,如果读多写少,考虑使用CopyOnWriteArrayList(写时拷贝副本)
拼接字符串的时候使用String相加还是使用StringBuilder进行append(在StringBuilder的容量预分配前提下,StringBuilder的性能比String相加性能高15倍左右)
是否正确初始化语句,有些全局共享的数据,饿汉式模式,在用户访问之前先初始化好。
列遍历用L1 Cache 列遍历由于不满足局部性原理,需要放到L3 cache。行遍历符合局部性原理,因此缓存命中率高,速度接近前者2倍。
CPU Cache架构,按照以下顺序速度越来越高:内存->L3->L2->L1。本质上内存使用一个大的一堆数组,二维数组在内存中按行排列,先存放a【0】行,再存放a【1】行
业务系统使用缓存降低响应时间提高性能,必须要提高缓存命中率。
很聚焦的高频访问,时效性要求不高很适合缓存提升性能,很聚焦的高频访问业务如banner、广告位时效性要求不是很高,比如更新了可以不用实时体现,很适合使用缓存提升性能。
如果对数据实时性要求很高,必须严格的时效性,需要慎重处理好更新缓存带来的一致性问题。
时效性和缓存的冲突,比如商品服务对商品进行了缓存,由于更新缓存和更新商品不是同一个事务,则对数据实时性要求高的如交易,就只能直接从数据库查询商品信息。
当读<=写的时候 没必要用缓存。、
当查询条件数据量超过总数据库总量的30%,就不会用索引,直接用遍历查询。缩小范围,让条件覆盖的数据量小一些。别查几年的,查半个月的。
算法逻辑层优化:
用更高效的算法替换现有算法,而不改变其接口
增量式算法,复用之前的计算结果,比如一个报表服务,要从全量数据中生成
报表数据量很大,但每次增量的数据较少,则可以考虑只计算增量数据和之前计算结果合并,这样处理的数据量就小很多。
并发和锁的优化:读多写少:乐观锁;读少写多:互斥锁
系统时间是瓶颈:如缓存复用计算结果,降低时间开销,因为CPU时间比内存容量更加昂贵。
数据大小是瓶颈:网络传输是瓶颈,使用系统时间换取换出的空间,使用http的gzip压缩算法。app的请求分类接口,使用版本号判断哪些数据更新,是下载更新的数据。
并行执行:一段靠逻辑调用了多个RPC接口,而这些接口之间并没有数据依赖,则可以考虑并行调用,降低响应时间。
异步执行:分析业务中的主次流程,把次要流程拆出来异步执行,更进一步拆分成单独的模块去执行,比如消息队列,彻底和核心流程解耦,提高核心流程的稳定性以及降低响应时间。
架构设计优化:
系统微服务
无状态化设计,动态水平弹性扩展
调用链路梳理,热点数据尽量靠近用户。
分布式缓存,多级多类型缓存
提前拒绝,保证柔性可用
容量规划
分布分表,读写分离,数据分片。