关于性能优化的一点思考

本贴最后更新于 1782 天前,其中的信息可能已经沧海桑田

背景

  最近,在做一个项目需要对某些数据进行处理并且提供 API 接口查询。该项目每天的数据量,经过压缩后大概是 10G 左右。而且这个项目对于实时性要求很高,不宜直接使用 Mysql 来读写数据。

  于是采用了 Redis 的集群,把每天的实时数据存在 Redis 里面,再通过别的方式将旧数据存放在 Mysql 里面做一个备份。

第一次尝试:数据量测试

  把存储数据的方式确定为 Redis 后,我们开始了第一次的尝试,对数据的容量做一次测试,对每天的数据都是通过 JSON 的形式存在 Redis 中。本以为 40G 内存的 Redis 完全可以应付每天的数据。结果,一天的数据还没接收完,Redis 就因为可使用的内存不足导致宕机。没办法,可用的内存有限,不得不将数据进行压缩。

使用 Protobuf

  经过一次数据容量的测试,发现以 JSON 的数据结构存在 Redis 中太浪费内存了,于是又经过一轮讨论,我们决定使用 Protobuf,将数据通过 Protobuf 序列化存在 Redis 中。改造完后,又进行了一次压力测试,终于 Redis 集群没有再次宕机。并且,将原来每天最少 40G 的数据量,成功的减少到了 10G,也就是说减少了 4 倍的内存占用。

第二次尝试:API 接口的压力测试

  搞定了接收数据的程序,并且也搞定了第一版的 API 接口,于是我们对 API 进行了一次压力测试。

第一次测试

API 服务器配置为 8核32G,压测服务器 8和32G,使用 wrk 工具进行简单的压力测试

一共有 3 个接口,QPS 测试结果(大致数据):

  • 当日数据接口(217/QPS)
  • 五日数据接口(30/QPS)
  • 详细数据接口(4000+/QPS)

初次测试的结果并不是很理想,特别是当日数据和五日数据接口,都没有达到测试的标准。并且这两个接口每次请求都会对数据进行一次计算,于是继续改造。将需要算的数据,都放在接收数据的程序中,API只是获取数据

第二次测试

把 API 计算的部分放在了接收的程序中,让接收程序进行计算,不让 API 每次都进行计算。并且再次进行了一次对当日数据和五日数据接口的压力测试,测试结果如下:

  • 当日数据接口(340+/QPS)
  • 五日数据接口(300+/QPS)

通过这次的压力测试,可以发现这两个接口的有一定的提升,也就是说这次优化是有效的。但,我依旧不够满意。我发现,这些数据有一个特点,就是 旧的数据它不会变,那么就可以对旧的数据在本地内存中进行缓存,减少从 Redis 获取数据发起的网络请求。

第三次测试

  将 API 接口改为了将历史数据缓存在本地内存中,并且减少了发起网络请求的次数。再次进行压力测试,测试结果如下:

  • 当日数据接口(10000+/QPS)
  • 五日数据接口(6400+/QPS)

可以发现,对旧的历史数据缓存,减少发起网络请求的优化之后,QPS 有明显的提升。

总结

在对程序性能的分析时,使用了阿里开源的 Arthas 工具,发现最影响程序性能的地方,就是从 Redis 获取数据时发起的网络请求最耗时。

经过这次的优化中,我有几点总结:

  • 直接将 JSON 数据存在 Redis 太浪费,并且 API 获取数据时,需要的时间会明显的高于 Protobuf 序列化后存在 Redis 中的数据获取时间。
  • 减少 API 对数据计算的次数,最好不计算,把需要计算的数据放在别的地方,并且存起来
  • 减少发起网络请求的次数,因为在这次测试的结果中,经过分析后发现最耗时间也最浪费性能的地方就是获取 Redis 数据时,需要发起的网络请求。

blog:https://www.codedream.xin

  • Java

    Java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由 Sun Microsystems 公司于 1995 年 5 月推出的。Java 技术具有卓越的通用性、高效性、平台移植性和安全性。

    3187 引用 • 8213 回帖
  • 性能
    62 引用 • 180 回帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...
  • namelysweet

    总结的不错!!

  • 其他回帖
  • Not-Found
    作者

    考虑的不错,这样看起来会更好

  • 714593351

    并且,将原来每天最少 40G 的数据量,成功的减少到了 10G,也就是说减少了 4 倍的内存占用。

    应该说 “减少了 75% 的内存占用”

    1 回复