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
}
}这里cHVidecode之后是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提供基础