boinc/vda/storage.txt

305 lines
8.0 KiB
Plaintext

Volunteer storage
There is a range of possible types applications of volunteer storage.
Each type of application has certain demands.
1) Data archival
Data originates at a server.
Stored on and retrieved from clients.
subgoals:
- support large files and lots of small files
- availability
- capacity
- bandwidth (put and/or get)
2) storage of computational inputs
have a large data set
want to balance storage and computation;
i.e., the amount of data stored on a host is proportional
to its available computing power.
may retain central copy of data.
in that case don't care about retrieval.
3) storage of computational outputs
E.g. Folding@Home, CPDN
-----------------------
Batches and multiple users
new DB fields
user.share_rate
user.share_value
maybe put this stuff in a new table?
need to maintain "avg share rate of users w/ active jobs"
(to estimate the throughput that a given user will get)
simple batch policy
- what jobs to send?
- what deadlines to assign?
new mechanism
require periodic callbacks
if a host doesn't contact in 2X period,
mark its outstanding jobs as timed out
------------------
Data archival
API:
ret = put_file(file)
returns error if insuff resources
ret = get_file(file)
ret = get_file_status(file)
has file been retrieved yet?
ret = release_file(file)
done w/ retrieved file
ret = delete_file(file)
Suppose:
- we have a 1TB file
- each client can store only 1 GB
- each client has same lifetime distribution
Single-level coding
Split file into 1000 + 200 packets
tolerate loss of any 200 packets
however, if lose any packet, need to reassemble entire file
Single-level coding + replication
Like the above, but replicate each packet to achieve
a target MTBF
If lose a packet
try to retrieve a replicate
Problems:
- space overhead
- may still need to reassemble sometimes
Two-level coding
Split file into 100+20 10-GB 1st-level packets
Split each 1st-level packet into 10+2 2nd-level packets
(space overhead: 1.2*1.2)
Store 2nd-level packets on hosts
If lose a 2nd-level packet,
recreate it by reassembling the 1st-level packet on the server
If lose a 1st-level packet
recreate it by reassembling the file
Two-level coding + replication
Same, but replicate 2nd-level packets
If lose a 2nd-level packet,
try to retrieve a replica
else reassemble the 1st-level packet and recreate 2nd-level packet
Simulator to compare these policies
want to be able to simulate:
- nothing
- plain replication
- N-level coding, with or without replication
sim parameters:
- n: # of file chunks
- k: n + # of checksum chunks
- m: if need to recover a unit, start upload of this many subunits
(n <= m <= k)
- ratio between host lifetime and network speed
experiments
things to vary
file transfer time parameter
may as well use exponential distribution;
combine unavailability
mean host lifetime
policies
levels of encoding
Ideally we'd like to divide each file so that
there is 1 chunk per host on average.
In practice, we need
Other ideas
variable chunk sizes
send large chunks to hosts with lots of space,
high expected availability
-----------------------
dir structure example
dir/
[ filename.ext (original file) ]
data.vda
symbolic link to filename.ext
NOTE: "encoder" crashes unless there's an extension
boinc_meta.txt
coding info
chunk_sizes.txt
size of chunks (each level on a separate line)
Coding/
jerasure_meta.txt
data_k001.vda (the number of digits depends on N)
...
data_k100.vda
data_m001.vda
data_m040.vda
0/
data.vda (symlink to ../Coding/data_k001.vda)
these are retained even when the file is deleted
if this is a meta-chunk:
Coding/
data_k001.vda
...
0/
1/
...
else:
md5.txt
1/
...
139/
...
other naming:
download dir has link to filename.ext
VDA_CHUNK_HOST::name: c1.c2.cn__filename.ext
physical file name for copy on a host:
vda_hostid_c1.c2.cn__filename.ext
uploads
result name is vda_upload_c1.c2.cn__filename.ext
client uploads to
upload/dir/vda_hostid_c1.c2.cn__filename.ext
when done, scheduler verifies checksum and moves to file dir
downloads
create symbolic link from download/ to (top level) file dir
------------
DB tables
vda_file
int id
create_time
char dir
char name
double size
double chunk_size;
need_update
initialized
retrieving
deleting
vda_chunk_host
create_time
int vda_file_id
int hostid
char name[256]
size
bool present_on_host
bool transfer_in_progress
bool transfer_wait
double transfer_request_time
double transfer_send_time
----------------
logic
scheduler RPC
enumerate vda_chunk_hosts for this host
use map based on physical name
completion of upload or download
lookup, update vda_chunk_host
process list of present files
if no vda_chunk_host
create one, mark file for update
update
foreach vda_chunk_host not in file list
delete, mark file for update
if project share is less than used space
decision to remove files
vda_transitioner
(put as much logic here as possible)
foreach archived_file with need_update
traverse its directory, build tree of CHUNKs, META_CHUNKs
NOTE: can cache these
enumerate vda_chunk_hosts from DB
do recovery_plan, recovery_action
to assign a chunk
select host (see below)
create vda_chunk_host record
foreach newly dead host
enumerate vda_chunk_hosts
delete them, mark files as need_update
------------------
encoding and decoding
principle: only store chunks (and possibly the entire file) on server
everything else gets created and deleted on the fly,
during one pass of vdad.
phases:
1) plan:
for each node
- set "status" as one of
PRESENT: can reconstruct from chunks on server
(chunk: is present on server)
RECOVERABLE: can recover by uploading chunks on hosts
(plus possibly some chunks already on server)
in this case, compute
"recovery cost": number of chunk uploads
needed to recover this node
"recovery set":
cheapest set of children to recover from
(chunk: a replica exists)
UNRECOVERABLE: neither
(chunk: no replica exists, and not present on server)
- compute fault tolerance
- for each chunk
set "need_data" if not PRESENT and not enough replicas exist
(this means we need to get the chunk on the server,
either by uploading it or reconstructing it)
set "need_reconstruct" if need_data and no replicas
- identify metachunks M that we should reconstruct now,
namely those that
- are PRESENT
- have a descendant chunk C with need_reconstruct
- all metachunks between M and C are UNRECOVERABLE
Note: minimizing disk usage has higher priority than
minimizing network transfer.
If we can recover C without reconstructing M, do so.
do_reconstruction(U)
do the reconstruction bottom-up.
At each stage do as much downward encoding as possible,
and clean up unused files
if not bottom level
for each child C
do_reconstruction(C)
if PRESENT and some child has need_reconstruct
plan_reconstruction(U)
- identify metachunks that we need to reconstruct in the future.
working down the recovery lists,
mark chunks as need_data
2) start transfers