簡(jiǎn)易的分布式文件系統(tǒng)
本來初期打算用Hadoop 2,可是后來有限的服務(wù)器部署了Solr Cloud,各種站點(diǎn),發(fā)現(xiàn)資源不夠了,近10T的文件,已經(jīng)幾乎把服務(wù)器的磁盤全部用光。想來想去,由于目前架構(gòu)基于Scala的,所以還是用Scala Akka實(shí)現(xiàn)了一個(gè)簡(jiǎn)單版本的分布式文件系統(tǒng)。
?
Scala版本是2.10.3:http://www.scala-lang.org,Akka版本是2.2.3:http://akka.io。
?
所有文件隨機(jī)放在不同的服務(wù)器上,在數(shù)據(jù)庫中記錄了文件存放的服務(wù)器IP地址、文件路徑。在服務(wù)端部署基于Akka的簡(jiǎn)單文件服務(wù),接收文件路徑,讀取并返回文件內(nèi)容。調(diào)用者根據(jù)文件地址,去數(shù)據(jù)庫中查找文件的服務(wù)IP地址和文件路徑,根據(jù)得到的服務(wù)器IP地址,傳入文件路徑,調(diào)用該服務(wù)器的文件服務(wù)。
?
以下是部分實(shí)現(xiàn)代碼。
?
1.文件服務(wù)參數(shù)
?
1
case
class
PatentFulltextArgs(
2
val url: String,
3
val start: Int,
4
val size: Int) {
5
6
}
?
2.文件服務(wù)Trait(有點(diǎn)像WCF中的服務(wù)契約)
?
1
trait PatentFulltextService {
2
def find(args: PatentFulltextArgs): Array[Byte]
3
}
?
3.文件服務(wù)實(shí)現(xiàn)
?
1
class
PatentFulltextServiceImpl
extends
PatentFulltextService with Disposable {
2
def find(args: PatentFulltextArgs): Array[Byte] =
{
3
val list =
ListBuffer[Byte]()
4
val file =
FileSystems.getDefault().getPath(args.url)
5
6
using(Files.newInputStream(file)) { in =>
7
{
8
val bytes =
new
Array[Byte](args.size + 1
)
9
in.skip(args.start)
10
in.read(bytes, 0
, bytes.length)
11
12
list ++=
bytes
13
}
14
}
15
16
list.toArray
17
}
18
}
?
4.用戶Akka Deploy發(fā)布的類
?
class
ServiceApplication
extends
Bootable {
val system
= ActorSystem("serivce", ConfigFactory.load.getConfig("service"
))
def startup() {
TypedActor(system).typedActorOf(TypedProps[PatentFulltextServiceImpl],
"patentfulltext"
)
}
def shutdown() {
system.shutdown
}
}
?
在這里,我使用的Akka的TypeActor,請(qǐng)參考:http://doc.akka.io/docs/akka/2.2.3/scala/typed-actors.html。
?
以下是部署過程。
?
把生成的jar包,發(fā)布在Akka的deploy目錄下,根據(jù)需要修改Akka的配置文件目錄config下的application.conf。以下是我配置的內(nèi)容,僅供參考:
?
actor {
?
provider = "akka.remote.RemoteActorRefProvider"
?
?
?
typed {
?
# Default timeout for typed actor methods with non-void return type
?
timeout = 6000s
?
}
?
}
?
remote {
?
transport = "akka.remote.netty.NettyRemoteTransport"
?
netty.tcp {
?
?? hostname ?= "服務(wù)端IP"
?
? port = 2552
?
}
?
客戶端使用時(shí)只需要服務(wù)契約Trait和相關(guān)實(shí)體類,以下是我寫的一個(gè)客戶端調(diào)用的類,僅供參考:
?
1
object RemoteService {
2
val logger = LoggerFactory.getLogger(
this
.getClass())
3
private
var system: ActorSystem =
null
4
5
def apply(configFile: String) =
{
6
system = ActorSystem("RemoteService", ConfigFactory.parseFile(
new
File(configFile)))
7
}
8
9
def findPatentFulltext(serverIp: String, patentFulltextArgs: PatentFulltextArgs) =
{
10
TypedActor(system).typedActorOf(TypedProps[com.cloud.akka.service.model.PatentFulltextService], system.actorFor("akka.tcp://serivce@" + serverIp + ":2552/user/patentfulltext"
)).find(patentFulltextArgs)
11
12
}
13
14
def shutdown =
{
15
if
(
null
!=
system) system.shutdown()
16
}
17
}}
?
以下問題是我還沒找到合適的解決辦法:
?
1.Akka無法傳輸大文件,即使修改配置,服務(wù)器可以返回,但是接收的客戶端還會(huì)報(bào)錯(cuò)。我的解決方案是在客戶端分塊讀取,然后合并。
?
2.在客戶端使用時(shí),TypedActor沒有找到使用ActorSelection構(gòu)建,因?yàn)锳ctorFor是標(biāo)記為 Deprecated。
?
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061
微信掃一掃加我為好友
QQ號(hào)聯(lián)系: 360901061
您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對(duì)您有幫助就好】元

