008_falcon磁盘io计算方法

一、falcon磁盘IO告警计算方法

(1)线上告警示例
【falcon】环境: prod 时间: 2018-11-10 22:29 共1条
【#主机磁盘io过高(appid)】主机hostname磁盘dfa io过高98.76>98%
(2)cat /proc/diskstats
252 0 dfa 2689642164 0 513826977162 100403006 6803204529 0 1348198360088 2893131263 0 934780608 3002409596
每项的具体含义如下:
1   252            主设备号    code:Major
2   0              次设备号    code:Minor
3   dfa            设备名称    code:Name
4   2689642164     <1>读完成次数{读磁盘的次数,成功完成读的总次数}[2689642164]  code:ReadIOs
5   0              <2>合并读完成次数  code:ReadMerges
6   513826977162   <3>读扇区的次数,成功读过的扇区总次数  5.ReadSectors
7   100403006      <4>读花费的毫秒数;这是所有读操作所花费的毫秒数{从__make_request()到end_that_request_last()的测量} code:ReadTicks
8   6803204529     <5>写完成次数;写完成的次数,成功写完成的总次数  code:WriteIOs
9   0              <6>合并写完成次数。为了效率可能会合并相邻的读和写,从而两次4K的读在它最终被处理到磁盘上之前可能会变成一次8K的读,才被计数(和排队),因此只有一次I/O操作,这个域使你知道这样的操作有多频繁 code:WriteMerges
10  1348198360088  <7>写扇区次数;写扇区的次数,成功写扇区总次数  code:WriteSectors
11  2893131263     <8>写操作花费的毫秒数;写花费的毫秒数,这是所有写操作所花费的毫秒数{是从__make_request()到end_that_request_last()的测量}  code:WriteTicks
12  0              <9>正在处理的输入/输出请求数;I/O的当前进度,只有这个域应该是0.当请求被交给适当的request_queue_t时增加和请求完成时减小 code:InFlight
13  934780608      <10>输入/输出操作花费的毫秒数;花在I/O操作上的毫秒数,只要field9不为0这个域就会增长 code:IOTicks
14  3002409596     <11>输入/输出操作花费的加权毫秒数;花在I/O操作上的毫秒数,在每次I/O开始,I/O结束,I/O合并或读取自动上次更新这个域以来(第<9>列正在进行的io数量乘以花费在io上的毫秒数)时这个域都会增加.这可以给I/O完成时间和存储那些可以累积的提供一个便利的测量标准 code:TimeInQueue
(3)告警计算公式
io_ticks{crt.IOTicks - last.IOTicks(上10s的值)}/100 > 98 会进行报警

二、实现代码

(1)
const diskStatPath = "/proc/diskstats"

type DiskStatCollector struct {
	lastDiskStats map[string]*linux.DiskStat
}

func (c *DiskStatCollector) Collect() ([]*model.Metric, error) {
	if c.lastDiskStats == nil {
		c.lastDiskStats = make(map[string]*linux.DiskStat)
	}
	disks, err := linux.ReadDiskStats(diskStatPath)
	if err != nil {
		return nil, fmt.Errorf("collect disk stat: %v", err)
	}
	var metrics []*model.Metric
	for _, crt := range disks {
		if len(crt.Name) == 3 && (strings.HasPrefix(crt.Name, "sd") || strings.HasPrefix(crt.Name, "vd") || strings.HasPrefix(crt.Name, "df")) {
			if last, ok := c.lastDiskStats[crt.Name]; ok {
				metrics = append(metrics, diskStatDiff(&crt, last)...)
			}
			tmp := crt
			c.lastDiskStats[crt.Name] = &tmp
		}
	}
	return metrics, nil
}

func diskStatDiff(crt *linux.DiskStat, last *linux.DiskStat) []*model.Metric {
	var metrics []*model.Metric
	if crt.IOTicks < last.IOTicks {
		return metrics
	}
	metrics = append(metrics, &model.Metric{
		Name: "disk.io",
		Fields: []*model.Field{
			{"read_ios", model.Gauge, crt.ReadIOs - last.ReadIOs},
			{"read_merges", model.Gauge, crt.ReadMerges - last.ReadMerges},
			{"read_sectors", model.Gauge, crt.ReadSectors - last.ReadSectors},
			{"read_ticks", model.Gauge, crt.ReadTicks - last.ReadTicks},
			{"write_ios", model.Gauge, crt.WriteIOs - last.WriteIOs},
			{"write_merges", model.Gauge, crt.WriteMerges - last.WriteMerges},
			{"write_sectors", model.Gauge, crt.WriteSectors - last.WriteSectors},
			{"write_ticks", model.Gauge, crt.WriteTicks - last.WriteTicks},
			{"in_flight", model.Gauge, crt.InFlight - last.InFlight},
			{"io_ticks", model.Gauge, crt.IOTicks - last.IOTicks},
			{"time_in_queue", model.Gauge, crt.TimeInQueue - last.TimeInQueue},
		},
		Tags:      map[string]string{"name": crt.Name},
		Timestamp: utils.Timestamp(),
	})
	return metrics
}

(2)

// ReadDiskStats reads and parses the file.
//
// Note:
// * Assumes a well formed file and will panic if it isn‘t.
func ReadDiskStats(path string) ([]DiskStat, error) {
	data, err := ioutil.ReadFile(path)
	if err != nil {
		return nil, err
	}
	devices := strings.Split(string(data), "\n")
	results := make([]DiskStat, len(devices)-1)

	for i := range results {
		fields := strings.Fields(devices[i])
		Major, _ := strconv.ParseInt(fields[0], 10, strconv.IntSize)
		results[i].Major = int(Major)
		Minor, _ := strconv.ParseInt(fields[1], 10, strconv.IntSize)
		results[i].Minor = int(Minor)
		results[i].Name = fields[2]
		results[i].ReadIOs, _ = strconv.ParseUint(fields[3], 10, 64)
		results[i].ReadMerges, _ = strconv.ParseUint(fields[4], 10, 64)
		results[i].ReadSectors, _ = strconv.ParseUint(fields[5], 10, 64)
		results[i].ReadTicks, _ = strconv.ParseUint(fields[6], 10, 64)
		results[i].WriteIOs, _ = strconv.ParseUint(fields[7], 10, 64)
		results[i].WriteMerges, _ = strconv.ParseUint(fields[8], 10, 64)
		results[i].WriteSectors, _ = strconv.ParseUint(fields[9], 10, 64)
		results[i].WriteTicks, _ = strconv.ParseUint(fields[10], 10, 64)
		results[i].InFlight, _ = strconv.ParseUint(fields[11], 10, 64)
		results[i].IOTicks, _ = strconv.ParseUint(fields[12], 10, 64)
		results[i].TimeInQueue, _ = strconv.ParseUint(fields[13], 10, 64)
	}

	return results, nil
}

  

原文地址:https://www.cnblogs.com/itcomputer/p/9950715.html

时间: 2024-12-25 02:11:31

008_falcon磁盘io计算方法的相关文章

Linux下java获取CPU、内存、磁盘IO、网络带宽使用率

一.CPU 使用proc文件系统,"proc文件系统是一个伪文件系统,它只存在内存当中,而不占用外存空间.它以文件系统的方式为访问系统内核数据的操作提供接口.用户和应用程序可以通过proc得到系统的信息,并可以改变内核的某些参数." 从/proc文件系统获取cpu使用情况:    cat /proc/stat 在Linux的内核中,有一个全 局变量:Jiffies. Jiffies代表时间.它的单位随硬件平台的不同而不同.系统里定义了一个常数HZ,代表每秒种最小时间间隔的数目.这样ji

磁盘io性能分析

一,概念 磁盘io,顾名思义就是磁盘的输入输出.即向磁盘写入数据和从磁盘读取数据. I/O 读写的类型,大体上讲,I/O 的类型可以分为: 读 / 写 I/O.大 / 小块 I/O.连续 / 随机 I/O, 顺序 / 并发 I/O.在这几种类型中,我们主要讨论一下:大 / 小块 I/O.连续 / 随机 I/O, 顺序 / 并发 I/O. 1,读 / 写 I/O 磁盘是用来给我们存取数据用的,因此当说到IO操作的时候,就会存在两种相对应的操作,存数据时候对应的是写IO操作,取数据的时候对应的是是读

mysql磁盘IO%util 居高不下之RAID卡 BBU Learn Cycle周期

最近遇到一个奇怪的问题 收到短信报警说磁盘IO很高 复制延迟 iostat -x 1 10 信息如下: QPS 如下: 负载很低  压力很低 这就很无解了. 只有一个MYSQL 其实这是个硬件问题 ,就是 MegaSAS RAID卡 BBU Learn Cycle周期 背景 最近遇到有些带MegaSAS RAID卡的服务器,在业务高峰时突然IO负载飚升得很高,IO性能急剧下降,查了日志及各种设置最后才发现是RAID卡的Cache写策略由WriteBack变成WriteThrough了.更深入的原

磁盘IO单线程顺序写时最快的,如果多线程写,磁盘的磁头要不断重新寻址,所以写入速度反而会慢

(1) 读写最好还是不要多线程,硬盘读写的速度有限,单线程时已经满负荷了,多线程又会增加线程之间的切换,会增加时间. 如果想增加读写速度,应该增加硬盘,做raid (2)首先是硬盘的写入是串行的,CPU的计算才是并行的,如果你偏重计算那么多线程能提高,要不怎么叫做并行计算呢: 如果侧重存储,除非数据量达到足以体现优势的程度,否则加上线程之间切换的损耗当然会效率更加地下. (3)这个是按照算法来说的,目前来说大多数的算法都是很快的,瓶颈都在磁盘的IO上,我们针对大多数的算法都进行过测试,基本一半以

通过blktrace, debugfs分析磁盘IO

前几天微博上有同学问我磁盘util达到了100%时程序性能下降的问题,由于信息实在有限,我也没有办法帮太大的忙,这篇blog只是想给他列一下在磁盘util很高的时候如何通过blktrace+debugfs找到发生IO的文件,然后再结合自己的应用程序,分析出这些IO到底是谁产生的,最终目的当然是尽量减少不必要的IO干扰,提高程序的性能. blktrace是Jens Axobe写的一个跟踪IO请求的工具,linux系统发起的IO请求都可以通过blktrace捕获并分析,关于这个工具的介绍请自行Goo

Cacti监控磁盘IO(rhel)

1.检查net-snmp是否支持IO监控 snmpwalk -v 1 -c public 监控机的IP UCD | more 执行如上命令,如果返回类似如下数据,则表示支持disk io的监控,否则需要重新编译增加diskio-module模块. 1. UCD-DISKIO-MIB::diskIOIndex.1 = INTEGER: 1 2. UCD-DISKIO-MIB::diskIOIndex.2 = INTEGER: 2 3. UCD-DISKIO-MIB::diskIOIndex.3 =

zabbix监控磁盘IO(二)

1.磁盘发现脚本 vim disk_io.sh  #!/bin/bash  diskarray=(`cat /proc/diskstats |grep -E "\bsd[a-z]\b|\bxvd[a-z]\b|\bvd[a-z]\b"|awk '{print $3}'|sort|uniq   2>/dev/null`)    length=${#diskarray[@]} printf "{\n" printf  '\t'"\"data\&

【好书摘要】性能优化中CPU、内存、磁盘IO、网络性能的依赖

系统优化是一项复杂.繁琐.长期的工作,优化前需要监测.采集.测试.评估,优化后也需要测试.采集.评估.监测,而且是一个长期和持续的过程,不 是说现在优化了,测试了,以后就可以一劳永逸了,也不是说书本上的优化就适合眼下正在运行的系统,不同的系统.不同的硬件.不同的应用优化的重点也不同. 优化的方法也不同.优化的参数也不同.性能监测是系统优化过程中重要的一环,如果没有监测.不清楚性能瓶颈在哪里,怎么优化呢?所以找到性能 瓶颈是性能监测的目的,也是系统优化的关键.系统由若干子系统构成,通常修改一个子系

Linux服务器用iotop命令分析服务器磁盘IO情况

Linux下的IO统计工具如iostat, nmon等大多数是只能统计到per设备的读写情况, 如果你想知道每个进程是如何使用IO的就比较麻烦.如果会systemtap, 或者blktrace这些事情难不到大家, 但是没专用工具总不是很舒服的. 幸运的是Linux 2.6.20内核以后提供了基于每个进程的IO记账功能,所以就有了类似iotop这样方便的工具.可以通过iotop工具进行分析,查看哪个进程占有读写比较高. 官网地址: http://guichaz.free.fr/iotop/ Iot