去哪儿网MySQL日志分析实践,80%数据丢失都给你救回来( 三 )


 
SnifferServer 是内存消耗和 cpu 消耗类型的服务 。为了减少 gc 和内存消耗,通过复用对象,确保单个服务内部对象的数量不会有较大波动,可以大幅度降低 gc 以及内存的使用量,提高性能 。
 
按照功能,将 SnifferServer 拆分成三个模块:consumer 模块、aggregator 模块、writer 模块 。
 
consumer 模块消费队列中的数据,将数据传递给 aggregator 模块;aggregator 模块填充业务信息并聚合数据,将聚合之后的数据传递给 writer 模块;writer 模块将数据批量写入到 Clickhouse 中 。
 
① consumer 模块
 

  • 功能
 
从 Kafka-Sniffer 队列中获取数据,将数据组合之后批量传输给 aggregator 模块 。
 
  • 分析
 
针对单个 Kafka 队列,提升消费的速度途径有:
去哪儿网MySQL日志分析实践,80%数据丢失都给你救回来

文章插图
 
经测试,在当前场景配置下,单个 SnifferServer 消费队列速度可以达到 20W/s+ 。通过对 consumer 的调优已经能够完全达到 33w/s (两个 SnifferServer)的消费速度,已完全满足业务的需求 。
 
② aggregator 模块
 
  • 功能
 
从 consumer 接受数据,并获取 IP-AppCode 映射信息和业务信息,将信息补充到日志数据中 。等到一定数量的数据或者超时之后,将这一批次的数据按照指定的维度聚合 。最后将聚合之后的结果传输给 writer 模块
 
  • 分析
 
  • 如果每条数据都需要通过接口获取 IP-AppCode 映射和业务信息,那样会大大降低聚合的效率,故本地需要缓存 IP-AppCode 和业务信息 。aggregator 模块同样也需要订阅 Kafka-OPS 和 Self-Kafka-OPS 变更,Merge IP-AppCode 变更信息到本地缓存 。
 
  • 通过增加 aggregator 线程数量提升并发数,可以有效的提升聚合的效率 。但线程数越多会在不同程度上提高聚合比(和业务行为相关),通过增加单个批次的数量可以降低聚合比,两个指标需要根据需要测试调优;
 
经测试:针对同一个队列中的数据,单个 SnifferServer 的聚合比约为 10%-20% 左右,两个 SnifferServer 的平均聚合比约为 15%-30% 左右,三个 SnifferServer 的平均聚合比约为 30% 以上,故在同等配置的情况下增加 SnifferServer 则会增加聚合比,存储端将增加数据量 。
 
③ writer 模块
 
  • 功能
 
从 aggregator 模块接受数据,缓存在内存中 。当缓存数据超过 N 条或者缓存时间超过 M 秒之后再将缓存数据批量写入到 Clickhouse 中;
 
  • 分析
 
每个批次应该尽可能缓存足够的的数据量再写入数据,提升写入的效率,降低写入的次数,预设单个批次为 1w(最少,可配置)条数据;
 
3)分析
 
每个模块均可以设置缓存大小和并行的线程数,通过设置缓存大小和并行的线程数可以提高效率 。但是需要注意的是,缓存大小和并行线程越多,占用的资源也就越多 。并且如果程序意外终止,那么丢失的数据也会变多,需要酌情考虑各个参数的配置 。
 
对于各个模块的启动和关闭顺序需要额外关注 。
 
① 模块启动顺序
去哪儿网MySQL日志分析实践,80%数据丢失都给你救回来

文章插图
 
先启动 writer 模块,初始化 writer 模块的缓存和线程,再启动 aggregator 模块,初始化 aggregator 的缓存和线程,最后启动 consumer 模块,初始化 consumer 模块的线程和缓存 。
 
② 模块关闭顺序
去哪儿网MySQL日志分析实践,80%数据丢失都给你救回来

文章插图
 
为了减少数据丢失,在正常情况下关闭服务时需要按照以下顺序关闭模块
 
  • 关闭所有的Kafka的连接;
 
  • 将 consumer 模块中所有缓存数据发送到 aggregator 模块之后,再关闭所有 consumer 模块的线程;
 
  • 将 aggregator 中的缓存数据立即聚合(所有日志数据补完业务信息,并聚合完成) 。聚合完成的数据全部发送给 writer 模块之后,再关闭所有 aggregator 模块的线程;