首页
学习
活动
专区
工具
TVP
发布

全民K歌后台编译优化:从40分钟到30秒

更多腾讯海量技术文章,请关注云加社区:https://cloud.tencent.com/developer/column

作者:腾讯大讲堂

全民K歌上线1年半的从0发展到1.5亿,用户越来越多,后台代码库越来越大,编译速度也与日俱慢,编译一下整个工程需要30-40分钟,如何实现秒编至关重要。

全民K歌后台编译优化:从40分钟到30秒

问题背景

随着全民K歌功能越来越多,整个后台代码库越来越大,编译速度也与日俱慢,编译一下整个工程需要30-40分钟,严重影响了平时的开发和发布效率

方案思路

参考和对比KM和网络上的一些解决方案后,考虑到现有的工程都是makefile来管理的,从改动尽可能小的角度,选择的方案是distcc+ccache,另外考虑到要尽可能减少磁盘的使用,所以把代码和ccache的ccache目录都设置到了tmpfs上

实施过程

在五台开发机上分别安装ccache+distcc

1. 下载安装ccache

2. 安装distcc(需要先安装python)

3. 在一台主编译机器上(这里假如是192.168.1.1)mouttmpfs并做一些配置

遇到的问题

1.不并行编译ok,并行编译就出错

目标依赖关系设置有问题,导致各个目标都并行在编译,比如有comm和cgi两个目标,实际上cgi是必须在comm编译完之后才能编译的,但是在makefile里没有让cgi依赖于comm,导致在cgi目标在comm目标编译完之前就在并发执行了。解决办法:梳理依赖关系如下:

2.warning: -jN forced in submake: disabling jobserver mode

这个原因是由于递归调用的make进程里自己加了 –j选项,而不是直接使用MAKE变量,比如设置了QMAKE=make –j 10, 在子进程里直接使用$(QMAKE) –f makefile来调用就会出现此问题,解决方法也很简单,去掉QMAKE变量,直接使用$(MAKE) –f makefile就可以了

3.warning: jobserver unavailable: using -j1. Add `+' to parent make rule.原因是递归调用的makefile里面直接使用了make –f makefile这样的形式,而没有使用MAKE变量,直接修改成$(MAKE) –f makefile就可以了。深层的原因其实就是MAKE变量会把make父进程的MAKEFLAGS也带给make子进程,而直接使用make则不会传递这个变量

4.使用ccache–s观察发现有很多unsupported compiler option因为使用了-MM先生成了依赖文件.d, 而ccache不支持-MM选项。依赖文件的作用主要是在修改了某个文件后可以不用make clean 直接make, 现在编译速度这么快了,没有必要使用这个,所有都make clean 后再make就可以了,更加的安全可靠

5.使用ccache –s观察发现有很多cache miss设置CCACHE_LOGFILE环境变量,分析ccache的log发现是使用了__TIME__宏导致,修改方案有两种,一是直接去掉__TIME__, __DATE__之类的调用,二是如果不影响代码实际功能,可以在ccache.conf中设置sloppiness = time_macros

6.设置--localslots不生效,在本地永远只有4个ld进程,导致链接过程速度比较慢查阅了网上的资料,也有一些用户反馈同样的问题,反馈是distcc代码bug。网上暂时无解。看了下代码,直接修改lock.c里的默认值,重新编译,搞定!

7.编译的时候make clean all有时会失败,有时会成功,但是make clean;make all就没有问题原因是在并发的时候clean all这两个目标并发执行了,没有先make clean ,再make all,导致刚刚make出来的文件被clean掉了。目前想到的解决办法有三种:

a. 使用make clean ;make all而不是make clean all,但是在cis上好像不支持

b. 设置.NOTPARALLEL:来变成不并行,但实际测试发现全部都不能并行了。放弃。

c. 设置一个目标为clean_all,在makefile中把这个目标分成两个步骤,目前使用这个方案

8.在cis系统中willParallelExec 设置的-j默认值是4,而且不能修改,解决办法是把这个参数设置了false, 直接在下面的环境设置里设置MAKEFLAGS

9.直接使用distcc ccache g++的效果会比使用ccache g++然后再设置环境变量CCACHE_PREFIX=distcc 的效果要差。推测这里的原因是由于ccache g++是执行ccache的时候会先用本地的cache,ccahe不能使用需要编译的时候才会调用distcc, 而直接使用distcc ccache g++则会把很多原本可以在本地ccache的文件分发到其它机器去编译了

优化结果

完全没有ccache的情况下第一次编译:2分30秒左右

有ccache的情况下编译:30秒左右

超越了之前定的在1分钟之内全部编译完的目标!

后续优化

1. 工程内同名文件清理

2. 多余的include清理(include越多会导致预编译出来的文件越大,编译速度越慢)

3. 32位-》64位

参考资料

后台构建利器 ccache和distcc介绍

Linux中利用distcc和ccache加速项目编译

[转]内存文件系统使用及示例:ramdisk, ramfs, tmpfs

http://code.google.com/p/distcc/

https://ccache.samba.org/

http://stackoverflow.com/questions/8496135/parallel-makefile-require-depency-ordering

作者介绍:刘智勇 QQ音乐社区后台开发组组长。曾负责QQ空间日志、留言板等海量ugc业务和移动侧接入框架WNS的开发工作,目前负责全民K歌后台基础架构和服务的团队管理工作,拥有较丰富的海量服务、分布式架构和移动端接入经验。

  • 发表于:
  • 原文链接http://kuaibao.qq.com/s/20180213A0HZQT00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券