高性能的Linux集群监控之道
扫描二维码
随时随地手机看文章
监控是集群管理的核心任务监控数据可用于调度任务负载平衡向管理员报告软硬件故障并广泛地控制系统使用情况监控信息必须在不影响集群性能的情况下获得本文将讨论使用/proc文件系统和Java来获得监控数据的方法
Java在Linux集群中的应用
Java技术为集群管理开发者提供了许多解决问题的办法Java是动态灵活可移植的这些不寻常的特征使得它成为了在异构网络及平台上构造集群管理的理想基础
Java具有广泛的例程库很容易处理IP协议如TCPUDP并可在multihomed主机上进行网络程序设计用它创建网络连接比用C或C++更容易通过Java本地接口(JNI)运行在Java 虚拟机(JVM)内的Java代码能够与用其它语言编写的应用及库文件相互操作并汇编
在构造集群监控和管理时Java早已是一个可选的语言然而Java语言通常只被用于系统的前端或集群主机部分而将用C 语言编写的守护进程安装在集群结点上尽管Java程序设计语言提供了许多优点但是对于高性能集群监控Java能够有效地替换运行在每个结点上的C 语言守护进程吗?这将是本文讨论的重点
高性能监控
监控Linux集群工具传统上以秒为测量频率来提供有限量的数据而高性能集群监控被定义为“以intrasecond为测量频率从结点有效地采集数据的能力”当涉及较大集群时监控软件的低效率问题就变得更加严重这是因为所运行的应用软件必须互相协调或共享全局资源
在一个结点上的阻隔冲突(Interference)能影响其它结点上作业的运行例如一个MPI作用需要与所有参与的结点同步一种解决办法是收集少量的数据并以小频率传输然而如果是高性能监控这种解决办法是不可接受的因为有较重利用率的集群应该被频繁持续地监控本地作业调度器必须能够基于资源使用情况做快速决策管理员经常希望收到紧急事件的立即通知并希望观察到历史趋势数据如果集群不能被频繁持续地监控那么这些要求是不可能实现的因此必须采取一些措施如使用更有效的算法增加传输的并行性提高传输协议及数据格式的效率减少冗余等
在跟踪运行中的资源使用情况时压缩Profiling应用有助于调试程序或优化程序对一个给定的应用而言像存储器网络CPU这样动态资源的使用可能快速地改变着为了能够观察应用是怎样使用这些资源的一种可能的办法是使用高频率的监控
即使用户对高频率监控没有兴趣如果算法是有效的不管监控频率是多少它也将消费很少的资源在异构集群中这种效率将更重要用户的作业可以被分散到较快的及较慢的结点上慢的结点需要全部CPU来跟上较快的结点并与之同步一个监控程序花费在较慢结点上的CPU时间是作业的关键路径
监控阶段
集群监控主要消耗CPU周期与网络带宽这两个重要资源然而资源消费问题与这两个资源是根本不同的CPU利用问题对结点而言是完全本地化的问题可通过创建有效的收集与合并算法来解决网络带宽是共享资源是规模问题可以通过最小化网络上传输的数据量来解决
为了解决这两个问题我们将集群监控分为三个阶段收集合并传输收集阶段负责从操作系统装载数据分析数据值并存储数据合并阶段负责将来自多个数据源的数据合在一起决定数据值是否改变并过滤它们传输阶段负责压缩并传输数据本文集中讨论Linux集群监控的收集阶段
收集阶段
Linux有几种方法来进行系统统计每种方法都各有其优缺点
◆ 使用现有的工具
标准及非标准工具能执行一个或多个收集合并及传输阶段如rstatd或SNMP工具然而标准的rstat后台程序提供的信息是有限的速度慢而且效率低
◆ 内核模块
几个系统监控工程利用内核模块来存取监控数据一般情况下这是很有效的收集系统数据的方法然而这种方法存在的问题是当主内核源内有其它改变时必须保持代码一致性一个内核模块可能与用户想使用的其它内核模块相冲突此外在使用监控系统之前用户必须获得或申请模块
◆ /proc虚拟文件系统
/proc 虚拟文件系统是一个较快的高效率执行系统监控的方法使用/proc的主要缺点是必须保持代码分析与/proc 文件格式改变的同步事实表明Linux内核的改变比/proc 文件格式的改变要更频繁所以用/proc虚拟文件系统比用内核模块存在的问题要少
◆ 混合系统
某些监控系统采用混合方式用内核模块收集数据用/proc虚拟文件系统作为数据接口
合并阶段
合并阶段的实现可以在结点上集群管理的主机上或者分布在两者上考虑到效率我们只采用在结点上的合并原因在于结点是监控数据的收集器与提供者两个或多个同时的数据请求不会引起两次操作系统调用来收集数据而是将第一次请求获得的数据缓存并可以提供给第二次请求调用这种方法减少了操作系统的负担提高了监控系统的响应性合并阶段也可以用于将多个数据源的数据以相互独立的收集速率结合因为并不是所有的数据都以同样的速度改变或者需要以同样的速率收集
使用在结点层上合并的另一个原因是减少了包括传输在内的信息量许多/proc文件既包含动态数据也包含静态数据删除最近一次传输后没有改变的值一个结点发送的数据量可以大大地减少合并不仅除去了不经常改变的动态值的传输也解决了从不改变的静态值的传输
传输阶段
监控数据几乎总是按一个层次结构组织起来传输阶段的任务就是将层次数据进行有效的编码形成一种能高效传输的数据格式Java拥有的文件格式是存储层次数据的有效方法并且用提供的Java APIs很容易完成SExpressions已经被认为是传输这种数据的另一个有效的方法
关于传输监控数据普遍讨论的问题是数据应该按二进制编码还是按文本格式编码二进制数据更容易压缩因此也能更有效地传输但是当采用/proc文件系统时监控数据通常以人们易读的格式存储在传输之前将数据转换为二进制格式将需要更多的处理资源与时间以文本格式保留收集的数据结点资源能被用于更多非监控性的相关工作
采用文本格式的数据将提供如下额外的益处
◆ 平台独立性
当监控异构集群时机器之间数据字节指令的配置不是永远相同的文本格式的使用在代码方面解决了这个问题而且体系结构独立不会影响更多的处理需求
◆ 易读的格式
文本数据能以人们易读的格式进行组织如果需要的话这种特征能容易地进行程序调试或允许用户观看数据流[!--empirenews.page--]
◆ 有效压缩
数值数据的文本表示由来自个字节集中的字符组成而不是二进制下的个字节集它们产生的数字及模式的相对频率允许有效地使用基于压缩算法的字典及熵(平均信息量)
/proc虚拟文件系统
/proc虚拟文件系统(也叫procfs)是Unix操作系统所使用的虚拟文件系统的Linux实现包括Sun SolarisLinuxBSD在/proc开始时它以一个标准文件系统出现并包含与正在运行的进程IDs同样名字的文件然而在/proc中的文件不占用磁盘空间它们存在于工作存储器(内存)中/proc最初的目的是便于进程信息的存取但是现在在Linux中它可被内核的每一部分使用来报告某些事情
在/proc文件系统提供的成百上千的值当中我们将集中考虑集群监控所需的最小集它们包括
◆ /proc/loadavg包含系统负载平均值;
◆ /proc/meminfo包含存储管理统计量;
◆ /proc/net/dev包含网卡度量;
◆ /proc/stat包含内核统计量;
◆ /proc/uptime包含总的系统正常工作时间及空闲时间
每个文件提供的值的数量是不同的这些文件的完整有效值列表如下
◆ /proc/loadavg提供以下数据
秒钟平均负载;
秒钟平均负载;
秒钟平均负载;
总作业数;
正在运行的作业总数
◆ /proc/meminfo提供的存储器信息包括
活动存储器;
不活动存储器;
缓冲存储器;
高速缓冲存储器;
总的自由存储器;
总的高位存储器;
自由高位存储器;
总的低位存储器;
自由低位存储器;
共享存储器;
交换存储器;
交换高速缓冲存储器;
交换自由存储器;
总存储器
◆ /proc/net/dev中包括每个网卡的如下数据
接收到的字节;
接收到的压缩字节;
收到的误码数;
收到的漏失误码;
收到的FIFO误码;
收到的帧误码;
收到的多播误码;
收到的总包数;
已传输的字节;
已传输的压缩字节;
传输误码总数;
传输载波误码;
传输冲突误码;
传输漏失误码;
传输FIFO误码;
传输的总包数
◆ /proc/stat提供
引导时间;
上下文切换数量;
中断总量;
进页面总数;
出页面总数;
进程总数;
换入总数;
换出总数;
合计CPU空闲时间;
合计CPU nice时间;
合计CPU系统时间;
合计CPU用户时间
同时提供对每个CPU的:
单个CPU空闲时间;
单个CPU nice时间;
单个CPU系统时间;
单个CPU用户时间
以及对每个磁盘驱动器的如下数据
单个磁盘块读;
单个磁盘块写;
单个磁盘I/O总数;
单个磁盘I/O读;
单个磁盘I/O写
◆ /proc/uptime中包括
系统总工作时间;
系统总空闲时间
值得注意的是每次某个/proc被读时一个句柄函数都被内核或特有模块调用来产生数据数据在运行中产生不管是读一个字符还是一个大的字块整个文件都将被重建这对效率是至关重要的一点因为使用/proc的任何系统监控器将吞下整个文件而不是一点一点地处理它
Java提供了丰富的文件I/O类集包括基于类的流基于类的块设备以及JSDK 提供的新的I/O库实验表明一般而言对基本的块读写文件操作用RandomAccessFile类进行I/O是最佳的例如块读文件操作如下
mFile = new RandomAccessFile( "/proc/meminfo" "r" );
//以读方式打开文件
mFileread( mBuffer ); //读文件块
结论
本文讨论了如何将Java语言有效地用于Linux集群结点上的高性能监控在程序设计中要注意以下方面
◆ 采用/proc文件系统;
◆ 以块形式读/proc文件而不是以行或字符形式;
◆ 在读文件期间保持文件打开;
◆ 消除不必要的数据转换;
◆ 在结点上合并数据;
◆ 以压缩形式传输数据;
◆ 注意与性能问题相关的语言或库
对高性能监控而言内核模块不是必要条件这点很重要因为它在Linux版本和分类之间提供了很大程度的可移植性在监控器实现语言上有很多的选择但是/proc文件系统的性能却很依赖内核代码的效率因此适当地理解有关的机制将对以任何语言编写的监控器性能有非常大的影响。