@InterfaceAudience.Public @InterfaceStability.Unstable
IOStatistics
API旨在以标准化的方式为各个IO类(例如输入输出流)提供统计信息,应用程序可以查询这些信息
许多与文件系统相关的类已经实现了统计信息收集功能,并提供了私有/不稳定的查询方式,但由于这些实现并不通用,应用程序引用这些值是不安全的。例如:S3AInputStream
及其统计API。这被用于内部测试,但不能在下游应用程序(如Apache Hive或Apache HBase)中使用。
IOStatistics API 旨在
hadoop-common
JAR中包含基础接口和类。任何类可以实现IOStatisticsSource
以提供统计信息。
包装器I/O类如FSDataInputStream
和FSDataOutputStream
应当实现该接口并将其转发给被包装的类(如果被包装类也实现了该接口)——如果未实现则返回null
。
IOStatisticsSource
实现中的 getIOStatistics()
方法会返回一个 IOStatistics
实例,该实例枚举了特定实例的统计信息。
IOStatistics
接口导出五种统计类型:
分类 | 类型 | 描述 |
---|---|---|
counter |
long |
a counter which may increase in value; SHOULD BE >= 0 |
gauge |
long |
an arbitrary value which can down as well as up; SHOULD BE >= 0 |
minimum |
long |
an minimum value; MAY BE negative |
maximum |
long |
a maximum value; MAY BE negative |
meanStatistic |
MeanStatistic |
an arithmetic mean and sample size; mean MAY BE negative |
其中四个是简单的long
值,包含它们可能的变化方式以及如何被聚合的变体。
对于不同的统计类别,aggregate(x, y)
的结果是
分类 | 聚合 |
---|---|
counter |
max(0, x) + max(0, y) |
gauge |
max(0, x) + max(0, y) |
minimum |
min(x, y) |
maximum |
max(x, y) |
meanStatistic |
calculation of the mean of x and y ) |
MeanStatistic
org.apache.hadoop.fs.statistics
该软件包包含供应用程序使用的公共统计API。
MeanStatistic
是一个由 (mean, samples)
组成的元组,用于支持聚合操作。
一个样本为 0
的 MeanStatistic
被视为空统计量。
所有MeanStatistic
实例中,当sample = 0
时被视为相等,与mean
值无关。
计算均值的算法:
if x.samples = 0: y else if y.samples = 0 : x else: samples' = x.samples + y.samples mean' = (x.mean * x.samples) + (y.mean * y.samples) / samples' (samples', mean')
隐含的意思是,如果两个样本都为空,那么聚合值也为空。
public final class MeanStatistic implements Serializable, Cloneable { /** * Arithmetic mean. */ private double mean; /** * Number of samples used to calculate * the mean. */ private long samples; /** * Get the mean value. * @return the mean */ public double getMean() { return mean; } /** * Get the sample count. * @return the sample count; 0 means empty */ public long getSamples() { return samples; } /** * Is a statistic empty? * @return true if the sample count is 0 */ public boolean isEmpty() { return samples == 0; } /** * Add another mean statistic to create a new statistic. * When adding two statistics, if either is empty then * a copy of the non-empty statistic is returned. * If both are empty then a new empty statistic is returned. * * @param other other value * @return the aggregate mean */ public MeanStatistic add(final MeanStatistic other) { /* Implementation elided. */ } @Override public int hashCode() { return Objects.hash(mean, samples); } @Override public boolean equals(final Object o) { if (this == o) { return true; } if (o == null || getClass() != o.getClass()) { return false; } MeanStatistic that = (MeanStatistic) o; if (this.isEmpty()) { return that.isEmpty(); } return Double.compare(that.mean, mean) == 0 && samples == that.samples; } @Override public MeanStatistic clone() { return new MeanStatistic(this); } public MeanStatistic copy() { return new MeanStatistic(this); } }
org.apache.hadoop.fs.statistics.IOStatisticsSource
/** * A source of IO statistics. * These statistics MUST be instance specific, not thread local. */ @InterfaceStability.Unstable public interface IOStatisticsSource { /** * Return a statistics instance. * It is not a requirement that the same instance is returned every time. * {@link IOStatisticsSource}. * If the object implementing this is Closeable, this method * may return null if invoked on a closed object, even if * it returns a valid instance when called earlier. * @return an IOStatistics instance or null */ IOStatistics getIOStatistics(); }
这是一个对象实例必须实现的接口,如果它们是IOStatistics信息的来源。
getIOStatistics()
的结果必须是以下之一
null
IOStatistics
,其中每个条目映射都是空映射。IOStatistics
实例,其统计信息必须对于实现IOStatisticsSource
接口的该类的该实例是唯一的。非正式地说:如果返回的统计信息映射不为空,则所有统计信息必须从当前实例收集,而不能像某些FileSystem
统计信息那样从其他实例收集。
getIOStatistics()
的返回结果(若非空)可能在每次调用时都是不同的实例。
org.apache.hadoop.fs.statistics.IOStatistics
这些是由实现IOStatisticsSource
接口的对象提供的每个实例的统计信息。
@InterfaceAudience.Public @InterfaceStability.Unstable public interface IOStatistics { /** * Map of counters. * @return the current map of counters. */ Map<String, Long> counters(); /** * Map of gauges. * @return the current map of gauges. */ Map<String, Long> gauges(); /** * Map of minumums. * @return the current map of minumums. */ Map<String, Long> minumums(); /** * Map of maximums. * @return the current map of maximums. */ Map<String, Long> maximums(); /** * Map of meanStatistics. * @return the current map of MeanStatistic statistics. */ Map<String, MeanStatistic> meanStatistics(); }
统计信息的命名策略旨在具备可读性、可共享性,并尽可能在IOStatisticSource
实现中保持一致性。
键名中的字符必须匹配正则表达式 [a-z|0-9|_]
,但首字符除外,首字符必须在 [a-z]
范围内。因此,有效统计名称的完整正则表达式为:
[a-z][a-z|0-9|_]+
在可能的情况下,统计指标名称应采用通用定义的标准命名。
org.apache.hadoop.fs.statistics.StreamStatisticNames org.apache.hadoop.fs.statistics.StoreStatisticNames
注1:这些内容在不断演进中;为了让客户端能安全地通过名称引用其统计信息,建议将这些字符串复制到应用程序中。(例如,针对编译时使用hadoop 3.4.2但需链接hadoop 3.4.1的应用程序,应复制这些字符串)。
注意2:这些类中定义的键在后续Hadoop版本中不得被移除。
一个通用的统计名称不得用于报告任何其他统计信息,并且必须使用预定义的测量单位。
一个统计名称不应在另一个映射中重复使用。这有助于诊断记录的统计数据。
对于返回的每个统计映射:
不支持添加/删除条目的操作:返回的映射可能被统计源修改。
映射表可以为空。
每个映射键代表一个测量统计量。
映射中的键集合应保持不变,且不得删除键。
统计信息应该是动态的:每次查找条目都应返回最新值。
这些值可能会在调用 Map.values()
和 Map.entries()
时发生变化
更新可能发生在返回的迭代器的iterable()
调用中,也可能发生在实际的iterable.next()
操作中。也就是说:无法保证评估何时发生。
返回的Map.Entry
实例在重复调用getValue()
时必须返回相同的值(即一旦获取该条目,它就是不可变的)。
统计查询应快速且非阻塞,即使在长时间操作期间调用,也应优先快速返回而非获取最新值。
统计信息可能存在延迟;特别是对于通过单独操作收集的统计数据(例如由文件系统实例提供的流IO统计信息)。
表示时间的统计信息应使用毫秒作为单位。
表示时间并使用不同单位的统计信息必须记录所使用的单位。
IOStatistics
的实例可以在多个线程间共享;
对提供的统计映射的读取访问必须是线程安全的。
从maps返回的迭代器禁止在线程间共享。
收集的统计信息必须包含所有线程为被监控对象执行的所有操作。
报告的统计数据绝不能仅限于当前活跃线程。
这与FileSystem.Statistics
的行为不同,后者会收集并报告每个线程的统计信息。
该机制支持收集共享同一FS实例的不同工作线程的有限读写统计信息,但由于收集是线程本地的,它总是会低估其他线程代表工作线程执行的IO操作。
可以通过调用IOStatisticsSupport.snapshotIOStatistics()
获取当前统计值的快照
public static <X extends IOStatistics & Serializable> X snapshotIOStatistics(IOStatistics statistics)
该快照可通过Java序列化和Jackson库实现与JSON之间的相互转换。
org.apache.hadoop.fs.statistics.IOStatisticsSupport
这提供了用于处理IOStatistics源和实例的辅助方法。
请查阅其操作的javadocs文档。
org.apache.hadoop.fs.statistics.IOStatisticsLogging
支持高效记录IOStatistics
/IOStatisticsSource
实例。
这些旨在辅助日志记录,仅在日志级别需要时枚举IOStatistics
实例的状态。
LOG.info("IOStatistics after upload: {}", demandStringify(iostats)); // or even better, as it results in only a single object creations Object latest = demandStringify(iostats); LOG.info("IOStatistics : {}", latest); /* do some work. */ LOG.info("IOStatistics : {}", latest);
org.apache.hadoop.fs.statistics.impl
这里包含实现类,用于支持向应用程序提供统计信息。
应用程序不得使用这些内容。如果需要此包中的功能,可以通过Hadoop开发渠道提出公开实现的请求。
这些可能被Hadoop FileSystem
、AbstractFileSystem
及相关类的实现所使用,但这些实现不在hadoop源码树中。实现者必须注意,此代码的实现不稳定,可能在Hadoop的小版本更新中发生变化。