美文网首页技术分享java架构设计专题优化专题
谈谈互联网的一些高并发设计手段

谈谈互联网的一些高并发设计手段

作者: 先生zeng | 来源:发表于2019-09-19 11:13 被阅读0次

    途径

    通过提高吞吐量降低响应延迟这两块方向来确保高并发。

    性能优化的目标

    1. 缩短响应时间
    2. 提高并发数
    3. 让系统处于合理状态

    优化手段

    1. 当时间是瓶颈的时候。

    当系统的运行时间是主要的瓶颈而空间绰绰有余时,可以采用缓存复用计算结果,把计算的结果存入缓存,降低系统时间上的开销,因为缓存比较容易访问。

    1. 当空间比较缺少时

    这时候就i可以考虑时间换空间了,当系统运行时间很快,而受限于空间的影响。举两个例子:

    1. 网络传输是瓶颈,这时候可以使用系统时间去使用http的gzip进行压缩,消费时间换取空间的

    2.App的请求分类接口,可以使用版本号来判断哪些数据需要更新,只要下载需要更新的数据就可以了

    1. 找到系统的瓶颈的一些思路

    2. 分析系统业务流程,找到关键路径并分解优化。

    3. 比如,一个服务集群,一般前五的几个接口占用了百分之80的流量,这几个接口就是关键路径

    4. 对关键路径的代码优化收益一般是最大的,其他路径也要想办法进行优化。

    整个优化手段上: 调用了多少rpc接口,载入多少数据,使用什么算法,非核心流程能否异步化,没有数据依赖的逻辑能否并行执行。

    优化的层次

    1. 架构设计层次

      关注系统控制、数据流。

      如何拆分系统,使各部分系统整体负载更加均衡,降低系统内部开销。

    2. 算法逻辑层次

    关注算法的选择是否高效,算法的逻辑进行优化,空间时间优化任务并行处理,使用无锁数据结构,避免加锁(CAS)。

    空间换时间

    ThradLocal

    时间换空间

    采用压缩算法压缩数据,更复杂的逻辑减少数据传输。

    1. 代码优化层次

    关注代码细节优化,代码实现是否合理,是否创建过多的对象,循环遍历是否高效,cache使用是否合理,是否重用结算结果。

    代码优化层次如下:

    循环遍历是否高效:

    不要在循环里调RPC接口、查询分布式缓存、执行SQL等,应该先调批量接口组装好数据,再循环处理。

    代码需要注意避免生成过多对象或无效对象,比如输出log时候的log级别需要判断,避免new无效对象。

    ArrayList、HashMap初始容量设置是否合理。

    对数据对象是否合理重用,比如通过RPC查到的数据能复用则必须复用。

    根据数据访问特性选择合适数据结构,比如读多写少,考虑 copyOnWrite。

    拼接字符串的时候是使用String相加还是StringBuilder进行append(在StringBuilder的容量预分配的情况下,StringBuilder的性能比String相加性能提高15倍左右)。

    是否正确初始化数据,有些全局共享的数据,饿汉式模式,在用户访问之前初始化。

    数据库建表语句能尽量小的数据结构比如表示状态的字段,如果状态值在255以内使用unisigned tinyint,IP使用int而非varchar。

    使用enum的场景使用tinyint,emum扩展需要该表。

    避免使用select * 查询数据,只查询需要的字段,避免浪费数据IO、内存、CPU、网络传输。

    分析查询场景建立合适的索引,分析字段的可选择性,索引长度,对长的varchar使用前缀索引

    字段金量为not null类型,MySql手册说明允许null字段需要额外的存储空间处理null,并且很难查询优化

    总结:

    以上都是为了降低服务器CPU使用率、IO流量、内存占用、网络消耗、降低响应时间等等。

    CPU Cache结构

    速度越来越快: 内存 -> L3 -> L2 -> L1多级缓存

    哪些数据适合缓存?

    很聚焦的高频访问,时效性要求不高的适合缓存,比如很聚焦很高频访问业务数据如频道,栏目,广告位。
    时效性要求不是很高的,更新了不用实时体现的适合缓存提高性能。

    如果对数据时效性要求很高,需要考虑更新缓存带来的一致性问题。

    时效性和缓存的冲突,比如商品服务对商品进行了缓存,由于缓存和更新商品不是同一个事务,则对数据时效性要求搞得如交易,就只能从数据库查询商品信息了。

    image

    算法逻辑优化层次如下:

    image

    架构设计优化逻辑

    1. 分布式系统微服务化
    2. 分库分表、读写分离、数据分片
    3. 无状态化设计、水平扩展
    4. 调用链路梳理、热点数据尽量靠近用户
    5. 分布式cache、多级多类型缓存
    6. 容量规划
    7. 提前拒绝,保证柔韧性可用。

    案例分析

    秒杀系统

    开发场景分析:
    • 大量并发,在某一时刻99%的用户请求进入服务器
    • 有效请求很低,与数据库剩余库存量一致
    • 库存一致性要求严格,不能超卖
    架构设计方面

    数据需要进行分层

    image

    数据分层次校验、上层尽量把无效请求过滤掉。

    上层可以是不准确的过滤。

    层层限流最后一层做数据一致性校验,扣减库存。

    具体手段

    1. Html、js、css等静态资源文件缓存到用户端(APP或浏览器)

    2. 非实时动态数据(秒杀期间如商品标题、商品描述、图片URL列表、店铺信息、秒杀活动信息等),这些数据缓存在用户访问链路中靠近用户的位置、粗过滤一分部流量,比如用户是否有秒杀的资格、秒杀是否已结束等、这些数据实时性要求不高,这些数据放在第一层cache上面,这些数据在数据库发生变化时,通过MQ同步到cache。

    3. 实时数据如用户营销数据(红包、折扣、商品库存等)再过滤掉一批用户。这些数据放到第二层缓存里面,这些数据需要通过MQ进行同步。

    4. 经过多层过滤最终落到数据库的流量已经很少了,最终在数据库层面使用事务保证扣库存准确性。

    image

    feed系统

    示例: 微信朋友圈

    image

    特性:

    1. 读多写少 100/1
    2. 冷热数据明显 80% 是当天数据,20%用户是活跃用户
    3. 热点效应明显 热点事件、重大节日、日常这些日期内,比较明显
    4. 高访问量

    注意点

    读多写少、冷热数据明显,热点数据缓存到调用链路更靠近用户的地方

    L1缓存容量小,负责抗最热点的数据,L2缓存容量考虑目标是容量,缓存更大范围的数据,比如一般用户的timeLine,高热点数据单独缓存,比如设置白名单,大V的用户数据单独缓存。

    数据分析各种timeline(关注的timeline、topic的timeline、一些运营的timeline)前几页的访问比例,像前三页占百分之97,把这种业务特性,把前几页的数据作为热点数据放进L1Cache。

    image

    push 或 pull

    当用户发布数据是,是需要考虑把数据发送push给关注者(朋友),还是用户个人从关注的人中主动pull取消息。这就是push或pull。

    比如微博,一个最火的明星有几千万关注者当发布一条消息时,考虑下,如何把消息传播出去。

    实现

    1. 基于写扩散消息同一推送频道

    2. 推送策略: 拆分数据并行推,活跃用户先推,非活跃用户慢慢推。
      比如: 有1万个用户关注,发了一条消息,先拆分成100份,每份100个并行推
      1万个用户里,活跃的假设有2000个,则活跃用户先推送,非活跃用户慢慢推

      每个用户会维护一份活跃用户列表,用户上线,则为活跃用户。

    3. 消息标准化格式

    4. 统一数据流,职责明确


      image

    数据存储选择

    image

    相关文章

      网友评论

        本文标题:谈谈互联网的一些高并发设计手段

        本文链接:https://www.haomeiwen.com/subject/axxructx.html