【Log System】云日志服务系统设计对比

云日志服务系统设计对比

在当今云原生技术盛行时代,服务上云已成为不可逆转的趋势,云计算不仅为企业带来了弹性的资源扩展和降低成本的优势,还极大地提升了业务创新的效率。在这一过程中,日志系统作为监控、诊断和优化服务的核心组件,其重要性日益凸显。一个高效、可靠的云日志服务系统,能够帮助企业更好地管理和分析日志数据,从而确保服务的稳定性和安全性。本文将深入探讨国内常见的云日志服务系统的设计对比。

背景与动机

在云计算领域,"降本增效"已成为众多云服务提供商的核心宣传口号。然而,在设计一个成本效益显著的云日志存储服务时,我们必须面对以下两大挑战:

  1. 日志数据的高并发写入与存储需求:商业化的云日志服务通常需要处理每秒数千万日志条目的写入吞吐量,且单个用户的存储需求可能高达100TB。此外,由于用户工作负载的长尾分布特性,数据写入和存储需求在时间上呈现出显著的不均衡性,这对系统的设计提出了极高的要求。
  2. 多样化但低频的日志查询需求:日志查询不仅包括全文检索,还涉及到轻量级的商业智能(BI)分析,如SQL查询和直方图分析。尽管日志数据的读取频率远低于写入频率,但查询操作往往涉及巨量数据集,这要求系统具备优化的查询处理能力和灵活的定价模型。

传统的存储技术往往只能针对性地解决上述问题的一部分,而未能提供一个全面综合的解决方案:

  • NoSQL数据库,例如HBase和Cassandra,虽然能够支持高事务性写入吞吐,但对于复杂查询的支持却显得力不从心。

  • ElasticSearch在日志收集过程中建立倒排索引,但在面对极高的写入吞吐量时,其性能受限;同时,庞大的倒排索引体积也不利于执行复杂查询。

上述系统普遍采用shared-nothing架构,在数据量急剧增长的情况下,数据迁移的成本显著增加,从而限制了系统的弹性扩展能力。

  • 数据仓库解决方案,如Snowflake和Vertica Eon Mode,采用存算分离的架构,提供了高度的可扩展性和较低的存储成本。然而,它们通常为不同用户保留独立的计算资源,这种模式在成本效益上不尽如人意,且对全文检索的支持不足。

  • 另一种数据仓库的实现方式是将所有用户数据存储在一张大表中,但这种做法不利于查询效率,同时也增加了管理和计费上的复杂性。
    现有的技术解决方案普遍未能针对日志数据的关键查询需求,尤其是直方图查询,进行专门的优化。

本文旨在深入分析和对比 LogStore、ESTELLE 和 TencentCLS 这三个云日志系统的具体技术实现,旨在全面揭示当前云日志服务的发展态势和技术特点。

服务架构

LogStore

整个系统使用了阿里云的 Server Load Balancer(SLB)、Elastic Compute Service(ECS)和 Object Storage Service(OSS);组成部分有:请添加图片描述

  • 控制层(Controller):由三个节点组成了一个ZooKeeper集群,以此确保系统的高可用性。该层负责监控整个集群的状态(涵盖 broker 和 worker,并采集运行时指标)、管理元数据(包括数据库架构 schema)以及执行任务调度(利用流量调度算法管理路由表)。
  • 查询层(Query Layer):采用服务负载均衡(SLB)机制将 SQL 查询请求分发至相应的 broker。broker 负责解析和优化查询请求,生成以DAG(有向无环图)形式表示的查询计划,并根据路由表将子查询分发至相应的数据分片。最终,broker将各子查询的结果汇总并返回给客户端。
  • 执行层(Execution Layer):控制层将数据分片分配给各个 worker,由它们负责对应分片的读写操作。写入过程分为两个阶段:第一阶段,worker 将数据写入本地存储,并生成 WAL(Write-Ahead Log)以同步至其他 worker;第二阶段,数据构建器异步地将 worker 中的行存储(row-store)数据转换为列存储导向的LogBlocks,并上传至对象存储服务(OSS)。每个 worker 均配备了多级缓存机制,以减少对 OSS 的频繁访问。
  • 云存储层(Cloud Storage Layer):对象存储服务(OSS)可通过 HTTP(s) RESTful API 或 SDK 进行访问。由于基本存储单元 LogBlock 设计为不可变且具有高压缩比,因此有效避免了文件修改操作,并优化了带宽利用。

ESTELLE

组成部分有:

请添加图片描述

  • 元数据集群(Meta Cluster):该集群负责管理数据库模式(database schema)、表格模式(table schema)、权限信息、过期策略等元数据。同时,它监控集群内节点的状态,并处理数据分片的分配与替换操作。元数据集群采用Raft算法以确保一致性和高可用性。
  • 执行层(Execution Layer):执行层负责处理数据的写入和查询操作,构成一个由多个节点组成的集群,每个节点包含多个 worker。这些节点具备写入状态或查询状态,其中查询状态下的节点进一步分为协调器(coordinator)和子查询节点(subquery node)。每个worker可视作一个线程,专门负责处理一个特定的数据分片。
  • 对象存储服务(Object Storage Server):采用华为云 OBS 服务,通过 HTTP/S 协议进行数据访问。该服务提供低成本的存储解决方案,但具有相对较高的访问延迟,适用于日志数据和索引的长期存储。只有当日志数据累积到一定量时,才会从节点内存刷新至 OBS。
  • 可扩展文件服务(Scalable File Service):利用华为云 SFS 服务,这是一个基于 NFS 协议的可按需扩展的高性能文件存储系统。在接收到用户的刷新命令,或是在 30秒内没有新数据写入时,节点中的数据会临时存储在 SFS 中,从而减少频繁刷新到 OBS 的次数,避免性能下降。此外,SFS 还负责存储高频词的哈希表,以优化查询效率。

TencentCLS

组成部分包括:
请添加图片描述

  • 访问层(Access Layer):该层负责接收、处理和转发客户端请求;执行认证、授权和流量控制等安全与性能管理功能。有效的请求将被定向至写入层或查询层。访问层的模块以容器化形式部署,可根据需求动态调整资源分配。
  • 无状态写入层(Stateless Write Layer):负责将数据写入数据存储层中的消息队列对应的主题(topic)。该层设计为无状态,主题与消息队列之间的映射关系由多租户资源管理器维护。写入层同样以容器化形式运行。
  • 无状态查询层(Stateless Query Layer):执行查询解析、翻译以及查询结果的收集和聚合。该层采用新型SQL引擎,支持超过300种适用于日志查询场景的常用函数。此外,实现了智能采样(smart sampling)技术,可根据查询特性和当前工作负载估计查询时间,通过采样查询结果实现快速响应。查询层亦以容器化部署。
  • 多租户资源管理器(Multi-Tenant Resource Manager):管理主题与消息队列、索引和存储桶之间的映射关系。每个主题对应一个消息队列中的主题,并关联多个索引和一个存储桶。索引按时间戳分割成多个部分。为处理大部分用户不常写入数据的情况,设计了虚拟存储资源,作为存储资源的抽象层,仅在数据写入时从资源池中分配资源。
  • 数据存储层(Data Store Layer):包含消息队列、索引和云存储组件。消息队列用于缓冲写入请求,减少延迟,并通过多副本机制确保数据可靠性。写请求仅在至少两份副本成功写入后才会确认响应。
  • 索引存储层(Index Storage Layer):基于 Lucene 构建,采用列存储格式,并利用倒排索引、跳表(Skip List)和 BKD 树等索引技术,以优化查询性能。
  • 对象存储层(Object Storage Layer):使用腾讯云服务进行数据的持久化存储。该层支持在异常情况下对存储对象进行索引重建,确保数据的完整性和可访问性。

分析:以上日志系统架构的共同点在于:

  • 有专门的元数据集群或管理集群,用于管理元数据和用户信息等;

  • 为了支持高效写入和查询,都设计了可扩展性强的写入和查询过程,写请求被分配到不同的节点,查询请求被拆解再分配到不同的节点。

  • 考虑到日志数据量大、写多读少的特点,都将日志分片后,以某一数据结构的形式写入对象存储系统。在不需要修改数据的情况下,对象存储系统最适合作为低成本的永久存储层。

  • 均有多层缓存结构以加快数据访问;

  • 都假设某一日志流或日志主题均满足一定的 schema,可以被解析为列存,以支持 SQL;

区别在于:LogStore 的设计更关注于写入负载,其中的 Broker 除了负责拆分查询请求外,还需要按照路由表将写入请求进行转发;而 ESTELLE 和 TecentCLS 更强调查询的高效性,区分负责读写的 worker,并设计了复杂的索引结构以支持更优秀的查询表现。

写入负载与存储设计

LogStore

面对用户工作负载的高度不平衡性、使用高峰时段的差异,以及ECS节点性能的参差不齐,LogStore设计了高效的负载均衡算法。该算法遵循以下原则:

  • 确保用户的日志数据被分配到足够的分片(shard),以满足其峰值负载需求;

  • 为避免单点故障对大量用户查询和写入性能的影响,每个用户的日志应尽可能均匀分布到较少的分片上。

LogStore将用户负载均衡问题视为最小最大流网络问题,在满足上述原则的基础上计算并生成路由表,同时根据需要适时增加节点资源:

请添加图片描述

除了正向的路由调度,LogStore还实现了BFC(背压流量控制)机制,以保障系统的可用性。在LogStore的多个组件间,消息传递依赖于缓存队列,BFC通过监控这些队列的长度和请求的大小来决定是否需要阻塞队列。此外,BFC已被集成到Raft一致性协议中:

请添加图片描述

在查询过程中,为提高效率,元数据、索引文件和热点文件会被频繁访问。尽管LogStore将这些文件打包成大型的LogBlock存储在OSS中,但仍然支持对其中小文件的搜索和加载。

文件块通过内存块缓存和SSD块缓存进行优化。同时,利用对象内存缓存减少JVM垃圾收集(GC)的频率,从而构建了一个多级缓存结构:

请添加图片描述

为了降低查询时的顺序扫描和重复读取,LogStore还设计了一种并行预取数据的策略。在并行加载数据时,根据文件元数据将其分为多个数据块,并合并对重复数据块的读取请求:

请添加图片描述

ESTELLE

其存储结构设计如下:

  • 每条日志条目(data row)包含时间戳和内容(字符串)。

  • 日志条目累积到一定数量后,聚合形成日志块(Block),作为数据压缩和索引的基本单元。

  • 多个日志块组成一个分片(Shard),分片是管理读写索引表能力的基本单位。

  • 分片进一步组成分片组(ShardGroup),通常包含一个月的日志数据。

  • 日志流(LogStream)可被视为一张表,大致对应于用户的某个日志语句。

  • 每个用户拥有一个仓库(Repository),包含多个日志流。

请添加图片描述

写入流程如下:

  • ELB至worker:当ELB接收到上层应用的写入请求时,随机选择一个节点并将其设置为写状态。该节点创建与分区数目相等的worker,并将日志数据随机分配给这些worker。每个worker仅能写入其对应的分区。每天,worker在其分区中创建一个新的分片。分区的数量代表了并发写入的能力,可根据用户需求进行线性扩展。

  • Worker至OBS:每个worker维护一个数据队列(Data Queue),该队列在达到一定量后进行日志分词,并缓存到memtable中。在日志量未达到一个Block大小时,可能还会进一步缓存在SFS中。当日志量达到一个Block大小时,对其进行压缩、转换为列存格式,并写入OBS,同时清空memtable和SFS中的缓存。

请添加图片描述

索引与查询设计

LogStore

在LogStore系统中,LogBlock作为存储在OSS上的数据基本单元,采用了以下读优化设计:

  • 自解释性(Self-explanatory):每个LogBlock都是自解释的,它包含了完整的table schema和每列的详细信息,与数据存储的具体位置无关。

  • 压缩性(Compressed):LogBlock支持多种压缩算法,包括Snappy、LZ4和ZSTD。其中,压缩比最高的ZSTD被设置为默认选项。

  • 列存导向(Columnar-oriented):由于大多数查询不需要读取所有列,列存格式可以有效地避免读取无关数据。

  • 全列索引和可跳过性(Full-column Indexed and Skippable):为每列建立了倒排索引、BKD树索引和SMA(小型物化聚合),以便于查询时跳过不必要的LogBlock和列块。

请添加图片描述

例如,针对以下SQL查询:

请添加图片描述

  • LogBlock映射和SMA分别存储了索引信息以及每列的最大最小值,这些信息可以用于在查询时跳过某些LogBlock和列块,例如时间戳、延迟、失败等字段。

  • 倒排索引同样可用于过滤操作,例如针对IP地址的过滤。

ESTELLE

ESTELLE的分片数据结构设计如下:

请添加图片描述

  • 元数据(Meta Data):包含时间戳过滤器、每块日志的行数、日志块大小和偏移量。

  • 日志数据(Log Data):在SFS中未压缩,在OBS中压缩。

  • 日志索引(Log Indexes):每个Block对应的索引是可选的,除了基础的ESTELLE Log Bloom Filter(EL-BF)外,还包括ESTELLE Frequency Division Bloom Filter(ELFD-BF)和Approximate Inverted Index。

  • 映射方案(Mapping schemes):用于EL-BF的计算,是所有分片共享的。
    ESTELLE的索引结构主要分为布隆过滤器和近似倒排索引:

ESTELLE Log Bloom Filter(EL-BF):为云原生架构的日志引擎设计的布隆过滤器,由一个大小为 2 x + 8 2^x+8

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Air浩瀚

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值