机器学习用于服务器监控
我正在研究pybrain这个工具,想用它来处理服务器监控报警,并找出问题的根本原因。我打算用监督学习来训练它,并整理训练数据集。我的数据结构大致是这样的:
* Server Type **A** #1
* Alarm type 1
* Alarm type 2
* Server Type **A** #2
* Alarm type 1
* Alarm type 2
* Server Type **B** #1
* Alarm type **99**
* Alarm type 2
这里有n台服务器,每台服务器有x个报警,这些报警可以是UP
(正常)或DOWN
(异常)。n和x的数量都是可以变化的。
比如,如果服务器A1的报警1和2都是DOWN
,那么我们可以说服务a在这台服务器上出现了问题,这就是导致故障的原因。
如果报警1在所有服务器上都是DOWN
,那么我们也可以说服务a是问题的原因。
可能会有多个原因,所以直接分类似乎不太合适。
我还想把后续的数据源和网络连接起来,比如一些脚本用来检测外部服务的状态。
所有的报警可能不会同时触发,因为服务检查是串行的,所以可能一开始只有一台服务器出现故障,过了5分钟又有另一台服务器故障。
我现在想先做一些基础的工作:
from pybrain.tools.shortcuts import buildNetwork
from pybrain.datasets import SupervisedDataSet
from pybrain.supervised.trainers import BackpropTrainer
INPUTS = 2
OUTPUTS = 1
# Build network
# 2 inputs, 3 hidden, 1 output neurons
net = buildNetwork(INPUTS, 3, OUTPUTS)
# Build dataset
# Dataset with 2 inputs and 1 output
ds = SupervisedDataSet(INPUTS, OUTPUTS)
# Add one sample, iterable of inputs and iterable of outputs
ds.addSample((0, 0), (0,))
# Train the network with the dataset
trainer = BackpropTrainer(net, ds)
# Train 1000 epochs
for x in xrange(10):
trainer.train()
# Train infinite epochs until the error rate is low
trainer.trainUntilConvergence()
# Run an input over the network
result = net.activate([2, 1])
但我在把可变数量的报警映射到固定数量的输入上遇到了困难。比如,如果我们给一台服务器添加一个报警,或者添加一台新服务器,整个网络就需要重建。如果这是必须做的,我可以做到,但我想知道有没有更好的方法。
我还在考虑另一种选择,就是为每种类型的服务器建立一个不同的网络,但我不明白这样怎么能得出整个环境的结论,因为这样只会对单个主机进行评估,而不是同时对所有主机进行评估。
我应该使用哪种算法?怎么才能把数据集映射到一起,从而得出整个环境的结论,尤其是在输入数量可变的情况下?
我对任何有效的算法都很开放,使用Go语言甚至比Python更好。
2 个回答
有几种方式可以处理变量输入,但有两种相对简单的方法:
1) 如果某个输入没有出现,就用0.5来表示;而如果输入出现了,就用0或1来表示。
2) 另外,你可以把输入分成两个部分,一个表示“出现”与“未出现”,另一个表示“活跃”与“静默”。这样,网络就需要通过这两个部分的互动来学习:第二个部分只有在第一个部分为1的时候才重要,而在第一个部分为0的时候就不重要。不过,只要有足够的训练案例,它应该能够做到这一点。
当然,这些方法也可以结合使用。
这个问题其实挺有挑战性的。
标签的表示
要为学习表示目标标签是很困难的。正如你提到的,
If Server A1 has alarm 1 & 2 as DOWN, then we can say that service a is down on that server and is the cause of the problem.
If alarm 1 is down on all servers, then we can say that service a is the cause.
There can potentially be multiple options for the cause ...
我想你需要列出所有可能的选项,否则我们不能指望机器学习算法能够进行泛化。为了简单起见,假设你只有两个可能导致问题的原因:
1. Service problem
2. Server problem
基于站点的二分类器
假设在你的第一个机器学习模型中,上面提到的就是唯一的两个原因。那么你现在正在做的是一个基于站点的二分类器。可能逻辑回归是个不错的起点,因为它比较容易理解。
要找出是哪个服务器出问题,或者是哪个服务出问题,这可以作为你的第二步。根据你的例子,解决第二步的方法是:
- 如果是服务问题,我认为可以手动制定一些决策规则,这样就能准确找到服务名称。这个想法是,你应该能看到很多服务器同时触发了同一个警报,对吧?另外,看看最后的高级阅读部分,了解更多选项。
- 如果是服务器问题,你可以构建一个第二个二分类器(单独的服务器分类器),它在每个服务器上运行,只使用来自该服务器的特征,并回答“我是否有问题”。
基于站点的二分类器的特征
我认为所有这些警报是你特征的最佳来源。我猜使用一些汇总统计数据作为特征可能会对基于站点的分类器更有帮助。例如:
- 接收到警报A为DOWN的服务器百分比
- 所有警报B为DOWN的服务器的平均时间长度
- 所有警报B为DOWN的服务器中,有多少百分比的服务器也有警报A为DOWN。 ...
基于服务器的二分类器的特征
你应该明确使用所有警报信号作为服务器侧分类器的特征。然而,在训练时,你应该使用所有服务器的数据。标签只有“有问题”或“没有问题”。训练数据看起来会像:
alarm A On, alarm B On, alarm C on, ..., alarm Z on, has-problem
YES, YES, NO, YES, YES
NO, YES, NO, NO, NO
?, NO, YES, NO, NO
注意,我用“?”来表示你可能缺少数据的某些警报(未知状态),这可以用来描述下面的情况:
All the appropriate alarms may not be triggered at once,
due to serial service checks, so it can start with one server down and
then another server down 5 minutes later.