15 个稳定版本 (6 个主要)
使用旧的 Rust 2015
6.0.4 | 2018年12月4日 |
---|---|
6.0.3 | 2018年3月4日 |
6.0.2 | 2018年2月15日 |
6.0.1 | 2017年12月23日 |
0.1.0 | 2016年7月9日 |
#15 in #error-value
用于 2 crates
310KB
4K SLoC
请使用 hdrhistogram
代替.
lib.rs
:
请使用 hdrhistogram
代替.
HdrSample 是 Gil Tene 的 HdrHistogram 到本地 Rust 的移植。它提供了在可配置的值范围内记录和分析样本数据值计数的功能,同时在该范围内提供可配置的精度。生成的“HDR”直方图允许快速准确地分析具有非正态分布的数据的极端范围,如延迟。
HdrHistogram
以下是从 HdrHistogram 网站 的描述。鼓励用户阅读来自原始 Java 实现 的文档,因为大多数概念可以直接转换为 Rust 移植。
HdrHistogram 支持在可配置的整数值范围内记录和分析样本数据值计数,并在该范围内提供可配置的值精度。值精度以记录的值中的有效数字数量表示,并提供了控制值量化行为在整个值范围以及任何给定级别的后续值分辨率的功能。
例如,直方图可以配置为跟踪0到3,600,000,000之间观察到的整数值的数量,同时在整个范围内保持3位有效数字的精度。因此,该范围内的值量化不会超过1/1,000(或0.1%)的任何值。此示例直方图可用于跟踪和分析在1微秒到1小时范围内变化的响应时间的数量,同时保持1微秒到1毫秒的分辨率,1毫秒(或更好)到1秒的分辨率,以及1秒(或更好)到1,000秒的分辨率。在其最大跟踪值(1小时)时,它仍将保持3.6秒(或更好)的分辨率。
HDR直方图是为记录延迟和性能敏感应用的值测量直方图而设计的。测量表明,在2014年的现代(约2014年)英特尔CPU上,值记录时间低至3-6纳秒。HDR直方图在空间和时间上保持固定成本。直方图的内存占用是固定的,不涉及任何分配操作,无论是记录数据值还是遍历它们。内存占用是固定的,无论记录的数据值样本数量如何,仅取决于选择的动态范围和精度。记录样本所需的工作量是固定的,并且直接计算存储索引位置,这样在记录数据值时就不会涉及迭代或搜索。
与库交互
HdrSample的API遵循原始HdrHistogram Java实现,并对Rust中的用法进行了修改,以使其更符合习惯。本节中的描述已从Python端口中提供的描述改编,因为它比Java文档提供了更好的首次使用HDRHistogram的介绍。
HdrSample通常用于两种模式之一:记录样本或查询分析。在分布式部署中,记录可能是在远程(可能在多个位置)进行的,然后可以在中央位置进行汇总以进行分析。
记录样本
使用Histogram
结构上的::new
方法创建直方图实例。这些方法有三种变体:new
、new_with_max
和new_with_bounds
。第一个这些仅设置所需样本数据的精度,但将值范围设置为开放,以便记录任何值。以这种方式创建的Histogram
(或其中已显式启用自动调整大小)将自动调整大小,如果遇到太大而无法适应当前数据集的值。使用new_with_max
设置要记录的值的上限,并禁用自动调整大小,从而防止在记录过程中进行任何重新分配。如果应用程序尝试记录比此最大限制更大的值,则record
调用将返回错误。最后,使用new_with_bounds
限制数据集可以表示的最低值,这样就需要覆盖更小的范围(从而减少总的分配大小)。
例如,下面的示例显示了如何创建一个可以计数[1..3600000]
范围内的值的Histogram
,具有1%的精度,可用于跟踪[1毫秒..1小时]
范围内的延迟)。
use hdrsample::Histogram;
let mut hist = Histogram::<u64>::new_with_bounds(1, 60 * 60 * 1000, 2).unwrap();
// samples can be recorded using .record, which will error if the value is too small or large
hist.record(54321).expect("value 54321 should be in range");
// for ergonomics, samples can also be recorded with +=
// this call will panic if the value is out of range!
hist += 54321;
// if the code that generates the values is subject to Coordinated Omission,
// the self-correcting record method should be used instead.
// for example, if the expected sampling interval is 10 msec:
hist.record_correct(54321, 10).expect("value 54321 should be in range");
请注意 u64
类型。此类型可以被更改以减少所有直方图分桶的存储开销,但这会增加大量样本集中在同一桶中时饱和的风险。
查询样本
在任何时候,直方图都可以被查询以返回有趣的统计度量,例如记录的样本总数,或给定分位数的值。
use hdrsample::Histogram;
let hist = Histogram::<u64>::new(2).unwrap();
// ...
println!("# of samples: {}", hist.len());
println!("99.9'th percentile: {}", hist.value_at_quantile(0.999));
还提供了几个有用的迭代器,以便快速了解数据集的概览。最简单的一个是 iter_recorded()
,它为每个非空样本桶生成一个项目。HdrSample 支持所有 HdrHistogram 迭代器,因此请查看 Java 文档 中的 *Iterator
类。
use hdrsample::Histogram;
let hist = Histogram::<u64>::new(2).unwrap();
// ...
for v in hist.iter_recorded() {
println!("{}'th percentile of data is {} with {} samples",
v.percentile(), v.value_iterated_to(), v.count_at_value());
}
恐慌和错误处理
只要您使用的是安全、非恐慌函数(见下文),则此库永远不会恐慌。您遇到的任何恐慌都是一个错误;请将其记录在问题跟踪器中。
一些函数的功能通过 AddAssign
和 SubAssign
实现公开。这些替代形式等同于简单地调用 unwrap()
正常函数,因此 unwrap()
的正常规则适用:在生产代码中使用时持怀疑态度等。
返回 Result | 在错误时恐慌 | 功能 |
---|---|---|
h.record(v) |
h+=v |
为值 v 增加计数 |
h.add(h2) |
h+=h2 |
将 h2 的计数添加到 h |
h.subtract(h2) |
h-=h2 |
从 h 中减去 h2 的计数 |
除了上述函数的恐慌形式外,其他所有操作在可以失败的情况下将返回 Result
或 Option
。
usize
限制
根据配置的有效数字数量和最大值,直方图的内部存储可能有数百万个单元。16位 usize
系统无法表示这么大的指针偏移量,因此相关操作(创建、反序列化等)将因适当的错误而失败(例如,CreationError::UsizeTypeTooSmall
)。如果您使用此类系统并遇到这些错误,减少有效数字的数量将大大减少内存消耗(因此需要较大的 usize
值)。只要禁用调整大小,降低最大值也可能有所帮助。
32位及以上的系统将不会有此类问题,因为所有可能的直方图都适合在32位索引中。
浮点精度
一些计算本质上是浮点值,例如 value_at_quantile
,因此受IEEE754浮点计算精度的限制。用户可见的后果是,在某些边界情况下,你可能会得到一个比使用任意精度算术计算更高的或更低的桶(以及相应的值)。然而,双精度IEEE754(即 f64
)在它的任务上做得非常好,因此这些情况应该是很少见的。此外,我们还没有看到超过一个桶的偏差情况。
为了最小化浮点精度损失,我们更倾向于使用分位数而不是百分比。分位数表示一个集合的一部分,用 [0, 1]
中的数字表示。百分比与分位数概念相同,只是它使用范围 [0, 100]
。仅使用分位数意味着我们可以在几个地方跳过一个浮点操作,从而避免精度损失的机会。
限制和注意事项
与其他所有HdrHistogram端口一样,此端口可能无法提供上游HdrHistogram实现中的最新特性和错误修复。还有一些特性尚未(尚)实现
- 并发支持(
AtomicHistogram
,ConcurrentHistogram
,……)。 双精度直方图
.- HdrHistogram的
Recorder
功能。 - 值移位(“归一化”)。
- 文本输出方法。这些似乎与HdrSample几乎正交,尽管如果我们实现了某些相关特性(CSV、JSON和可能简单的
fmt::Display
)可能很方便。
大多数这些应该相当简单添加,因为代码与原始Java/C#代码非常吻合。如果你决定实现一个并发提交PR,请确保你也将测试用例移植过来,并尝试确保你实现适当的特性,以便使特性的使用尽可能舒适。
依赖关系
~325–790KB
~14K SLoC