云计算平台容错能力评估方法的研究
- 该项目是采用软件技术实现的故障注入方法进行云计算平台容错能力的评估。本项目包括对Hadoop平台容错能力分析,云计算平台虚拟机容错能力分析等等方面,最终形成一个全方位的云平台容错能力评估系统,该系统是用JAVA实现的。
- 作为参与者,我主要负责的是Hadoop平台下的人为配置故障注入测试,软件健壮性测试,过载测试以及块校验故障测试和最后评估系统中的平台节点状态监控模块的实现。
- 人为配置故障注入测试,是通过写一个自动化更改hadoop配置的工具,更改hadoop配置文件的参数,主要有三种错误:拼写错误,语义错误(认知层次错误),结构错误(配置文件内容重复,缺失,配置结构错误),主要更改的文件包括,core-default.xml,hdfs-default.xml, mapred.default.xml
- 软件健壮性,用的工具是findbugs, findbugs是一种静态的java代码分析工具,寻找真正的缺陷和潜在的性能问题,尽可能减少误报率,谷歌,Sun,Oracle等公司都在用findbugs来寻找代码的缺陷。 主要检查bytecode中的bug patterns,如NullPoint空指针检查、没有合理关闭资源、字符串相同判断错(==,而不是equals)等。
Bad practice 坏的实践 一些不好的实践,下面列举几个:
HE: 类定义了equals(),却没有hashCode();或类定义了equals(),却使用Object.hashCode();或类定义了hashCode(),却没有equals();或类定义了hashCode(),却使用Object.equals();类继承了equals(),却使用Object.hashCode()。
SQL:Statement 的execute方法调用了非常量的字符串;或Prepared Statement是由一个非常量的字符串产生。
DE: 方法终止或不处理异常,一般情况下,异常应该被处理或报告,或被方法抛出。
Correctness 一般的正确性问题
可能导致错误的代码,下面列举几个:
NP: 空指针被引用;在方法的异常路径里,空指针被引用;方法没有检查参数是否null;null值产生并被引用;null值产生并在方法的异常路径被引用;传给方法一个声明为@NonNull的null参数;方法的返回值声明为@NonNull实际是null。
Nm: 类定义了hashcode()方法,但实际上并未覆盖父类Object的hashCode();类定义了tostring()方法,但实际上并未覆盖父类Object的toString();很明显的方法和构造器混淆;方法名容易混淆。
SQL:方法尝试访问一个Prepared Statement的0索引;方法尝试访问一个ResultSet的0索引。
UwF:所有的write都把属性置成null,这样所有的读取都是null,这样这个属性是否有必要存在;或属性从没有被write。
Internationalization 国际化
当对字符串使用upper或lowercase方法,如果是国际的字符串,可能会不恰当的转换。
Malicious code vulnerability 可能受到的恶意攻击
如果代码公开,可能受到恶意攻击的代码,下面列举几个:
FI: 一个类的finalize()应该是protected,而不是public的。
MS:属性是可变的数组;属性是可变的Hashtable;属性应该是package protected的。
Multithreaded correctness 多线程的正确性
多线程编程时,可能导致错误的代码,下面列举几个:
ESync:空的同步块,很难被正确使用。
MWN:错误使用notify(),可能导致IllegalMonitorStateException异常;或错误的使用wait()。
No: 使用notify()而不是notifyAll(),只是唤醒一个线程而不是所有等待的线程。
SC: 构造器调用了Thread.start(),当该类被继承可能会导致错误。
Performance 性能问题
可能导致性能不佳的代码,下面列举几个:
DM:方法调用了低效的Boolean的构造器,而应该用Boolean.valueOf(…);用类似Integer.toString(1) 代替new Integer(1).toString();方法调用了低效的float的构造器,应该用静态的valueOf方法。
SIC:如果一个内部类想在更广泛的地方被引用,它应该声明为static。
SS: 如果一个实例属性不被读取,考虑声明为static。
UrF:如果一个属性从没有被read,考虑从类中去掉。
UuF:如果一个属性从没有被使用,考虑从类中去掉。
Dodgy 危险的
具有潜在危险的代码,可能运行期产生错误,下面列举几个:
CI: 类声明为final但声明了protected的属性。
DLS:对一个本地变量赋值,但却没有读取该本地变量;本地变量赋值成null,却没有读取该本地变量。
ICAST: 整型数字相乘结果转化为长整型数字,应该将整型先转化为长整型数字再相乘。
INT:没必要的整型数字比较,如X <= Integer.MAX_VALUE。
NP: 对readline()的直接引用,而没有判断是否null;对方法调用的直接引用,而方法可能返回null。
REC:直接捕获Exception,而实际上可能是RuntimeException。
ST: 从实例方法里直接修改类变量,即static属性
资源过载, 资源过载是指使CPU和内存的使用率达到一定的高负荷值,是测试hadoop节点在高负荷的情况下的容错能力。hadoop的mapreduce是用来进行海量数据的处理的,属于计算资源敏感性任务。将MapReduce子任务所在的JobTracker和TaskTracker所在的节点的CPU和内存资源占用,从而模拟资源过载时对MR任务的执行的影响。MEM占用就是通过不断的malloc内存使内存达到一定阀值,然后通过一定方法保持他不被回收。CPU占用就是先通过sysconf函数来获得CPU的核数,然后每个CPU核心都启动一个线程并使用pthread_setaffinity_np函数绑定在对应的CPU核心上,然后线程定期获取CPU的利用率,并通过调整CPU时间片的空闲时间与占用比例来使CPU的使用稳定在阀值附近。
节点级和进程级故障注入:模拟节点宕机,和进程失效,通过杀死进程,是节点关机等
网络故障注入:流量控制器--tc工具,在流量输入输出端口上建立一个队列进行流量控制,TC在IP层与网卡层之间进行干扰。的netem模块,主要可以实现网络的丢包,延时,乱序,数据包副本等网络错误。
‘hdfs文件系统故障注入包括两部分,包括数据块文件进行故障注入和数据块校验文件进行故障注入。DataNode都有数据块的校验文件,如果校验文件发生错误的话就会发生故障。数据块文件就是通过文件名找到对应的数据块的存储位置,然后更改数据块的权限或者是破坏数据块数据,进而使得该数据开文件不好用。检验文件可以通过两个方面来着手,一个是通过更改校验文件的本身,另一个是从数据方面入手,更改hadoop源码。Hadoop本身就提供Hadoop-FI接口来对hadoop源码CheckSum类进行故障注入。
节点监控模块实现,我是使用一种ssh的远程登录jar包进行linux系统的ssh远程登录,然后远程执行命令,并获取执行结果。这样实现了节点的信息采集,包括节点的CPU状态,系统IO状态,MEM状态,硬盘状态,网络IO状态等等,分别用读取mpstat -P -ALL, top,iostat,df -h, netstat等等指令获取响应信息,并通过jfreechart动态画出对应的图像。
项目困难点:首先是要学习的东西比较多,首先得对hadoop整个的工作流程以及源码有一定的了解,整个过程比较繁杂,得分模块一块一块的进行解决。找到哪些地方可以进行故障注入,以及采取什么样的故障注入方法都是非常需要考虑的。因此该项木的困难点就是相关文献,文章的查找,无论是看论文,还是上网查资料都或非了很多的时间。除了故障注入以外,还要对故障注入后系统的反应做出记录,整个过程必须非常繁杂,只有一步一个脚印方可完成。