From f17845965dd65670b03f9ca8ed1b826ceb10e553 Mon Sep 17 00:00:00 2001 From: Sebastiaan Huber Date: Thu, 16 Dec 2021 21:49:36 +0100 Subject: [PATCH] AEP: Abstract and improve the file repository (#7) --- .../readme.md | 2 +- 007_improved_file_repository/readme.md | 353 ++++++++++++++++++ .../schematic_design_class_hierarchy.png | Bin 0 -> 92576 bytes .../schematic_design_class_hierarchy.svg | 248 ++++++++++++ README.md | 29 +- _toc.yml | 1 + 6 files changed, 616 insertions(+), 17 deletions(-) create mode 100644 007_improved_file_repository/readme.md create mode 100644 007_improved_file_repository/schematic_design_class_hierarchy.png create mode 100644 007_improved_file_repository/schematic_design_class_hierarchy.svg diff --git a/006_efficient_object_store_for_repository/readme.md b/006_efficient_object_store_for_repository/readme.md index bd3d225..8dfe3cb 100644 --- a/006_efficient_object_store_for_repository/readme.md +++ b/006_efficient_object_store_for_repository/readme.md @@ -43,7 +43,7 @@ The goal of this proposal is to have a very efficient implementation of an "obje **NOTE**: This AEP does not address the actual implementation of the object store within AiiDA, but rather the implementation of an object-store-like service as an independent package, to solve a number of performance issues. This is now implemented as part of the [disk-objecstore](https://github.com/aiidateam/disk-objectstore) package that will be used by AiiDA from version 2.0. -The description of the integration with AiiDA will be discussed in a different AEP (see [PR #7](https://github.com/aiidateam/AEP/pull/7) for some preliminary discussion, written before this AEP). +The integration with AiiDA will be described in AEP 007. ## Detailed Explanation diff --git a/007_improved_file_repository/readme.md b/007_improved_file_repository/readme.md new file mode 100644 index 0000000..7f010c2 --- /dev/null +++ b/007_improved_file_repository/readme.md @@ -0,0 +1,353 @@ +# Abstract and improve the file repository + +| AEP number | 007 | +|------------|-----------------------------------------------------------------| +| Title | Abstract and improve the file repository | +| Authors | [Sebastiaan P. Huber](mailto:sebastiaan.huber@epfl.ch) (sphuber)| +| Champions | [Sebastiaan P. Huber](mailto:sebastiaan.huber@epfl.ch) (sphuber) [Leopold Talirz](mailto:leopold.talirz@epfl.ch) (ltalirz)| +| Type | S - Standard | +| Created | 18-Oct-2019 | +| Status | submitted | + +## Background +The persistent state of a node in the provenance graph is stored across two resources. +The relational database and a file repository. + +Currently, the implementation of the file repository is not configurable but is hardcoded as a custom solution on the file system that is local to the AiiDA instance. +The custom solution suffers from performance issues when scaled to a large number of nodes that contain many files. +The reason is that each node gets its own folder on the disk, even if it doesn't contain any files, and each file is stored separately in the folder of the corresponding node. +This leads to a large number of inodes being required, which are limited on any file system. + +File systems can be reformatted to provide more inodes, however, this is not really an operation we should be requiring users to perform. +In addition, even if the file system has sufficient inodes, the storing of files as individual files has an enormous impact on performance when indexing the disk. +For example, merely counting the number of files for the current repository architecture will be extremely costly for even moderately sized repositories. +This has a direct impact on important operations such as creating a backup. +Even with optimized tools as `rsync` creating a backup can take days for large databases (of the order of 10 million nodes), where a large part is not even due to the data transfer but merely the indexing of the repository to detect the changes. + +These scaling performance issues of the file repository pose concrete problems for users with large databases. +The current implementation of the file repository needs to be replaced with a solution that scales with many files and is easy to backup, while keeping writing performance during operation of AiiDA's daemon. +Alternatively, or additionally, it should be possible to configure an alternative repository implementation for a profile. +For this the repository implementation should be abstracted such that it can be implemented for alternative backends that are potentially more suitable for certain use cases. + +## Proposed Enhancement +The scaling problem of the original file repository implementation has already been described in great detail in [AEP 006: Efficient object store for the AiiDA repository](https://github.com/aiidateam/AEP/tree/master/006_efficient_object_store_for_repository#readme). +It also describes an efficient key-value store that is implemented in the [`disk-objectstore`](https://github.com/aiidateam/disk-objectstore) library. +This AEP describes how the `disk-objectstore` is integrated into `aiida-core` to replace the original solution for the file repository, solving the scaling problems in performance. + +The following requirements were considered during the design of the file repository implementation: + +* Scalability: the repository should be able to store millions of files, all the while permitting efficient backups. +* Heterogeneity: the repository should operate efficiently for data that is heterogeneous in size, with object of size ranging from a few bytes to multiple gigabytes. +* Simplicity: the solution should not require an actively running server to operate. +* Concurrency: the repository should support multiple concurrent reading and writing processes. +* Efficiency: the repository should automatically deduplicate file content in an effort to reduce the total amount of required storage space. + +The interface to the file repository is also properly abstracted to support any file or object store. +The support of a (virtual) directory hierarchy, as provided by a local file system, is not assumed and therefore not required. +The decoupling and abstraction of the file repository makes it possible, in theory, to implement it in the future for another backend than the `disk-objectstore`. + +However, this AEP intentionally does not go into detail how an alternative backend can be configured on a per-profile basis, but will assume that only support for the `disk-objectstore` will be provided for now. +Nevertheless, the file repository is integrated in such a decoupled manner that it will be easy to implement this additional functionality in the future. +Possible use-cases might be to have a file repository on a remote file system, accessed over SSH or even a traditional object store (like [S3](https://aws.amazon.com/s3/) or [SWIFT](https://wiki.openstack.org/wiki/Swift)) that communicate through REST APIs. + +## Detailed Explanation + +### Abstracting the file repository interface +Currently the integration of the repository is tightly coupled to the implementation of the ORM. +This makes it difficult to provide different implementations. +The first step then would be to abstract the repository concept and write a generic interface to list, create, get and delete objects in it. + +The new interface for the file repository is defined through an abstract class, called the `AbstractRepositoryBackend`. +Its interface is shown below. +```python +class AbstractRepositoryBackend(metaclass=abc.ABCMeta): + """Class that defines the abstract interface for an object repository.""" + + @property + @abc.abstractmethod + def uuid(self) -> Optional[str]: + """Return the unique identifier of the repository.""" + + @property + @abc.abstractmethod + def key_format(self) -> Optional[str]: + """Return the format for the keys of the repository. + + Important for when migrating between backends (e.g. archive -> main), as if they are not equal then it is + necessary to re-compute all the `Node.repository_metadata` before importing (otherwise they will not match + with the repository). + """ + + @abc.abstractmethod + def initialise(self, **kwargs) -> None: + """Initialise the repository if it hasn't already been initialised. + + :param kwargs: parameters for the initialisation. + """ + + @property + @abc.abstractmethod + def is_initialised(self) -> bool: + """Return whether the repository has been initialised.""" + + @abc.abstractmethod + def erase(self) -> None: + """Delete the repository itself and all its contents. + + .. note:: This should not merely delete the contents of the repository but any resources it created. For + example, if the repository is essentially a folder on disk, the folder itself should also be deleted, not + just its contents. + """ + + @staticmethod + def is_readable_byte_stream(handle) -> bool: + return hasattr(handle, 'read') and hasattr(handle, 'mode') and 'b' in handle.mode + + def put_object_from_filelike(self, handle: BinaryIO) -> str: + """Store the byte contents of a file in the repository. + + :param handle: filelike object with the byte content to be stored. + :return: the generated fully qualified identifier for the object within the repository. + :raises TypeError: if the handle is not a byte stream. + """ + + @abc.abstractmethod + def _put_object_from_filelike(self, handle: BinaryIO) -> str: + pass + + def put_object_from_file(self, filepath: Union[str, pathlib.Path]) -> str: + """Store a new object with contents of the file located at `filepath` on this file system. + + :param filepath: absolute path of file whose contents to copy to the repository. + :return: the generated fully qualified identifier for the object within the repository. + :raises TypeError: if the handle is not a byte stream. + """ + + @abc.abstractmethod + def has_objects(self, keys: List[str]) -> List[bool]: + """Return whether the repository has an object with the given key. + + :param keys: + list of fully qualified identifiers for objects within the repository. + :return: + list of logicals, in the same order as the keys provided, with value True if the respective + object exists and False otherwise. + """ + + def has_object(self, key: str) -> bool: + """Return whether the repository has an object with the given key. + + :param key: fully qualified identifier for the object within the repository. + :return: True if the object exists, False otherwise. + """ + + @abc.abstractmethod + def list_objects(self) -> Iterable[str]: + """Return iterable that yields all available objects by key. + + :return: An iterable for all the available object keys. + """ + + @contextlib.contextmanager + def open(self, key: str) -> Iterator[BinaryIO]: + """Open a file handle to an object stored under the given key. + + .. note:: this should only be used to open a handle to read an existing file. To write a new file use the method + ``put_object_from_filelike`` instead. + + :param key: fully qualified identifier for the object within the repository. + :return: yield a byte stream object. + :raise FileNotFoundError: if the file does not exist. + :raise OSError: if the file could not be opened. + """ + + def get_object_content(self, key: str) -> bytes: + """Return the content of a object identified by key. + + :param key: fully qualified identifier for the object within the repository. + :raise FileNotFoundError: if the file does not exist. + :raise OSError: if the file could not be opened. + """ + + @abc.abstractmethod + def iter_object_streams(self, keys: List[str]) -> Iterator[Tuple[str, BinaryIO]]: + """Return an iterator over the (read-only) byte streams of objects identified by key. + + .. note:: handles should only be read within the context of this iterator. + + :param keys: fully qualified identifiers for the objects within the repository. + :return: an iterator over the object byte streams. + :raise FileNotFoundError: if the file does not exist. + :raise OSError: if a file could not be opened. + """ + + def get_object_hash(self, key: str) -> str: + """Return the SHA-256 hash of an object stored under the given key. + + .. important:: + A SHA-256 hash should always be returned, + to ensure consistency across different repository implementations. + + :param key: fully qualified identifier for the object within the repository. + :raise FileNotFoundError: if the file does not exist. + :raise OSError: if the file could not be opened. + """ + + @abc.abstractmethod + def delete_objects(self, keys: List[str]) -> None: + """Delete the objects from the repository. + + :param keys: list of fully qualified identifiers for the objects within the repository. + :raise FileNotFoundError: if any of the files does not exist. + :raise OSError: if any of the files could not be deleted. + """ + + def delete_object(self, key: str) -> None: + """Delete the object from the repository. + + :param key: fully qualified identifier for the object within the repository. + :raise FileNotFoundError: if the file does not exist. + :raise OSError: if the file could not be deleted. + """ +``` +Since it is envisioned that solutions will be implemented that are not necessarily file system based, it is important that the interface does not implicitly bake-in file-system-only concepts. +Therefore, the abstract repository interface talks exclusively about "objects" in the repository, where an object essentially refers to a byte stream.. +The repository is also not forced to support a file hierarchy, i.e., a structure where files can be stored in (nested) directories, but is simply a flat key-value store. + +The values in the key-value store are plain byte streams and the key is a string-based identifier that is generated by the implementation when a new object is stored. +The identifier should be persistent and uniquely identify its associated object in the repository. + +### Abstract file repository interface implementations +AiiDA ships with two implementations of the `AbstractRepositoryBackend` interface described in the previous section: + + * `SandboxRepositoryBackend`: implements the interface for a temporary directory on the local file system. + * `DiskObjectStoreRepositoryBackend`: implements the interface for the `disk-objectstore` key-value store. + +The `SandboxRepositoryBackend` is used for unstored nodes. +This enables quick and efficient writing of files and when the node is never stored, the files are automatically deleted from the file system when the node goes out of scope. +When a node is stored, the contents of the `SandboxRepositoryBackend` are copied to the `DiskObjectStoreRepositoryBackend`. + +Note that the `DiskObjectStoreRepositoryBackend` doesn't have a concept of nodes, nor does it have the concept of file hierarchies, like the node does. +This concept of virtual file hierarchies is managed through the `Repository` class, which sits on top of the file repository backend. +The important parts of the interface of the `Repository` class are sketched below: +```python +class Repository: + """Interface to the file repository backend that keeps a record of the virtual file hierarchy and key mapping. + + This class provides an interface to a backend file repository instance, but unlike the backend repository, this + class keeps a reference of the virtual file hierarchy. This means that through this interface, a client can create + files and directories with a file hierarchy, just as they would on a local file system, except it is completely + virtual as the files are stored by the backend which can store them in a completely flat structure. This also means + that the internal virtual hierarchy of a ``Repository`` instance does not necessarily represent all the files that + are stored by repository backend. The repository exposes a mere subset of all the file objects stored in the + backend. This is why object deletion is also implemented as a soft delete, by default, where the files are just + removed from the internal virtual hierarchy, but not in the actual backend. This is because those objects can be + referenced by other instances. + """ + + def __init__(self, backend: AbstractRepositoryBackend = None): + """Construct a new instance with empty metadata. + + :param backend: instance of repository backend to use to actually store the file objects. By default, an + instance of the ``SandboxRepositoryBackend`` will be created. + """ + + @classmethod + def from_serialized(cls, backend: AbstractRepositoryBackend, serialized: Dict[str, Any]) -> 'Repository': + """Construct an instance where the metadata is initialized from the serialized content. + + :param backend: instance of repository backend to use to actually store the file objects. + """ + instance = cls.__new__(cls) + instance.__init__(backend) + + if serialized: + for name, obj in serialized['o'].items(): + instance.get_directory().objects[name] = cls._file_cls.from_serialized(obj, name) + + return instance + + def serialize(self) -> Dict[str, Any]: + """Serialize the metadata into a JSON-serializable format. + + :return: dictionary with the content metadata. + """ + return self._directory.serialize() + +``` +A node uses an instance of the `Repository` to write content to the file repository. +The methods for object creation and retrieval of the `Repository` class (which are not explicitly shown in the design above) match that of the interface of the repository backend. +This allows the `Repository` to simply call through to the same method. +The one difference between the interfaces is that the methods of the `Repository` operate on relative file paths (which represent the location of file in the virtual file hierarchy) whereas the `AbstractRepositoryBackend` works with unique identifiers. +The `Repository` keeps a mapping of the objects in its virtual hierarchy to the unique identifier under which they are stored in the backend. + +The constructor of the `Repository` initializes a new instance with an empty file hierarchy. +However, the `from_serialized` classmethod allows to instantiate it from a serialized file hierarchy. +This serialization is generated by the `serialize` method. +These two methods provide a closed loop: a constructed `Repository` instance, which is used to store files through, can be reconstructed identically using `from_serialized`, passing in the serialized version of the hierarchy returned by the `serialize` method. +```python +backend = SandboxRepositoryBackend() +repository = Repository(backend=backend) +# Perform some object creation operations +serialized = repository.serialize() +reconstructed = Repository.from_serialized(serialized) +assert reconstructed.serialize() == serialized +``` + +### Index of node repository contents in database +Although the `Repository` class is capable of keeping track of the virtual hierarchy of objects stored and the mapping of the keys with which they are stored in the backend, this information is stored in memory and therefore would be lost once the interpreter exits. +To persist the data, the serialized virtual hierarchy of a node is stored in the relational database. +The node table is extended with the column `repository_metadata` that is a JSON field. + +When a node is stored, the contents of the sandbox repository is copied to the main file repository. +The virtual hierarchy is then serialized and stored in the `repository_metadata` field of the table row. +When a node is loaded, the repository is initialized from the serialized hierarchy stored in that field. + +The serialized virtual hierarchy has the following structure: +```python +{ + 'o': { + 'empty': {}, + 'file.txt': { + 'k': 'abcdef', + } + } +} +``` +Each key can either represent a directory or a file, where the key itself represents the relative name of the directory or file in the hierarchy. +If a key is a directory, its value is another dictionary that contain other directories or files. +If a key is a file, the value is a dictionary that contains the key `k` that represents the unique identifier with which it is stored in the file repository backend. + +The format was chosen to allow storing of additional metadata in the future, such as encoding, permissions etc. +It also tries to minimize the size of the serialized hierarchy since it is stored in the relational database, and unnecessary bloating of it can reduce the efficiency of queries and retrieving of data. + +### Integration of file repository in the ORM front-end +To expose the functionality of storing files in the file repository for a given node to the end-user through the `Node` interface, it composes the `NodeRepositoryMixin` class. +This mixin initializes the `Repository` class for any given node, based on the contents of its `repository_metadata` field. +It also exposes those methods from the `Repository` class after having performed a mutability check. +If a node is stored, it is immutable, which includes its file repository. +If a user attempts to create a new object or delete an existing one for a stored node, a `ModificationNotAllowed` exception is thrown. + +The entire class UML can be represented schematically as follows: +![Class schematic](schematic_design_class_hierarchy.png "Class schematic") + +### Migration of existing file repositories +The implementation of the new file repository backend needs to come with a data migration. +The content of the existing file repository needs to be copied to the disk object store and the corresponding virtual file hierarchies need to be serialized and stored in the `repository_metadata` fields of the corresponding nodes. + + +## Pros and Cons + +### Pros +* Abstracting the repository interface allows for having more options that gives more freedom to users. + High-throughput projects may require a remote file system or object store solution to be able to support the quantities of data that are produced. +* The `disk-objectstore` has been designed especially for AiiDA's use case and is optimized to scale for a large number of files, making bulk retrieval operations very efficient. + With this new implementation, it now also becomes feasible to regularly update the file repository through standard tools, such as `rsync`. +* The node repository index stored in the database makes it faster to determine what objects are contained in its repository since it is no longer necessary to access the file repository. +* The node repository index allows to provide a uniform set of repository object metadata across repository implementations. + +### Cons +* Storing an index of all objects in a node's repository has a non-negligible overhead in database load as well as storage space. +* The storage of files in the repository becomes even more opaque for the user then it already was. + In the case of an object store this is necessary and not even a downside, but for users only using a local file system, this may be unintuitive. + However, even in the current situation the user is not supposed to directly access or interact with the repository on the local file system. diff --git a/007_improved_file_repository/schematic_design_class_hierarchy.png b/007_improved_file_repository/schematic_design_class_hierarchy.png new file mode 100644 index 0000000000000000000000000000000000000000..45535845c38e004cb3ed374c03ddeb0b7d9c8d9f GIT binary patch literal 92576 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 literal 0 HcmV?d00001 diff --git a/007_improved_file_repository/schematic_design_class_hierarchy.svg b/007_improved_file_repository/schematic_design_class_hierarchy.svg new file mode 100644 index 0000000..af75c4a --- /dev/null +++ b/007_improved_file_repository/schematic_design_class_hierarchy.svg @@ -0,0 +1,248 @@ + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + Node NodeRepository Repository Sandbox DiskObjectStore + + + + diff --git a/README.md b/README.md index 2fd747f..d2019e0 100644 --- a/README.md +++ b/README.md @@ -1,25 +1,22 @@ # AiiDA Enhancement Proposals (AEPs) -This repository contains enhancement proposals for [AiiDA](https://www.aiida.net) (AiiDA -enhancement proposals = AEPs), similar to -[PEPs](https://www.python.org/dev/peps/) of the python core language but -less 'formalized' and closer to the way the [Jupyter project deals -with enhancement proposals](https://github.com/jupyter/enhancement-proposals). +This repository contains enhancement proposals for [AiiDA](https://www.aiida.net) (AiiDA enhancement proposals = AEPs). +It is similar to [PEPs](https://www.python.org/dev/peps/) of the Python core language but less 'formalized' and closer to the way the [Jupyter project](https://github.com/jupyter/enhancement-proposals) deals with enhancement proposals. -The purpose is to publicly discuss new features & design choices in the AiiDA -ecosystem and to document the decision making process. +The purpose is to publicly discuss new features & design choices in the AiiDA ecosystem and to document the decision making process. ## Index of AEPs -| Number | Status | Title | -|--------|------------------|------------------------------------------------------------------| -| 000 | active | [AEP guidelines](000_aep_guidelines/readme.md) | -| 001 | implemented | [Drop support for Python 2.7](001_drop_python2/readme.md) | -| 002 | implemented | [AiiDA Dependency Management](002_dependency_management/readme.md) | -| 003 | active | [Adopt NEP 29](003_adopt_nep_29/readme.md) | -| 004 | implemented | [Infrastructure for importing completed `CalcJob`s](004_calcjob_importer/readme.md) | -| 005 | draft | [New Export Format](005_exportformat/readme.md) | -| 006 | implemented | [Efficient object store for the AiiDA repository](006_efficient_object_store_for_repository/readme.md) | +| Number | Status | Title | +|--------|------------------|--------------------------------------------------------------------------------------------------------| +| 000 | active | [AEP guidelines](000_aep_guidelines/readme.md) | +| 001 | implemented | [Drop support for Python 2.7](001_drop_python2/readme.md) | +| 002 | implemented | [AiiDA Dependency Management](002_dependency_management/readme.md) | +| 003 | active | [Adopt NEP 29](003_adopt_nep_29/readme.md) | +| 004 | implemented | [Infrastructure for importing completed `CalcJob`s](004_calcjob_importer/readme.md) | +| 005 | draft | [New Export Format](005_exportformat/readme.md) | +| 006 | implemented | [Efficient object store for the AiiDA repository](006_efficient_object_store_for_repository/readme.md) | +| 007 | implemented | [Abstract and improve the file repository](007_improved_file_repository/readme.md) | ## Submitting an AEP diff --git a/_toc.yml b/_toc.yml index c661e59..5c7dee9 100644 --- a/_toc.yml +++ b/_toc.yml @@ -9,3 +9,4 @@ subtrees: - file: 004_calcjob_importer/readme.md - file: 005_exportformat/readme.md - file: 006_efficient_object_store_for_repository/readme.md + - file: 007_improved_file_repository/readme.md