




版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
第一篇次并行封等到名計(jì)算
第1章并行計(jì)算與云計(jì)算........2
U并行計(jì)算到云計(jì)算的演變..........2
1.2云計(jì)算需要定義嗎?.......4
1.3云計(jì)算是否是新瓶裝舊酒..........5
1.4MP1與Hadoop,不同學(xué)科
學(xué)者的選擇.…6
1.5云計(jì)算與瀏覽器.........8
第2章MPI并行計(jì)算環(huán)境的建立..........10
2.1配置前的準(zhǔn)備工作....10
2.2掛載NFS文件系統(tǒng).........11
2.3配置ssh實(shí)現(xiàn)MPI節(jié)點(diǎn)間
用戶的無(wú)密碼訪問(wèn)..........12
2.4安裝MPICH2......................12
2.5建立并行計(jì)算環(huán)境時(shí)的
注意事項(xiàng).…..…14
第3章并行計(jì)算時(shí)代的程序設(shè)計(jì)方法.……15
3.1最簡(jiǎn)單的并行程序..........15
3.2獲取進(jìn)程標(biāo)志和機(jī)器名...........18
3.3有消息傳遞功能的并行程序...........20
3.4MonteCarlo法在并行程序設(shè)計(jì)
中的應(yīng)用.........23
3.5并行計(jì)算中節(jié)點(diǎn)間的
Reduce操作.25
3.6用MPI的6個(gè)基本函數(shù)實(shí)現(xiàn)
Reduce函數(shù)功能.......28
3.7計(jì)算與通信的并行.—30
3.8節(jié)點(diǎn)間自定義復(fù)雜數(shù)據(jù)
結(jié)構(gòu)的傳輸.?34
3.9MP1與MySQL數(shù)據(jù)庫(kù)的
結(jié)合應(yīng)用.........37
3.10設(shè)計(jì)MPI并行程序時(shí)的
注意事項(xiàng)…41
第4章從MP1走向云計(jì)算.....43
4.1MPI沒(méi)有分布式文件系統(tǒng)支持....43
4.2MPI無(wú)法應(yīng)對(duì)節(jié)點(diǎn)的失效.......44
4.3假如用MPI來(lái)構(gòu)建云計(jì)算系統(tǒng)...44
第二篇云計(jì)算的關(guān)鍵技術(shù)
第5章Map/Reduce是云計(jì)算的選擇嗎.....48
5.1Map/Reduce跨越5Q年的
歷史..........48
5.2實(shí)現(xiàn)Map/Reduce的C語(yǔ)言實(shí)例.49
5.3采用MPI實(shí)現(xiàn)并行化的
Map/Reduce功能.......51
第6章Hadoop技術(shù)..58
6.1Hadoop與MPI在數(shù)據(jù)處理上的
對(duì)比..........58
6.2Hadoop的主從式結(jié)構(gòu).59
6.2.1主從式文件系統(tǒng)HDFS.......59
6.2.2主從式計(jì)算系統(tǒng)
Map/Reduce.........60
6.2.3文件分塊策略分析........61
6.3Hadoop文件系統(tǒng)HDFS的
前輩GFS.........64
6.4構(gòu)建云文件系統(tǒng)需要解決的
關(guān)鍵問(wèn)題...……66
6.5云計(jì)算不相信節(jié)點(diǎn)服務(wù)器........67
6.6揭密云計(jì)算架構(gòu)下的典型
服務(wù)器----Google務(wù)器........68
6.6.1Google服務(wù)器概述.......68
6.6.2揭開(kāi)Goo原e服務(wù)器的
神秘面紗.......69
6.6.3Google服務(wù)器的配置
情況.69
6.6.4Goog/e服務(wù)器的性能
評(píng)測(cè).73
第7章Hadoop環(huán)境的建立....75
7.1Hadoop配置環(huán)境.....75
7.2配置ssh實(shí)現(xiàn)Hadoop結(jié)點(diǎn)間
用戶的無(wú)密碼訪問(wèn).………76
7.3JDK的安裝配置.....76
7.4Hadoop的安裝配置........77
7.5Hadoop中的HelloWorld..................81
7.6C語(yǔ)言程序在Hadoop
上運(yùn)行.......82
第8章動(dòng)手做自己的云計(jì)算
V0.01系統(tǒng).....86
8.1系統(tǒng)總體分析...........86
8.1.1系統(tǒng)架構(gòu)........86
8.1.2文件分布式存儲(chǔ)流程.....88
8.1.3計(jì)算與存儲(chǔ)的整合流程......88
8.2管理節(jié)點(diǎn)程序設(shè)計(jì)與分析.......89
8.2.1管理節(jié)點(diǎn)服務(wù)器程序
主函數(shù)...........90
8.2.2管理節(jié)點(diǎn)各線程函數(shù)的
設(shè)計(jì)..93
8.2.3主服務(wù)器中其他函數(shù)的
設(shè)計(jì)..95
8.3子節(jié)點(diǎn)程序分析.......98
8.3.1子節(jié)點(diǎn)主函數(shù).....99
8.3.2子節(jié)點(diǎn)各線程函數(shù)設(shè)計(jì)..102
8.4客戶端API設(shè)計(jì).....107
8.4.1客戶端文件的存儲(chǔ).......108
8.4.2客戶端啟動(dòng)子節(jié)點(diǎn)計(jì)算...113
8.4.3客戶端應(yīng)用的簡(jiǎn)單實(shí)例...114
8.5客戶端應(yīng)用開(kāi)發(fā)實(shí)例115
第三篇云計(jì)算應(yīng)用實(shí)例
第9章基于不可信服務(wù)器節(jié)點(diǎn)的云計(jì)算
基礎(chǔ)架構(gòu).......118
9.1云計(jì)算基礎(chǔ)架構(gòu)的應(yīng)用場(chǎng)景........118
9.2云計(jì)算基礎(chǔ)架構(gòu)......120
9.3基于單向指針目錄映射的分層
用戶隔離......121
9.4云文件系統(tǒng)的物理存儲(chǔ)管理..……123
9.5云存儲(chǔ)的安全級(jí)別劃分..........124
9.6計(jì)算和存儲(chǔ)的整合.……125
9.7計(jì)算和存儲(chǔ)的遷移.......126
9.8任務(wù)的可并行性和分類分析........127
9.9簡(jiǎn)化的服務(wù)器級(jí)粗粒度計(jì)算和
存儲(chǔ)資源分配方案...130
9.10數(shù)據(jù)的云計(jì)算系統(tǒng)之旅.......133
第10章云計(jì)算與智能.........135
W.1云計(jì)算的智能與人類
智能的比較..........735
10.2云計(jì)算提升終端智能..........136
10.3云計(jì)算智能與MonteCarb
方法.......138
10.4云計(jì)算時(shí)代不確定性智能算法
示例——模擬諧振子算法....138
10.4.1簡(jiǎn)諧振動(dòng)的描述.........139
10.4.2模擬諧振子算法描述......141
1043模擬諧振子算法流程......144
10.4.4模擬諧振子算法分析......146
10.4.5模擬諧振子算法應(yīng)用于
旅行商問(wèn)題.....149
10.4.6模擬諧振子算法在連續(xù)
和非線性優(yōu)化問(wèn)題中的
應(yīng)用.............161
10.4.7模擬諧振子算法的隱含
并行性........162
10.5云計(jì)算中的人工智能..........162
第11章云計(jì)算企業(yè)之間的競(jìng)爭(zhēng)性
分析........164
11.1云計(jì)算技術(shù)流派分析...........164
存儲(chǔ)型一數(shù)據(jù)密集云
計(jì)算平臺(tái).....164
11.1.2計(jì)算型一計(jì)算密集云
計(jì)算平臺(tái).....165
11.1.3綜合云計(jì)算平臺(tái)........165
11.2國(guó)際云計(jì)算公司分析...........165
1121云計(jì)算技術(shù)的提出者
Google..................166
11.2.2“端”的霸主微軟......166
11.2.3藍(lán)色巨人IBM的藍(lán)云....167
11.2.4云計(jì)算的市場(chǎng)先行者
Amazon公司.168
11.2.5Salesforce從SaaS走入
云中...........168
11.2.6熱愛(ài)白皮書(shū)的Sun...........169
11.2.7EMC云計(jì)算的核心是
虛擬化........170
11.2.8漁翁得利的思科.........170
11.3國(guó)內(nèi)云計(jì)算公司分析............171
11.3.1擁有基礎(chǔ)設(shè)施的
世紀(jì)互聯(lián).....171
11.3.2阿里巴巴下決心
入云...........172
11.3.3中國(guó)移動(dòng)的BigCloud......172
11.3.4國(guó)產(chǎn)旗幟友友云計(jì)算
平臺(tái)...........173
11.3.5曙光高性能與云計(jì)算......173
11.3.6展覽也要云..…173
11.4開(kāi)源云計(jì)算平臺(tái)分析............174
11.5國(guó)際國(guó)內(nèi)云計(jì)算平臺(tái)提供商
對(duì)比研究..175
11.6產(chǎn)業(yè)綜合分析.......179
H.6.1云計(jì)算與網(wǎng)絡(luò)設(shè)備商的
關(guān)系...........179
11.6.2云計(jì)算與移動(dòng)通訊運(yùn)
營(yíng)商的關(guān)系..…180
11.6.3云計(jì)算與服務(wù)器提
供商的關(guān)系..…180
1164云計(jì)算與應(yīng)用程序開(kāi)
發(fā)商的關(guān)系..…181
后記:未來(lái)的計(jì)算機(jī)一不確定性和
隱含并行計(jì)算...........182
附錄:計(jì)算力的標(biāo)準(zhǔn)Unpack測(cè)試詳細(xì)
指南..........186
參考文獻(xiàn)196
面對(duì)云計(jì)算,有的人越來(lái)越糊涂,經(jīng)常聽(tīng)到有人用云里霧里來(lái)形容現(xiàn)在的云計(jì)算。云計(jì)算系
統(tǒng)
確實(shí)是一個(gè)龐大和綜合的系統(tǒng),即使是國(guó)際大公司也不敢貿(mào)然進(jìn)軍云計(jì)算領(lǐng)域,大量的企業(yè)
不
是將自己的傳統(tǒng)技術(shù)優(yōu)勢(shì)稱為云計(jì)算,就是雷聲大雨點(diǎn)小的觀望。一般開(kāi)發(fā)者更是不適應(yīng)在
機(jī)
群的環(huán)境下工作,所以本章將用一個(gè)簡(jiǎn)單的例子來(lái)展現(xiàn)云計(jì)算的基本特點(diǎn)和技術(shù)開(kāi)發(fā)方式,
我
們并不保證這個(gè)系統(tǒng)是一個(gè)完善的系統(tǒng),但它具備了云計(jì)算的一些基本特點(diǎn)如計(jì)算和存儲(chǔ)的
整
合、計(jì)算向存儲(chǔ)的遷移、文件的分布式存儲(chǔ)、計(jì)算的并行化等,我們對(duì)這些功能采用了最簡(jiǎn)
單
的實(shí)現(xiàn)方法以使大多數(shù)讀者能從中體會(huì)到云計(jì)算技術(shù)的核心理念,所以我們命名這個(gè)系統(tǒng)為
云
計(jì)算V0.01,運(yùn)行環(huán)境為Windows.
8.1
系統(tǒng)總體分析
我們進(jìn)行系統(tǒng)總體結(jié)構(gòu)設(shè)計(jì)時(shí)主要著眼于云計(jì)算基本特征的實(shí)現(xiàn),不考慮系統(tǒng)中很多細(xì)節(jié)性
的
要求和高級(jí)要求,并采用中等水平的讀者能完成的難度設(shè)計(jì)。
設(shè)計(jì)需要實(shí)現(xiàn)的基本功能如下。
(1)向開(kāi)發(fā)云應(yīng)用的客戶提供可以調(diào)用的API函數(shù),利用API函數(shù)實(shí)現(xiàn)對(duì)云計(jì)算系統(tǒng)的訪
問(wèn)。
(2)實(shí)現(xiàn)分布式的文件存儲(chǔ)。
(3)實(shí)現(xiàn)計(jì)算向存儲(chǔ)的遷移,使計(jì)算和存儲(chǔ)在同一個(gè)節(jié)點(diǎn)完成,避免數(shù)據(jù)在網(wǎng)絡(luò)中的傳送。
(4)向用戶隔離計(jì)算的并行性和存儲(chǔ)的分布性,用戶無(wú)需關(guān)心系統(tǒng)具體的操作過(guò)程。
(5)初步實(shí)現(xiàn)對(duì)數(shù)據(jù)求和及求最大值的處理,演示云計(jì)算的基本特點(diǎn)。讀者可以通過(guò)增加處
理
函數(shù)實(shí)現(xiàn)更多的計(jì)算功能。
8.1.1
系統(tǒng)架構(gòu)
云計(jì)算V0.01系統(tǒng)是一個(gè)完全模型化的實(shí)驗(yàn)用系統(tǒng),開(kāi)發(fā)和運(yùn)行環(huán)境為Windows系統(tǒng),通過(guò)
對(duì)該
系統(tǒng)的學(xué)習(xí)使讀者對(duì)云計(jì)算技術(shù)的基本要點(diǎn)有一定的了廨,云計(jì)算V0.01將云計(jì)算設(shè)備分為
3個(gè)
角色:管理節(jié)點(diǎn)、子節(jié)點(diǎn)和客戶端。管理節(jié)點(diǎn)和子節(jié)點(diǎn)構(gòu)成了云計(jì)算的服務(wù)器端,客戶端通
過(guò)
對(duì)API的調(diào)用實(shí)現(xiàn)對(duì)云計(jì)算系統(tǒng)的訪問(wèn),并通過(guò)API整合為不同的應(yīng)用程序。為了簡(jiǎn)化系統(tǒng)
的設(shè)
計(jì)難度,我們?cè)谧鲈朴?jì)算V0.01時(shí)限定所做的計(jì)算任務(wù)包括對(duì)大數(shù)據(jù)量數(shù)組求和、求最大值
等操
作,讀者可通過(guò)實(shí)際的系統(tǒng)體會(huì)存儲(chǔ)的分布化與計(jì)算的并行化的關(guān)系,并理解計(jì)算向存儲(chǔ)遷
移
的作用。云計(jì)算V0.01沒(méi)有實(shí)現(xiàn)存儲(chǔ)的副本策略,因此暫時(shí)不能處理節(jié)點(diǎn)失效的問(wèn)題,這也
是為
了降低系統(tǒng)難度的需要。以下的系統(tǒng)架構(gòu)方法僅供參考和學(xué)習(xí),并且不代表我們贊成這一架
構(gòu),
不同的讀者可以設(shè)計(jì)不同的系統(tǒng)架構(gòu)。
系統(tǒng)的整個(gè)架構(gòu)如圖8.1所示,這種架構(gòu)方式是一個(gè)以客戶端為核心的架構(gòu)方法,系統(tǒng)中的
所有
操作指令均由客戶端發(fā)出,管理節(jié)點(diǎn)不和任一子節(jié)點(diǎn)作數(shù)據(jù)和指令的通信,管理節(jié)點(diǎn)的作用
主
要是維護(hù)root.dat和node.dat兩個(gè)系統(tǒng)文件。rootdat文件存儲(chǔ)著現(xiàn)在系統(tǒng)中已注冊(cè)的用戶名
及該用
戶所對(duì)應(yīng)的文件分塊描述文件所在節(jié)點(diǎn)的IP地址,系統(tǒng)利用這一文件可實(shí)現(xiàn)用戶的注冊(cè)、認(rèn)
證
及用戶登錄后獲得文件分塊描述文件所在節(jié)點(diǎn)的IP地址。node.dat文件則維護(hù)著整個(gè)云計(jì)算
系統(tǒng)
所有子節(jié)點(diǎn)的IP地址、端口、最大空間、剩余空間等信息,客戶端通過(guò)該文件能夠獲得整個(gè)
機(jī)
群的信息,從而實(shí)現(xiàn)向各子節(jié)點(diǎn)的直接連接。客戶端從管理節(jié)點(diǎn)獲得了相關(guān)的系統(tǒng)信息后將
根
據(jù)這一信息直接向各個(gè)子節(jié)點(diǎn)發(fā)起連接,完成文件存儲(chǔ)及計(jì)算的功能,這大大提高了數(shù)據(jù)傳
輸
的速率,減輕了管理節(jié)點(diǎn)的負(fù)荷。各用戶文件的具體分塊和存儲(chǔ)方式被系統(tǒng)用該用戶的用戶
名
(username)作為文件名的文件分塊描述文件存儲(chǔ)于其中的一個(gè)子節(jié)點(diǎn),這一子節(jié)點(diǎn)的IP可
在
root,dat文件中找到。
圖8.1云計(jì)算V0.01的系統(tǒng)結(jié)構(gòu)
在云計(jì)算V0.01系統(tǒng)中不同角色間存在兩類數(shù)據(jù)的傳送:一類是命令數(shù)據(jù)CMD,管理節(jié)點(diǎn)和
子
節(jié)點(diǎn)通過(guò)命令數(shù)據(jù)判斷自己下一步所要完成的任務(wù);一類是信息數(shù)據(jù),這類數(shù)據(jù)是系統(tǒng)要完
成
相關(guān)任務(wù)所需要數(shù)據(jù),如系統(tǒng)描述信息、文件信息等,這類數(shù)據(jù)的數(shù)據(jù)量相對(duì)較大。由于采
用
了計(jì)算向存儲(chǔ)的遷移策略,系統(tǒng)中出現(xiàn)用戶文件數(shù)據(jù)傳輸?shù)那闆r很少,這大大提高了系統(tǒng)的
運(yùn)
行效率。
8.1.2
文件分布式存儲(chǔ)流程
系統(tǒng)在進(jìn)行文件存儲(chǔ)時(shí)先通過(guò)客戶端連接管理節(jié)點(diǎn),讀取rootdat文件數(shù)據(jù),檢驗(yàn)是否有該
用戶
存在,并獲取用戶數(shù)據(jù)塊文件所在節(jié)點(diǎn)的IP地址。通過(guò)讀取node.dat文件從管理節(jié)點(diǎn)讀取子
節(jié)點(diǎn)
的IP地址的列表,根據(jù)以上信息完成對(duì)數(shù)據(jù)的分割,啟動(dòng)多線程函數(shù)同時(shí)連接各子節(jié)點(diǎn)將數(shù)
據(jù)
分別保存在各個(gè)節(jié)點(diǎn)上,最后更新username表以備訪問(wèn)時(shí)重新找到文件的分布情況。
uesername
文件將被存儲(chǔ)于某一節(jié)點(diǎn)上,管理節(jié)點(diǎn)會(huì)根據(jù)現(xiàn)有username文件的分布情況向用戶分配一個(gè)
節(jié)
點(diǎn)的IP地址存放username文件,文件名就是該用戶的用戶名,由于用戶名在系統(tǒng)中是惟一
的,
所以每個(gè)用戶的username也是惟一的,不會(huì)造成混亂,如圖8.2所示。
圖8.2文件的分布式存儲(chǔ)流程
8.1.3
計(jì)算與存儲(chǔ)的整合流程
如圖&3所示,在云計(jì)算V0.01系統(tǒng)中,我們利用獲得的用戶名、文件名、數(shù)據(jù)塊號(hào)以及數(shù)據(jù)
分
塊信息文件的IP地址信息,可以惟一地確定任一數(shù)據(jù)塊的位置和文件名,客戶端同時(shí)向各個(gè)
子
節(jié)點(diǎn)發(fā)送啟動(dòng)計(jì)算的命令,各節(jié)點(diǎn)就地讀取數(shù)據(jù)塊本她文件,并對(duì)其進(jìn)行計(jì)算,計(jì)算完成后
發(fā)
送回客戶端匯總得到最后的結(jié)果。
圖8.3計(jì)算與存儲(chǔ)的整合流程
這一計(jì)算過(guò)程不用移動(dòng)任何數(shù)據(jù),對(duì)于數(shù)據(jù)的處理就在存儲(chǔ)數(shù)據(jù)塊的節(jié)點(diǎn)完成,系統(tǒng)根據(jù)客
戶
端的指令,將計(jì)算遷移到節(jié)點(diǎn)上分布式的完成,大大提高了計(jì)算效率,避免了數(shù)據(jù)在網(wǎng)絡(luò)中
的
大量流動(dòng)所造成的效率下降,對(duì)于海量數(shù)據(jù)來(lái)說(shuō),這一做法的效果是相當(dāng)明顯的。對(duì)于不同
的
數(shù)據(jù),我們可以定義不同的數(shù)據(jù)處理方法,從而擴(kuò)展系統(tǒng)的應(yīng)用領(lǐng)域。
8.2
管理節(jié)點(diǎn)程序設(shè)計(jì)與分析
管理節(jié)點(diǎn)在云計(jì)算V。.01系統(tǒng)中只與客戶端進(jìn)行通信,存儲(chǔ)系統(tǒng)中的節(jié)點(diǎn)信息和用戶注冊(cè)信
息,
并不負(fù)責(zé)任務(wù)的調(diào)度工作。
在管理節(jié)點(diǎn)我們將保存root.dat和node.dat兩個(gè)系統(tǒng)信息文件。root.dat文件保存用戶名及該
用戶文
件系統(tǒng)所在的子節(jié)點(diǎn)的IP地址,采用userinfo數(shù)據(jù)結(jié)構(gòu)來(lái)描述。客戶端程序只有獲得了子節(jié)
點(diǎn)JP
地址才能和該子節(jié)點(diǎn)直接建立連接獲取子節(jié)點(diǎn)上的用戶存儲(chǔ)情況文件,該文件的文件名就是
用
戶的用戶名,通過(guò)這一個(gè)文件可以知道數(shù)據(jù)的具體存儲(chǔ)情況,從而由客戶端直接與數(shù)據(jù)塊存
儲(chǔ)
節(jié)點(diǎn)建立連接。nodedat文件保存了云計(jì)算系統(tǒng)的所有子節(jié)點(diǎn)的1P地址、總空間和可用空間
等信
息,由nodclnfo數(shù)據(jù)結(jié)構(gòu)來(lái)描述。
管理節(jié)點(diǎn)各函數(shù)調(diào)用關(guān)系如圖8.4所示。
圖8.4管理節(jié)點(diǎn)函數(shù)調(diào)用結(jié)構(gòu)
8.2.1
管理節(jié)點(diǎn)服務(wù)器程序主函數(shù)
管理節(jié)點(diǎn)主程序?yàn)檎麄€(gè)管理程序的主入口,通過(guò)4個(gè)線程函數(shù)來(lái)監(jiān)聽(tīng)并完成客戶端所提交的
任
務(wù)。
程序8.1
/*文件名mainsever.cpp*/
//定義管理節(jié)點(diǎn)服務(wù)器程序的入口點(diǎn)
voidtcst();
int_tmain(intargc,_TCHAR*argv[J)
{
openfilcO;//獲得root,dat、node,dat的文件指針
tcstO;//該函數(shù)完成對(duì)主服務(wù)器的配置工作
WSADATAwsn;
intret:-0;
intPORT=5100;
SOCKETs_socket;
SOCKETc_sockct;
structsockaddr__ins_socknddr;
structsockaddjinc_socknddr;
intc__socknddr__lcn—sizcof(c_socknddr);
ret=WSAStartup(MAKEWORD(2,2),&wsa);
if(ret!=O)
{
cout<<"InkWinSockfailed:"<<ret<<cndl;
return0;
}
if((s_socket=socket(AF」NET,SOCK_STREAMfJPPROTO_TCP))==SOCKET_ERROR)
{
cout<<"CreateSocketFailed:"vvWSAGetLastErrorQ<<end/;
WSAClennupO;
return0;
s_sockaddr.sin_family=AF_1NET;
s_sockaddr.sin_port—htons(PC)RT);
s_sockaddr.sin_addr.s_addr=htonl(INADDR_ANY);
if(bind(s_socketf(SOCKADDR*)&s_sockaddr,sizeof(s_sockaddr))==SOCKET_ERROR)
{
cout<<"bindfailed:"<<WSAGetLustErrorQ?endl;
c/osesocket(s_socket);
WSAClennupO;
return0;
/
if(listen(s_socket,5)=-SOCKET_ERROR)
{
cout<<"ListenFailed:"vvWSAGetLastErrorQ?endl;
closesockct(s_socket);
WSAClcanupO;
return0;
}
CMDemd;
//進(jìn)入循環(huán)接收來(lái)自客戶端的操作命令emd
whilc(l)
{
c_socket—accept(s_socket,(SOCKADDR*)&c_sockaddr,&c_socknddr_len);
r€cv(c_sockct,(char*)&cmd,sizcof(CMD),0);〃從客戶端獲取操作命令
SOCKET*tsock=(SOCKET*)malloc(sizeof(SOCI<ET));
*tsock—c_socket;
switch(cmd)
{
caseUSERADD:
_beginthreadex(NULL,0,&usernddthread,tsock,OfNULL);//進(jìn)入增加用戶線程
break;
caseUSERGET:
_beginthreadex(NULL,Of&uscrgctdirciidftsock,0,NULL);//進(jìn)入獲取用戶信息
線程
caseUSERDEL:
_beginthreadex(NULL,0,&userdelthrend,tsock,0,NULL);//刪除用戶,暫未定
義
caseGETNODE:
_beginthreadex(NULL,0,&getnodeaddrthrendftsock,0,NULL);〃進(jìn)入獲取節(jié)點(diǎn)
信息線程
default:
break;
}
}
cin.getQ;
cin.getO;
return0;
}
//test。函數(shù)用于配置各子節(jié)點(diǎn)的IP、端口等信息,并將信息存儲(chǔ)到管理節(jié)點(diǎn)的ncde.dat文件
voidtest()
{
cout?"輸入地址信息”vvendl;
charip[16];
intport:=5101;
while(l)
{
cout<<〃輸入IP"<<cndl;
scanf(”%s”jp);
if(strcmp(ip,"0")--0)
break;
if(nodendd(ipfport,1024*10)——0)
cout?〃該記錄已經(jīng)存在"wcncll;
}
cout?〃主服務(wù)器配置完成“vvendl;
}
上面的管理服務(wù)器主程序在5100端口監(jiān)聽(tīng)來(lái)自客戶端的連接及操作命令,其命令由emd定
根據(jù)從客戶端接收到的命令進(jìn)入不同的處理線程,在本系統(tǒng)已實(shí)現(xiàn)的功能有添加用戶功能、
獲
取用戶信息功能和獲取節(jié)點(diǎn)信息功能。管理節(jié)點(diǎn)服務(wù)器在啟動(dòng)時(shí)就調(diào)用心埼函數(shù)完成對(duì)子節(jié)
點(diǎn)
信息的添加及配置。節(jié)點(diǎn)信息被存到node.dat文件,用戶信息被存到root.dat。在用戶需要進(jìn)
行數(shù)
據(jù)訪問(wèn)時(shí)將讀取這兩個(gè)文件獲得當(dāng)前云計(jì)算系統(tǒng)所有已接入系統(tǒng)的子節(jié)點(diǎn),并判斷當(dāng)前用戶
是
否存在,如存在則返回其文件分配信信息存儲(chǔ)位置。
我們要注意的是在現(xiàn)在這個(gè)系統(tǒng)中管理節(jié)點(diǎn)并不和任何的子節(jié)點(diǎn)進(jìn)行通信,也不直接協(xié)調(diào)子
節(jié)
點(diǎn)的工作。用戶在獲取相關(guān)信息后將直接與子節(jié)點(diǎn)聯(lián)系進(jìn)行操作和數(shù)據(jù)訪問(wèn),這樣可以大大
減
輕主節(jié)點(diǎn)的負(fù)載。
在管理節(jié)點(diǎn)程序中我們定義了一些常用的數(shù)據(jù)結(jié)構(gòu)主要有userinf。,該數(shù)據(jù)結(jié)構(gòu)與root.dat文
件有
若包括用戶名、用戶數(shù)據(jù)配置文件所在節(jié)點(diǎn)的IP地址等信息,因?yàn)橛脩魯?shù)據(jù)文件的信息沒(méi)
有
存放在管理節(jié)點(diǎn)而是放在某一個(gè)子節(jié)點(diǎn)上的,客戶端要訪問(wèn)文件數(shù)據(jù)首先要從管理節(jié)點(diǎn)的
rootdat文件中獲取該用戶數(shù)據(jù)配置文件所在節(jié)點(diǎn)的IP地址,再通過(guò)該IP地址獲取數(shù)據(jù)的存
儲(chǔ)信
息。另一個(gè)數(shù)據(jù)結(jié)構(gòu)是nodelnfd,該數(shù)據(jù)結(jié)構(gòu)與node.dat文件有關(guān),包括節(jié)點(diǎn)IP、端口、芾
點(diǎn)總
容量、可用空間等,系統(tǒng)中所有節(jié)點(diǎn)的相關(guān)內(nèi)容都采用這一數(shù)據(jù)結(jié)構(gòu)存入nodcdat文件。
主節(jié)點(diǎn)服務(wù)器程序部分參數(shù)及數(shù)據(jù)結(jié)構(gòu)的定義如程序8.2所示。
程序8.2
/*文件名melem.h*/
^defineUSERADD1//添加用戶
^defineUSERGET2〃獲取用戶信息
#defineUSERDEL3
#defineGETNODE4//獲取節(jié)點(diǎn)信息
#defineBLOCKSIZE1024//定義文件塊大小
typedefintCMD;//CMD為命令標(biāo)識(shí)
/*此結(jié)構(gòu)體寫(xiě)入root.dat文件*/
typedefstruct
{
charuser[20];〃用戶名
charip[16];〃用戶數(shù)據(jù)配置文件所在節(jié)點(diǎn)的IP地址
/ntport;
}uscrlnfo;
/*此結(jié)構(gòu)體寫(xiě)入node.dat文件*/
typedefstruct
{
charip[16];//存儲(chǔ)節(jié)點(diǎn)的IP地址
import;〃端口號(hào)
intuserNum;//用戶數(shù)目
_off_ttotalsize;//節(jié)點(diǎn)的總?cè)萘?/p>
freesize;//節(jié)點(diǎn)的可用空間
}nodclnfo;
typedefstruct
(
charip[16];
intport;
}nodeaddr;
8.2,2
管理節(jié)點(diǎn)各線程函數(shù)的設(shè)計(jì)
管理節(jié)點(diǎn)程序的功能基本是由其定義的4個(gè)線程函數(shù)(其中刪除用戶未定義)提供的,這些
函數(shù)
的功能主要是完成用戶信息的注冊(cè)、服務(wù)器節(jié)點(diǎn)信息的管理和用戶數(shù)據(jù)配置信息的管理。管
理
節(jié)點(diǎn)可以看作是一個(gè)信息的中轉(zhuǎn)站,其自身并不完成任何的數(shù)據(jù)操作和處理工作。
各線程的函數(shù)定義如下。
1
.增加新用戶線程函數(shù)
程序8.3
/*文件名znthread.epp*/
/*增加新的用戶,用于新用戶注冊(cè)功能*/
unsigned_stdcnlluscraddthrcad(LPVOIDp)
{
SOCKET*tsock=(SOCKET*)p;
structsockaddr_intaddr;
intlen=20;
char*username=(char*)malloc(len*sizeof(chnr));
rccv(*tsock,username,len,0);〃從客戶端接收用戶名
intresult=useradd(username);
send(*tsockf(char*)&result,size。f(int),0);
dosesocket(*tsock);
frcc(uscrnnmc);
free(tsock);
return1;
}
函數(shù)uscraddthreadO接收來(lái)自于客戶端的新注冊(cè)用戶名,調(diào)用uscradd。函數(shù)將用戶名及存儲(chǔ)該
用
戶文件信息的節(jié)點(diǎn)IP地址寫(xiě)入主節(jié)點(diǎn)的rootdat文件,客戶端訪問(wèn)該文件可以獲得某一用戶
的文
件存儲(chǔ)信息文件所在的子節(jié)點(diǎn)IP地址,該文件的文件名就是用戶名。
2
.獲取用戶信息線程函數(shù)
程序8.4
/*文件名mthread.cpp*/
/*客戶端獲取用戶信息文件*/
unsigned_stdciillusergetthread(LPVOIDp)
{
SOCKET*tsock=(SOCKET*)p;
structsockaddr_intaddr;
intlen—20;
char*username—(char*)malloc(len);
userinfo*user—(userinfo*)molloc(sizeof(userinfo));
recv(*tsock,username,len,0);
cout<<"接收到的用戶名:〃<vusername<<cndl;
/*根據(jù)用戶名讀取rootle中的用戶及對(duì)應(yīng)存儲(chǔ)文件描述信息的子節(jié)點(diǎn)1P*/
if(userget(usernnme,user)——0)
{
cout<<"getfalse"<<cndl;
strepy(user->user,〃0");
strcpy(uscr->ip,"");
user->port—0;
}
cout<<"int_dircnd:,r<<uscr->uscr<<",r<<uscr->ip<<,r:rr<<uscr->port<<cndl;
scnd(*tsockt(char*)uscr,sizcof(uscrlnfo),0);
closesocket:(*tsock);
frec(uscrnamc);
free(user);
return1;
}
函數(shù)usergetthread。接收來(lái)自客戶端的用戶名,并在root.dat文件中查找該用戶名對(duì)應(yīng)的
userinfo
數(shù)據(jù)結(jié)構(gòu),并傳回紿客戶端。其中調(diào)用userget。函數(shù)從rootdat讀取與username對(duì)應(yīng)的uscrlnfo
信
息。通過(guò)調(diào)用這一函數(shù)客戶端可以知道對(duì)應(yīng)用戶的文件描述文件存儲(chǔ)在哪個(gè)子節(jié)點(diǎn)上,通過(guò)
連
接該子節(jié)點(diǎn)獲取文件的具體存儲(chǔ)方式??蛻舳嗽谡{(diào)用一這函數(shù)后將通過(guò)返回的IP地址與存儲(chǔ)
7
數(shù)據(jù)分塊描述情況文件的子節(jié)點(diǎn)進(jìn)行連接。
.文件分塊線程函數(shù)
程序8.5
/*文件名mthread.cpp*/
/*根據(jù)nodcdat文件中的節(jié)點(diǎn)信息,將數(shù)據(jù)塊分配到各節(jié)點(diǎn)*/
unsigned_stdca]]getnodenddrthrend(LPVOIDp)
{
SOCKET*tsock=(SOCKET*)p;
intbJocknuni—0;
nodeinfo*node—(nodeinfo*)mnlloc(sizeof(nodelnfd));
nodeaddr*naddr—(nodcaddr*)nialJoc(sizcof(nodcaddr));
recv(*tsock,(char*)&blocknumfsizeof(int),0);〃獲取數(shù)據(jù)塊個(gè)數(shù)
for(inti=0;i<blocknum;i++)
{
mcmsct(nodc,0,sizcof(nodclnfb));
memset(naddr,0,sizeof(nodenddr));
datagcmodu(nodc);〃獲取該數(shù)據(jù)塊的存儲(chǔ)位置
naddr->port—nodc->port;
strcpy(naddr->ip,node->ip);
scnd(*tsockf(char*)nnddr,sizcof(nodcaddr),0);〃該數(shù)據(jù)塊的存儲(chǔ)位置發(fā)送回客戶端
}
closesocket(*tsock);
frce(node);
frcc(naddr);
free(tsock);
return1;
}
函數(shù)浮modeaddrthread。接收來(lái)自客戶端的數(shù)據(jù)塊個(gè)數(shù),并為每個(gè)數(shù)據(jù)塊分配一個(gè)存儲(chǔ)節(jié)點(diǎn),
數(shù)
據(jù)塊的分配通過(guò)調(diào)用datagetnode。函數(shù)來(lái)完成,該函數(shù)按剩余空間最大的策略向各數(shù)據(jù)塊分
配存
儲(chǔ)節(jié)點(diǎn),并將分配結(jié)果發(fā)送回客戶端,由客戶端根據(jù)接收到的子節(jié)點(diǎn)IP直接連接子節(jié)點(diǎn)來(lái)完
成
文件的存儲(chǔ)工作,并將存儲(chǔ)結(jié)果寫(xiě)入子節(jié)點(diǎn)中的數(shù)據(jù)分塊描述文件中,以便系統(tǒng)在下次讀取
時(shí)
獲得數(shù)據(jù)的存儲(chǔ)情況。
8.2.3
主服務(wù)器中其他函數(shù)的設(shè)計(jì)
主服務(wù)器其他函數(shù)定義。
程序8.6
/*文件名mfilc.cpp*/
/*向node.datX件添加節(jié)點(diǎn)信息*/
intnodeadd(char*ip,hitport,_off_ttotalsizc)
{
nodeinfo*temp=(nodeinfo*)mulloc(sizeof(nodelnfo));
fseek(fp_node,0,0);
/*判斷該節(jié)點(diǎn)是否已存在*/
while(&ead(temp,sizeof(nodeinfo),1,fp_node)——1)
{
if(strcmp(temp->ipfip)——0&&temp->port——port)
{
frcc(tcmp);
return0;
}
}
strcpy(tcmp->ipfip);
temp->port-port;
tcmp->uscrNum—0;
temp->totalsize-totalsize;
temp->freesize—totulsize;
/*寫(xiě)入nodu.dat文件*/
fwritc(t:cmp9sizcof(nodclnfo),1,fp_node);
fseek(fp_node,0,0);
fflush(fp_nodc);
free(temp);
return1;
}
/*分配用戶數(shù)據(jù)描述文件存儲(chǔ)節(jié)點(diǎn)的IP*/
intusergetnode(nodelnfd*node)
{
nodeinfo*temp=(nodeinfo*)malloc(sizeof(nodeinfo));
fscck(fp__nodc,0,0);
intnum=0;
intno-0;
/*尋找已分配uesername文件最少的節(jié)點(diǎn)TP*/
if(fread(node,sizeof(nodeinfo),1,fp_node)/—1)
return0;
while(freiid(temp}sizeof(nodeinfo),7,fp_node)——1)
(
++num;
if(tcmp->uscrNum<node->userNum)
(
*node—*temp;
no=num;
}
/
memset(teinp,0,sizeof(nodeinfo));
*temp—*node;
temp->userNum+=1;
fscek(fp_nodc,no^sizcof(nodclnfo),0);
Avri【c(【cmp,sizeof(nodclnfo),1,fp_nodc);
fseek(fp_node,0,0);
fflush(fp_nodc);
frcc(tcmp);
return1;
}
/*將username及對(duì)應(yīng)存儲(chǔ)數(shù)據(jù)描述文件的節(jié)點(diǎn)IP寫(xiě)入rootdat文件*/
intuseradd(char*username)
(
uscrlnfo*tcmp—(uscrlnfo*)malloc(sizcof(uscrlnfo));
nodeinfo*node=(nodeinfo*)malloc(sizeof(nodeJnfo));
fseck(fp_uscr,Of0);
while(frend(temp,sizeof(userlnfo),1,fp_user)==1)
/*檢測(cè)該用戶名是否存在*/
if(strcmp(temp->user,username)==0)
{
free(temp);
frcc(nodc);
return0;//該用戶名已經(jīng)存在
}
if(usergetnode(node)==0)〃獲取該用戶數(shù)據(jù)描述文件存儲(chǔ)節(jié)點(diǎn)的IP,通過(guò)node參數(shù)傳出
return-1;//獲取節(jié)點(diǎn)失敗
memset(temp,0,si^eof(userlnfd));
strcpy(temp->userfusername);
strcpy(teinp->ipfnodc->ip);
temp->port—node->port;
/*將userinfo信息寫(xiě)入root.dat文件,確認(rèn)數(shù)據(jù)塊描述文件的存儲(chǔ)位置*/
fwrite(temp,sizeof(userlnfo),1,fp_user);
fseck(fp_user,0,0);
fflush(fp_user);
free(temp);
free(node);
return1;
}
/*根據(jù)用戶名,讀取root.dat文件中的uscrlnfo數(shù)據(jù)*/
intuserget(char*username,userinfo*user)
{
uscrlnfo*tcmp—(uscrlnfo*)mulloc(sizcof(uscrlnfo));
fscek(fp_uscrt0,0);
while(fread(temp,sizeof(userinfo),1,fp_user)——1)
if(strcmp(temp->userfusername)==0)
{
*user=*temp;
return1;
}
return0;
}
/*根據(jù)nodc.datX件獲取系統(tǒng)中的節(jié)點(diǎn)信息nodclnfo,并按最大剩余空間優(yōu)先策略分配給數(shù)
據(jù)塊
*/
/*分配完成后更新nodedat文件的內(nèi)容*/
intdatngetnode(nodelnfo*node)
{
nodclnfo*tcmp—(nodclnfo*)mulloc(sizcof(nodclnfb));
fseek(fp_node,0,0);
intnum—0;
intno=0;
if(frcad(nodc,sizcof(nodclnfo),1,fp_nodc)/—1)
return0;
/*首先向剩余空間最大的節(jié)點(diǎn)分配數(shù)據(jù)塊*/
while(fread(temp,sizeof(nodeinfo),1,fp_node)==1)
++num;
if(temp->freesize>node->freesize)
(
*node—*temp;
no—num;
}
}
memset(temp,0,sizeof(nodelnfo));
*tcmp=*nodc;
temp->freesize--BLOCKSIZE;
fscck(fp_nodc9no*sizcof(nodclnfo),0);
/*將分配后的信息寫(xiě)回node.dat文件,更新文件信息*/
fwrite(temp,sizeof(nodeJnfo),1,fp_node);
fscck(fp_nodc,0,0);
fflush(fp_nodc);
free(temp);
return1;
}
/*獲得rood.dat和node.dat的文件指針*/
/*fp_uscr指向root.d就文件*/
/*fp_node指向node.dat文件*/
voidopenfileO
{
if((fp_uscr=6pcn(\oot.dat':,b+"))==NULL)
fp_user=fopen("root.dat':"wb+");
H,r
if((fp_nodc=fopcn("nodc.datf"rb-b))==NULL)
fp_node=fdpenC'node.dat","wb+');
}
8.3
子節(jié)點(diǎn)程序分析
云計(jì)算vaoi中子節(jié)點(diǎn)主要完成數(shù)據(jù)的存儲(chǔ)及用戶文件存儲(chǔ)信息的保存,各用戶文件存儲(chǔ)信
息的
文件名為該用戶的用戶名,子節(jié)點(diǎn)程序需要在所有的節(jié)點(diǎn)上同時(shí)運(yùn)行。文件的存儲(chǔ)和訪問(wèn)由
客
戶端與子節(jié)點(diǎn)直接連接來(lái)完成,子節(jié)點(diǎn)和管理節(jié)點(diǎn)不進(jìn)行任何的數(shù)據(jù)通信工作。
各數(shù)據(jù)塊存儲(chǔ)的文件名為uscrnnmc_filcnnmc_blockNo,即用戶名加文件名加數(shù)據(jù)塊號(hào),之間
用
下劃線連接。
子節(jié)點(diǎn)函數(shù)調(diào)用結(jié)構(gòu)如圖8.5所示。
圖8.5子節(jié)點(diǎn)函數(shù)調(diào)用結(jié)構(gòu)
8.3.1
子節(jié)點(diǎn)主函數(shù)
子節(jié)點(diǎn)的主程序啟動(dòng)后監(jiān)聽(tīng)來(lái)自于客戶端發(fā)過(guò)來(lái)的命令cmd,根據(jù)不同的命令進(jìn)入不同的線
程
進(jìn)行處理。
程序8.7
/*文件名blockscvcr.cpp*/
//blocksever.cpp:定之控制臺(tái)應(yīng)用程序的入口點(diǎn)
int_tmain(intargc,_TCHAR*argv[])
{
WSADATAwsa;
intret=0;
intPORT=5101;
SOCKETs_socket;
SOCKETc_sockct;
structsockaddr_ins_sockaddr;
structsockaddr_inc_sockaddr;
intc__sockaddr_lcn—sizeof(c__sockaddr);
ret=WSAStartup(MAKEWORD(2,2),&wsa);
if(ret!=0)
(
cout<<HInitWinSockfailed:"<<ret<<endJ;
return0;
}
if((s_socket=socket(AF_INETfSOCK_STREAM,IPPROTO_TCP))==SOCKET_ERROR)
{
cout<<"CreateSocketFailed:f,<<WSAGetLustErrorQ<<end/;
WSACleanup0;
return0;
}
s_sockaddr.sin_family=AF_INET;
s_sockaddr.sin_port—htons(PORT);
s_sockaddr.sin_addr.s_nddr=htonl(INADDR_ANY);
if(bind(s_sockctt(SOCKADDR*)&s_sockaddjsizcof(s_socknddr))==SOCKET^ERROR)
cout?"bindfailed:"<vWSAGetLastErrorQ?endl;
closcsockct:(s_socket);
WSACleanupO;
return0;
}
if(listen(s_socket,5)-=SOCKET_ERROR)
{
cout?"ListenFailed:"vvWSAGetLastErrorf)?endl;
closesocket(s_socket);
WSACleanup0;
return0;
}
CMDemd;
while。)
{
c_sockct—accept(s_socket,(SOCKADDR*)&c_sockaddj&c_sockaddr_lcn);
recv(c_socketf(char*)&cmdfsizeof(CMD),0);
SOCKET*tsock=(SOCKET^)malloc(sizcof(SOCKET));
*tsock—c_sockct;
/*獲取用戶文件存儲(chǔ)信息,該文件存儲(chǔ)于其中一個(gè)子節(jié)點(diǎn)*/
/*用戶根據(jù)管理節(jié)點(diǎn)提供的IP,直接連接該子節(jié)點(diǎn)獲取*/
if(cmd==USERINFOGET)
_beginthreadex(NULL,Of&userinfogetthrendftsock,0,NULL);
elseif(cmd==FILEINFOADD)
_beginthrcadcx(NULL,0,&Hlcinfbaddthread,tsock,0,NULL);//添加文件存儲(chǔ)
信息
elseif(cmd==STOREBLOCK)
_beginthrendex(NULI.,0,&storedatathread,tsock,0,NULI);〃存儲(chǔ)數(shù)據(jù)塊
elseif(cmd==GETDATA)
_begindireadex(NULL,0,&getdatathread,tsock,0,NULL);//完成計(jì)算工作
else
continue;
}
return0;
子節(jié)點(diǎn)的主函數(shù)的功能是啟動(dòng)對(duì)客戶端發(fā)出命令的監(jiān)聽(tīng)和執(zhí)行,主要是完成4項(xiàng)工作,分別
由4
個(gè)不同的線程函數(shù)來(lái)完成。一是獲取文件存儲(chǔ)信息;二是在文件分塊描述文件中添加信息;
是實(shí)現(xiàn)數(shù)據(jù)塊的存儲(chǔ)工作;四是在各節(jié)點(diǎn)啟動(dòng)計(jì)算,完成存儲(chǔ)與計(jì)算的整合工作。
子節(jié)點(diǎn)程序要用到的一些常用數(shù)據(jù)結(jié)構(gòu)定義如下。
程序&8
/*文件名belem.h*/
#ifndefBELEM_H
#defineBELEM_H
#include"stdafx.h"
#defineUSERNAME_LEN20
#defineFILENAME_LEN64
#defineBLOCKNAME_LEN128
ffdefineL1STLEN5
#defineMAINIP〃〃
ffdefineUSERADD1
#defineUSERGET2
#defineUSERDEL3
^defineUSERINFOGET5
^defineFILEINFOADD6
#defineSTOREBLOCK7
#defineGETDATA8
typedefintCMD;
/*filelnfo數(shù)據(jù)結(jié)構(gòu)為子節(jié)點(diǎn)上用戶數(shù)據(jù)文件描述的內(nèi)容*/
typedefstruct
(
charfilenamc[FILENAME_LEN];//文件名
intb/ockNO;//數(shù)據(jù)塊號(hào)
charip[16];//數(shù)據(jù)塊存放節(jié)點(diǎn)的IP地址
intport;
}fileinfo;
/*數(shù)據(jù)塊描述數(shù)據(jù)結(jié)構(gòu)*/
typedefstruct:
{
intblockNO;
charip[16];
intport;
}blockinfd;
typedefstruct
Hlelnfo*e;
intlength;
intsize;
}filelnfoList;
#endif
8.3.2
子節(jié)點(diǎn)各線程函數(shù)設(shè)計(jì)
1
.獲取文件存儲(chǔ)信息線程函數(shù)
程序8.9
/*文件名bthrend.cpp*/
unsigned_stdcidluserinfogetthread(LPVOIDp)//獲取用戶信息文件線程
{
SOCKET*tsock=(SOCKET*)p;
charuscrnamc[USERNAME_LEN];
rccv(*tsockfusername,USERNAME_LEN,0);
FILE*fp;
if((fp=fbpcn(uscrnamc,"rb"))==NULL)
fp-fopcn(uscniamc,"wb+〃);//打開(kāi)用戶存儲(chǔ)信息描述表
struct_statinfo;
_sm(uscrnamc,&info);//度取文件信息
filelen=info.st_size;
send(*tsock,(char*)&filelen,sizeof(_off_t),0);
if(filcicn>0)
{
char*buf=(char*)malloc(fiielen);
fread(buf91,filelcn,fp);
send(*tsock,buf,filelen,0);
free(buf);
}
closesockct(*tsock);
fclose(fp);
return1;
}
用戶從管理節(jié)點(diǎn)獲取到數(shù)據(jù)塊描述文件所在的節(jié)點(diǎn)IP地址后,即可連接該節(jié)點(diǎn)并調(diào)用此函數(shù)
獲
取文件內(nèi)容,由于該文件的文件名就是用戶名,所以子節(jié)點(diǎn)只要知道了用戶名即可知道需要
打
開(kāi)的文件名,該節(jié)點(diǎn)通過(guò)socket接收用戶名就是這個(gè)原因。
2
.添加數(shù)據(jù)塊描述信息線程函數(shù)
程序&10
/*文件名bthrend.cpp*/
unsigned_stdcaUfileinfbacldthread(LPVOIDp)〃添加文件信息線程
{
SOCKET*tsock=(SOCKET*)p;
intlistlen-0;
char6Icnamc[FlLENAME_LEN];
charusername[USERNAME_LEN];
fileinfoftmp;〃定義文件信息數(shù)據(jù)結(jié)構(gòu)
blockinfobtrnp;
filelnfoListL;
rccv(*tsockfusername,USERNAME_LEN,0);〃獲取用戶名
recv(*tsockffilename,FILENAME_LEN,0);//獲取文件名
rccv(*tsock,(char*)&UstJen,sizcof(int),0)//獲取文件分塊個(gè)數(shù),即獲取順序表的長(zhǎng)度
for(inti=O;ivlistlcn;i++)//獲取各個(gè)數(shù)據(jù)塊的存儲(chǔ)信息與在文件中的順序號(hào),順序號(hào)以0
開(kāi)始
{
recv(*tsock,(char*)&btrnp,sizeof(btmp),0);//接收數(shù)據(jù)塊信息,包括塊號(hào)、存儲(chǔ)的IP地
址
strcpy(ftmp.filename,filename);
strcpy(ftmp.ip,btmp.ip);
ftmp.blockNO=bmp.blockNO;
fmp.port—bmp.port;
addlist(&L,ftmp);//加入順序表
}
FILE*fp;
if((fp—fbpcn(uscrnnmc,”rb+"))--NULL)
fp=fopen(username,"wb+");
£lcadd(&L,fp);//將文件存儲(chǔ)信息的順序表添加到數(shù)據(jù)分塊文件中,文件名就為用戶名
fclose(fp);
intresult—1;
send(*tsock,(char*)&resu/t,sizeof(int),0);
dcstroylist:(&L);
closesocket(*tsock);
free(tsock);
return1;
/
添加數(shù)據(jù)塊描述信息線程函數(shù)從客戶端通過(guò)socket接收用戶名、文件名及文件分塊個(gè)數(shù),并
將每
個(gè)數(shù)據(jù)塊的塊號(hào)blockNO和存儲(chǔ)位置所在IP地址等信息建立順序表,將此順序表存到該用
戶的文
件分塊描述文件中。
這一線程函數(shù)調(diào)用HleaddO函數(shù)實(shí)現(xiàn)向username添加文件塊存儲(chǔ)信息,這個(gè)信息由fileinfo數(shù)
據(jù)結(jié)
構(gòu)來(lái)描述,fHeadd。函數(shù)定義如下。
程序8.11
/*位于文件bfile.cpp中*/
intfilendd(fileJnfolAst*L,FILE*fp)//fp為username文件指針
{
charfilcnamc[20];
fileinfofile;
strcpy(filcnamc,L->c[OJ.filename);
if(filcscnrch(61cnnmeffp)--0)//檢測(cè)是否有同名文件
filedel(filename,fp);〃如有同名文件則刪除并覆蓋該文件
fscck(fptOfSEEK_END);
for(inti=0;i<L->length;i++)
{
file=L->c[iJ;
fwritc(&filc,sizcof(filclnfo),1,fp);
)
return1;
}
/*在username.文件中檢測(cè)是杳有同名文件*/
intfilesearch(char*filename,FILE*fp)
{
fileinfoftmp;
fscck(fp,0,0);
while(fread(&ftmp,sizeof(filelnfo)91,fp)==1)
if(strcmp(ftmp.filename,filename)——0)
return0;
return1;
/*覆蓋同名文件*/
intfilcdcl(chnr*filename,FILE*fjp)
{
filclnfbftmp;
fseek(fpfOf0);
whilc(!feof(fp))
{
fread(&ftmp,sizeof(filelnfo),/,fp);
if(strcmp(fmp.filename,filename)——0)
{
strcpy(fmp.filename,"0");
fseek(fp,ftcll(fp)-sizcof(filclnfo),0);
sizeof(fileinfo),7,fp);
fseek(fp,ftell(fp),0);
}
}
return1;
)
在文件存儲(chǔ)信息的添加過(guò)程中我們采用順序表來(lái)維護(hù)各數(shù)據(jù)塊的存儲(chǔ)信息,因此定義了幾個(gè)
基
本的順序表操作。
程序8.12
/*位于文件blist.cpp*/
/*初始化順序表函數(shù)*/
intinitlist(BldnfoList*L)
{
L->c—(filclnfb*)malloc(LISTLEN*sizcof(filclnfb));
if(I.->e==NULL)
{
printf("初始化表,分配內(nèi)存失敗
return0;
}
L->lcngth—0;
L->size=LISTLEN;
return1;
}
/*向順序表中加入一個(gè)數(shù)據(jù)塊存儲(chǔ)信息*/
intaddlist(fileInfoList*L,fileinfoe)
if(L->lcngth>=L->size)
flicinfo*ncwbasc—(filclnfo*)rcalloc(L->e,(L->sizc+L1STLEN)*sizeof(filclnfb));
if(newbase==NULL)
{
printf("向表添加數(shù)據(jù),增加內(nèi)存空間失敗");
return0;
}
L->c—ncwbasc;
L->size+=LISTLEN;
}
L->e[L->length]—e;
++L->length;
return0;
}
/*釋放存儲(chǔ)空間*/
intdcstroylist(filclnfoList*L)
{
L->length=0;
L->sizc—0;
free(I.->e);
return0;
}
3
.保存數(shù)據(jù)塊線程函數(shù)
程序8.13
/*文件名bthread.cpp*/
unsigned_stdcallstoredatathread(LPVOIDp)//保存數(shù)據(jù)塊
{
SOCKET*tsock=(SOCKET*)p;
intdatalen--1;
intblockNo--1;
char印ename[FILENAME_LEN];
charuscrnamc[USERNAME_LEN];
recv(*tsock,username,USERNAME_LEN,0);
rccv(*tsockffilename,FILENAME_LEN,0);
recv(*tsock,(char*)&blockNo,sizeof(int),0);
recv(*tsockf(char*)&dntalen,sizeof(int),0);
char*buf=(char*)malloc(datalcn);
recv(*tsock,buf,datolen,0);
cout?"storcdatathrcadblockNo:r,<<biockNo<<cndl;
cout<<"storedutathrendbuflen:,f?dutulen<<endl;
charblocknamc[BLOCKNAME_LEN];//數(shù)據(jù)塊文件名
sprintf(blockname,username,filename,blockNc);//生成數(shù)據(jù)塊文件名
FILE*fp;
fp-fopen(blockname,''w-F");//打開(kāi)數(shù)據(jù)塊文件
fwrit€(buf,1,datalen,fp);//寫(xiě)入信息
fclose(fp);
frcc(buf);
closesocket(*tsock);
free(tsock);
return1;
}
本函數(shù)完成對(duì)各數(shù)據(jù)塊的存儲(chǔ)工作,客戶端根據(jù)管理節(jié)點(diǎn)的數(shù)據(jù)塊存儲(chǔ)安排,獲取各數(shù)據(jù)塊
存
儲(chǔ)節(jié)點(diǎn)的IP地址,由客戶端直接連接各存儲(chǔ)節(jié)點(diǎn),調(diào)用storedatathread。函數(shù),本函數(shù)獲取數(shù)
據(jù)
塊的所屬用戶名、文件名、塊號(hào)、塊大小和數(shù)據(jù)塊的具體內(nèi)容,將數(shù)據(jù)塊存儲(chǔ)在當(dāng)前節(jié)點(diǎn),
各
個(gè)數(shù)據(jù)塊的命名原則為用戶名一文件名一塊號(hào)(username_filename_blockNO),這樣任何一"A數(shù)
據(jù)
塊將有一個(gè)惟一的文件名,該數(shù)據(jù)塊的存儲(chǔ)信息同時(shí)被寫(xiě)入了數(shù)據(jù)塊描述文件。雖然文件被
分
割為多個(gè)數(shù)據(jù)塊并存儲(chǔ)在不同的子節(jié)點(diǎn)上,但由于有數(shù)據(jù)塊描述文件,我們可以在任何時(shí)候
恢
復(fù)并訪問(wèn)該文件。
4
.獲取數(shù)據(jù)計(jì)算結(jié)果線程函數(shù)
程序8.14
/*文件名btbrcad.cpp*/
unsigned_stdcallgetdatathread(I.PVOIDp)〃獲取數(shù)據(jù)計(jì)算結(jié)果
SOCKET*tsock=(SOCKET*)p;
intdatalcn=0;
intbiockNo=0;
result—0;
char61ennmc[FlLENAME_LEN];
charusername[USERNAME_LEN];
rccv(*tsock,username,USERNAME_LEN,0);
recv(*tsock,filename,FILENAME_LEN,0);
recv(*tsock,(char*)&blockNo,sizeof(int),0);
FILE*fp;
charblockname[BLOCK^AME_LEN;〃數(shù)據(jù)塊文件名
sprintf(blocknnme,"%s_%s_%d”,username,filename,blockNo);
fp=fopcn(blocknamc,"r");//打開(kāi)本節(jié)點(diǎn)上的數(shù)據(jù)塊文件
getresLilt(&resLiltffp);〃在本節(jié)點(diǎn)完成計(jì)算工作
fclosc(fp);
cout<<"num:"<<result<<endl;
send(*tsock,(char*)&result,sizcof(_off_t),0);
closcsocket(*tsock);
frcc(tsock);
return1;
}
獲取數(shù)據(jù)計(jì)算結(jié)果線程函數(shù)實(shí)現(xiàn)了在這個(gè)云計(jì)算系統(tǒng)中計(jì)算與存儲(chǔ)的整合演示,我們以對(duì)一
串
數(shù)據(jù)求和操作為例,客戶端根據(jù)數(shù)據(jù)塊存儲(chǔ)描述文件的描述向各個(gè)存儲(chǔ)有數(shù)據(jù)塊的節(jié)點(diǎn)發(fā)送
用
戶名、文件名和數(shù)據(jù)塊號(hào),這些信息實(shí)際上就確定了一個(gè)數(shù)據(jù)塊文件的位置,存儲(chǔ)每個(gè)數(shù)據(jù)
塊
的節(jié)點(diǎn)就在該節(jié)點(diǎn)就地啟動(dòng)對(duì)該數(shù)據(jù)塊的計(jì)算工作,完成計(jì)算后將自己的局部計(jì)算結(jié)果發(fā)送
到
客戶端,由客戶端完成數(shù)據(jù)的最后整合工作。這樣就避免了大量數(shù)據(jù)在機(jī)群中的移動(dòng),大火
提
高系統(tǒng)的工作效率,體現(xiàn)了“計(jì)算向存儲(chǔ)遷移”的云計(jì)算理念。這一線程函數(shù)中的getresultO
函數(shù)
就是完成計(jì)算工作的函數(shù),根據(jù)不同的數(shù)據(jù)和工作需要我們定義不同的計(jì)算函數(shù),這一函數(shù)
必
需在所有的節(jié)點(diǎn)上都要駐留,這樣系統(tǒng)才能將計(jì)算向該節(jié)點(diǎn)遷移。函數(shù)getresultO在本例中的
定
義如下。
程序8.15
/*位于文件bfilc.cpp中*/
/*完成對(duì)本節(jié)點(diǎn)數(shù)據(jù)塊內(nèi)數(shù)據(jù)的求和操作*/
intgetresult(_off_t*numfFILE*fp)
fseek(fp,Of0);
charc;
inti=0;
intj=O;
while(!feof(fp))
{
c-fgetc(fp);
cout<<c;
i=0;
whilc(!fcof(fp))
{
i=0;
if(c>='O'&&c<=刃
(
i—ntoi(&c);
j=10*j+i;
}
c=fgetc(fp);
cout<<c;
if(c<fOfllc>力
break;
}
*num+二j;
}
return1;
}
我們的計(jì)算數(shù)據(jù)是按字符串存儲(chǔ),函數(shù)getresultO對(duì)本節(jié)點(diǎn)數(shù)據(jù)塊實(shí)施求和操作,我們同樣也
定
義其他的數(shù)據(jù)處理函數(shù),如類似wordcount函數(shù)等,通過(guò)這一函數(shù)我們實(shí)現(xiàn)對(duì)數(shù)據(jù)的本地化
處理,
每個(gè)gptresultO函數(shù)只處理本節(jié)點(diǎn)所存儲(chǔ)數(shù)據(jù)塊的數(shù)據(jù)。這一函數(shù)演示了計(jì)算向存儲(chǔ)的遷移過(guò)
程。
8.4
客戶端API
設(shè)計(jì)
云計(jì)算V0.01為客戶端提供7可以訪問(wèn)的API函數(shù),從負(fù)載上我們給客戶端增加了一些負(fù)載,
將
文件的分塊等工作交給了客戶端來(lái)完成,只是將計(jì)算工作交給子節(jié)點(diǎn)來(lái)完成??蛻舳说闹饕?/p>
工
作模式是從管理節(jié)點(diǎn)讀取系統(tǒng)信息,根據(jù)這一信息與各子節(jié)點(diǎn)直接進(jìn)行聯(lián)系完成文件操作及
計(jì)
算任務(wù)。
T面是系統(tǒng)提供的主要API函數(shù),分別在capi.
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 汽車租賃協(xié)議合同書(shū)
- 廣告標(biāo)識(shí)制作合同
- 保溫施工協(xié)議合同
- 對(duì)外勞務(wù)輸出合同
- 印刷廠全員勞動(dòng)合同書(shū)
- 三方建筑工程施工合同
- 拆遷合同終止協(xié)議
- 外協(xié)維修協(xié)議合同
- 解除托管合同協(xié)議
- 合伙協(xié)議經(jīng)營(yíng)合同
- 放療皮膚反應(yīng)分級(jí)護(hù)理
- 2025年03月內(nèi)蒙古鄂爾多斯市東勝區(qū)事業(yè)單位引進(jìn)高層次人才和緊缺專業(yè)人才50人筆試歷年典型考題(歷年真題考點(diǎn))解題思路附帶答案詳解
- 小學(xué)消防知識(shí)教育
- 深入貫徹學(xué)習(xí)2025年中央八項(xiàng)規(guī)定精神教育測(cè)試題及答案
- 安徽2025年03月合肥高新技術(shù)產(chǎn)業(yè)開(kāi)發(fā)區(qū)管理委員會(huì)公開(kāi)招考60名工作人員筆試歷年參考題庫(kù)考點(diǎn)剖析附解題思路及答案詳解
- 2025年第三屆天揚(yáng)杯建筑業(yè)財(cái)稅知識(shí)競(jìng)賽題庫(kù)附答案(601-700題)
- 2025年四川綿陽(yáng)市投資控股(集團(tuán))有限公司招聘筆試參考題庫(kù)附帶答案詳解
- (二調(diào))棗莊市2025屆高三模擬考試歷史試卷(含答案)
- 上海市普陀區(qū)2024-2025學(xué)年高三下學(xué)期二模地理試題(含答案)
- 【初中語(yǔ)文】第11課《山地回憶》課件+2024-2025學(xué)年統(tǒng)編版語(yǔ)文七年級(jí)下冊(cè)
- 2025年公務(wù)員遴選考試公共基礎(chǔ)知識(shí)必考題庫(kù)170題及答案(四)
評(píng)論
0/150
提交評(píng)論