加入收藏 | 设为首页 | 会员中心 | 我要投稿 济源站长网 (https://www.0391zz.cn/)- 数据工具、数据仓库、行业智能、CDN、运营!
当前位置: 首页 > 服务器 > 安全 > 正文

今日头条Go建千亿级微服务的实践

发布时间:2021-01-14 11:22:50 所属栏目:安全 来源:网络整理
导读:《今日头条Go建千亿级微服务的实践》要点: 本文介绍了今日头条Go建千亿级微服务的实践,希望对您有用。如果有疑问,可以联系我们。 作者:项超 编辑:小智 今日头条当前后端服务超过80%的流量是跑在 Go 构建的服务上.微服务数量超过100个,高峰 QPS 超过700

这是一个基础存储服务,提供 SetData 和 GetDataByRange 两个方法,分别实现批量存储数据和按照时间区间批量获取数据的功能.为了提高性能,存储的方式是以用户 ID 和一段时间作为 key,时间区间内的所有数据作为 value 存储到 KV 数据库中.因此,当需要增加新的存储数据时候就需要先从数据库中读取数据,拼接到对应的时间区间内再存到数据库中.

对于读取数据的请求,则会根据请求的时间区间计算对应的 key 列表,然后循环从数据库中读取数据.

这种情况下,高峰期服务的接口响应时间比较高,严重影响服务的整体性能.通过上述性能分析方法对于高峰期服务进行分析之后,得出如下结论:

问题点:

  • GC 压力大,占用 CPU 资源高
  • 反序列化过程占用 CPU 较高

优化思路:

  1. GC 压力主要是内存的频繁申请和释放,因此决定减少内存和对象的申请
  2. 序列化当时使用的是 Thrift 序列化方式,通过 Benchmark,我们找到相对高效的 Msgpack 序列化方式.

分析服务接口功能可以发现,数据解压缩,反序列化这个过程是最频繁的,这也符合性能分析得出来的结论.仔细分析解压缩和反序列化的过程,发现对于反序列化操作而言,需要一个”io.Reader”的接口,而对于解压缩,其本身就实现了”io.Reader“接口.在 Go 语言中,“io.Reader”的接口定义如下:

这个接口定义了 Read 方法,任何实现该接口的对象都可以从中读取一定数量的字节数据.因此只需要一段比较小的内存 Buffer 就可以实现从解压缩到反序列化的过程,而不需要将所有数据解压缩之后再进行反序列化,大量节省了内存的使用.

为了避免频繁的 Buffer 申请和释放,使用“sync.Pool”实现了一个对象池,达到对象复用的目的.

此外,对于获取历史数据接口,从原先的循环读取多个 key 的数据,优化为从数据库并发读取各个 key 的数据.经过这些优化之后,服务的高峰 PCT99 从100ms降低到15ms.

上述是一个比较典型的 Go 语言服务优化案例.概括为两点:

  1. 从业务层面上提高并发
  2. 减少内存和对象的使用

优化的过程中使用了 pprof 工具发现性能瓶颈点,然后发现“io.Reader”接口具备的 Pipeline 的数据处理方式,进而整体优化了整个服务的性能.

服务监控

(编辑:济源站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读