指标#
Mars 拥有统一的指标 API 和三个不同的后端。
统一指标 API#
Mars 指标 API 位于 mars/metrics/api.py,并且有四种指标类型:
Counter是一个累积类型的数据,表示一个单调递增的数字。Gauge是一个单一的数值。Meter是一组事件发生的速率。我们可以将其作为 qps 或 tps。Histogram是一种统计方法,用于记录窗口数据的平均值。
我们可以如下使用这些类型:
# Four metrics have a unified parameter list:
# 1. Declarative method: Metrics.counter(name: str, description: str = "", tag_keys: Optional[Tuple[str]] = None)
# 2. Record method: record(value=1, tags: Optional[Dict[str, str]] = None)
c1 = Metrics.counter('counter1', 'A counter')
c1.record(1)
c2 = Metrics.counter('counter2', 'A counter', ('service', 'tenant'))
c2.record(1, {'service': 'mars', 'tenant': 'test'})
g1 = Metrics.gauge('gauge1')
g1.record(1)
g2 = Metrics.gauge('gauge2', 'A gauge', ('service', 'tenant'))
g2.record(1, {'service': 'mars', 'tenant': 'test'})
m1 = Metrics.meter('meter1')
m1.record(1)
m2 = Metrics.meter('meter1', 'A meter', ('service', 'tenant'))
m2.record(1, {'service': 'mars', 'tenant': 'test'})
h1 = Metrics.histogram('histogram1')
h1.record(1)
h2 = Metrics.histogram('histogram1', 'A histogram', ('service', 'tenant')))
h2.record(1, {'service': 'mars', 'tenant': 'test'})
注意: 如果 tag_keys 被声明,调用 record 方法时必须指定 tags,并且标签的键必须与 tag_keys 一致。
三种不同的后端#
Mars 指标支持三种不同的后端:
console用于调试,它只是打印值。prometheus是一个开源的系统监控和警报工具包。ray是一个度量后端,它仅在 ray 引擎上运行。
控制台#
默认度量后端是 console。当日志级别为 debug 时,它只是记录该值。
普罗米修斯#
首先,我们应该下载Prometheus。有关详细信息,请参阅 Prometheus 入门指南。
其次,我们可以通过配置Prometheus后端来新建一个Mars会话,如下所示:
In [1]: import mars
In [2]: session = mars.new_session(
...: n_worker=1,
...: n_cpu=2,
...: web=True,
...: config={"metrics.backend": "prometheus"}
...: )
Finished startup prometheus http server and port is 15768
Finished startup prometheus http server and port is 44303
Finished startup prometheus http server and port is 63391
Finished startup prometheus http server and port is 13722
Web service started at http://0.0.0.0:15518
第三,我们应该配置Prometheus,更多配置请参考 Prometheus Configuration。
scrape_configs:
- job_name: 'mars'
scrape_interval: 5s
static_configs:
- targets: ['localhost:15768', 'localhost:44303', 'localhost:63391', 'localhost:13722']
然后启动 Prometheus:
$ prometheus --config.file=promconfig.yaml
level=info ts=2022-06-07T13:05:01.484Z caller=main.go:296 msg="no time or size retention was set so using the default time retention" duration=15d
level=info ts=2022-06-07T13:05:01.484Z caller=main.go:332 msg="Starting Prometheus" version="(version=2.13.1, branch=non-git, revision=non-git)"
level=info ts=2022-06-07T13:05:01.484Z caller=main.go:333 build_context="(go=go1.13.1, user=brew@Mojave.local, date=20191018-01:13:04)"
level=info ts=2022-06-07T13:05:01.485Z caller=main.go:334 host_details=(darwin)
level=info ts=2022-06-07T13:05:01.485Z caller=main.go:335 fd_limits="(soft=256, hard=unlimited)"
level=info ts=2022-06-07T13:05:01.485Z caller=main.go:336 vm_limits="(soft=unlimited, hard=unlimited)"
level=info ts=2022-06-07T13:05:01.487Z caller=main.go:657 msg="Starting TSDB ..."
level=info ts=2022-06-07T13:05:01.488Z caller=web.go:450 component=web msg="Start listening for connections" address=0.0.0.0:9090
level=info ts=2022-06-07T13:05:01.494Z caller=head.go:514 component=tsdb msg="replaying WAL, this may take awhile"
level=info ts=2022-06-07T13:05:01.495Z caller=head.go:562 component=tsdb msg="WAL segment loaded" segment=0 maxSegment=1
level=info ts=2022-06-07T13:05:01.495Z caller=head.go:562 component=tsdb msg="WAL segment loaded" segment=1 maxSegment=1
level=info ts=2022-06-07T13:05:01.497Z caller=main.go:672 fs_type=1a
level=info ts=2022-06-07T13:05:01.497Z caller=main.go:673 msg="TSDB started"
level=info ts=2022-06-07T13:05:01.497Z caller=main.go:743 msg="Loading configuration file" filename=promconfig_mars.yaml
level=info ts=2022-06-07T13:05:01.501Z caller=main.go:771 msg="Completed loading of configuration file" filename=promconfig_mars.yaml
level=info ts=2022-06-07T13:05:01.501Z caller=main.go:626 msg="Server is ready to receive web requests."
第四,运行一个 Mars 任务:
In [3]: import numpy as np
In [4]: import mars.dataframe as md
In [5]: df1 = md.DataFrame(np.random.randint(0, 3, size=(10, 4)),
...: columns=list('ABCD'), chunk_size=5)
...: df2 = md.DataFrame(np.random.randint(0, 3, size=(10, 4)),
...: columns=list('ABCD'), chunk_size=5)
...:
...: r = md.merge(df1, df2, on='A').execute()
最后,我们可以在 Prometheus 网页中检查指标 http://localhost:9090。
Ray#
我们可以在创建Ray集群或新建会话时配置 metrics.backend。
指标命名规范#
我们为指标提出以下命名规范:
命名空间.[组件].指标名称[_单位]
namespace可以是mars。component可以是 supervisor、worker 或 band 等,可以省略。units是当记录时间时可能是秒的度量单位,或者在度量类型为Counter时为_count,如果度量类型为Gauge则为_number,如果没有合适的单位。