我想存储时间序列数据,例如 6 个月以上的 CPU 使用率(每 2 分钟轮询一次 CPU 使用率,因此稍后我可以获得多个分辨率,例如 - 1 周、1 个月,甚至更高的分辨率、5 分钟等)。
我正在使用 Perl,我不想使用 RRDtool 或关系数据库,我正在考虑使用具有以下属性的某种循环缓冲区(环形缓冲区)来实现我自己的:
- 6 个月 = 186 天 = 4,464 小时 = 267,840 分钟。
- 将它分成 2 分钟的部分:267,840/2 = 133,920。
- 133,920 是环形缓冲区大小。
- 环形缓冲区中的每个元素都是一个 hashref,其中键为纪元(使用
localtime
可以轻松转换为日期时间),值是给定时间的 CPU 使用率。< - 我将序列化这个环形缓冲区(我猜是使用
Storable
)
还有其他建议吗? 谢谢,
请您参考如下方法:
我怀疑你想多了。为什么不只使用一个平面(例如)TAB 分隔文件,每个时间间隔一行,每行包含一个时间戳和 CPU 使用率?这样,您就可以在收集新条目时将其附加到文件中。
如果您想自动丢弃超过 6 个月的数据,您可以通过每天(或每周或每月或其他)使用一个单独的文件并删除旧文件来实现。这比每次读取和重写整个文件效率更高。
编写和解析此类文件在 Perl 中是微不足道的。下面是一些示例代码,来 self 的脑海:
写作:
use strict;
use warnings;
use POSIX qw'strftime';
my $dir = '/path/to/log/directory';
my $now = time;
my $date = strftime '%Y-%m-%d', gmtime $now; # ISO 8601 datetime format
my $time = strftime '%H:%M:%S', gmtime $now;
my $data = get_cpu_usage_somehow();
my $filename = "$dir/cpu_usage_$date.log";
open FH, '>>', $filename
or die "Failed to open $filename for append: $!\n";
print FH "${date}T${time}\t$data\n";
close FH or die "Error writing to $filename: $!\n";
阅读:
use strict;
use warnings;
use POSIX qw'strftime';
my $dir = '/path/to/log/directory';
foreach my $filename (sort glob "$dir/cpu_usage_*.log") {
open FH, '<', $filename
or die "Failed to open $filename for reading: $!\n";
while (my $line = <FH>) {
chomp $line;
my ($timestamp, $data) = split /\t/, $line, 2;
# do something with timestamp and data (or save for later processing)
}
}
(注意:我现在无法测试这些示例程序中的任何一个,因此它们可能包含错误或拼写错误。使用风险自负!)