Skyline 简介
- 2. • Etsy 技 博客:术团队
• http://codeascraft.com/2013/06/11/introd
ucing-kale/
• Qcon London2013 演 稿:讲
• https://speakerdeck.com/astanway/bring-
the-noise-continuously-deploying-under-a-
hailstorm-of-metrics
介简
- 4. skyline 部署
• apt-get install git numpy scipy python-pip python-msgpack
python-pandas python-statsmodels
• git clone https://github.com/etsy/skyline
• cd skyline
• pip install -r requirement.txt
• cp src/settings.py.example src/settings.py
• mkdir /var/log/skyline
• mkdir /var/run/skyline
• mkdir /var/log/redis
• # 必 用须 2.6 版以上的 redis-server 才能正常存储
• wget http://redis.googlecode.com/files/redis-2.6.13.tar.gz
• tar zxvf redis-2.6.13.tar.gz
• cd redis-2.6.13
• make
- 5. skyline 启动
• ./src/redis-server ../bin/redis.conf
• cd bin
• # 分析器
• sudo ./analyzer.d start
• # 数据接收
• sudo ./horizon.d start
• # flask 界面
• sudo ./webapp.d start
- 6. horizon 支持
• 2024 端口支持转发 graphite 数据
• 2025 端口支持 pickle 和 msgpack 两种
网 数据格式络
• 数据存 在储 redis 中, key 的命名格式类
似 graphite 的的 group.item.time 这样
- 8. analyzer 原理
• first_hour_average
• 是最 的。先求本周期内最前面的第这 简单
一个小 的平均 和 准差,然后和最新时 值 标
的三个 的平均值 值 (tail_avg() , 是后面这
多数算法都通用的做法 ) 做比 。如果较
tail_avg 和 第一小 平均 的差距大于时 值
3 倍的 准差,那么 定 常。标 认 为异
- 12. analyzer 原理
• least_squares
• 采用最小二乘法 近 序列,然后用拟 时间 实
去 近 得到新序列。然后判断新际值减 拟 值
序列的最后三个 的平均 是否大于值 值 3 倍
的新序列 准差。标
• 所 最小二乘法, 就是 一个谓 简单说 对 [x,
y] 序列,会有一 常数对 [m, c] ,让 Y =
mx + c 等式中的 Y 和 y 在全序列上最
接近。
- 13. analyzer 原理
• histogram_bins
• 将整个周期序列的数据按照直方 法图统计
入归 15 个直方中,然后看最后三个 的值
平均 属于值 这 15 个直方的具体 个。如哪
果 个直方中包含的数据小于这 20 个,判
断 常。为异
• 从算法中可以知道,如果周期内数据量不
,很容易被判断 常的。够 为异
- 14. analyzer 原理
• grubbs
• 将整个周期序列的数据按照格拉布斯法求 常 。异 值
• 准的格拉布斯法是 的:标 这样
• 从小到大排序;
• 求序列的平均 和 准差;值 标
• 算最小 和最大 与平均 的差距,更大的那个 可疑 ;计 值 值 值 为 值
• 可疑 去平均 ,再除以 准差,如果大于格拉布斯 界 ,那么值减 值 标 临 值
就是 常 ;异 值
• 排除 常 , 剩余序列循 做异 值 对 环 1-5 步 。骤
• 里只用判断 序列的最后是否 常,所以直接将最后三个 的平这 时间 异 值
均 作 可疑 判断是否 常即可。值 为 值 异
- 17. webapp 原理
• 一个 flask 面,通页 过 ajax 求请 json 画
。图
• 个这 anomalies.json 是 analyzer 程进 实
生成到时 src/webapp/static/dump 目录
下的。在没有 常的 候的基 式如下异 时 础样
:
• handle_data([])
- 18. 示例
• use Data::MessagePack;
• use AnyEvent::Handle::UDP;
• my $mp = Data::MessagePack->new->utf8->prefer_integer;
• my $sock = AnyEvent::Handle::UDP->new(
• connect => [ '127.0.1.1', '2025' ],
• on_recv => sub { },
• autoflush => 1,
• );
• my $timer = AnyEvent->timer(
• after => 0,
• interval => 1,
• cb => sub {$sock->push_send($mp->pack(['localhost.loadavg', [time, rand*2]]))}
• );
• my $atimer = AnyEvent->timer(
• after => 200,
• interval => 1,
• cb => sub {
• $timer = undef;
• $sock->push_send($mp->pack(['localhost.loadavg', [time, rand*2000]]));
• },
• );
• AnyEvent->condvar->recv;