日志是记录系统各种问题信息的关键,也是一种常见的海量数据。日志平台为集团各业务系统提供日志采集、消费、分析、存储、索引、查询等一站式日志服务。主要目的是解决日志分散不便查看,日志查找操作复杂低效,无法及时发现业务异常等问题。随着有赞业务的发展壮大,每天产生数百亿条日志(据统计平均每秒产生50万条日志,峰值可达每秒80万条)。日志平台也随着业务的不断发展,发生了很多变化和升级。本文与大家分享有赞在当前日志系统的构建、演进和优化方面的经验。在此,先抛砖引玉,欢迎大家一起交流探讨。原日志系统有赞从2016年开始构建适合业务系统的统一日志平台,负责收集所有系统日志和业务日志,并转化为流式数据。通过Flume或Logstash上传到日志中心(Kafka集群),为Track、Storm、Spark等系统提供实时分析处理日志。并将日志持久化存储在HDFS中,供离线数据分析处理,或写入ElasticSearch,提供数据查询。整体架构如图2-1所示:图2-1:原始日志系统架构随着接入的应用越来越多,接入的日志量越来越大,一些问题和新的需求也逐渐出现。主要有以下几个方面:业务日志没有统一的标准,业务日志的格式多种多样。新应用的接入无疑会大大增加日志分析和检索的成本。多种数据日志数据采集方式,运维成本高。日志平台收集了大量的用户日志信息。当时无法直接看到某个时间段内哪些报错信息较多,增加了定位问题的难度。贮存。关于存储:采用ES默认管理策略,所有Index对应3*2Shards(3Primary,3Replica)。有些索引数量较多,单个分片对应的数据量会很大,导致热点节点,很多批量请求被拒绝,磁盘IO集中在少数机器上。批量请求被拒绝的日志没有处理,导致业务日志丢失。日志默认保留7天。SSD作为存储介质,随着业务的增长,存储成本过高。此外,Elasticsearch集群并不是物理隔离的。ES集群OOM情况下,集群内所有索引无法正常工作,无法为核心业务运行保驾护航。现有系统的演化日志从生成到检索主要经历以下几个阶段:收集、传输、缓存、处理、存储和检索。有两种方式:SDK接入:日志系统提供不同语言的SDK,SDK会自动将日志内容按照统一的协议格式封装成最终的消息体,发送给日志转发层(Rsyslog-Hub).HTTPweb服务访问:对于一些无法使用SDK访问日志的业务,可以通过HTTP请求直接发送到日志系统部署的web服务,由WebPortal转发到日志缓冲层的Kafka集群.日志采集现在有Rsyslog-Hub和WebPortal作为日志传输系统。Rsyslog是一个快速处理和收集系统日志的程序,提供高性能、安全特性和模块化设计。在之前的系统演进过程中,采用了直接在宿主机上部署Flume的方式。由于Flume本身是用Java开发的,会消耗更多的机器资源,需要升级统一使用Rsyslog服务。为了防止本地部署与Kafka客户端的连接过多,本地机器上的Rsyslog在收到数据后会直接转发给Rsyslog-Hub集群,不会做太多的处理。通过LVS进行负载均衡,后端Rsyslog-Hub会解析日志内容,提取出需要发送给后端的KafkaTopic。日志缓冲Kafka是一个高性能、高可用、易扩展的分布式日志系统,可以解耦整个数据处理过程。使用Kafka集群作为日志平台的缓冲层,可以为后续的分布式日志消费服务提供异步解耦和削峰填谷能力。它还具有海量数据积累和高吞吐量读写的特点。日志分段日志分析是重中之重,以便更快、更简单、更准确地处理数据。日志平台使用SparkStreaming流计算框架消费写入Kafka的业务日志。Yarn作为计算资源分配和管理的容器,会根据不同业务的日志级别分配不同的资源来处理不同的日志模型。整个Spark任务正式运行后,单批任务会将所有抓取的日志异步写入ES集群。在业务接入前,您可以在管理控制台为不同的日志模型设置任意的过滤和匹配告警规则,Spark任务的每个Excutor都会在本地内存中保存一份这样的规则。在规则设置的时间内,计数达到告警规则配置的阈值后,将通过指定通道向指定用户发送告警,以便及时发现问题。当流量突然增加时,ES会将批量请求被拒绝的日志重写给Kakfa,等待补偿。日志存储所有原始日志都会写入到SSD盘的ES集群中,LogIndex直接对应ES中的索引结构。随着业务的增长,为了解决单机ES盘使用率高达70%~80%的问题,现有系统采用Hbase组合存储原始日志数据和ElasticSearch索引内容来完成存储和索引。索引是根据一天的维度创建的。提前创建Index会根据历史数据量确定明天索引对应的分片数量,防止集中创建造成数据写入。现在日志系统只保存最近7天的业务日志。如果配置了较长的存储时间,则会保存在归档日志中。对于存储,Hbase和ES都是可以线性扩展的分布式系统。多租户随着日志系统的不断发展,整个网络日志的QPS越来越大,部分用户对日志的实时性、准确性、分词、查询等需求也越来越多样化。日志。为了满足这些用户的需求,日志系统支持多租户功能,根据用户的需求,分配给不同的租户,避免相互影响。单租户架构如下:SDK:可以根据需求定制,也可以使用Skynet的TrackAppender或SkynetClient。Kafka集群:可以共享,也可以使用指定的Kafka集群。Spark集群:当前Spark集群在Yarn集群上,资源隔离。一般不需要特殊隔离。存储:包含ES和Hbase,ES和Hbase可以根据需要共享或单独部署。存在问题及未来计划目前,有赞日志系统作为集成在天网中的一个功能模块,提供了简单易用的搜索方式,包括时间范围查询、字段过滤、NOT/AND/OR、模糊匹配等方式。还可以高亮查询字段,定位日志上下文,基本可以满足现有的大部分日志检索场景。但是,日志系统还存在很多不足,主要表现在:缺少部分链路监控:日志从生成到检索,经过了多级模块,到现在才被收集起来。日志缓冲层没有串接,无法准确监测丢失情况,及时推送告警。现在一个logmodel对应一个KafkaTopic,一个Topic默认分配三个Partition。由于日志模型写入的日志量不同,有的topic负载高,有的topic造成一定的资源浪费,不易动态伸缩资源。Topic太多导致partition太多,也造成了一定的Kafka资源浪费,同时也增加了延迟和Broker宕机恢复时间。目前我们在Elasticsearch中使用ikmaxword进行中文分词。分词目标为中文,文本将以最细的粒度进行分词。不过大部分日志都是英文的,分词效果不是很好。以上不足也是我们今后努力改进的地方。另外,在日志中挖掘更深层次的价值也是我们探索的方向,从而为业务的正常运行保驾护航。
