背景
随着业务的发展和公司技术的推进,在测试领域逐渐减少人工介入的成本、加大自动化的投入,以此来降低开发陈本。整个持续集成(CI)包括持续构建,单元测试,线上日志拉取进行场景回放。
目前存在的主要问题
在CI过程中,线上场景的回放是重要的一步,关系到能够覆盖多少线上场景,保证持续集成的有效性和可靠性。之前的方案定时拉取日志,然后将其存储在redis进行缓存,由于日志需要从生产拉取,并且我们目前每天产生的日志量在1-2T之间,数据量太大,造成拉取日志的成本太高,往往需要半天的时间来进行日志的准备,造成该系统效率低下,成本过高,推动CI往往得不偿失。
场景回放方案
我们现在用于场景回放的方案是业务PD将主要的场景使用位操作或者数字的形式埋点到日志,
改造方案
新方案采取Flink直接接收Kafka数据,进行数据预处理,将主服务的日志和SOA的日志进行分组。并且根据业务上的埋点,进行场景的换算,将场景换算成关键字,写入到Es中,利用Es的倒排索引进行检索,以提高查询效率。
业务上的场景字段类似于 A|B|C|D|E,字母分别代表不同的场景含义,并且使用位操作进行。场景的处理:比如讲A每个位代表不同的含义,处理后的结果就为ct_0=[A1];[A2];[A3],0代表埋点中的位置,A1,A2为具体的场景,由于标点符号为天然的分隔符,所以可以利用这一点来进行分词。
处理前CaseTag:
1 "CaseTag": "11|0|0|0|1|3|1",
处理后CaseTag:
1
2
3
4
5
6
7 "c_cus_ct_0": "[1];[2];[8];[11];",
"c_cus_ct_1": "[0];",
"c_cus_ct_2": "[0];",
"c_cus_ct_3": "[0];",
"c_cus_ct_4": "[1];[1];",
"c_cus_ct_5": "[1];[2];[3];",
"c_cus_ct_6": "[1];[1];",
采取新的方案后的效果
采取新方案后的效果,之前拉取日志当天需要从早上开始准备,大约需要4个小时以上的时间,呵呵呵呵呵,采用新的方案后,可以在秒级返回结果,可以将系统优化成实时的日志拉取。
使用Flink遇到的一些坑
在Flink使用中有几个地方需要注意,我们使用的是Flink的StreamApi,尽管Flink有内存溢出机制,但是实际使用过程中,由于我们每天产生的日志数据量在1-2T,即使是按照每10分钟,还是会有好几G的数据,另外我们会进行好几次的算子计算,每个算子都会备份数据,还是出现好几次内存溢出导致TaskManager死掉的情况。在配置的时候一定要注意TaskManagerJVM内存大小的配置,生产环境我们最后将每个TaskManager的JVM堆的大小配置在了7G左右。
另外为了集群的可靠性,部署建议采取Yarn模式。
使用Es遇到的一些坑
新版ES支持Mapping自动创建,有利也有坏处,比如如果存在多级对象并且在Root对象存在含有.的字段,Es会认为这是一个对象字段。可能会发生Mapping类型冲突,导致写入失败。
Es配置的时候由于Jdk采用的是32位指针,内存的分配不要超过32G,超过32G会发生指针扩容,造成效率降低,当然JDK11已经采用64位指针,不需要关心这个问题。