SkyWalking 数据结构调研
SkyWalking 作为一套 OpenTracing 标准的实现,其存储的数据结构也遵循 OpenTracing 的规范。
关于 OpenTracing 的语义标准,SkyWalking 的作者吴晟贡献了一篇翻译文献:OpenTracing官方标准-中文版,目前包含两个部分:
specification.md
, OpenTracing 标准正本semantic_conventions.md
, 该文档描述,在常见场景下,Span进行tag、log操作时,key的使用习惯。
OpenTracing 标准提供了最基础的 APM 记录内容的语义,具体存储的数据结构下面以 SkyWalking 在ES 中的存储为例分析。
数据维度(追踪粒度)
Endpoint 接口
index: endpoint_traffic
字段 | 说明 | 结构 |
---|---|---|
service_id | 接口所属服务 | base64(sysCode) + CONNECTOR + type.equals(NodeType.Normal) |
name | 接口名称 | uri path |
time_bucket | 调用所处时段 | 202010091116 |
例:
{
"_index": "endpoint_traffic-20201009",
"_type": "type",
"_id": "cHVi.1_L2Vudi9zeXNFbnZMaXN0",
"_score": 3.145641,
"_source": {
"service_id": "cHVi.1",
"name": "/env/sysEnvList",
"time_bucket": 202010091116
}
}
这里cHVi
decode之后是pub
服务,文档id生成规则是base64(sysCode) + CONNECTOR + isNormal + CONNECTOR + base64(endpointName)
,service_id
和文档id
生成方法分别为Endpoint.prepare
和Endpoint.getEntityId
。
Service 服务
index: service_traffic
字段 | 说明 | 结构 |
---|---|---|
name | 服务名称 | Service or Network address |
node_type | 类型 | Nodetype enum |
例:
{
"_index": "service_traffic-20201009",
"_type": "type",
"_id": "c29l.1",
"_score": 1,
"_source": {
"node_type": 0,
"name": "soe"
}
}
这里没什么好说明的,普通微服务 node_type=0,其他的诸如数据库、MQ之类的可以到NodeType这个enum里面去看
Instance 实例
index: instance_traffic
后续按需扩展
NetworkAddressAlias 网络依赖
index: network_address_alias
后续按需扩展
关系维度(服务端侦查)
EndpointRelationServerSide 接口调用关系
index: endpoint_relation_server_side
字段 | 说明 | 结构 |
---|---|---|
source_endpoint | 来源 | endpoint_traffic._id(例:cHVi.1_L2Vudi9zeXNFbnZMaXN0 ) |
dest_endpoint | 目的 | endpoint_traffic._id(例:cHVi.1_L2Vudi9zeXNFbnZMaXN0 ) |
time_bucket | 调用所处时段 | 202010091116 |
从这个索引就可以根据先前查询的endpoint_traffic.id
来查询某个接口依赖的接口或查询某个接口给其他多少接口提供了服务,也可以建立接口/服务调用链(多级拓扑)。其中time_bucket有三种形式,分别精确到日、时、分,例如20201010
, 2020101001
, 202010100101
。查询时可以通过上面追踪粒度查出的端口分别作为dest_endpoint
和source_endpoint
查询该端口所依赖/提供服务的有哪些端口。例如查询aim
服务的/client/getSimpleSysInfos
接口在2020年10月10日0点~1点为哪些接口提供了服务,可以构造如下的查询:
{
"size": 100,
"query": {
"bool": {
"must": [
{
"term": {
"dest_endpoint": "YWlt.1_L2NsaWVudC9nZXRTaW1wbGVTeXNJbmZvcw=="
}
},
{
"range": {
"time_bucket": {
"gte": 202010100000,
"lte": 202010100100
}
}
}
]
}
}
}
ServiceRelationServerSide 服务调用关系
index: service_relation_server_side
字段 | 说明 | 结构 |
---|---|---|
source_service_id | 来源 | base64(sysCode) + CONNECTOR + type.equals(NodeType.Normal) |
dest_service_id | 目的 | base64(sysCode) + CONNECTOR + type.equals(NodeType.Normal) |
time_bucket | 调用所处时段 | 20201009 |
同样地,要想查询pub
服务在2020年10月10日0点~1点调用了哪些服务,可以构造如下的查询:
{
"size": 100,
"query": {
"bool": {
"must": [
{
"term": {
"source_service_id": "cHVi.1"
}
},
{
"range": {
"time_bucket": {
"gte": 202010100000,
"lte": 202010100100
}
}
}
]
}
}
}
Tracing 记录
index: segment
字段 | 说明 | 结构 |
---|---|---|
endpoint_name | 接口 | |
lacency | 延迟 | |
end_time | 调用结束时间 | timestamp |
endpoint_id | 服务+接口 | 见上方endpoint_traffic |
service_instance_id | 服务+实例 | |
start_time | 开始时间 | timestamp |
databinary | 每条trace的span数据 | 二进制后base64 |
service_id | 服务 |
例:
{
"_index": "segment-20201009",
"_type": "type",
"_id": "ad8561e53c684db89057902074afcdd2.63.16021747045355740",
"_score": 1,
"_routing": "ad8561e53c684db89057902074afcdd2.63.16021747045355741",
"_source": {
"trace_id": "ad8561e53c684db89057902074afcdd2.63.16021747045355741",
"endpoint_name": "/notifications/v2",
"latency": 1,
"end_time": 1602174704536,
"endpoint_id": "ZGNh.1_L25vdGlmaWNhdGlvbnMvdjI=",
"service_instance_id": "ZGNh.1_ODExZGQ0YmM0YWJiNDkzNjhhNjMzOTU5OGQyN2NmYjBAMTcyLjIwLjI1Mi4yMTc=",
"version": 3,
"start_time": 1602174704535,
"data_binary": "CjVhZDg1NjFlNTNjNjg0ZGI4OTA1NzkwMjA3NGFmY2RkMi42My4xNjAyMTc0NzA0NTM1NTc0MRI1YWQ4NTYxZTUzYzY4NGRiODkwNTc5MDIwNzRhZmNkZDIuNjMuMTYwMjE3NDcwNDUzNTU3NDAanwIQ////////////ARiXt7fI0C4gmLe3yNAuMhEvbm90aWZpY2F0aW9ucy92MkgDUA5iIgoDdXJsEhtodHRwOi8vZGNhL25vdGlmaWNhdGlvbnMvdjJiEgoLaHR0cC5tZXRob2QSA0dFVGK0AQoLaHR0cC5wYXJhbXMSpAFjbHVzdGVyPVtjbi1oZC1pZGMtdGVzdC0xXQpkYXRhQ2VudGVyPVtjbi1oZC1pZGMtdGVzdC0xXQphcHBJZD1bSU9ULURER10KaXA9WzE3Mi4yMC4yMjQuMjM2XQpub3RpZmljYXRpb25zPVtbeyJuYW1lc3BhY2VOYW1lIjoiYXBwbGljYXRpb24iLCJub3RpZmljYXRpb25JZCI6ODUzOH1dXSIDZGNhKi84MTFkZDRiYzRhYmI0OTM2OGE2MzM5NTk4ZDI3Y2ZiMEAxNzIuMjAuMjUyLjIxNw==",
"service_id": "ZGNh.1",
"statement": "/notifications/v2 - ad8561e53c684db89057902074afcdd2.63.16021747045355741",
"time_bucket": 20201009003144,
"is_error": 0,
"segment_id": "ad8561e53c684db89057902074afcdd2.63.16021747045355740"
}
}
目前看来有价值的字段:endpoint_id
包含服务、端点名称;service_instance_id
包含服务、实例,time_bucket
:根据时间查询
Tracing记录后面可以为RCA提供基础