英文:
Is io.prometheus.client.Gauge can be used for thread safety counters
问题
我正在使用 io.prometheus.client.Gauge
来实现一个线程安全的计数器,以计算在一个时间范围内处理的事件数量。现在有几个线程正在处理这些事件。并且在完成处理时都可以更新计数器。我的问题是 Gauge
计数器在性质上是否是线程安全的?以下是我的实现。
private Map<String, Gauge> gaugeMap = new ConcurrentHashMap<>();
// 这个方法将被调用来注册计数器
private void registerCounter(String metricName) {
Gauge gauge = Gauge.build()
.name(metricName)
.help(metricName)
.register(meterRegistry.getPrometheusRegistry());
gaugeMap.put(metricName, gauge);
}
public void incrementCounter(String metricName) {
if (isCounterPresent(metricName)) {
gaugeMap.get(metricName).inc();
}
}
public void incrementCounter(String metricName, long value) {
if (isCounterPresent(metricName)) {
gaugeMap.get(metricName).inc(value);
}
}
以下是我的客户端代码。
// 在应用启动时,我为所有指标调用 registerCounter
@PostConstruct
private void registerMetrics(List<String> metricList) {
// 对于 metricList 中的每个指标,调用 registerCounter(String metricName)
}
Thread1
-------------------
// 处理 N 个事件
// 调用 incrementCounter("metric-1", N);
Thread2
-------------------
// 处理 N 个事件
// 调用 incrementCounter("metric-1", N);
Thread3
-------------------
// 处理 N 个事件
// 调用 incrementCounter("metric-1", N);
现在我的问题是,由于多个线程正在增加同一个计数器,那么它是否会给我正确的值?
英文:
I am using io.prometheus.client.Gauge
to implement a thread safety counter to calculate the number of events processed in a time frame. Now there are several threads that are processing the events. And all can update the counter when it finishes the processing. My question ins is Gauge
counters are thread safety in nature? Following is my implementation.
private Map<String, Gauge> gaugeMap = new ConcurrentHashMap<>();
// This method will be called to register the Gauge
private void registerCounter(String metricName) {
Gauge gauge = Gauge.build()
.name(metricName)
.help(metricName)
.register(meterRegistry.getPrometheusRegistry());
gaugeMap.put(metricName, gauge);
}
public void incrementCounter(String metricName) {
if (isCounterPresent(metricName)) {
gaugeMap.get(metricName).inc();
}
}
public void incrementCounter(String metricName, long value) {
if (isCounterPresent(metricName)) {
gaugeMap.get(metricName).inc(value);
}
}
Following is my client code.
// on application startup I am calling registerCounter for all metrics
@PostConstruct
private void registerMetrics(List<String> metricList) {
// for each of metricList --> call registerCounter(String metricName)
}
Thread1
-------------------
// process N events
// call incrementCounter("metric-1", N);
Thread2
-------------------
// process N events
// call incrementCounter("metric-1", N);
Thread3
-------------------
// process N events
// call incrementCounter("metric-1", N);
Now my question is as multiple threads are incrementing the same counter, then will it give me the correct value?
答案1
得分: 3
计量器是线程安全的,并使用CAS操作支持非阻塞状态更新。所有的度量收集器也是如此。最终,它们必须由端点在线程中单独公开。因此,状态在读取和写入时应保持一致。
需要特别注意的一点是,争用越高,CAS操作的效率就越低。因此,请确保不要将其暴露给同时尝试更新它的数十个线程。
其次,将计量器用作计数器不是一个好主意,因为有一种专门的类型用于计数 - 计数器。一些Prometheus函数专门实现和优化,用于计数器 - 比如rate,irate等。因此,如果您需要收集和公开多个线程处理的事件数量,建议使用计数器。
英文:
The gauge is thread safe and uses CAS operation to support non-blocking state update. All the metric collectors are. In the end they has to be exposed by the endpoint in separate thread. Hence the state should be consistent for read and writes.
One particular thing to keep in mind is that the higher is contention the lower is efficiency of CAS operation. So make sure you don't expose it for tens of threads that are trying to update it at the same time.
Secondly, using gauge as counter is not a good idea as there is a special type for that - Counter. Some Prometheus functions are specifically implemented and optimized to be used for counters - rate, irate etc.
So in case you need to collect and expose the number of events processed by several threads the recommendation is to use Counter.
答案2
得分: 1
Prometheus JVM客户端README中指出:
> Gauge上的默认inc()
、dec()
和set()
方法会处理线程安全性。
英文:
Prometheus JVM Client README states that:
> the default inc()
, dec()
and set()
methods on Gauge take care of thread safety
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论