From 1203c11d7a3df09f8c95d1c8b5e45e9ec9405fb3 Mon Sep 17 00:00:00 2001 From: Dashamir Hoxha Date: Tue, 12 Nov 2019 08:22:43 +0100 Subject: [PATCH 1/3] Data sharing scenarios --- src/Documentation/sidebar.json | 23 ++ static/docs/user-guide/data-sharing/index.md | 43 +++ .../data-sharing/mounted-storage.md | 115 +++++++ .../user-guide/data-sharing/remote-storage.md | 193 ++++++++++++ .../user-guide/data-sharing/shared-server.md | 107 +++++++ .../user-guide/data-sharing/synced-storage.md | 174 ++++++++++ .../data-sharing/mounted-storage.png | Bin 0 -> 21354 bytes .../data-sharing/mounted-storage.uxf | 279 ++++++++++++++++ .../user-guide/data-sharing/shared-server.png | Bin 0 -> 21942 bytes .../user-guide/data-sharing/shared-server.uxf | 297 ++++++++++++++++++ .../user-guide/data-sharing/ssh-storage.png | Bin 0 -> 17797 bytes .../user-guide/data-sharing/ssh-storage.uxf | 233 ++++++++++++++ .../data-sharing/synced-storage.png | Bin 0 -> 21207 bytes .../data-sharing/synced-storage.uxf | 279 ++++++++++++++++ 14 files changed, 1743 insertions(+) create mode 100644 static/docs/user-guide/data-sharing/index.md create mode 100644 static/docs/user-guide/data-sharing/mounted-storage.md create mode 100644 static/docs/user-guide/data-sharing/remote-storage.md create mode 100644 static/docs/user-guide/data-sharing/shared-server.md create mode 100644 static/docs/user-guide/data-sharing/synced-storage.md create mode 100644 static/img/user-guide/data-sharing/mounted-storage.png create mode 100644 static/img/user-guide/data-sharing/mounted-storage.uxf create mode 100644 static/img/user-guide/data-sharing/shared-server.png create mode 100644 static/img/user-guide/data-sharing/shared-server.uxf create mode 100644 static/img/user-guide/data-sharing/ssh-storage.png create mode 100644 static/img/user-guide/data-sharing/ssh-storage.uxf create mode 100644 static/img/user-guide/data-sharing/synced-storage.png create mode 100644 static/img/user-guide/data-sharing/synced-storage.uxf diff --git a/src/Documentation/sidebar.json b/src/Documentation/sidebar.json index 7138e05c6c..432d8fcc97 100644 --- a/src/Documentation/sidebar.json +++ b/src/Documentation/sidebar.json @@ -119,6 +119,29 @@ "label": "Managing External Data", "slug": "managing-external-data" }, + { + "label": "Data Sharing", + "slug": "data-sharing", + "source": "data-sharing/index.md", + "children": [ + { + "label": "Remote DVC Storage", + "slug": "remote-storage" + }, + { + "label": "Shared Development Server", + "slug": "shared-server" + }, + { + "label": "Mounted DVC Storage", + "slug": "mounted-storage" + }, + { + "label": "Synced DVC Storage", + "slug": "synced-storage" + } + ] + }, { "label": "Contributing", "slug": "contributing", diff --git a/static/docs/user-guide/data-sharing/index.md b/static/docs/user-guide/data-sharing/index.md new file mode 100644 index 0000000000..9171170bd5 --- /dev/null +++ b/static/docs/user-guide/data-sharing/index.md @@ -0,0 +1,43 @@ +# Data Sharing and Collaboration with DVC + +Like Git, DVC facilitates collaboration and data sharing on a distributed +environment. It makes it easy to consistently get all your data files and +directories to any machine, along with matching source code. + +![](/static/img/model-sharing-digram.png) + +There are several ways to setup data sharing with DVC. We will discuss the most +common scenarios. + +- [Sharing Data Through a Remote DVC Storage](/doc/user-guide/data-sharing/remote-storage) + + This is the recommended and the most common case of data sharing. In this case + we setup a [remote storage](/doc/command-reference/remote) on a data storage + provider, to store data files online, where others can reach them. Currently + DVC supports Amazon S3, Google Cloud Storage, Microsoft Azure Blob Storage, + SSH, HDFS, and other remote locations, and the list is constantly growing. + +- [Using Local Storage on a Shared Development Server](/doc/user-guide/data-sharing/shared-server) + + Some teams may prefer using a single shared machine to run their experiments. + This allows them to have better resource utilization such as the ability to + use multiple GPUs, etc. In this case we can use a local data storage, which + allows the team to store and share data very efficiently, with no duplication + of data files and instantaneous transfer. + +- [Sharing Data Through a Mounted DVC Storage](/doc/user-guide/data-sharing/mounted-storage) + + If the data storage server (or provider) has a protocol that is not supported + yet by DVC, but it allows us to mount a remote directory on the local + filesystem, then we can still make a setup for data sharing with DVC. This + case might be useful for example when the data files are located on a + network-attached storage (NAS) and can be accessed through protocols like NFS, + Samba, SSHFS, etc. + +- [Sharing Data Through a Synchronized DVC Storage](/doc/user-guide/data-sharing/synched-storage) + + There are cloud data storage providers that are not supported yet by DVC. But + this does not mean that we cannot use them to share data with the help of DVC. + If it is possible to synchronize a local directory with a remote one (which is + supported by almost all storage providers), then we are good to go. We can + make a setup that allows us to share DVC data. diff --git a/static/docs/user-guide/data-sharing/mounted-storage.md b/static/docs/user-guide/data-sharing/mounted-storage.md new file mode 100644 index 0000000000..0912cf5379 --- /dev/null +++ b/static/docs/user-guide/data-sharing/mounted-storage.md @@ -0,0 +1,115 @@ +# Sharing Data Through a Mounted DVC Storage + +If the data storage server (or provider) has a protocol that is not supported +yet by DVC, but it allows us to mount a remote directory on the local +filesystem, then we can still make a setup for data sharing with DVC. + +This case might be useful when the data files are located on a network-attached +storage (NAS), for example, and can be accessed through protocols like NFS, +Samba, SSHFS, etc. + +## SSHFS Mounted Storage Example + +In this example we will see how to share data with the help of a storage +directory that is mounted through SSHFS. Normally we don't need to do this, +since we can +[use a SSH remote storage](https://katacoda.com/dvc/courses/examples/ssh-storage) +directly. But we are using it just as an example, since it is easy to +network-mount a directory with SSHFS. Once you understand how it works, it +should be easy to implement it for other types of mounted storages (like NFS, +Samba, etc.). + +> For more detailed instructions check out this +> [interactive example](https://katacoda.com/dvc/courses/examples/mounted-storage). + +

+ +

+ +### Setup the server + +We have to do these configurations on the SSH server: + +- Create accounts for each user and add them to groups for accessing the Git + repository and the DVC storage. +- Create a bare git repository (for example on `/srv/project.git/`) and an empty + directory for the DVC storage (for example on `/srv/project.cache/`). + +- Grant users read/write access to these directories (through the groups). + +### Setup each user + +When we have to access a SSH server, we definitely want to generate ssh key +pairs and setup the SSH config so that we can access the server without a +password. + +Let's assume that for each user we can use the private ssh key +`~/.ssh/dvc-server` to access the server without a password, and we have also +added on `~/.ssh/config` lines like these: + +``` +Host dvc-server + HostName host01 + User user1 + IdentityFile ~/.ssh/dvc-server + IdentitiesOnly yes +``` + +Here `dvc-server` is the name or alias that we can use for our server, `host01` +can actually be the IP or the FQDN of the server, and `user1` is the username of +the first user on the server. + +### Setup the DVC storage + +First of all we have to mount the remote storage directory to a local directory. +With SSHFS (and the SSH configuration on the section above) it is as simple as +this: + +```dvc +$ mkdir ~/project.cache +$ sshfs \ + dvc-server:/srv/project.cache \ + ~/project.cache +``` + +Once it is mounted, the default storage configuration of the project can be done +like this: + +```dvc +$ dvc remote add --local --default \ + mounted-cache $HOME/project.cache +$ dvc remote list --local +mounted-cache /home/username/project.cache +``` + +Note that this configuration is specific for each user, so we have used the +`--local` option in order to save it on `.dvc/config.local`, which is ignored by +Git. Now this configuration file should have a content like this: + +``` +['remote "mounted-cache"'] +url = /home/username/project.cache +[core] +remote = mounted-cache +``` + +### Sharing data + +After adding data to the project with `dvc add` and `dvc run`, it is stored in +`.dvc/cache`. We can push both the code changes and the data like this: + +```dvc +$ git push +$ dvc push +``` + +The command `dvc push` copies the cached files from `.dvc/cache/` to +`~/project.cache/`. However, since this is a mounted directory, the cached files +are immediately copied to the server as well, and they become available on the +mounted directories of the other users. So, all the other users have to do in +order to receive the code changes and the data files is this: + +```dvc +$ git pull +$ dvc pull +``` diff --git a/static/docs/user-guide/data-sharing/remote-storage.md b/static/docs/user-guide/data-sharing/remote-storage.md new file mode 100644 index 0000000000..3b2fbe2ea7 --- /dev/null +++ b/static/docs/user-guide/data-sharing/remote-storage.md @@ -0,0 +1,193 @@ +# Sharing Data Through a Remote DVC Storage + +This is the recommended and the most common case of data sharing. In this case +we setup a [remote storage](/doc/command-reference/remote) on a data storage +provider, to store data files online, where others can reach them. Currently DVC +supports Amazon S3, Google Cloud Storage, Microsoft Azure Blob Storage, SSH, +HDFS, and other remote locations, and the list is constantly growing. + +## S3 Remote Example + +As an example, let's take a look at how you could setup an S3 +[remote storage](/doc/command-reference/remote) for a DVC project, +and push/pull to/from it. + +### Create an S3 bucket + +If you don't already have one available in your S3 account, follow instructions +in +[Create a Bucket](https://docs.aws.amazon.com/AmazonS3/latest/gsg/CreatingABucket.html). +As an advanced alternative, you may use the +[`aws s3 mb`](https://docs.aws.amazon.com/cli/latest/reference/s3/mb.html) +command instead. + +### Setup DVC remote + +To actually configure a S3 remote in the project, supply the URL to +the bucket where the data should be stored to the `dvc remote add` command. For +example: + +```dvc +$ dvc remote add -d myremote s3://mybucket/myproject +Setting 'myremote' as a default remote. +``` + +> The `-d` (`--default`) option sets `myremote` as the default remote storage +> for this project. + +This will add `myremote` to your `.dvc/config`. The `config` file now have a +section like this: + +```dvc +['remote "myremote"'] +url = s3://mybucket/myproject +[core] +remote = myremote +``` + +`dvc remote` provides a wide variety of options to configure S3 bucket. For more +information see `dvc remote modify`. + +Let's commit your changes and push your code: + +```dvc +$ git add .dvc/config +$ git push +``` + +### Upload data and code + +After adding data to the project with `dvc run` or other commands, +it should be stored in your local cache. Upload it to remote +storage with the `dvc push` command: + +```dvc +$ dvc push +``` + +Code and [DVC-files](/doc/user-guide/dvc-file-format) should be committed and +pushed with Git. + +### Download code + +Please use regular Git commands to download code and DVC-files from your Git +servers. For example: + +```dvc +$ git clone https://github.com/myaccount/myproject.git +$ cd myproject +``` + +or + +```dvc +$ git pull +``` + +### Download data + +To download data files for your project, run: + +```dvc +$ dvc pull +``` + +`dvc pull` will download the missing data files from the default remote storage +configured in the `.dvc/config` file. + +## SSH Remote Example + +As an other example, let's see how to setup an SSH remote storage for a project +and share data through it. + +> For more detailed instructions check out this +> [interactive example](https://katacoda.com/dvc/courses/examples/ssh-storage). + +In this example we will assume a central data storage server that can be +accessed through SSH from two different users. For the sake of example the +central Git repository will be located in this server too, but in general it can +be anywhere, it doesn't have to be on the same server with the DVC data storage. + +

+ +

+ +### Setup the server + +Usually we need to do these configurations on a SSH server: + +- Create accounts for each user and add them to groups for accessing the Git + repository and the DVC storage. +- Create a bare git repository (for example on `/srv/project.git/`) and an empty + directory for the DVC storage (for example on `/srv/project.cache/`). + +- Grant users read/write access to these directories (through the groups). + +### Setup each user + +When we have to access a SSH server, we definitely want to generate ssh key +pairs and setup the SSH config so that we can access the server without a +password. + +Let's assume that for each user we can use the private ssh key +`~/.ssh/dvc-server` to access the server without a password, and we have also +added on `~/.ssh/config` lines like these: + +``` +Host dvc-server + HostName host01 + User user1 + IdentityFile ~/.ssh/dvc-server + IdentitiesOnly yes +``` + +Here `dvc-server` is the name or alias that we can use for our server, `host01` +can actually be the IP or the FQDN of the server, and `user1` is the username of +the first user on the server. + +### Setup DVC remote + +The configuration of the project with the SSH remote storage can be done with a +command like this: + +```dvc +$ dvc remote add --default \ + ssh-cache ssh://dvc-server:/srv/project.cache +``` + +This command will add a default remote configuration on `.dvc/config` that looks +like this: + +``` +['remote "ssh-cache"'] +url = ssh://dvc-server:/srv/project.cache +[core] +remote = ssh-cache +``` + +Note that this configuration is the same for all the users, so we can add it to +Git in order to share it with the other users: + +```dvc +$ git add .dvc/config +$ git commit -m 'Add a SSH remote cache' +$ git push +``` + +### Sharing data + +After adding data to the project with `dvc add` and `dvc run`, it is stored in +`.dvc/cache`. We can upload to the server both the code changes and the data +like this: + +```dvc +$ git push +$ dvc push +``` + +On the other end, we can receive the code changes and data like this: + +```dvc +$ git pull +$ dvc pull +``` diff --git a/static/docs/user-guide/data-sharing/shared-server.md b/static/docs/user-guide/data-sharing/shared-server.md new file mode 100644 index 0000000000..bcfde277a9 --- /dev/null +++ b/static/docs/user-guide/data-sharing/shared-server.md @@ -0,0 +1,107 @@ +# Local Storage on a Shared Development Server + +Some teams may prefer using a single shared machine to run their experiments. +This allows them to have better resource utilization such as the ability to use +multiple GPUs, etc. + +With DVC, you can easily setup a local data storage on the server. This allows +your team to store and share data of your projects efficiently, and to have +almost instantaneous data retrieval speed, similar to `git pull` for your code. + +## Shared Server Example + +Let's see an example of how two different users on the same host can share data +with the help of a local data storage. So, both of the users and the data +storage are located on the same machine and no remote server or storage is +involved. + +> For more detailed instructions check out this +> [interactive example](https://katacoda.com/dvc/courses/examples/shared-server). + +

+ +

+ +### Setup the server + +We need to do these configurations on the server: + +- Create accounts for each user and add them to groups for accessing the Git + repository and the DVC storage. +- Create a bare git repository (for example on `/var/local/data/project.git/`) + and an empty directory for the DVC storage (for example on + `/var/local/data/project.cache/`). + +- Grant users read/write access to these directories (through the groups). + +### Configure local DVC storage + +Clone the Git project to the homedir of the users. Then set the local DVC +storage as the default remote, like this: + +```dvc +$ export DATA=/var/local/data +$ dvc remote add --default \ + local-storage $DATA/project.cache +$ dvc remote list +local-storage /var/local/data/project.cache +``` + +The configuration file `.dvc/config` now should look like this: + +``` +['remote "local-storage"'] +url = /var/local/data/project.cache +[core] +remote = local-storage +``` + +We can add it to Git and commit, since it is the same for all the users: + +```dvc +$ git add .dvc/config +$ git commit -m "Set default storage" +$ git push +``` + +### Sharing data + +Data sharing among the different users is done the normal way, with `dvc push` +and `dvc pull`, except that in this case it is the local storage that is acting +as an intermediary between the users, instead of a remote storage. + +After adding data to the project with `dvc add` and `dvc run`, it is stored in +`.dvc/cache`. We can share the code changes and the data like this: + +```dvc +$ git push +$ dvc push +``` + +From the other users we can receive the code changes and data like this: + +```dvc +$ git pull +$ dvc pull +``` + +### Optimizations + +If all the user projects and the data storage are located on the same +deduplicating filesystem, then everything is fine, copying data around will be +done instantly and without increasing the disk usage. + +If they are not on the same filesystem, or if the filesystem does not support +deduplication of data, then some optimizations are needed to make things +efficient. These optimizations may include: + +1. Creating, formatting and mounting a filesystem which supports deduplication + (like XFS, Btrfs, etc.) + +2. Locating the data storage and all the user projects on this filesystem. + +3. Adding symbolic links from the home directories of the users to their + projects (which are located on the optimized filesystem). + +For more detailed instructions check out this +[interactive example](https://katacoda.com/dvc/courses/examples/shared-server). diff --git a/static/docs/user-guide/data-sharing/synced-storage.md b/static/docs/user-guide/data-sharing/synced-storage.md new file mode 100644 index 0000000000..f8222aad34 --- /dev/null +++ b/static/docs/user-guide/data-sharing/synced-storage.md @@ -0,0 +1,174 @@ +# Sharing Data Through a Synced DVC Storage + +There are cloud data storage providers that are not supported yet by DVC (for +example look at the ones supported by [rclone](https://rclone.org/)). But this +does not mean that we cannot use them to share data with the help of DVC. If it +is possible to synchronize a local directory with a remote one (which is +supported by almost all storage providers), then we are good to go. We can still +make a setup that allows us to share DVC data. This setup is similar to that of +a mounted storage, except that the synchronization of the data does not happen +transparently. + +## Synced Storage Example + +In this example we will see how to achieve this with the help of a SSH storage +and `rsync`. Yes, SSH is one the storage types that is already supported by DVC, +and normally we don't need to do this. But we are using it just as an example, +since SSH is easy to be used for synchronizing with a remote directory. Once you +understand how it works, it should be easy to implement it for other storage +types. + +> For more detailed instructions check out this +> [interactive example](https://katacoda.com/dvc/courses/examples/synced-storage). + +

+ +

+ +### Setup the server + +We have to do these configurations on the SSH server: + +- Create accounts for each user and add them to groups for accessing the Git + repository and the DVC storage. +- Create a bare git repository (for example on `/srv/project.git/`) and an empty + directory for the DVC storage (for example on `/srv/project.cache/`). + +- Grant users read/write access to these directories (through the groups). + +### Setup each user + +When we have to access a SSH server, we definitely want to generate ssh key +pairs and setup the SSH config so that we can access the server without a +password. + +Let's assume that for each user we can use the private ssh key +`~/.ssh/dvc-server` to access the server without a password, and we have also +added on `~/.ssh/config` lines like these: + +``` +Host dvc-server + HostName host01 + User user1 + IdentityFile ~/.ssh/dvc-server + IdentitiesOnly yes +``` + +Here `dvc-server` is the name or alias that we can use for our server, `host01` +can actually be the IP or the FQDN of the server, and `user1` is the username of +the first user on the server. + +### Setup the DVC storage + +We will use a local directory as the default storage of the project, like this: + +```dvc +$ mkdir ~/project.cache +$ dvc remote add --local --default \ + synced-cache $HOME/project.cache +$ dvc remote list --local +synced-cache /home/username/project.cache +``` + +Note that this configuration is specific for each user, so we have used the +`--local` option in order to save it on `.dvc/config.local`, which is ignored by +Git. Now this configuration file should have a content like this: + +``` +['remote "synced-cache"'] +url = /home/username/project.cache +[core] +remote = synced-cache +``` + +### Sharing data + +After adding data to the project with `dvc add` and `dvc run`, it is stored in +`.dvc/cache`. We can push both the code changes and the data like this: + +```dvc +$ git push +$ dvc push +``` + +The command `dvc push` copies the cached files from `.dvc/cache/` to +`~/project.cache/`. In order to send the data to the server we also have to +synchronize the local storage with the remote storage. With `rsync` (and with +the help of SSH configurations that we have done on the previous sections) it +can be as simple as this: + +```dvc +$ rsync -r -P \ + ~/project.cache/ \ + dvc-server:/srv/project.cache/ +``` + +To get the cached files on their local storage, the other users have to +synchronize first with a command like this: + +```dvc +$ rsync -r -P \ + dvc-server:/srv/project.cache/ \ + ~/project.cache/ +``` + +Then they can receive the code changes and the data files like this: + +```dvc +$ git pull +$ dvc pull +``` + +### Deduplicate the storage + +For each file that is cached, there is a copy on the workspace, a copy on +`.dvc/cache/`, and another copy on `~/project.cache/` (besides the copy on the +remote storage). + +If you have a deduplicating filesystem (like XFS, Btrfs, etc.) then everything +is fine because making copies of the same file does not actually increase the +disk usage. If not, then you can create and mount by loopback a deduplicating +filesystem, and move the project and caches there. + +For more detailed instructions check out the +[interactive example](https://katacoda.com/dvc/courses/examples/synced-storage). + +### Automate synchronization steps + +Notice that whenever we run `dvc push` we also have to run `rsync`, and before a +`dvc pull` we also have to run `rsync`. This can be automated and simplified by +defining aliases or functions on `~/.bashrc`, which might look like + +```dvc +push() { + set -x + git push + dvc push + rsync -rP ~/project.cache/ dvc-server:/srv/project.cache/ + set +x +} + +pull() { + set -x + git pull + rsync -rP dvc-server:/srv/project.cache/ ~/project.cache/ + dvc pull + set +x +} +``` + +Then, to share code changes and data you just run: + +```dvc +$ push +``` + +And to receive code changes and data you just run: + +```dvc +$ pull +``` + +Another way to make the synchronization transparent to the users is to setup +cron jobs that synchronize periodically the local DVC storage with the central +one. diff --git a/static/img/user-guide/data-sharing/mounted-storage.png b/static/img/user-guide/data-sharing/mounted-storage.png new file mode 100644 index 0000000000000000000000000000000000000000..27f69591d465976ef7aa6a6cb5e202df31b033c8 GIT binary patch literal 21354 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 + + // Uncomment the following line to change the fontsize and font: +// fontsize=14 +fontfamily=Monospaced //possible: SansSerif,Serif,Monospaced + +////////////////////////////////////////////////////////////////////////////////////////////// +// Welcome to UMLet! +// +// Double-click on elements to add them to the diagram, or to copy them +// Edit elements by modifying the text in this panel +// Hold Ctrl to select multiple elements +// Use Ctrl+mouse to select via lasso +// +// Use +/- or Ctrl+mouse wheel to zoom +// Drag a whole relation at its central square icon +// +// Press Ctrl+C to copy the whole diagram to the system clipboard (then just paste it to, eg, Word) +// Edit the files in the "palettes" directory to create your own element palettes +// +// Select "Custom Elements > New..." to create new element types +////////////////////////////////////////////////////////////////////////////////////////////// + + +// This text will be stored with each diagram; use it for notes. + 10 + + UMLClass + + 170 + 70 + 180 + 30 + + halign=left +*/srv/project.cache/ * +bg=#9802f5 +lw=0 + + + + UMLClass + + 170 + 110 + 180 + 30 + + halign=left +*/srv/project.git/ * +bg=#fc5e03 +lw=0 + + + + Relation + + 260 + 130 + 70 + 170 + + lt=<<<->>> +lw=1.5 +fg=#fc5e03 + 10.0;10.0;10.0;150.0;50.0;150.0 + + + Relation + + 200 + 130 + 70 + 170 + + lt=<<<->>> +lw=1.5 +fg=#fc5e03 + 50.0;10.0;50.0;150.0;10.0;150.0 + + + Relation + + 430 + 220 + 60 + 120 + + lt=<<<->>> +lw=1.5 +fg=#9802f5 + 40.0;10.0;40.0;100.0;10.0;100.0 + + + Relation + + 120 + 80 + 70 + 140 + + lt=<<<<<->>>>> +lw=4 +fg=#9802f5 + 50.0;10.0;10.0;10.0;10.0;120.0 + + + UMLClass + + 290 + 240 + 190 + 110 + + halign=left +*user2/project/* +lt=.. + + + + UMLClass + + 310 + 310 + 130 + 30 + + halign=left +*.dvc/cache/* +bg=#9802f5 +lw=0 + + + + UMLClass + + 310 + 270 + 130 + 30 + + halign=left +*.git/* +bg=#fc5e03 +lw=0 + + + + UMLUseCase + + 140 + 50 + 240 + 110 + + lt=.. + + + + + UMLClass + + 280 + 170 + 210 + 190 + + *host2* +halign=left + + + + UMLClass + + 40 + 240 + 190 + 110 + + halign=left +* user1/project/* +lt=.. + + + + UMLClass + + 80 + 310 + 130 + 30 + + halign=left +*.dvc/cache/* +bg=#9802f5 +lw=0 + + + + UMLClass + + 80 + 270 + 130 + 30 + + halign=left +*.git/* +bg=#fc5e03 +lw=0 + + + + UMLClass + + 30 + 170 + 210 + 190 + + *host1* +halign=left + + + + UMLClass + + 40 + 200 + 190 + 30 + + halign=left +*user1/project.cache/* +bg=#9802f5 +lw=0 + + + + Relation + + 40 + 220 + 60 + 120 + + lt=<<<->>> +lw=1.5 +fg=#9802f5 + 10.0;10.0;10.0;100.0;40.0;100.0 + + + UMLClass + + 290 + 200 + 190 + 30 + + halign=left +*user2/project.cache/* +bg=#9802f5 +lw=0 + + + + Relation + + 340 + 80 + 70 + 140 + + lt=<<<<<->>>>> +lw=4 +fg=#9802f5 + 10.0;10.0;50.0;10.0;50.0;120.0 + + diff --git a/static/img/user-guide/data-sharing/shared-server.png b/static/img/user-guide/data-sharing/shared-server.png new file mode 100644 index 0000000000000000000000000000000000000000..9c3039472c8d9cea997763a100680d328e4e6885 GIT binary patch literal 21942 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 tRn=2WKbD{!i}=5G`{?l + + // Uncomment the following line to change the fontsize and font: +// fontsize=14 +fontfamily=Monospaced //possible: SansSerif,Serif,Monospaced + +////////////////////////////////////////////////////////////////////////////////////////////// +// Welcome to UMLet! +// +// Double-click on elements to add them to the diagram, or to copy them +// Edit elements by modifying the text in this panel +// Hold Ctrl to select multiple elements +// Use Ctrl+mouse to select via lasso +// +// Use +/- or Ctrl+mouse wheel to zoom +// Drag a whole relation at its central square icon +// +// Press Ctrl+C to copy the whole diagram to the system clipboard (then just paste it to, eg, Word) +// Edit the files in the "palettes" directory to create your own element palettes +// +// Select "Custom Elements > New..." to create new element types +////////////////////////////////////////////////////////////////////////////////////////////// + + +// This text will be stored with each diagram; use it for notes. + 10 + + UMLClass + + 200 + 30 + 250 + 350 + + halign=left +*/var/local/data (XFS)* +lt=.. + + + + + UMLClass + + 250 + 60 + 150 + 30 + + halign=left +* project.cache/* +bg=#9802f5 +lw=0 + + + + UMLClass + + 250 + 100 + 150 + 30 + + halign=left +* project.git/* +bg=#fc5e03 +lw=0 + + + + UMLClass + + 250 + 140 + 150 + 110 + + halign=left +*user1-project/* +lt=.. + + + + UMLClass + + 270 + 170 + 110 + 30 + + halign=left +*.git/* +bg=#fc5e03 +lw=0 + + + + UMLClass + + 270 + 210 + 110 + 30 + + halign=left +*.dvc/cache/* +bg=#9802f5 +lw=0 + + + + UMLClass + + 250 + 260 + 150 + 110 + + halign=left +*user2-project/* +lt=.. + + + + UMLClass + + 270 + 290 + 110 + 30 + + halign=left +*.git/* +bg=#fc5e03 +lw=0 + + + + UMLClass + + 270 + 330 + 110 + 30 + + halign=left +*.dvc/cache/* +bg=#9802f5 +lw=0 + + + + Relation + + 370 + 110 + 70 + 90 + + lt=<<<->>> +lw=1.5 +fg=#fc5e03 + 30.0;10.0;50.0;10.0;50.0;70.0;10.0;70.0 + + + Relation + + 370 + 100 + 80 + 220 + + lt=<<<->>> +lw=1.5 +fg=#fc5e03 + 30.0;10.0;60.0;10.0;60.0;200.0;10.0;200.0 + + + Relation + + 220 + 70 + 70 + 170 + + lt=<<<->>> +lw=1.5 +fg=#9802f5 + 30.0;10.0;10.0;10.0;10.0;150.0;50.0;150.0 + + + Relation + + 210 + 60 + 80 + 300 + + lt=<<<->>> +lw=1.5 +fg=#9802f5 + 40.0;10.0;10.0;10.0;10.0;280.0;60.0;280.0 + + + UMLClass + + 30 + 30 + 150 + 350 + + halign=left +*/home* +lt=.. + + + + UMLClass + + 50 + 110 + 110 + 90 + + halign=left +*user1/* +lt=.. +group=5 + + + + UMLClass + + 60 + 150 + 80 + 30 + + *project/* +lt=.. +lw=2 +group=5 + + + + UMLClass + + 50 + 230 + 110 + 90 + + halign=left +*user2/* +lt=.. +group=6 + + + + UMLClass + + 60 + 270 + 80 + 30 + + *project/* +lt=.. +lw=2 +group=6 + + + + Relation + + 130 + 140 + 140 + 40 + + lt=<. +lw=1.5 + + 120.0;20.0;10.0;20.0 + + + Relation + + 130 + 270 + 140 + 30 + + lt=<. +lw=1.5 + 120.0;10.0;10.0;10.0 + + diff --git a/static/img/user-guide/data-sharing/ssh-storage.png b/static/img/user-guide/data-sharing/ssh-storage.png new file mode 100644 index 0000000000000000000000000000000000000000..a48b3341144117b047909f962eccd0be5379ee24 GIT binary patch literal 17797 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 + + // Uncomment the following line to change the fontsize and font: +// fontsize=14 +fontfamily=Monospaced //possible: SansSerif,Serif,Monospaced + +////////////////////////////////////////////////////////////////////////////////////////////// +// Welcome to UMLet! +// +// Double-click on elements to add them to the diagram, or to copy them +// Edit elements by modifying the text in this panel +// Hold Ctrl to select multiple elements +// Use Ctrl+mouse to select via lasso +// +// Use +/- or Ctrl+mouse wheel to zoom +// Drag a whole relation at its central square icon +// +// Press Ctrl+C to copy the whole diagram to the system clipboard (then just paste it to, eg, Word) +// Edit the files in the "palettes" directory to create your own element palettes +// +// Select "Custom Elements > New..." to create new element types +////////////////////////////////////////////////////////////////////////////////////////////// + + +// This text will be stored with each diagram; use it for notes. + 10 + + UMLClass + + 170 + 60 + 170 + 30 + + halign=left +*/srv/project.cache/ * +bg=#9802f5 +lw=0 + + + + UMLClass + + 170 + 100 + 170 + 30 + + halign=left +*/srv/project.git/ * +bg=#fc5e03 +lw=0 + + + + Relation + + 250 + 120 + 70 + 140 + + lt=<<<->>> +lw=1.5 +fg=#fc5e03 + 10.0;10.0;10.0;120.0;50.0;120.0 + + + Relation + + 190 + 120 + 70 + 140 + + lt=<<<->>> +lw=1.5 +fg=#fc5e03 + 50.0;10.0;50.0;120.0;10.0;120.0 + + + Relation + + 330 + 70 + 140 + 230 + + lt=<<<->>> +lw=1.5 +fg=#9802f5 + 10.0;10.0;120.0;10.0;120.0;210.0;80.0;210.0 + + + Relation + + 40 + 70 + 150 + 230 + + lt=<<<->>> +lw=1.5 +fg=#9802f5 + 130.0;10.0;10.0;10.0;10.0;210.0;50.0;210.0 + + + UMLClass + + 280 + 200 + 150 + 110 + + halign=left +*user2/project/* +lt=.. +group=9 + + + + UMLClass + + 300 + 270 + 110 + 30 + + halign=left +*.dvc/cache/* +bg=#9802f5 +lw=0 +group=9 + + + + UMLClass + + 300 + 230 + 110 + 30 + + halign=left +*.git/* +bg=#fc5e03 +lw=0 +group=9 + + + + UMLUseCase + + 130 + 40 + 250 + 110 + + lt=.. + + + + + UMLClass + + 270 + 170 + 170 + 150 + + *host2* +halign=left +group=9 + + + + UMLClass + + 70 + 200 + 150 + 110 + + halign=left +*user1/project/* +lt=.. +group=10 + + + + UMLClass + + 90 + 270 + 110 + 30 + + halign=left +*.dvc/cache/* +bg=#9802f5 +lw=0 +group=10 + + + + UMLClass + + 90 + 230 + 110 + 30 + + halign=left +*.git/* +bg=#fc5e03 +lw=0 +group=10 + + + + UMLClass + + 60 + 170 + 170 + 150 + + *host1* +halign=left +group=10 + + + diff --git a/static/img/user-guide/data-sharing/synced-storage.png b/static/img/user-guide/data-sharing/synced-storage.png new file mode 100644 index 0000000000000000000000000000000000000000..c5f4ea66c2b349b61ec9db9feac88a6a39596834 GIT binary patch literal 21207 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 m(N@S!r?VJwp8NREUhNRqhq=XqtAPhrGI+ZBxvX + + // Uncomment the following line to change the fontsize and font: +// fontsize=14 +fontfamily=Monospaced //possible: SansSerif,Serif,Monospaced + +////////////////////////////////////////////////////////////////////////////////////////////// +// Welcome to UMLet! +// +// Double-click on elements to add them to the diagram, or to copy them +// Edit elements by modifying the text in this panel +// Hold Ctrl to select multiple elements +// Use Ctrl+mouse to select via lasso +// +// Use +/- or Ctrl+mouse wheel to zoom +// Drag a whole relation at its central square icon +// +// Press Ctrl+C to copy the whole diagram to the system clipboard (then just paste it to, eg, Word) +// Edit the files in the "palettes" directory to create your own element palettes +// +// Select "Custom Elements > New..." to create new element types +////////////////////////////////////////////////////////////////////////////////////////////// + + +// This text will be stored with each diagram; use it for notes. + 10 + + UMLClass + + 190 + 70 + 170 + 30 + + halign=left +*/srv/project.cache/ * +bg=#9802f5 +lw=0 + + + + UMLClass + + 190 + 110 + 170 + 30 + + halign=left +*/srv/project.git/ * +bg=#fc5e03 +lw=0 + + + + Relation + + 270 + 130 + 70 + 180 + + lt=<<<->>> +lw=1.5 +fg=#fc5e03 + 10.0;10.0;10.0;160.0;50.0;160.0 + + + Relation + + 210 + 130 + 70 + 180 + + lt=<<<->>> +lw=1.5 +fg=#fc5e03 + 50.0;10.0;50.0;160.0;10.0;160.0 + + + Relation + + 430 + 230 + 60 + 120 + + lt=<<<->>> +lw=1.5 +fg=#9802f5 + 40.0;10.0;40.0;100.0;10.0;100.0 + + + Relation + + 140 + 70 + 70 + 160 + + lt=<<<->>> +lw=1.5 +fg=#9802f5 + 50.0;10.0;10.0;10.0;10.0;140.0 + + + UMLClass + + 300 + 250 + 180 + 110 + + halign=left +*user2/project/* +lt=.. + + + + UMLClass + + 320 + 320 + 120 + 30 + + halign=left +*.dvc/cache/* +bg=#9802f5 +lw=0 + + + + UMLClass + + 320 + 280 + 120 + 30 + + halign=left +*.git/* +bg=#fc5e03 +lw=0 + + + + UMLUseCase + + 160 + 50 + 230 + 110 + + lt=.. + + + + + UMLClass + + 290 + 180 + 200 + 190 + + *host2* +halign=left + + + + UMLClass + + 60 + 250 + 180 + 110 + + halign=left +* user1/project/* +lt=.. + + + + UMLClass + + 100 + 320 + 120 + 30 + + halign=left +*.dvc/cache/* +bg=#9802f5 +lw=0 + + + + UMLClass + + 100 + 280 + 120 + 30 + + halign=left +*.git/* +bg=#fc5e03 +lw=0 + + + + UMLClass + + 40 + 180 + 210 + 190 + + *host1* +halign=left + + + + UMLClass + + 60 + 210 + 180 + 30 + + halign=left +*user1/project.cache/* +bg=#9802f5 +lw=0 + + + + Relation + + 60 + 230 + 60 + 120 + + lt=<<<->>> +lw=1.5 +fg=#9802f5 + 10.0;10.0;10.0;100.0;40.0;100.0 + + + UMLClass + + 300 + 210 + 180 + 30 + + halign=left +*user2/project.cache/* +bg=#9802f5 +lw=0 + + + + Relation + + 350 + 70 + 70 + 160 + + lt=<<<->>> +lw=1.5 +fg=#9802f5 + 10.0;10.0;50.0;10.0;50.0;140.0 + + From ef27cb2d685e038f0487f92601920762ccc71f13 Mon Sep 17 00:00:00 2001 From: Dashamir Hoxha Date: Mon, 25 Nov 2019 08:48:01 +0100 Subject: [PATCH 2/3] Add the case of mounted DVC cache --- src/Documentation/sidebar.json | 4 + static/docs/user-guide/data-sharing/index.md | 10 + .../user-guide/data-sharing/mounted-cache.md | 125 ++++++++++ .../user-guide/data-sharing/mounted-cache.png | Bin 0 -> 15771 bytes .../user-guide/data-sharing/mounted-cache.uxf | 225 ++++++++++++++++++ 5 files changed, 364 insertions(+) create mode 100644 static/docs/user-guide/data-sharing/mounted-cache.md create mode 100644 static/img/user-guide/data-sharing/mounted-cache.png create mode 100644 static/img/user-guide/data-sharing/mounted-cache.uxf diff --git a/src/Documentation/sidebar.json b/src/Documentation/sidebar.json index 432d8fcc97..6a7caa903c 100644 --- a/src/Documentation/sidebar.json +++ b/src/Documentation/sidebar.json @@ -136,6 +136,10 @@ "label": "Mounted DVC Storage", "slug": "mounted-storage" }, + { + "label": "Mounted DVC Cache", + "slug": "mounted-cache" + }, { "label": "Synced DVC Storage", "slug": "synced-storage" diff --git a/static/docs/user-guide/data-sharing/index.md b/static/docs/user-guide/data-sharing/index.md index 9171170bd5..613c5a16e2 100644 --- a/static/docs/user-guide/data-sharing/index.md +++ b/static/docs/user-guide/data-sharing/index.md @@ -34,6 +34,16 @@ common scenarios. network-attached storage (NAS) and can be accessed through protocols like NFS, Samba, SSHFS, etc. +- [Sharing Data Through a Mounted DVC Cache](/doc/user-guide/data-sharing/mounted-cache) + + Instead of mounting the DVC storage from the server, we can directly mount the + cache directory (`.dvc/cache/`). If all the users do this, then effectively + they will be using the same cache directory (which is mounted from the NAS + server). So, if one of them adds something to the cache, it will appear + automatically to the cache of all the others. As a result, no `dvc push` and + `dvc pull` are needed to share the data, just a `dvc checkout` will be + sufficient. + - [Sharing Data Through a Synchronized DVC Storage](/doc/user-guide/data-sharing/synched-storage) There are cloud data storage providers that are not supported yet by DVC. But diff --git a/static/docs/user-guide/data-sharing/mounted-cache.md b/static/docs/user-guide/data-sharing/mounted-cache.md new file mode 100644 index 0000000000..1d4d04cfd8 --- /dev/null +++ b/static/docs/user-guide/data-sharing/mounted-cache.md @@ -0,0 +1,125 @@ +# Sharing Data Through a Mounted Cache + +We have seen already how to share data through a +[mounted DVC storage](/doc/user-guide/data-sharing/mounted-storage). In that +setup we have a copy of the data on the remote server and at least one copy of +the data on the local filesystem. This situation can be further optimized +(regarding data management) if we use a shared cache. + +The idea is that instead of mounting the DVC storage from the server, we can +directly mount the cache directory (`.dvc/cache/`). If all the users do this, +then effectively they will be using the same cache directory (which is mounted +from the NAS server). So, if one of them adds something to the cache, it will +appear automatically to the cache of all the others. As a result, no `dvc push` +and `dvc pull` are needed to share the data, just a `dvc checkout` will be +sufficient. + +> ** ❗ Caution:** Deleting data from the cache will also make it vanish from +> the cache of the other users. So, be careful with the command `dvc gc` which +> cleans obsolete data from the cache and consult the other users of the cache +> before using it. + +The optimization in data management comes from using the _symlink_ cache type. +You can find more details about it in the page of +[Large Dataset Optimization](https://dvc.org/doc/user-guide/large-dataset-optimization). + +## SSHFS Mounted Cache Example + +In this example we will see how to share data with the help of a cache directory +that is mounted through SSHFS. We are using a SSHFS example because it is easy +to network-mount a directory with SSHFS. However once you understand how it +works, it should be easy to implement it for other types of network-mounted +storages (like NFS, Samba, etc.). + +> For more detailed instructions check out this +> [interactive example](https://katacoda.com/dvc/courses/examples/mounted-cache). + +

+ +

+ +### Setup the server + +We have to do these configurations on the SSH server: + +- Create accounts for each user and add them to groups for accessing the Git + repository and the DVC storage. +- Create a bare git repository (for example on `/srv/project.git/`) and an empty + directory for the DVC cache (for example on `/srv/project.cache/`). +- Grant users read/write access to these directories (through the groups). + +### Setup each user + +When we have to access a SSH server, we definitely want to generate ssh key +pairs and setup the SSH config so that we can access the server without a +password. + +Let's assume that for each user we can use the private ssh key +`~/.ssh/dvc-server` to access the server without a password, and we have also +added on `~/.ssh/config` lines like these: + +``` +Host dvc-server + HostName host01 + User user1 + IdentityFile ~/.ssh/dvc-server + IdentitiesOnly yes +``` + +Here `dvc-server` is the name or alias that we can use for our server, `host01` +can actually be the IP or the FQDN of the server, and `user1` is the username of +the first user on the server. + +### Mount the DVC cache + +With SSHFS (and the SSH configuration on the section above), we can mount the +remote directory to `.dvc/cache/` of the project like this: + +```dvc +$ mkdir -p ~/project/.dvc/cache +$ sshfs \ + dvc-server:/srv/project.cache/ \ + ~/project/.dvc/cache/ +``` + +### Optimize data management + +Since the cache directory is located on a mounted filesystem, we cannot use the +_reflink_ optimization for data management. However we can use _symlinks_ (which +work across the filesystems): + +```dvc +$ dvc config cache.type 'reflink,symlink,hardlink,copy' +$ dvc config cache.protected true +``` + +The configuration file `.dvc/config` should look like this: + +```ini +[cache] +type = "reflink,symlink,hardlink,copy" +protected = true +``` + +### Sharing data + +Let's say that one of the users has added some data with `dvc add` or `dvc run`. +This data is stored in `.dvc/cache` and it is linked (with symlink) from the +workspace. He can share the DVC-files with: + +```dvc +$ git push +``` + +In order to receive the changes, the other users should do: + +```dvc +$ git pull +$ dvc checkout +``` + +Notice that there is no need to use `dvc push` and `dvc pull` for sharing the +data, because it is like all the collaborating users are using the same +directory for the DVC cache. As soon as one of them saves a file in cache, it is +immediately available for `dvc checkout` to all the others. All they need to do +is to synchronize their DVC-files (with `git push` and `git pull`). diff --git a/static/img/user-guide/data-sharing/mounted-cache.png b/static/img/user-guide/data-sharing/mounted-cache.png new file mode 100644 index 0000000000000000000000000000000000000000..a67db9778c4798b9d5de704138d94973d9bae51c GIT binary patch literal 15771 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 literal 0 HcmV?d00001 diff --git a/static/img/user-guide/data-sharing/mounted-cache.uxf b/static/img/user-guide/data-sharing/mounted-cache.uxf new file mode 100644 index 0000000000..2d2d3bbb28 --- /dev/null +++ b/static/img/user-guide/data-sharing/mounted-cache.uxf @@ -0,0 +1,225 @@ + + + // Uncomment the following line to change the fontsize and font: +// fontsize=14 +fontfamily=Monospaced //possible: SansSerif,Serif,Monospaced + +////////////////////////////////////////////////////////////////////////////////////////////// +// Welcome to UMLet! +// +// Double-click on elements to add them to the diagram, or to copy them +// Edit elements by modifying the text in this panel +// Hold Ctrl to select multiple elements +// Use Ctrl+mouse to select via lasso +// +// Use +/- or Ctrl+mouse wheel to zoom +// Drag a whole relation at its central square icon +// +// Press Ctrl+C to copy the whole diagram to the system clipboard (then just paste it to, eg, Word) +// Edit the files in the "palettes" directory to create your own element palettes +// +// Select "Custom Elements > New..." to create new element types +////////////////////////////////////////////////////////////////////////////////////////////// + + +// This text will be stored with each diagram; use it for notes. + 10 + + UMLClass + + 170 + 270 + 200 + 30 + + halign=left +* /srv/project.cache/ * +bg=#9802f5 +lw=0 + + + + UMLClass + + 180 + 50 + 180 + 30 + + halign=left +*/srv/project.git/ * +bg=#fc5e03 +lw=0 + + + + Relation + + 270 + 70 + 70 + 130 + + lt=<<<->>> +lw=1.5 +fg=#fc5e03 + 10.0;10.0;10.0;110.0;50.0;110.0 + + + Relation + + 210 + 70 + 70 + 130 + + lt=<<<->>> +lw=1.5 +fg=#fc5e03 + 50.0;10.0;50.0;110.0;10.0;110.0 + + + UMLClass + + 300 + 140 + 190 + 110 + + halign=left +*user2/project/* +lt=.. + + + + UMLClass + + 320 + 210 + 130 + 30 + + halign=left +*.dvc/cache/* +bg=#9802f5 +lw=0 + + + + UMLClass + + 320 + 170 + 130 + 30 + + halign=left +*.git/* +bg=#fc5e03 +lw=0 + + + + UMLUseCase + + 150 + 30 + 240 + 70 + + lt=.. + + + + + UMLClass + + 290 + 110 + 210 + 150 + + *host2* +halign=left + + + + UMLClass + + 50 + 140 + 190 + 110 + + halign=left +* user1/project/* +lt=.. + + + + UMLClass + + 90 + 210 + 130 + 30 + + halign=left +*.dvc/cache/* +bg=#9802f5 +lw=0 + + + + UMLClass + + 90 + 170 + 130 + 30 + + halign=left +*.git/* +bg=#fc5e03 +lw=0 + + + + UMLClass + + 40 + 110 + 210 + 150 + + *host1* +halign=left + + + + Relation + + 190 + 230 + 30 + 60 + + lt=.. +lw=20 +fg=#9802f5 + 10.0;10.0;10.0;40.0 + + + Relation + + 330 + 230 + 30 + 60 + + lt=.. +lw=20 +fg=#9802f5 + 10.0;40.0;10.0;10.0 + + From e2486a5dc33560e00da11fa4bfecf0e75a9022a9 Mon Sep 17 00:00:00 2001 From: Dashamir Hoxha Date: Mon, 25 Nov 2019 23:35:58 +0100 Subject: [PATCH 3/3] Improve the pages by using collapsed sections, better explanations, etc. --- static/docs/user-guide/data-sharing/index.md | 29 ++-- .../user-guide/data-sharing/mounted-cache.md | 43 +++-- .../data-sharing/mounted-storage.md | 104 ++++++++---- .../user-guide/data-sharing/remote-storage.md | 159 +++++++++--------- .../user-guide/data-sharing/shared-server.md | 80 +++++---- .../user-guide/data-sharing/synced-storage.md | 88 ++++++---- 6 files changed, 299 insertions(+), 204 deletions(-) diff --git a/static/docs/user-guide/data-sharing/index.md b/static/docs/user-guide/data-sharing/index.md index 613c5a16e2..56346d4769 100644 --- a/static/docs/user-guide/data-sharing/index.md +++ b/static/docs/user-guide/data-sharing/index.md @@ -2,7 +2,7 @@ Like Git, DVC facilitates collaboration and data sharing on a distributed environment. It makes it easy to consistently get all your data files and -directories to any machine, along with matching source code. +directories to any machine, along with the source code. ![](/static/img/model-sharing-digram.png) @@ -19,11 +19,11 @@ common scenarios. - [Using Local Storage on a Shared Development Server](/doc/user-guide/data-sharing/shared-server) - Some teams may prefer using a single shared machine to run their experiments. - This allows them to have better resource utilization such as the ability to - use multiple GPUs, etc. In this case we can use a local data storage, which - allows the team to store and share data very efficiently, with no duplication - of data files and instantaneous transfer. + Some teams may prefer to use a single shared machine for running their + experiments. This allows them to have better resource utilization such as the + ability to use multiple GPUs, etc. In this case we can use a local data + storage, which allows the team to store and share data very efficiently, with + no duplication of data files and instantaneous transfer time. - [Sharing Data Through a Mounted DVC Storage](/doc/user-guide/data-sharing/mounted-storage) @@ -36,18 +36,17 @@ common scenarios. - [Sharing Data Through a Mounted DVC Cache](/doc/user-guide/data-sharing/mounted-cache) - Instead of mounting the DVC storage from the server, we can directly mount the - cache directory (`.dvc/cache/`). If all the users do this, then effectively - they will be using the same cache directory (which is mounted from the NAS - server). So, if one of them adds something to the cache, it will appear - automatically to the cache of all the others. As a result, no `dvc push` and - `dvc pull` are needed to share the data, just a `dvc checkout` will be - sufficient. + This case is similar to the Mounted DVC Storage (mentioned above), but instead + of mounting the DVC storage from the server, we can directly mount the cache + directory (`.dvc/cache/`). If all the users do this, then effectively they + will be using the same cache directory (which is mounted from the NAS server). + So, if one of them adds something to the cache, it will appear automatically + to the cache of all the others. - [Sharing Data Through a Synchronized DVC Storage](/doc/user-guide/data-sharing/synched-storage) There are cloud data storage providers that are not supported yet by DVC. But this does not mean that we cannot use them to share data with the help of DVC. If it is possible to synchronize a local directory with a remote one (which is - supported by almost all storage providers), then we are good to go. We can - make a setup that allows us to share DVC data. + supported by almost all storage providers), then we can still make a setup + that allows us to share DVC data. diff --git a/static/docs/user-guide/data-sharing/mounted-cache.md b/static/docs/user-guide/data-sharing/mounted-cache.md index 1d4d04cfd8..f12afda41e 100644 --- a/static/docs/user-guide/data-sharing/mounted-cache.md +++ b/static/docs/user-guide/data-sharing/mounted-cache.md @@ -2,10 +2,10 @@ We have seen already how to share data through a [mounted DVC storage](/doc/user-guide/data-sharing/mounted-storage). In that -setup we have a copy of the data on the remote server and at least one copy of -the data on the local filesystem. This situation can be further optimized -(regarding data management) if we use a shared cache. +case we have a copy of the data on the DVC storage and at least one copy on each +user project, since deduplication does not work across filesystems. +However the data management can be further optimized if we use a shared cache. The idea is that instead of mounting the DVC storage from the server, we can directly mount the cache directory (`.dvc/cache/`). If all the users do this, then effectively they will be using the same cache directory (which is mounted @@ -14,16 +14,16 @@ appear automatically to the cache of all the others. As a result, no `dvc push` and `dvc pull` are needed to share the data, just a `dvc checkout` will be sufficient. -> ** ❗ Caution:** Deleting data from the cache will also make it vanish from -> the cache of the other users. So, be careful with the command `dvc gc` which -> cleans obsolete data from the cache and consult the other users of the cache -> before using it. +> ** ❗ Caution:** Deleting data from the cache will also make it disappear from +> the cache of the other users. So, be careful with the command `dvc gc` (which +> cleans obsolete data from the cache) and consult the other users of the +> project before using this command. The optimization in data management comes from using the _symlink_ cache type. You can find more details about it in the page of [Large Dataset Optimization](https://dvc.org/doc/user-guide/large-dataset-optimization). -## SSHFS Mounted Cache Example +## Mounted Cache Example In this example we will see how to share data with the help of a cache directory that is mounted through SSHFS. We are using a SSHFS example because it is easy @@ -38,7 +38,9 @@ storages (like NFS, Samba, etc.).

-### Setup the server +
+ +### Prerequisites: Setup the server We have to do these configurations on the SSH server: @@ -48,6 +50,10 @@ We have to do these configurations on the SSH server: directory for the DVC cache (for example on `/srv/project.cache/`). - Grant users read/write access to these directories (through the groups). +
+ +
+ ### Setup each user When we have to access a SSH server, we definitely want to generate ssh key @@ -70,6 +76,8 @@ Here `dvc-server` is the name or alias that we can use for our server, `host01` can actually be the IP or the FQDN of the server, and `user1` is the username of the first user on the server. +
+ ### Mount the DVC cache With SSHFS (and the SSH configuration on the section above), we can mount the @@ -101,11 +109,22 @@ type = "reflink,symlink,hardlink,copy" protected = true ``` +This configuration is the same for all the users, so we can add it to Git in +order to share it with the other users: + +```dvc +$ git add .dvc/config +$ git commit -m "Use symlinks if reflinks are not available" +$ git push +``` + ### Sharing data -Let's say that one of the users has added some data with `dvc add` or `dvc run`. -This data is stored in `.dvc/cache` and it is linked (with symlink) from the -workspace. He can share the DVC-files with: +When we add data to the project with `dvc add` or `dvc run`, some DVC-files are +created, the data is stored in `.dvc/cache/`, and it is linked (with symlink) +from the workspace. + +We can share the DVC-files with: ```dvc $ git push diff --git a/static/docs/user-guide/data-sharing/mounted-storage.md b/static/docs/user-guide/data-sharing/mounted-storage.md index 0912cf5379..1e9901b1f4 100644 --- a/static/docs/user-guide/data-sharing/mounted-storage.md +++ b/static/docs/user-guide/data-sharing/mounted-storage.md @@ -4,29 +4,45 @@ If the data storage server (or provider) has a protocol that is not supported yet by DVC, but it allows us to mount a remote directory on the local filesystem, then we can still make a setup for data sharing with DVC. -This case might be useful when the data files are located on a network-attached -storage (NAS), for example, and can be accessed through protocols like NFS, -Samba, SSHFS, etc. +> This case might be useful when the data files are located on a +> network-attached storage (NAS) for example, and can be accessed through +> protocols like NFS, Samba, SSHFS, etc. -## SSHFS Mounted Storage Example +The solution is very similar to that of a +[Shared Development Server](/doc/user-guide/data-sharing/shared-server), using a +local DVC storage, which is actually located on the mounted directory. Whenever +we push data to our mounted storage, it is made available immediately to the +mounted storage of each user. So, the data sharing workflow is the normal one, +with `dvc push` and `dvc pull`. + +> Different from the case of Shared Development Server, the local DVC storage +> and the project cannot be on the same filesystem (because the DVC storage is +> on a mounted remote directory). So, the deduplication optimization does not +> work that well. We have a copy of the data on the DVC storage, and at least +> one copy on each user project. + +## Mounted Storage Example In this example we will see how to share data with the help of a storage -directory that is mounted through SSHFS. Normally we don't need to do this, -since we can -[use a SSH remote storage](https://katacoda.com/dvc/courses/examples/ssh-storage) -directly. But we are using it just as an example, since it is easy to -network-mount a directory with SSHFS. Once you understand how it works, it -should be easy to implement it for other types of mounted storages (like NFS, -Samba, etc.). +directory that is mounted through SSHFS. -> For more detailed instructions check out this -> [interactive example](https://katacoda.com/dvc/courses/examples/mounted-storage). +> Normally we don't need to do this, since we can +> [use a SSH remote storage](https://katacoda.com/dvc/courses/examples/ssh-storage) +> directly. But we are using it just as an example, since it is easy to +> network-mount a directory with SSHFS. Once you understand how it works, it +> should be easy to implement it for other types of mounted storages (like NFS, +> Samba, etc.).

-### Setup the server +> For more detailed instructions check out this +> [interactive example](https://katacoda.com/dvc/courses/examples/mounted-storage). + +
+ +### Prerequisite: Setup the server We have to do these configurations on the SSH server: @@ -34,10 +50,13 @@ We have to do these configurations on the SSH server: repository and the DVC storage. - Create a bare git repository (for example on `/srv/project.git/`) and an empty directory for the DVC storage (for example on `/srv/project.cache/`). - - Grant users read/write access to these directories (through the groups). -### Setup each user +
+ +
+ +### Prerequisite: Setup each user When we have to access a SSH server, we definitely want to generate ssh key pairs and setup the SSH config so that we can access the server without a @@ -59,44 +78,58 @@ Here `dvc-server` is the name or alias that we can use for our server, `host01` can actually be the IP or the FQDN of the server, and `user1` is the username of the first user on the server. -### Setup the DVC storage +
+ +
-First of all we have to mount the remote storage directory to a local directory. -With SSHFS (and the SSH configuration on the section above) it is as simple as -this: +### Prerequisite: Mount the remote storage directory + +With SSHFS (and the SSH configuration on the section above) we can mount the +remote directory on the server to a local one (let's say `$HOME/project.cache`), +like this: ```dvc -$ mkdir ~/project.cache +$ mkdir -p $HOME/project.cache $ sshfs \ dvc-server:/srv/project.cache \ - ~/project.cache + $HOME/project.cache ``` -Once it is mounted, the default storage configuration of the project can be done -like this: +
+ +### Set the DVC storage + +We can setup the project to use `$HOME/project.cache` as +[local DVC storage](/doc/user-guide/external-data/local#local-dvc-storage), by +adding a _default remote_ like this: ```dvc $ dvc remote add --local --default \ - mounted-cache $HOME/project.cache + mounted-storage $HOME/project.cache + $ dvc remote list --local -mounted-cache /home/username/project.cache +mounted-storage /home/username/project.cache ``` Note that this configuration is specific for each user, so we have used the `--local` option in order to save it on `.dvc/config.local`, which is ignored by -Git. Now this configuration file should have a content like this: +Git. + +Now this configuration file should have a content like this: ``` -['remote "mounted-cache"'] +['remote "mounted-storage"'] url = /home/username/project.cache [core] -remote = mounted-cache +remote = mounted-storage ``` ### Sharing data -After adding data to the project with `dvc add` and `dvc run`, it is stored in -`.dvc/cache`. We can push both the code changes and the data like this: +When we add data to the project with `dvc add` or `dvc run`, some DVC-files are +created and the data is stored in `.dvc/cache/`. We can upload DVC-files to the +Git server with `git push`, and upload the cached files to the DVC storage with +`dvc push`: ```dvc $ git push @@ -104,10 +137,11 @@ $ dvc push ``` The command `dvc push` copies the cached files from `.dvc/cache/` to -`~/project.cache/`. However, since this is a mounted directory, the cached files -are immediately copied to the server as well, and they become available on the -mounted directories of the other users. So, all the other users have to do in -order to receive the code changes and the data files is this: +`$HOME/project.cache/`. However, since this is a mounted directory, the cached +files are immediately copied to the server as well, and they become available on +the mounted directories of the other users. + +The other users can receive the DVC-files and the cached data like this: ```dvc $ git pull diff --git a/static/docs/user-guide/data-sharing/remote-storage.md b/static/docs/user-guide/data-sharing/remote-storage.md index 3b2fbe2ea7..b409c27237 100644 --- a/static/docs/user-guide/data-sharing/remote-storage.md +++ b/static/docs/user-guide/data-sharing/remote-storage.md @@ -1,18 +1,28 @@ # Sharing Data Through a Remote DVC Storage -This is the recommended and the most common case of data sharing. In this case -we setup a [remote storage](/doc/command-reference/remote) on a data storage -provider, to store data files online, where others can reach them. Currently DVC -supports Amazon S3, Google Cloud Storage, Microsoft Azure Blob Storage, SSH, -HDFS, and other remote locations, and the list is constantly growing. +We can setup a _default_ [remote storage](/doc/user-guide/external-data) to a +data storage provider, where we can upload the cached data files, so that the +other users can access them. -## S3 Remote Example +> Currently DVC supports Amazon S3, Google Cloud Storage, Microsoft Azure Blob +> Storage, SSH, HDFS, and other remote storage types/providers, and the list is +> constantly growing. -As an example, let's take a look at how you could setup an S3 -[remote storage](/doc/command-reference/remote) for a DVC project, -and push/pull to/from it. +We can share data using `git push` (to upload DVC-files) and `dvc push` (to +upload cached data files). The other users can use `git pull` followed by +`dvc pull` to receive them. -### Create an S3 bucket +> This is the recommended and the most common case of data sharing. + +## Example: S3 Remote Storage + +As an example, let's take a look at how we could setup an +[Amazon S3 remote storage](/doc/user-guide/external-data/amazon) for a DVC +project, and share data through it. + +
+ +### Prerequisite: Create first an S3 bucket If you don't already have one available in your S3 account, follow instructions in @@ -21,98 +31,79 @@ As an advanced alternative, you may use the [`aws s3 mb`](https://docs.aws.amazon.com/cli/latest/reference/s3/mb.html) command instead. -### Setup DVC remote +
-To actually configure a S3 remote in the project, supply the URL to -the bucket where the data should be stored to the `dvc remote add` command. For -example: +### Set the DVC storage + +To setup an S3 DVC storage we need to create a _default_ remote like this: ```dvc -$ dvc remote add -d myremote s3://mybucket/myproject -Setting 'myremote' as a default remote. -``` +$ dvc remote add --default s3storage s3://mybucket/myproject +Setting 's3storage' as a default remote. -> The `-d` (`--default`) option sets `myremote` as the default remote storage -> for this project. +$ dvc remote list +s3storage s3://mybucket/myproject +``` -This will add `myremote` to your `.dvc/config`. The `config` file now have a -section like this: +This command will add to `.dvc/config` some lines like these: ```dvc -['remote "myremote"'] +['remote "s3storage"'] url = s3://mybucket/myproject [core] -remote = myremote +remote = s3storage ``` -`dvc remote` provides a wide variety of options to configure S3 bucket. For more -information see `dvc remote modify`. - -Let's commit your changes and push your code: +This configuration is the same for all the users, so let's commit it to Git: ```dvc $ git add .dvc/config +$ git commit -m 'Setup S3 storage' $ git push ``` -### Upload data and code +### Sharing data -After adding data to the project with `dvc run` or other commands, -it should be stored in your local cache. Upload it to remote -storage with the `dvc push` command: +When we add data to the project with `dvc add` or `dvc run`, some DVC-files are +created and the data is stored in `.dvc/cache/`. We can upload DVC-files to the +Git server with `git push`, and upload the cached files to the remote storage +with `dvc push`: ```dvc +$ git push $ dvc push ``` -Code and [DVC-files](/doc/user-guide/dvc-file-format) should be committed and -pushed with Git. - -### Download code - -Please use regular Git commands to download code and DVC-files from your Git -servers. For example: - -```dvc -$ git clone https://github.com/myaccount/myproject.git -$ cd myproject -``` - -or +The other users can receive the DVC-files and the cached data files like this: ```dvc $ git pull -``` - -### Download data - -To download data files for your project, run: - -```dvc $ dvc pull ``` -`dvc pull` will download the missing data files from the default remote storage -configured in the `.dvc/config` file. - -## SSH Remote Example +## Example: SSH Remote Storage -As an other example, let's see how to setup an SSH remote storage for a project -and share data through it. +As an other example, let's see how to setup an +[SSH remote storage](/doc/user-guide/external-data/ssh) for a project and share +data through it. > For more detailed instructions check out this > [interactive example](https://katacoda.com/dvc/courses/examples/ssh-storage). In this example we will assume a central data storage server that can be -accessed through SSH from two different users. For the sake of example the -central Git repository will be located in this server too, but in general it can -be anywhere, it doesn't have to be on the same server with the DVC data storage. +accessed through SSH from two different users. + +> For the sake of example the central Git repository will be located in this +> server too, but in general it can be anywhere, it doesn't have to be on the +> same server with the DVC data storage.

-### Setup the server +
+ +### Prequisite: Setup the SSH server Usually we need to do these configurations on a SSH server: @@ -120,10 +111,13 @@ Usually we need to do these configurations on a SSH server: repository and the DVC storage. - Create a bare git repository (for example on `/srv/project.git/`) and an empty directory for the DVC storage (for example on `/srv/project.cache/`). - - Grant users read/write access to these directories (through the groups). -### Setup each user +
+ +
+ +### Prerequisite: Setup each user When we have to access a SSH server, we definitely want to generate ssh key pairs and setup the SSH config so that we can access the server without a @@ -145,47 +139,54 @@ Here `dvc-server` is the name or alias that we can use for our server, `host01` can actually be the IP or the FQDN of the server, and `user1` is the username of the first user on the server. -### Setup DVC remote +
+ +### Set the DVC storage -The configuration of the project with the SSH remote storage can be done with a -command like this: +We can setup the project to use the +[SSH remote storage](/doc/user-guide/external-data/ssh) by adding a _default +remote_ like this: ```dvc $ dvc remote add --default \ - ssh-cache ssh://dvc-server:/srv/project.cache + ssh-storage ssh://dvc-server:/srv/project.cache +Setting 'ssh-storage' as a default remote. + +$ dvc remote list +ssh-storage ssh://dvc-server:/srv/project.cache ``` -This command will add a default remote configuration on `.dvc/config` that looks -like this: +The configuration file `.dvc/config` now should look like this: ``` -['remote "ssh-cache"'] +['remote "ssh-storage"'] url = ssh://dvc-server:/srv/project.cache [core] -remote = ssh-cache +remote = ssh-storage ``` -Note that this configuration is the same for all the users, so we can add it to -Git in order to share it with the other users: +This configuration is the same for all the users, so we can add it to Git in +order to share it with the other users: ```dvc $ git add .dvc/config -$ git commit -m 'Add a SSH remote cache' +$ git commit -m 'Add a SSH remote storage' $ git push ``` ### Sharing data -After adding data to the project with `dvc add` and `dvc run`, it is stored in -`.dvc/cache`. We can upload to the server both the code changes and the data -like this: +When we add data to the project with `dvc add` or `dvc run`, some DVC-files are +created and the data is stored in `.dvc/cache/`. We can upload DVC-files to the +Git server with `git push`, and upload the cached files to the remote storage +with `dvc push`: ```dvc $ git push $ dvc push ``` -On the other end, we can receive the code changes and data like this: +The other users can receive the DVC-files and the cached data like this: ```dvc $ git pull diff --git a/static/docs/user-guide/data-sharing/shared-server.md b/static/docs/user-guide/data-sharing/shared-server.md index bcfde277a9..c6a01669f4 100644 --- a/static/docs/user-guide/data-sharing/shared-server.md +++ b/static/docs/user-guide/data-sharing/shared-server.md @@ -1,19 +1,28 @@ # Local Storage on a Shared Development Server -Some teams may prefer using a single shared machine to run their experiments. -This allows them to have better resource utilization such as the ability to use -multiple GPUs, etc. - -With DVC, you can easily setup a local data storage on the server. This allows -your team to store and share data of your projects efficiently, and to have -almost instantaneous data retrieval speed, similar to `git pull` for your code. +Some teams may prefer to use a single shared machine for running their +experiments. This allows them to have better resource utilization such as the +ability to use multiple GPUs, etc. + +With DVC, we can easily setup a +[local data storage](/doc/user-guide/external-data/local#local-dvc-storage) on +the shared server. To share data we use the normal DVC workflow of `dvc push` +(for sending cached data to the local DVC storage), and `dvc pull` (for +retrieving them from the DVC storage). + +> For having the best performance on this workflow we should make sure that the +> (local) DVC storage and all the user projects are located on the same +> deduplicating filesystem. In this case DVC would automatically use _reflink +> copy_ and this would ensure a minimal disk space usage and an instantaneous +> data transfer speed. ## Shared Server Example Let's see an example of how two different users on the same host can share data -with the help of a local data storage. So, both of the users and the data -storage are located on the same machine and no remote server or storage is -involved. +with the help of a +[local DVC storage](/doc/user-guide/external-data/local#local-dvc-storage). So, +both of the users and the data storage are located on the same machine and no +remote server or storage is involved. > For more detailed instructions check out this > [interactive example](https://katacoda.com/dvc/courses/examples/shared-server). @@ -22,7 +31,9 @@ involved.

-### Setup the server +
+ +### Prerequisite: Setup the server We need to do these configurations on the server: @@ -31,18 +42,21 @@ We need to do these configurations on the server: - Create a bare git repository (for example on `/var/local/data/project.git/`) and an empty directory for the DVC storage (for example on `/var/local/data/project.cache/`). - - Grant users read/write access to these directories (through the groups). -### Configure local DVC storage +
-Clone the Git project to the homedir of the users. Then set the local DVC -storage as the default remote, like this: +### Set the DVC storage + +We can setup the project to use the +[local DVC storage](/doc/user-guide/external-data/local#local-dvc-storage) by +adding a _default remote_, like this: ```dvc $ export DATA=/var/local/data -$ dvc remote add --default \ - local-storage $DATA/project.cache +$ dvc remote add --default local-storage $DATA/project.cache +Setting 'local-storage' as a default remote. + $ dvc remote list local-storage /var/local/data/project.cache ``` @@ -60,48 +74,52 @@ We can add it to Git and commit, since it is the same for all the users: ```dvc $ git add .dvc/config -$ git commit -m "Set default storage" +$ git commit -m "Setup local DVC storage" $ git push ``` ### Sharing data Data sharing among the different users is done the normal way, with `dvc push` -and `dvc pull`, except that in this case it is the local storage that is acting -as an intermediary between the users, instead of a remote storage. +and `dvc pull`, except that in this case it is the _local DVC storage_ that is +acting as an intermediary between the users, instead of a remote one. -After adding data to the project with `dvc add` and `dvc run`, it is stored in -`.dvc/cache`. We can share the code changes and the data like this: +When we add data to the project with `dvc add` or `dvc run`, some DVC-files are +created and the data is stored in `.dvc/cache/`. We can upload DVC-files to the +Git server with `git push`, and upload the cached files to the DVC storage with +`dvc push`: ```dvc $ git push $ dvc push ``` -From the other users we can receive the code changes and data like this: +The other users can receive the DVC-files and the cached data like this: ```dvc $ git pull $ dvc pull ``` -### Optimizations +
-If all the user projects and the data storage are located on the same -deduplicating filesystem, then everything is fine, copying data around will be +### Data sharing optimizations + +If all the user projects and the local DVC storage are located on the same +_deduplicating_ filesystem, then everything is fine, copying data around will be done instantly and without increasing the disk usage. If they are not on the same filesystem, or if the filesystem does not support deduplication of data, then some optimizations are needed to make things efficient. These optimizations may include: -1. Creating, formatting and mounting a filesystem which supports deduplication - (like XFS, Btrfs, etc.) - -2. Locating the data storage and all the user projects on this filesystem. - +1. Creating, formatting and mounting a deduplicating filesystem (like XFS, + Btrfs, etc.) +2. Locating the DVC storage and all the user projects on this filesystem. 3. Adding symbolic links from the home directories of the users to their projects (which are located on the optimized filesystem). For more detailed instructions check out this [interactive example](https://katacoda.com/dvc/courses/examples/shared-server). + +
diff --git a/static/docs/user-guide/data-sharing/synced-storage.md b/static/docs/user-guide/data-sharing/synced-storage.md index f8222aad34..e880553c21 100644 --- a/static/docs/user-guide/data-sharing/synced-storage.md +++ b/static/docs/user-guide/data-sharing/synced-storage.md @@ -5,27 +5,35 @@ example look at the ones supported by [rclone](https://rclone.org/)). But this does not mean that we cannot use them to share data with the help of DVC. If it is possible to synchronize a local directory with a remote one (which is supported by almost all storage providers), then we are good to go. We can still -make a setup that allows us to share DVC data. This setup is similar to that of -a mounted storage, except that the synchronization of the data does not happen -transparently. +make a setup that allows us to share DVC data. + +This setup is similar to that of a mounted storage, except that the +synchronization of the data does not happen transparently. We first make a +`dvc push` to send data to the local DVC storage, then synchronize the local DVC +storage with the central one. To receive the data we should first synchronize +the central DVC storage with the local one, then we can make a `dvc pull` to get +it from the local DVC storage to the project. ## Synced Storage Example In this example we will see how to achieve this with the help of a SSH storage -and `rsync`. Yes, SSH is one the storage types that is already supported by DVC, -and normally we don't need to do this. But we are using it just as an example, -since SSH is easy to be used for synchronizing with a remote directory. Once you -understand how it works, it should be easy to implement it for other storage -types. +and `rsync`. -> For more detailed instructions check out this -> [interactive example](https://katacoda.com/dvc/courses/examples/synced-storage). +> SSH is one the storage types that is already supported by DVC, and normally we +> don't need to do this. But we are using it just as an example, since SSH is +> easy to be used for synchronizing with a remote directory. Once you understand +> how it works, it should be easy to implement it for other storage types.

-### Setup the server +> For more detailed instructions check out this +> [interactive example](https://katacoda.com/dvc/courses/examples/synced-storage). + +
+ +### Prerequisite: Setup the server We have to do these configurations on the SSH server: @@ -33,10 +41,13 @@ We have to do these configurations on the SSH server: repository and the DVC storage. - Create a bare git repository (for example on `/srv/project.git/`) and an empty directory for the DVC storage (for example on `/srv/project.cache/`). - - Grant users read/write access to these directories (through the groups). -### Setup each user +
+ +
+ +### Prerequisite: Setup each user When we have to access a SSH server, we definitely want to generate ssh key pairs and setup the SSH config so that we can access the server without a @@ -58,16 +69,19 @@ Here `dvc-server` is the name or alias that we can use for our server, `host01` can actually be the IP or the FQDN of the server, and `user1` is the username of the first user on the server. -### Setup the DVC storage +
+ +### Set the DVC storage We will use a local directory as the default storage of the project, like this: ```dvc -$ mkdir ~/project.cache +$ mkdir -p $HOME/project.cache $ dvc remote add --local --default \ - synced-cache $HOME/project.cache + synced-storage $HOME/project.cache + $ dvc remote list --local -synced-cache /home/username/project.cache +synced-storage /home/username/project.cache ``` Note that this configuration is specific for each user, so we have used the @@ -75,16 +89,18 @@ Note that this configuration is specific for each user, so we have used the Git. Now this configuration file should have a content like this: ``` -['remote "synced-cache"'] +['remote "synced-storage"'] url = /home/username/project.cache [core] -remote = synced-cache +remote = synced-storage ``` ### Sharing data -After adding data to the project with `dvc add` and `dvc run`, it is stored in -`.dvc/cache`. We can push both the code changes and the data like this: +When we add data to the project with `dvc add` or `dvc run`, some DVC-files are +created and the data is stored in `.dvc/cache/`. We can upload DVC-files to the +Git server with `git push`, and upload the cached files to the local DVC storage +with `dvc push`: ```dvc $ git push @@ -92,38 +108,40 @@ $ dvc push ``` The command `dvc push` copies the cached files from `.dvc/cache/` to -`~/project.cache/`. In order to send the data to the server we also have to -synchronize the local storage with the remote storage. With `rsync` (and with +`$HOME/project.cache/`. In order to send the data to the server we also have to +synchronize the local DVC storage with the remote one. With `rsync` (and with the help of SSH configurations that we have done on the previous sections) it can be as simple as this: ```dvc $ rsync -r -P \ - ~/project.cache/ \ + $HOME/project.cache/ \ dvc-server:/srv/project.cache/ ``` -To get the cached files on their local storage, the other users have to +To get the cached files on their local DVC storage, the other users have to synchronize first with a command like this: ```dvc $ rsync -r -P \ dvc-server:/srv/project.cache/ \ - ~/project.cache/ + $HOME/project.cache/ ``` -Then they can receive the code changes and the data files like this: +Then they can receive the DVC-files and the cached data like this: ```dvc $ git pull $ dvc pull ``` -### Deduplicate the storage +
+ +### Optimization: Deduplicate the storage For each file that is cached, there is a copy on the workspace, a copy on -`.dvc/cache/`, and another copy on `~/project.cache/` (besides the copy on the -remote storage). +`.dvc/cache/`, and another copy on `$HOME/project.cache/` (besides the copy on +the remote storage). If you have a deduplicating filesystem (like XFS, Btrfs, etc.) then everything is fine because making copies of the same file does not actually increase the @@ -133,11 +151,15 @@ filesystem, and move the project and caches there. For more detailed instructions check out the [interactive example](https://katacoda.com/dvc/courses/examples/synced-storage). -### Automate synchronization steps +
+ +
+ +### Optimization: Automate synchronization steps Notice that whenever we run `dvc push` we also have to run `rsync`, and before a `dvc pull` we also have to run `rsync`. This can be automated and simplified by -defining aliases or functions on `~/.bashrc`, which might look like +defining aliases or functions on `~/.bashrc`, which might look like these: ```dvc push() { @@ -172,3 +194,5 @@ $ pull Another way to make the synchronization transparent to the users is to setup cron jobs that synchronize periodically the local DVC storage with the central one. + +