高并发系统项目开发实战经验

最近参与实现了一个CCU预计240w+ 项目,学习了各位大佬们的思路和代码。记录分享一下一些拙见。

  1. 一般的架构瓶颈首先出现的都是存储瓶颈
  2. redis官方给出的单key的最高qps大概是10w/s,自己测了一下多个命令get、set、zadd等等都能达到10w/s(本机)
  3. 用redis存储的话,几乎就能支持接近10wqps量级的流量。(单机)
  4. 但也带来的持久化的问题,自己的想法(口嗨):
    ----------a 在写redis的同时,发送kafka消息,消费者去持久化数据。
    ----------b 定时任务以不高的频率(尽量不影响业务)去从redis中拉取信息持久化
    —不管怎样还是以redis为第一准确数据
  5. 在设计数据结构、业务逻辑的时候遵循原则:能够只访问一次redis就不访问两次。尽可能的降低redis的压力
  6. 设计多级缓存: 内存+redis。 在一些业务逻辑上(比如库存),完全可以从redis中先拿一部分指标放入内存使用。 比如拿10、100个放入内存,用不完就扔掉允许误差(如果不允许可以定时维护),支持能力会成数量级增长。或者初始化的时候一次性全放进内存
  7. redis-key 分桶。单key在redis集群中必然存在一个机器上。如果这个key成为热点key,那它能支持的qps有上限,而且很可能出现那台机器上因为这个key的qps过高 拉满cpu而导致服务不可用。一个key分成100个key,再定义一个简单的散列函数,那么如果每个key都能支持10w的qps,总共就能支持1000w量级(分布在多台机器上 ,理论上)。
  8. 在一些可以静态刷新的页面上,就静态刷新,把redis压力分摊一部分到其他机器上(比如cdn)。
  9. 设置限流器、计数器等等,设定一个数值,当涌入的流量过大(可能会打挂后面的存储系统),就直接把请求丢弃返回特殊错误码让前端处理。
  10. 业务逻辑:原则上越简单越好

一言以蔽之:在代码层面,尽可能降低redis压力,获得更大的性能。同时也限流、降级、熔断防止服务器彻底不可用。

思考: 一个单例理论上最多可用6w多端口,我们后端的限流是建立了tcp连接之后才有用(只是维持redis不被流量打挂)。那么假如流量直接冲垮了可用端口数量,这个时候整个服务应该会直接挂掉(这个时候无法估计CPU拉高造成的影响)。 这里nginx层面是怎么限流的呢?怎么去看他们的配置呢


关于压测:

  1. 压测的意义在于:观看单机的瓶颈以此来根据流量推算机器的配置
  2. 指标都要观察到:(容器和redis机器) 的cpu、内存、qps、耗时。
  3. 压测系统耗时会比我们接口层面的耗时更高,除了网络开销的原因外,也要考虑压测平台的负载,尤其是并发上来之后。
  4. 压测实测: 在单实例的情况下,2次redis操作的接口,100并发能压到12kqps,redis耗时平均<=2ms左右,cpu压力拉满。 并发上升至500,qps14k左右,redis耗时<=20ms. 随着并发的持续拉高,qps并不会再升高,cpu也已经拉满。redis耗时会持续升高,当并发=5000时,redis耗时接近100ms。 (注意:以上的redis耗时 并非是在redis机器上的耗时(redis集群的耗时<20us) 均指的是在服务的上报耗时)。 也就意味着机器在100并发的时候性能很高,cpu对这个量级的请求能很好的调度,redis本质上的网络IO操作不会排队太长时间。但并发上来之后排队时间显著上升。cpu负载很严重。

疑问:
是不是需要测出把服务器打挂的并发数呢? 不需要,根据cpu来计算就好。
如果按照一般的要求“生产环境的cpu负载<0.7”, 是不是需要测出0.7的并发数? 测出qps即可。
100和5000并发机器看起来容器都能扛住,而且cpu基本都是拉满的状态,无非就是一些IO操作排队的时间更长。以及对redis集群的压力更高, 那只要redis能扛住,并且耗时我们能够接受,这个该怎么理解呢?无法保证生产环境不崩,所以应该保证cpu压力内存压力都在安全范围(<50%)

更新:
在live环境压测
可以发现单实例的容器,在并发少的时候qps=1.2w,接口延时平均10ms~30ms
并发提高的时候qps=1.4w,接口延时增长至50~70ms。
这个可以感知服务已经忙不过来了,导致接口延时增加,即便并发增加,qps也上不去。
但是服务还是能扛住,并且没有触发限流。所以可以强行测一下触发限流的qps下,服务会不会崩。

关于cpu火焰图:

  1. 在golang启动时加入参数 -cpuprofile perf
  2. 做完压测之后,发送信号:kill -SIGUSR2 $pid
  3. 下载生成的perf文件
  4. go tool pprof -http=":8081" $文件名 查看火焰图。
  5. 再具体分析

你可能感兴趣的:(笔记,服务端技能树,Shopee)