Hadoop 的一个较大、但并不总是被提出来的问题是,它提供了一个只能附加的数据存储来存储大量信息。尽管此方法听起来似乎非常适合存储机器数据,但它会诱使人们长期存储大量信息。这就带来了问题,不是因为 Hadoop 无法存储该数据,而是因为这一数据量为需要获得实时的有效信息的环境增加了不必要的负担。
因此,在使用 Hadoop 来存储机器数据时,需要仔细的管理。不能存储该数据并假设您可在以后检索需要的数据,您需要制定一个计划。举例而言,为了使用该数据发出实时警报,您可能不希望筛选多年的数据点来挑选出最新的细节。在识别某个问题和发送警报时,除了帮助构建趋势和基准信息,来自两年前(甚至来自 6 个月前)的数据不可能还有用。
选择要存储的数据
对要存储的数据进行有意的选择。问自己以下问题,并为要存储的数据和存储时长制定一个计划。
您打算存储多少数据?
要确定此数据量,可估算您的记录的大小和数据到来的时间间隔。根据此信息,您可以很好地了解创建了多少数据,存储了多少数据点,以及每天或每周会使用多大比例的信息。例如,一个 3 字段的数据单元(例如日期、时间和数据点)虽然很小,但每 15 秒记录一次,就会创建大约 46 KB 的数据。将此值乘以 2000 个机器,每天就会生成 92 MB 的数据。如果记录多个数据点,数据量还会进一步增长。
您希望存储多久以前的数据?
问自己两个问题:您希望能够查看所有数据点的多久以前的数据,您希望能够确定多久以前的趋势?一周以前的单个最新数据不是很有用,因为在问题得到解决后,对该信息的需求就会很小。
考虑到这一观点,您需要确定一个基准。基准是表示正常操作的数据点或矩阵。有了基准之后,就更容易识别异常的趋势或峰值。
您希望如何确定基准?
与前述问题相关的是,基准是您存储的比较值,用于确定何时一个新数据超出了正常水平。例如,您可能记录了磁盘空间,而且将阈值设置为一个表示空闲磁盘空间量太小的特定百分比或硬性数据。
基准可以是以下三种基本类型之一:
- 已存在的基准:如果监视机器数据,用于比较的基准可能已经存在。例如,一个以 2000 rpm 的转速运行的风扇拥有不会不断调整的固定基准。
- 受控的基准:对于受控,进而受监视的组件和系统,通过将受控的值与报告的值向比较来确定基准。举例而言,一个温控系统拥有设定的问题和报告的温度。 HVAC 可能被设定为 5°C,而报告温度被设定为 4.8°C,所以在此示例中,设定的(需要的)温度就变成了实际数据用于比较的基准。
- 历史基准:这种类型的基准适用于根据现有值来计算基准的系统。例如,对一条河的高度或流速的监视不是基于您知道的情形,而基于您之前识别和体验到的情形。
历史基准显然会不断改变,而且除了在极少的情况下,历史基准通常不会被设定为硬性数据。相反,历史基准应该是一个变量,应该基于您拥有的传感器信息和值来设定历史基准。
例如,随着时间的推移,您可能添加磁盘空间,或者应用程序需要信息的时间和原因可能改变。使用一个百分比来进行基准比较可能不起作用。在拥有 10 TB 存储时,5% 被视为很低的存储,此时使用百分比没有问题。但在您拥有 30 TB 到 50 TB 存储时,5% 就是 2.5 TB,如此大的数字可能无法被用作警告阈值。
基准需要通过查看过去的值来计算。因此,您需要确定希望比较多少数据,比较多久以前的数据。您将新数据与上周、上个月还是过去 6 个月的数据进行比较?
您是否希望描绘并报告历史数据?
您可存储并生成信息的图形表示,但与基本存储一样,您不可能返回到特定的分钟或秒。但是,您可能希望记录一天中每 15 分钟的最小值、最大值和平均值,以便生成图表信息。
考虑了这些问题之后,分析如何解决存储数据的基本问题,如何确定触发警报和通知的异常,以及如何处理在该过程中生成的信息量。
在 Hadoop 中存储数据
第一个问题是如何在 Hadoop 中存储数据。因为这个主题已超出本文的讨论范围,所以请参见 参考资料 中的链接,以便了解有关的更多信息。
一般而言,Hadoop 不是很适合被用作此类信息和存储的实时数据库。尽管 Hadoop 是一个将数据附加到系统中的实用解决方案,但使用近线性的 SQL 数据库来存储该数据是更好的选择。
但是,不要让这一 Hadoop 限制阻碍了您。一种将数据加载到数据库中的实用方式是,通过附加到一个现有的开放文件,使用向 Hadoop Distributed File System (HDFS) 的永久写入。也可以使用 CSV 的仅支持附加的性质来记录数据批次。Hadoop 可用作集中器。
这里遇到的一个难点是:要将所有不同的信息都记录在单个文件中一段时间,然后将此信息复制到 HDFS 进行处理。您也可以直接写入 HDFS 上一个可从 Hive 或 HBase 访问的文件。
在 Hadoop 内,许多小文件没有少量大文件那么高效和有用。更大的文件能够更高效地分布在整个集群中。因此,数据能够更好地分布在集群中的不同节点上。这种分布使得通过 MapReduce 处理该信息变得更高效,因为更多节点拥有该数据的不同块。
将来自多个数据点的信息整理或分组到少量涵盖更长时间段(比如一天中的所有数据),或者涵盖多个主机、机器或其他主要数据收集器的更大文件中,这样做会更高效。
这种方法会生成一个依据收集器、机器和可能的日期来命名的文件,其中每一项位于不同的行中。例如:siteid、collectorid、datetime、settemp、reportedtemp。
确保数据广泛分布在整个系统中很重要。举例而言,对于一个 30 节点的 Hadoop 集群,您可能希望数据有效地分散到整个集群中,不会在处理期间浪费 CPU 或磁盘 I/O。这种分布会得到最快的处理和响应时间,这在您希望将数据用于监视和警报用途时很重要。
这些文件可通过单个集中器来附加,通过从多个主机收集数据,该集中器将信息写入这些较大的文件中。
以这种方式分解数据,还意味着您可以依据主机和/或日期来有效地分区数据。这种分布使得信息的分析和处理变得更高效,因为 Hive 等工具可按这些分区来限制对特定数据的处理。
使用 Hive 生成基准
如果还没有硬性或受控的基准,那么第一个工作就是创建基准数据和统计数据,确定正常的状态。
此信息可能会不断被更改,所以您需要能够通过分析现有的信息,确定这段时间内的基准。在 Hive 中,可通过使用合适的查询来生成一段时间内的最小、最大或平均统计数据,从而分析该信息。
如清单 1 所示,可根据来自多个传感器和主机的温度传感器数据的报告值来计算该信息。按日期汇总数据。
清单 1. 使用 Hive 生成一段时间的最小/最大/平均统计数据
Hive> select to_date(from_unixtime(timelogged)),host,machine ,min(reportval),max(reportval),avg(reportval) from temp group by to_date(from_unixtime(timelogged)),host,machine; ... 2014-03-05 1 1 2 14 7.995752916509865 2014-03-05 1 2 2 14 7.992366001827858 2014-03-05 1 3 2 14 8.003709477985055 2014-03-05 1 4 2 14 8.00448004587567 2014-03-05 2 1 2 14 8.006505026611473 2014-03-05 2 2 2 14 7.999910399082487 2014-03-05 2 3 2 14 7.994068419260613 2014-03-05 2 4 2 14 7.993674175223554 2014-03-06 1 1 2 14 8.00225504934963 2014-03-06 1 2 2 14 7.988397934505524 2014-03-06 1 3 2 14 7.99003202823714 2014-03-06 1 4 2 14 7.992385123210667 2014-03-06 2 1 2 14 7.999705863128309 2014-03-06 2 2 2 14 7.975227139028695 2014-03-06 2 3 2 14 8.016471664814693 2014-03-06 2 4 2 14 7.990849075102948 Time taken: 22.655 seconds
此代码提供了一些硬性数据来进行比较。举例而言,在这里可以看到,所有传感器都有一个 2C 到 14C 的范围,但平均值为 7C 到 8C。此数据提供了一些重要的数据,这些数据可作为在正常操作期间执行一些有关警告通知的决定的基础。
在此示例中,您汇总了记录的该数据点的数据,但是,如果您记录数据的频率更高,那么可以按小时或分钟来进一步汇总数据。也可以按不同元素进行分组 — 这里的示例假设每个传感器和主机都是分开的,但在某些情况下,传感器可能获得同一个静态元素的不同读数,这些读数需要放在一起。
为了避免每次重新计算,可将此数据写入一个新表中,以便在识别输入的数据流中的一个问题时将它们用作比较基础。您可以使用一个 INSERT INTO,使用清单 2 中的查询的输出来完成此任务。
清单 2. 使用 INSERT INTO
insert into table baselines select to_date(from_unixtime(timelogged)),host,machine,min(reportval) ,max(reportval),avg(reportval) from temp group by to_date (from_unixtime(timelogged)),host,machine;
对于持续的检查,计算您认为的最新的值作为当前值。检查整个表,为相应的传感器和主机计算一个在整个数据集中都是正确的值。可以按日期来删除基准,如清单 3 所示。
清单 3. 按日期删除基准
select host,machine,min(reportval),max(reportval),avg(reportval) from temp group by host,machine; ... Job 0: Map: 1 Reduce: 1 Cumulative CPU: 2.76 sec HDFS Read:13579346 HDFS Write: 215 SUCCESS Total MapReduce CPU Time Spent: 2 seconds 760 msec OK 1 1 2 14 7.998055578060439 1 2 2 14 7.990960752769065 1 3 2 14 7.998865753868589 1 4 2 14 8.00019675698198 2 1 2 14 8.004097174801217 2 2 2 14 7.991169083691161 2 3 2 14 8.002002291640142 2 4 2 14 7.992673695906297
您可以计算其他值,比如标准偏差或计算百分比。也可以计算超过这些值的特定点,创建您想要的基准。
现在您已经有了可供使用的基准。接下来,我们将尝试识别何时会出现一个问题。
识别实时问题
如果您的基准嵌入在数据中,要确定一个存在于所配置的参数之外的条目,您需要比较两个值:select * from temp where temp.setval != temp.reportval;。
其中存在一个间隔或容错值,通过执行一种更复杂的查询来执行这一比较,如清单 4 所示。
清单 4. 复杂查询
select * from temp where (temp.reportval <= (temp.setval-2)) or (temp.reportval >= (temp.setval+2);
如果拥有基准数据,可使用该信息来执行一次合并,这基于主机和机器在一天内的平均值,如清单 5 所示。
清单 5. 执行一次合并
select * from temp join baselines on (to_date(from_unixtime (temp.timelogged)) = baselines.basedate and temp.machine = baselines.machine and temp.host = baselines.host) where reportval > baselines.logavg; 2 1394089343 4 7 9 2014-03-06 2 4 2 14 7.990849 2 1394082857 4 10 11 2014-03-06 2 4 2 14 7.990849 2 1394085272 4 9 12 2014-03-06 2 4 2 14 7.990849 2 1394091433 4 10 12 2014-03-06 2 4 2 14 7.990849 2 1394082209 4 11 9 2014-03-06 2 4 2 14 7.990849 2 1394087662 4 9 10 2014-03-06 2 4 2 14 7.990849 2 1394083754 4 10 9 2014-03-06 2 4 2 14 7.990849
对于每个机器、温度传感器和相应的日期,此输出从最初的源数据生成所有超出所计算的基准的行。采样值可能比您预期的还要多。针对一个更严格的版本计算实际值,例如比计算的值多 10%。
清单 6 与所有基准进行了比较。
清单 6. 与所有基准进行比较
select * from temp join baselines_all on (baselines_all.machine = temp.machine and baselines_all.host = temp.host) where reportval > baselines_all.logavg;
对于警报数据,执行一次检查,以便在发生错误时输出一条特定的消息,如清单 7 所示。
清单 7. 警报数据
create table errors as select temp.host,temp.machine,temp.reportval ,if (reportval > baselines_all.logavg,'Overtemp','Normal') from temp join baselines_all on (baselines_all.machine = temp.machine and baselines_all.host = temp.host);
现在可以查询这个表,确定 Overtemp 条目,并下钻该数据。
现在可查询实时信息。可以根据以前确定的限制和异常点来触发警报。因为此信息仅包含 Hive 查询,所以可在广泛的环境和应用程序中,以可报告和可跟踪的元素形式访问它。
归档旧信息和创建汇总信息
要归档信息(执行比较和生成基准的一个必要步骤),则需要压缩数据。在压缩数据之后,压缩包仅包含关键的静态信息(也就是当前状态的平均值),用于与平均值之外的条目对比,然后可以相应地标记它们。
此方法需要生成一种调整过的基准查询形式,该查询使用最小值和最大值来汇总此信息,还包含落在该信息外部的异常值。
存储多少数据和存储的频率完全取决于您。确保存储了可汇总的数据,这会生成该数据之外的信息和值。
图 1 中的示例图形是根据类似于上一个示例的传感器数据而生成的。
图 1. 示例图
两行(顶部为红色,底部为绿色)之间的信息是不相关的数据。这些信息很有用,因为它提供了可用于确定温度的两个极端的平均值。但在该时间段内,您可以获取这个时间段的平均值,并表明它大体相同。
汇总之后,提取汇总结果,忽略您确定的限制之外的数据点,然后创建一个汇总了这些外部数据的表。
使用一个插入命令来完成此操作,仅汇总落在这些元素之间的数据,如清单 8 中所示。
清单 8. 插入
create table temparchive as select to_date(from_unixtime(temp.timelogged)),temp.host,temp.machine ,temp.reportval,0 from temp join baselines_all on (baselines_all .machine = temp.machine and baselines_all.host = temp.host) where (reportval < baselines_all.logavg+1) and (reportval > baselines_all.logavg-1) group by to_date(from _unixtime(temp.timelogged)),temp.host,temp.machine ,temp.reportval;
此代码创建了一个表,其中包含首先按日期汇总,然后按机器和传感器汇总的数据。该表包含报告的读数,最后一列始终包含 0。此表告诉您,该数据可安全地用作基准,因为计算的值包含在以前计算的基准内。您仅指定了在基准平均值上下 1C 范围内的值的基本差异。
可执行相反的操作,获取以前为该日期/机器/传感器组合计算的基准之外的值。在这种情况下,可提取所有值,而不是汇总的信息,如清单 9 所示。
清单 9. 提取所有值
insert into table temparchive select temp.timelogged,temp .host,temp.machine,temp.reportval,1 from temp join baselines_all on (baselines_all.machine = temp.machine and baselines_all.host = temp.host) where (reportval > baselines_all.logavg+1) and (reportval < baselines_all.logavg-1);
这些条目是基准平均值之外的原始数据,在最后一列使用值 1 来标记。使用此标记,在根据汇总和归档的日志信息来计算长期基准数据时,您可以有选择地排除或包含这些值。
结束语
使用和处理原始机器数据时,获取信息并将它们存储在 Hadoop 中是最简单的问题。您需要确定该信息代表的含义,以及希望如何汇总和报告该数据。
在 拥有原始数据并能在 Hive 中对它们运行查询之后,您还需要计算您的基准测试(如果它们还未修复)。然后运行一个查询,首先确定基准,然后对它进行查询,以便查找这些基准限制之外的 数据。本文介绍了一些基本技术,涉及处理和识别这些实时异常,以便识别需要报告和警告或描绘,然后向管理应用程序公开的错误。