如何在CentOS7上使用Skyline检测异常

来自菜鸟教程
跳转至:导航、​搜索

介绍

如果您使用监控系统(如 Zabbix 或 Nagios),那么您就会知道监控是如何工作的。 简而言之,它可以描述如下:监控系统接收各种指标(CPU/内存使用情况、网络使用情况等)。 一旦其中一个指标的值超出预定阈值,它就会激活相应的触发器,并且监控系统会通知您其中一个指标超出正常限制。 每个指标的阈值通常是手动设置的,这并不总是很方便。

在本教程中,您将学习如何安装和配置 Skyline — 一个实时异常检测系统。 它能够实时分析一组指标,而无需为每个指标设置或调整阈值。 它旨在用于需要持续监控的大量时间序列(数十万)的任何地方。

阈值触发器

让我们看一个手动设置阈值的监控系统示例。 下图显示了 CPU 负载的图表。 虚线表示触发器的阈值。

图1

在图 1 中的第 1 点,一个进程已经启动,并且 CPU 负载显着增加。 触发器已被激活,管理员注意到了它。 管理员确定它在正常值范围内,并将触发阈值更改为上方虚线所示的阈值。

经过一段时间后,触发器在图 1 中的点 2 再次触发。 管理员发现第二个服务定期进行备份并导致负载增加。 那么问题来了:您是提高阈值还是保持原样但忽略警报?

让我们看一下第 3 点。 此时,事件负载下降,但由于未超过阈值,因此未通知管理员。 触发器没有激活。

这个简单的案例向我们展示了尝试设置阈值时存在一些困难。 在不触发误报错误或误报错误的情况下,很难调整阈值来捕捉性能问题。

为了帮助解决这些问题,创建了 Skyline。 它使用一组非参数算法对异常指标进行分类。

天际线组件

Skyline 由以下组件组成:Horizon Agent、Analyzer Agent 和 Webapp。

地平线代理

Horizon Agent 负责收集数据。 它有 Listeners,用于监听传入的数据。

它接受两种格式的数据:pickle (TCP) 和 MessagePack (UDP)。 它读取传入的指标并将它们放入 Workers 读取的共享队列中。 Worker 将数据编码到 Messagepack 中,并将其附加到 Redis 数据库中。 Horizon Agent 还使用 Roombas 定期修剪和清理旧指标。 如果不这样做,那么所有空闲内存将很快耗尽。

分析器代理

Analyzer Agent 负责分析数据。 它从 Redis 接收指标列表,运行多个进程,并将指标分配给每个进程。 每个过程使用几种算法分析数据。 每个算法都会报告结果——数据是否异常。 如果大多数算法报告当前度量存在异常,则数据被认为是异常

所有异常指标都写入文件。 在此文件的基础上,在 Web 应用程序中创建并显示图像。

Analyzer 还可以发送通知:电子邮件、HipChat 或 PagerDuty。 本文稍后会配置电子邮件通知。

网页应用

Skyline 提供了一个小型 Web 应用程序来显示异常指标。 这是一个使用 Flask 框架用 Python 编写的简单 Web 应用程序。 上半部分显示了两个图表——过去的一小时和过去的一天。 图表下方是所有异常指标的列表。

Redis 数据库

Redis 是一个开源的键值缓存和存储数据库。

Skyline 将所有指标和编码时间序列存储在 Redis 数据库中。 当数据点进入时,Horizon 工作人员将具有模式 [timestamp, value] 的数据点打包到 MessagePack 编码的二进制字符串中,并将此字符串附加到适当的指标键中。

图2显示了Skyline组件的交互图。

图 2

先决条件

在安装 Skyline 之前,您需要完成以下先决条件:

第 1 步 — 安装 Skyline 和 Redis

要安装 Skyline,首先安装所需的应用程序,包括一些 Python 相关工具和 Apache Web 服务器:

sudo yum install httpd gcc gcc-c++ git pycairo mod_wsgi python-pip python-devel blas-devel lapack-devel libffi-devel

从 GitHub 获取 Skyline 的最新源文件:

cd /opt
sudo git clone https://github.com/etsy/skyline.git

安装一些必需的 Python 包:

cd /opt/skyline
sudo pip install -U six
sudo pip install -r requirements.txt

按此指定顺序安装以下 Python 包:

sudo pip install numpy
sudo pip install scipy
sudo pip install pandas
sudo pip install patsy
sudo pip install statsmodels
sudo pip install msgpack-python

安装部分包可能需要较长时间,请耐心等待。


其中大部分是用于科学和技术计算的开源 Python 库。 msgpack-python 包是读取和写入 MessagePack 数据所必需的。

将示例 Skyline 设置文件复制到正确的文件位置:

sudo cp /opt/skyline/src/settings.py.example /opt/skyline/src/settings.py

创建以下目录:

sudo mkdir /var/log/skyline
sudo mkdir /var/run/skyline
sudo mkdir /var/log/redis
sudo mkdir /var/dump/

正如我们上面提到的,Skyline 将所有指标存储在 Redis 数据库中,因此您还需要安装它:

sudo yum install redis

您可以从教程 如何安装和使用 Redis 中找到有关 Redis 的更多信息。

启动 Skyline 和 Redis 服务:

cd /opt/skyline/bin
sudo redis-server redis.conf
sudo ./horizon.d start
sudo ./analyzer.d start
sudo ./webapp.d start

要测试安装,请运行包含的测试脚本:

python /opt/skyline/utils/seed_data.py

您应该看到以下输出:

Loading data over UDP via Horizon...                                           
Connecting to Redis...                                                         
Congratulations! The data made it in. The Horizon pipeline seems to be working.

Skyline 的安装和基本配置就完成了。 现在您需要向其中发送数据。

第 2 步 — 将数据导入 Skyline

如前所述,Skyline 接受两种格式的数据:pickle (TCP) 和 MessagePack (UDP)。

您可以将自己的脚本或模块编写到您最喜欢的监控代理中,并使用 MessagePack 对数据进行编码以发送到 Skyline 进行分析。 Skyline 接受 UDP 上 MessagePack 编码字符串形式的指标。 MessagePack 是类似 JSON 的对象序列化规范。 格式为 [<metric name>, [<timestamp>, <value>]]。 MessagePack 具有适用于大多数编程语言的 API。 更多信息和 API 示例可以在 MessagePack 官方网站 上找到。

本教程将向您展示如何将数据从 Graphite 和 collectd 发送到 Skyline。

从 Graphite 获取数据

Graphite 由几个组件组成,其中之一是 carbon-relay 服务。 Carbon-relay 将传入的指标转发到另一个 Graphite 实例以实现冗余。 因此,您可以将 carbon-relay 服务指向运行 Skyline 的主机。

图 3

图 3 显示了数据流的示意图。 来自外部监控代理(collectddiamondstatsd 等)或系统(NagiosIcinga 的数据, Sensu 等)被转移到 Graphite 中。 接下来,carbon-relay 将数据转发到 Skyline。 Carbon-relay、carbon-cache 和 Skyline 可以在单个主机或单独的主机上运行。

您需要配置 Graphite、collectd 和 Skyline 才能使此数据流正常工作。

如果您之前没有将示例 relay-rules.conf 复制到 carbon-relay 配置文件的正确位置,您现在必须这样做:

sudo cp /opt/graphite/conf/relay-rules.conf.example /opt/graphite/conf/relay-rules.conf

让我们打开relay-rules.conf配置文件进行编辑:

sudo vi /opt/graphite/conf/relay-rules.conf

将您的 Skyline 主机添加到目的地列表中,其中 YOUR_SKYLINE_HOST 是您的 Skyline 主机的 IP 地址:

/opt/graphite/conf/relay-rules.conf

[default]
default = true
destinations = 127.0.0.1:2004, YOUR_SKYLINE_HOST:2024

relay-rules.conf 中使用的所有目的地也必须在 carbon.conf 配置文件中定义。

打开 carbon.conf 配置文件进行此更改:

sudo vi /opt/graphite/conf/carbon.conf

然后找到 [relay] 部分,并编辑 DESTINATIONS 行:

/opt/graphite/conf/carbon.conf

[relay]
...
DESTINATIONS = 127.0.0.1:2004, YOUR_SKYLINE_HOST:2024
...

完成这些更改后,启动 carbon-relay 服务:

sudo systemctl start carbon-relay

允许 Skyline 访问 Graphite-Web

How To Keep Effective History Logs with Graphite, Carbon, and collectd on CentOS 7 中,如果您选择密码保护 Graphite web 界面,您 必须允许 从 localhost 无密码访问让 Skyline 正常工作。

为此,请编辑 Graphite 配置文件:

sudo vi /etc/httpd/conf.d/graphite.conf

将以红色添加以下行到 <Location> 块:

/etc/httpd/conf.d/graphite.conf

<Location "/"> 
  AuthType Basic
  AuthName "Private Area" 
  AuthUserFile /opt/graphite/secure/.passwd
  Require user sammy
    Order Deny,Allow
    Deny from all
    Allow from localhost
    Satisfy Any
</Location>

然后重启 Apache 服务:

sudo systemctl restart httpd

从 Collectd 获取数据

您还可以配置 collectd 以将数据发送到 Skyline。 打开它的配置文件:

sudo vi /etc/collectd.conf

<Plugin write_graphite> 块中的端口号更改为 2013

/etc/collectd.conf

<Plugin write_graphite>
    . . .       
    Port "2013"
    . . .

然后重启collectd:

sudo systemctl restart collectd.service

为避免混淆,图 4 显示了具有正确端口号的简化方案。

图 4

正确的端口号如下:

  1. Carbon-relay 在端口 2013 上侦听 plaintext 格式的传入数据
  2. Carbon-relay 以 pickle 格式发送数据
  3. Carbon-cache 在端口 2004 上侦听 pickle 格式的传入数据
  4. Horizon 代理在端口 2024 上侦听 pickle 格式的传入数据

注意力! 如果在同一主机上启动 Horizon 代理和可选的 carbon-aggregator,则必须更改它们的端口。 默认情况下,它们都设置为相同的端口 2024


第 3 步 — 设置天际线

Skyline 配置文件包含许多设置。 打开文件进行编辑:

sudo vi /opt/skyline/src/settings.py

此文件中的每个设置都通过文件本身中的信息注释进行记录。 至少,您需要设置以下参数,将红色文本替换为您的值:

  • GRAPHITE_HOST = 'YOUR_GRAPHITE_HOST'
  • HORIZON_IP = '0.0.0.0'
  • WEBAPP_IP = 'YOUR_SKYLINE_HOST_IP'

其他选项可以保留其默认值。 它们如下:

  • FULL_DURATION - 此选项指定数据将存储在 Redis 中并进行分析的最长时间。 更长的持续时间需要更长的分析时间,但它们可以帮助减少噪音并提供更准确的异常检测。 默认值为 86400 秒。
  • CARBON_PORT — 此选项指定碳端口。 默认值为 2003
  • ANALYZER_PROCESSES - 此选项指定 Skyline 分析器将生成的进程数。 建议将此参数设置为比主机上的 CPU 总数少几个。 默认值为 5
  • WORKER_PROCESSES - 此选项指定将从 Horizon 队列中消耗的工作进程数。 默认值为 2
  • PICKLE_PORT - 此选项指定侦听 Graphite 泡菜的 TCP 端口。 默认值为 2024
  • UDP_PORT — 此选项指定侦听 MessagePack 编码数据包的 UDP 端口。 默认值为 2025
  • WEBAPP_PORT - 此选项指定 Skyline web 应用程序的端口。 默认值为 1500

进行这些更改后,您必须重新启动相应的应用程序:

sudo /opt/skyline/bin/horizon.d restart
sudo /opt/skyline/bin/analyzer.d restart
sudo /opt/skyline/bin/webapp.d restart

然后您可以打开链接 http://your_server_ip:1500 并查看 Skyline 网页(图 5)。 它将在发现异常度量时显示它们。

图 5

要让 Skyline 满负荷运行,您需要等待 FULL_DURATION 秒过去。 默认情况下,FULL_DURATION 设置为 1 天(86400 秒)。

您应该等待至少一小时才能开始跟踪异常。 这将使 Skyline 有时间积累有关正常负载水平的信息。 在 Skyline 建立基线时,尽量不要在系统上产生额外的负载。

第 4 步 — 启用电子邮件警报

默认情况下,Skyline 在其 Web 界面 (http://your_server_ip:1500) 中显示检测到的异常,因为它们被发现并且仍在发生。 一旦异常消失,其相应的度量就会从此界面消失。 因此,您必须监视网页才能看到这些异常,这并不总是很方便。

您可以配置电子邮件警报,以免错过它们。

为此,请打开 Skyline 配置文件:

sudo vi /opt/skyline/src/settings.py

确保启用警报:

/opt/syline/src/settings.py

ENABLE_ALERTS = True

然后找到以下 ALERTS 部分并以红色添加以下架构:

/opt/syline/src/settings.py

ALERTS = (
    (^)("collectd", "smtp", 1800)(^),
)

模式中的第一个值是要监控的进程。 在这种情况下,它是 collectd. 模式的第二个值是 smtp,它代表电子邮件警报。 1800 的最后一个值以秒为单位。 这意味着即使检测到触发器,警报也不会在 30 分钟(1800 秒)内多次触发。 修改此值以最适合您的需求。

还可以找到以下部分并将其修改为您要使用的电子邮件地址。 电子邮件警报将从 (^)skyline-alerts@example.com(^) 发送到 (^)administrator@example.com(^) 帐户。

/opt/syline/src/settings.py

SMTP_OPTS = {
    "sender": "(^)skyline-alerts@example.com(^)",
    "recipients": {
        "collectd": ["(^)administrator@example.com(^)"],
    },
}

进行所有这些更改后,您必须重新启动分析器守护程序:

sudo /opt/skyline/bin/analyzer.d restart

第 5 步 — 测试 Skyline

要测试 Skyline,我们可以使用 bash 命令创建 CPU 峰值:

dd if=/dev/zero of=/dev/null

您可以随时按 CTRL-C 停止该命令。 几分钟应该足以产生异常。

如果您在运行此命令时查看 Skyline Web 界面,您将看到检测到的异常。 图 6 显示了一个示例。

图 6

您可以看到,由于 CPU 负载高,Skyline 组件的速度降低了。 所有检测到的异常指标都以列表的形式显示在网页底部。 当您将鼠标悬停在其中一个指标的名称上时,您可以在上方的图表中看到最后一小时和当天的相应时间序列。 单击度量的名称以打开由 Graphite 生成的更详细的图表(参见图 7 中的示例)。

图 7

在这个例子中 CPU 负载没有达到极高的值,也没有超过阈值。 在这种情况下,经典监控系统无法发现偏差。 前面提到过这种情况(图 1,第 3 点)。

与经典监控系统不同,Skyline 可以快速发现偏差并通知您。

第 6 步 — 调整算法(可选)

如前所述,Skyline 正在使用一组算法来检测异常。 当前实现了以下算法:

  • 平均绝对偏差
  • 格拉布斯测试
  • 第一小时平均
  • 与平均值的标准偏差
  • 移动平均线的标准差
  • 最小二乘
  • 直方图箱
  • Kolmogorov-Smirnov 检验

其中大部分基于с控制图(也称为Shewhart图)和三西格玛规则。 他们在计算中使用 Python 库 SciPy 和 NumPy。

您可以自定义任何使用的算法。 您还可以修改、删除或添加新的。 为此,您必须编辑配置文件:

sudo vi /opt/skyline/src/analyzer/algorithms.py

此文件中的每个算法都有一个简短的描述。 例如,让我们检查以下算法:

/opt/skyline/src/analyzer/algorithms.py

def median_absolute_deviation(timeseries):
    """
    A timeseries is anomalous if the deviation of its latest datapoint with
    respect to the median is X times larger than the median of deviations.
    """
        
    series = pandas.Series([x[1] for x in timeseries])
    median = series.median()
    demedianed = np.abs(series - median)
    median_deviation = demedianed.median()
        
    # The test statistic is infinite when the median is zero,
    # so it becomes super sensitive. We play it safe and skip when this happens.
    if median_deviation == 0:
        return False
        
    test_statistic = demedianed.iget(-1) / median_deviation
                                                                                    
    # Completely arbitary...triggers if the median deviation is
    # 6 times bigger than the median
    if test_statistic > 6:
        return True                                                       

根据数据的性质,您可能需要将阈值从 6 更改为其他值 - 457 等。

您还可以调整 settings.py 文件中的一些设置:

/opt/skyline/src/settings.py

ALGORITHMS = [
    'first_hour_average',
    'mean_subtraction_cumulation',
     'stddev_from_average',
     'stddev_from_moving_average',
     'least_squares',
     'grubbs',
     'histogram_bins', 
     'median_absolute_deviation',
     'ks_test',
]
    
CONSENSUS = 6

ALGORITHMS 选项指定分析器将运行的算法。 您可以将其中任何一个注释掉以禁用它们或添加新算法。 CONSENSUS 选项指定在将度量分类为异常之前必须返回 True 的算法数量。 要提高灵敏度,您可以减少此选项,反之亦然。

结论

Skyline 在复杂的动态变化的 IT 系统中得到了很好的证明。 对于定期更改操作系统并希望在新软件发布后快速检测系统指标异常的程序员来说,它可能很有用。

其主要优点包括:

  • 高速分析大量数据
  • 无需为每个指标设置单独的参数
  • 能够添加您自己的异常检测算法

它也有一些缺点:

  • 每个指标的数据由需要大量计算系统资源的几种算法分析。
  • 所有数据都存储在 RAM 中,这使系统能够非常快速地运行。 如果有大量的指标和长时间的分析,您将需要大量的 RAM。