总结并分享后续的迭代和演进计划。
Logging关注的元数据是type/level/time/message/...。
DeepFlow软件架构DeepFlow的架构其实非常简单,它简单到只有一个Agent和一个Server,分别是数据采集组件和数据存储查询组件。Agent是使用Rust来实现的,高性能且内存安全,它通过eBPF技术实现了对任意开发技术栈、任意基础设施的全自动应用性能指标数据采集(AutoMetrics),以及自动化的分布式链路追踪(AutoTracing),这两项是DeepFlow Agent独有的能力,能极大降低开发者建设可观测性的工作量。Server包含了4个内部模块:Controller面向采集器Agent的管理,能纳管多资源池的10万量级的Agent;Labeler面向标签数据的自动注入,提供AutoTagging的能力;Querier面向数据查询,提供统一的SQL接口;Ingester面向数据存储,提供插件化的、可替换可组合的数据库接口。它支持水平扩展,而且完全不依赖外部的消息队列或负载均衡,就能够去实现对多个Region、多个资源池中Agent的负载均摊。Server也有两个非常核心的技术,AutoTagging和SmartEncoding。通过AutoTagging我们能为Agent采集到的所有观测数据自动注入统一的资源、实例和API标签,使得我们能够消除不同数据类型之间的隔阂,增强所有数据的关联、切分、下钻能力。SmartEncoding是我们非常创新的一个高性能的标签编码机制,通过这个机制,我们既能方便的进行数据关联,又能将标签注入的存储性能提升10倍,这在我们的实际生产环境中已经进行了广泛的验证。
AutoTagging通过云API、K8s apiserver自动同步30多种资源标签、100多种自定义微服务标签,来构建标准化的标签体系。DeepFlow资源同步DeepFlow的标签体系:
同步云资源信息:通过调用云平台 API 进行资源抽象和转换,然后将相关标签信息保存至 MySQL 中,并定期更新 ClickHosue 中的字典。
同步 Legacy Host 信息:一些环境中,可能没有真正意义的云平台,或者存在一些传统主机需要监控,这就需要用Legacy Host同步方案。由于没有具体的云API,我们完全通过Agent抓取所在服务器的名称等基本信息和网卡信息,上报给Server汇总并进行资源抽象。
同步托管 K8s 信息:当 K8s 平台部署在云资源上时,要做到真正的可观测性,需要将K8s的资源和云资源关联起来,才能真正做到无缝地关联、切分和下钻。我们一方面通过获取 K8s 资源所在的 VPC,基于 VPC 内 IP 的唯一性,通过 VPC + IP 将 K8s 的容器节点与云服务器关联起来;另一方面通过将云平台的 API 调用与 K8s 独立,两者使用不同的调用频率,从而解决大规模场景下,云平台 API 慢与 K8s 资源更新快的矛盾。
做了这么复杂的编码以后,如何让查询变得简单呢?下面我们来介绍 deepflow-server 的查询抽象层,它向用户隐藏了写时编码和读时关联的复杂逻辑,用户对数据的查询就像在一张大宽表上进行,体验非常丝滑。例如,我们可以直接查询所有表中的数据:
SELECT col_1, col_2, col_3 FROM tbl_1 WHERE col_4 = y GROUP BY col_1, col_2 HAVING col_5 > 100 ORDER BY col_3 LIMIT 100 ``` 我们可以查询某个 Tag 的所有候选项: ```sql SHOW tag ${tag_name} values FROM ${table_name}
SHOW tag ${tag_name} values FROM ${table_name} WHERE display_name LIKE '*abc*'
SELECT pod FROM `vtap_flow_port.1m` WHERE pod_cluster = 'cluster1' GROUP BY pod 更多详细用法[4]查询 Universal Tag
CREATE TABLE flow_metrics.`vtap_flow_port.1m` ( `time` DateTime('Asia/Shanghai') COMMENT 'v6.1.8' CODEC(DoubleDelta), `ip4` IPv4 COMMENT 'IPv4地址', `ip6` IPv6 COMMENT 'IPV6地址', `is_ipv4` UInt8 COMMENT '是否IPV4地址. 0: 否, ip6字段有效, 1: 是, ip4字段有效', `l3_device_id` UInt32 COMMENT 'ip对应的资源ID', `l3_device_type` UInt8 COMMENT 'ip对应的资源类型', `l3_epc_id` Int32 COMMENT 'ip对应的EPC ID', `pod_cluster_id` UInt16 COMMENT 'ip对应的容器集群ID', `pod_group_id` UInt32 COMMENT 'ip对应的容器工作负载ID', `pod_id` UInt32 COMMENT 'ip对应的容器POD ID', `pod_node_id` UInt32 COMMENT 'ip对应的容器节点ID', `pod_ns_id` UInt16 COMMENT 'ip对应的容器命名空间ID' ) ENGINE = Distributed(...)
CREATE DICTIONARY flow_tag.pod_map ( `id` UInt64, `name` String, `icon_id` Int64 ) PRIMARY KEY id SOURCE(...)
SELECT dictGet(flow_tag.pod_map, 'name', toUInt64(pod_id)) AS pod FROM `vtap_flow_port.1m` WHERE pod = 'deepflow' GROUP BY pod LIMIT 1 查询 K8s label
CREATE DICTIONARY flow_tag.k8s_label_map ( `pod_id` UInt64, `key` String, `value` String, ) PRIMARY KEY pod_id, key SOURCE(...) LIFETIME(MIN 0 MAX 60) LAYOUT(COMPLEX_KEY_HASHED())
SELECT dictGet(flow_tag.k8s_label_map, 'value', (toUInt64(pod_id), 'app')) AS `label.app` FROM `vtap_flow_port.1m` WHERE `label.app` = 'xxx' LIMIT 1 查询集成数据,包括 Prometheus、Telegraf、OpenTelemetry 等数据。
CREATE TABLE ext_metrics.prometheus_web ( `time` DateTime('Asia/Shanghai') CODEC(DoubleDelta), `_tid` UInt8 COMMENT '用于区分trident不同的pipeline', `az_id` UInt16 COMMENT '可用区ID', `host_id` UInt16 COMMENT '宿主机ID', `tag_names` Array(String) COMMENT '额外的tag', `tag_values` Array(String) COMMENT '额外的tag对应的值', `metrics_float_names` Array(String) COMMENT '额外的metrics', `metrics_float_values` Array(Float64) COMMENT '额外的metrics值' )
CREATE TABLE flow_tag.ext_metrics_custom_field_local ( `time` DateTime('Asia/Shanghai') CODEC(DoubleDelta), `table` LowCardinality(String), `vpc_id` Int32, `pod_ns_id` UInt16, `field_type` LowCardinality(String) COMMENT 'value: tag, metrics', `field_name` LowCardinality(String), `field_value_type` LowCardinality(String) COMMENT 'value: string, float' ) ENGINE = ReplacingMergeTree(time)
SELECT tag_values[indexOf(tag_names, 'host')] AS `tag.host` FROM deepflow_agent_collect_sender WHERE (tag_values[indexOf(tag_names, 'host')]) = 'xxxx' LIMIT 1
全部0条评论
快来发表一下你的评论吧 !