三高问题解决思路

在互联网公司,经常面临一个“三高”问题:

  • 高并发
  • 高性能
  • 高可用

三高问题解决思路

 一、缓存

  • 使用空间换时间的思想
  • 代码在访问数据的时候,尽量使用缓存命中率高的方式
  • 缓存之所以能够大幅提高系统的性能,关键在于二八定律:「百分之八十的数据访问是集中在 20% 的数据上」
  • 缓存分类:1. 本地缓存 2. 分布式缓存(一致性 Hash 算法)
  • 适合缓存的场景:1、读多写少 2、计算耗时大,且实时性不高
  • 不适合缓存的场景:1、写多读少,频繁更新 2、对数据一致性要求严格 3、数据访问完全随机
  • 缓存更新的策略:Cache-Aside 和 Cache-As-SoR

 

二、预处理和延后处理

  • 预处理:比如缓存预热,通过预先处理减少了实时链路上的 RPC 调用,既减少了系统的外部依赖,也极大的提高了系统的吞吐量
  • 延后处理:比如中了红包的延期到账,如果去实时的做到账,那么大概率数据库的 TPS(每秒处理的事务数) 会是瓶颈。通过产品提示,将到账操作延后处理,解决了数据库 TPS 瓶颈。延后处理还有一个非常著名的例子,COW(Copy On Write,写时复制)。

 

三、池化

  • 后台开发过程中你一定离不开各种 「池子」: 内存池、连接池、线程池、对象池......
  • 内存、连接、线程这些都是资源,创建线程、分配内存、数据库连接这些操作都有一个特征, 那就是创建和销毁过程都会涉及到很多系统调用或者网络 IO。 每次都在请求中去申请创建这些资源,就会增加请求处理耗时,但是如果我们用一个 容器(池) 把它们保存起来,下次需要的时候,直接拿出来使用,避免重复创建和销毁浪费的时间。

 

四、同步变异步

  • 对于处理耗时的任务,如果采用同步的方式,那么会增加任务耗时,降低系统并发度。同步轮训, 这样效率显然太低了。
  • 可以通过将同步任务变为异步进行优化。
  • 异步,在很多编程语言中有异步编程的库,比如 C++ std::future、Python asyncio 等,但是异步编程往往需要回调函数(Callback function),如果回调函数的层级太深,这就是回调地狱(Callback hell)。回调地狱如何优化又是一个庞大的话题。

 

五、消息队列

  • 异步
  • 解耦
  • 削峰

 

六、批量处理

  • 通过合并一些频繁请求的小资源可以获得更快的加载速度。

 

七、数据库

  • 索引
  • 读写分离
  • 分库分表

 

八、其他

  • 零拷贝

mmap

sendfile

......

  • 无锁化:锁的代价也是比较高的,锁会导致上线文切换,甚至被挂起直到锁被释放。

基于硬件提供的原子操作 CAS(Compare And Swap) 实现一些高性能无锁的数据结构,比如无锁队列,可以在保证并发安全的情况下,提供更高的性能。

  • 序列化与反序列化:序列化解决了对象持久化和跨网络数据交换的问题

序列化一般按照序列化后的结果是否可读,可分为以下两类:

  • 文本类型:

    如 JSON、XML,这些类型可读性非常好,是自解释的。也常常用在前后端数据交互上,因为接口调试,可读性高非常方便。但是缺点就是信息密度低,序列化后占用空间大。

  • 二进制类型

    如 Protocol Buffer、Thrift等,这些类型采用二进制编码,数据组织得更加紧凑,信息密度高,占用空间小,但是带来的问题就是基本不可读。

具体可见:三高