Skip to content

Commit 4c75f7d

Browse files
committedJan 8, 2020
update docs [skip ci]
1 parent 1c6ddc4 commit 4c75f7d

File tree

3 files changed

+138
-26
lines changed

3 files changed

+138
-26
lines changed
 

‎HDFS.md

+39-3
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ The DFS can be navigated using the same Julia APIs as used for a traditional fil
2525
julia> pwd(dfs)
2626
"/"
2727
28+
julia> du(dfs)
29+
0x0000000000000017
30+
2831
julia> readdir(dfs)
2932
5-element Array{AbstractString,1}:
3033
"testdir"
@@ -65,6 +68,28 @@ HDFSFileInfo: bar
6568
6669
julia> isfile(bar_file)
6770
true
71+
72+
julia> isdir(bar_file)
73+
false
74+
75+
julia> islink(bar_file)
76+
false
77+
78+
julia> filemode(bar_file)
79+
0x000001a4
80+
81+
julia> mtime(bar_file)
82+
0x0000016f7f71aa30
83+
84+
julia> atime(bar_file)
85+
0x0000016f7f71a980
86+
87+
julia> dirname(bar_file)
88+
HDFSFile: hdfs://userid@localhost:9000/tmp/foo/
89+
90+
julia> joinpath(dirname(bar_file), "baz_file")
91+
HDFSFile: hdfs://userid@localhost:9000/tmp/foo/baz_file
92+
6893
...
6994
````
7095

@@ -90,13 +115,24 @@ HDFSFileInfo: baz.txt
90115
julia> open(bar_file, "w") do f
91116
write(f, b"hello world")
92117
end
93-
0x000000000000000b
118+
11
94119
95120
julia> open(bar_file, "r") do f
96-
bytes = Array(UInt8, filesize(f))
121+
bytes = Vector{UInt8}(undef, filesize(f))
97122
read!(f, bytes)
98-
println(bytestring(bytes))
123+
println(String(bytes))
99124
end
100125
hello world
101126
````
102127

128+
Elly also supports block level access to files, to enable distributed processing.
129+
130+
```
131+
julia> hdfs_blocks(huge_file)
132+
1-element Array{Tuple{UInt64,Array},1}:
133+
(0x0000000000000000, AbstractString["node1"])
134+
(0x0000000007d00000, AbstractString["node2"])
135+
(0x000000000fa00000, AbstractString["node3"])
136+
137+
```
138+

‎YARN.md

+71-18
Original file line numberDiff line numberDiff line change
@@ -32,37 +32,48 @@ YarnNodes: 1 (connected to 0)
3232
YarnNode: /default-rack/tanlt:36080 running, Used mem: 0/8192, cores: 0/8
3333
````
3434

35-
### YarnAppMaster
35+
### Yarn Applications (The YarnAppMaster)
3636

37-
Elly supports only unmanaged application masters. A `YarnAppMaster` can be constructed by providing the address of the Yarn Scheduler and a
38-
`UserGroupInformation` object. It is then registered with Yarn using the `submit` API to get an application as a `YarnApp` instance.
37+
An ApplicationMaster, in Yarn terminology, is the part of an application that negotiates resources from the Yarn ResourceManager and works
38+
with the Yarn NodeManager to execute and monitor the granted resources (bundled as containers) for a given application. Application masters
39+
can either be:
40+
41+
- Managed: managed by Yarn and run inside the cluster, resources are allocated inside the Yarn cluster and Yarn instantiates the process
42+
- Unmanaged: not managed by Yarn and run outside the cluster, it is the application writers responsibility to ensure that it has the resources it needs and is kept running throughout the course of the application
43+
44+
Elly supports both managed and unmanaged application masters.
45+
46+
#### Unmanaged YarnAppMaster
47+
48+
An unmanaged `YarnAppMaster` can be constructed by providing the address of the Yarn Scheduler and a
49+
`UserGroupInformation` object. It needs to be then registered with Yarn using the `submit` API to get an application as a `YarnApp` instance.
3950

4051
````
4152
julia> yarnam = YarnAppMaster("localhost", 8030, ugi)
4253
YarnAppMaster: tan@localhost:8030/
4354
id: 6c215ce3-0070-4b
4455
connected: false
45-
Memory: available:0, max:0, can schecule:false
46-
Cores: available:0, max:0, can schedule:false
47-
Queue:
48-
YarnNodes: 0 (connected to 0)
49-
Containers: 0/0 active, 0 in use
5056
````
5157

52-
Applications may register callbacks for container allocation and finish events to be able to start a task on the allocated container or
53-
read the results.
58+
Once registered, the application master can then allocate one or more containers in the cluster.
59+
But before they can do that, applications should register callbacks for container allocation and
60+
finish events, so that they can start a task on the allocated container or read the results after
61+
termination.
5462

5563
````
56-
julia> cids = Dict()
64+
julia> cids = Set()
5765
Dict{Any,Any} with 0 entries
5866
5967
julia> function on_alloc(cid)
6068
# start container process
6169
println("allocated $cid")
62-
env = Dict("JULIA_PKGDIR" => "/home/tan/.julia");
70+
env = Dict(
71+
"JULIA_LOAD_PATH" => join([Base.LOAD_PATH..., "/home/tan/.julia/dev", "/home/tan/.julia/packages"], ':'),
72+
"JULIA_DEPOT_PATH" => join(Base.DEPOT_PATH, ':')
73+
);
6374
clc = launchcontext(cmd="/bin/julia /tmp/simplecontainer.jl 1>/tmp/stdout 2>/tmp/stderr", env=env);
6475
container_start(yarnam, cid, clc)
65-
cids[cid] = "some identifier"
76+
push!(cids, cid)
6677
nothing
6778
end
6879
on_alloc (generic function with 1 method)
@@ -71,7 +82,7 @@ julia> function on_finish(cid)
7182
# release the container (or can start a new process here also)
7283
println("finished $cid")
7384
container_release(yarnam, cid)
74-
delete!(cids, cid)
85+
pop!(cids, cid)
7586
nothing
7687
end
7788
on_finish (generic function with 1 method)
@@ -83,18 +94,16 @@ YarnApp YARN (EllyApp/2): accepted-0.0
8394
location: tan@N/A:0/default
8495
````
8596

86-
Containers can then be allocated/de-allocated and started/stopped as required.
97+
With event handlers registered, containers can then be allocated/de-allocated and started/stopped as required.
8798

8899
````
89100
julia> container_allocate(yarnam, 1);
90101
allocated Elly.hadoop.yarn.ContainerIdProto(#undef,Elly.hadoop.yarn.ApplicationAttemptIdProto(Elly.hadoop.yarn.ApplicationIdProto(2,1461548151454),1),1)
91102
92-
julia> cid = collect(keys(cids))[1]
103+
julia> cid = collect(cids)[1]
93104
Elly.hadoop.yarn.ContainerIdProto(#undef,Elly.hadoop.yarn.ApplicationAttemptIdProto(Elly.hadoop.yarn.ApplicationIdProto(2,1461548151454),1),1)
94105
95106
julia> container_stop(yarnam, cid);
96-
97-
julia> container_release(yarnam, cid);
98107
finished Elly.hadoop.yarn.ContainerIdProto(#undef,Elly.hadoop.yarn.ApplicationAttemptIdProto(Elly.hadoop.yarn.ApplicationIdProto(2,1461548151454),1),1)
99108
````
100109

@@ -104,3 +113,47 @@ Finally the application master can be terminated with a call to `unregister`:
104113
julia> unregister(yarnam, true)
105114
true
106115
````
116+
117+
#### Managed YarnAppMaster
118+
119+
A managed `YarnAppMaster` can be deployed simply by submitting a command to the YarnClient with the `unmanaged` flag set to `false`.
120+
121+
```julia
122+
ugi = UserGroupInformation()
123+
clnt = YarnClient(host, rmport, ugi)
124+
yarn_host = "yarnhost"
125+
yarn_scheduler_port = 8030
126+
127+
env = Dict(
128+
"JULIA_LOAD_PATH"=>join([Base.LOAD_PATH..., "/usr/local/julia/packages"], ':'),
129+
"JULIA_DEPOT_PATH"=>join([Base.DEPOT_PATH..., "/usr/local/julia"], ':')
130+
)
131+
132+
testscript = "/application/masterprocess.jl"
133+
app = submit(clnt, ["/usr/local/julia/bin/julia", testscript], env; schedaddr="$(yarn_host):$(yarn_scheduler_port)", unmanaged=false)
134+
```
135+
136+
Once submitted, the submitting process can exit, leaving the application master running inside the cluster. It can also monitor the application if so desired.
137+
138+
```julia
139+
@info("status", status(app))
140+
```
141+
142+
And wait for application to reach a certain state.
143+
144+
```julia
145+
Elly.wait_for_state(app, Elly.YarnApplicationStateProto.FINISHED)
146+
```
147+
148+
The Yarn master process thus submitted can create an instance of `YarnAppMaster` and use it to manage itself and also allocate and launch more containers into the cluster.
149+
150+
151+
For example, the `/application/masterprocess.jl` script launched above, can instantiate a `YarnAppMaster` and register itself.
152+
153+
```
154+
ugi = UserGroupInformation()
155+
am = YarnAppMaster(ugi)
156+
register(am)
157+
```
158+
159+
And then it can proceed to allocate and execute more containers exactly as how we did with the unmanaged `YarnAppMaster`.

‎YARNCM.md

+28-5
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,35 @@
22

33
`YarnManager` provides a Julia [ClusterManager](http://docs.julialang.org/en/latest/manual/parallel-computing/#clustermanagers) interface for
44
working with Yarn. It does not have the full functionality of the direct Yarn APIs, but it provides the familiar `addprocs`, `rmprocs` methods
5-
for starting and stopping containers.
5+
for starting and stopping containers.
6+
7+
`YarnManager` works in both managed mode (both master and workers launched inside the cluster) and unmanaged mode (only workers launched inside the cluster). See section on ["Yarn Applications using Elly"](YARN.md) for details.
68

79
It can be also used to get a distributed Julia shell in the Yarn cluster.
810

911
The below example walks through a simple example using a Julia on a Yarn cluster.
1012
You can find the YARN manager parameters in the `$HADOOP_CONFIG_DIR/yarn-site.xml` file
1113
[Hadoop Docs](https://hadoop.apache.org/docs/current/hadoop-project-dist/hadoop-common/ClusterSetup.html).
1214

13-
Bring up the Julia processes on the Yarn cluster:
15+
Bring up the Julia processes on the Yarn cluster. Note that Julia should be installed on all nodes of the cluster at the same path for this to work.
1416

1517
````
1618
julia> using Elly
1719
18-
julia> yarncm = YarnManager(yarnhost="localhost", rmport=8032, schedport=8030, launch_timeout=60);
20+
julia> yarncm = YarnManager(
21+
yarnhost="localhost",
22+
rmport=8032,
23+
schedport=8030,
24+
launch_timeout=60,
25+
unmanaged=false # pass true when running in unmanaged mode
26+
);
27+
28+
julia>env = Dict(
29+
"JULIA_LOAD_PATH"=>join([Base.LOAD_PATH..., "/usr/local/julia/packages"], ':'),
30+
"JULIA_DEPOT_PATH"=>join([Base.DEPOT_PATH..., "/usr/local/julia"], ':')
31+
);
1932
20-
julia> addprocs(yarncm; np=8, env=Dict("JULIA_PKGDIR"=>Pkg.dir()));
33+
julia> addprocs(yarncm; np=8, env=env);
2134
2235
julia> @everywhere println(myid())
2336
1
@@ -32,7 +45,8 @@ julia> @everywhere println(myid())
3245
````
3346

3447
Next, we try some trivial computation on all nodes. We use a file `dart.jl` that contains some code to
35-
arrive at an approximate value of pi using a Monte Carlo method:
48+
arrive at an approximate value of pi using a Monte Carlo method. Note that `dart.jl` should be made
49+
available throughout the cluster on all nodes at the same path.
3650

3751
````
3852
# dart.jl
@@ -88,3 +102,12 @@ julia> @everywhere println(myid())
88102
89103
julia> Elly.disconnect(yarncm);
90104
````
105+
106+
`YarnManager` can also be used in the familiar Julia `do` block by passing a function to execute in the context of the manager, e.g.:
107+
108+
```
109+
YarnManager(launch_timeout=60, unmanaged=false) do yarncm
110+
# use yarncm here...
111+
...
112+
end
113+
```

0 commit comments

Comments
 (0)
Please sign in to comment.