ArcticDB Documentation

repository·master·Indexed 25 days ago

https://github.com/man-group/arcticdb

A high-performance, serverless DataFrame database for the Python Data Science ecosystem, optimized for time-series data. It enables reading and writing Pandas DataFrames and NumPy arrays to S3 or LMDB using a C++ backed implementation. The documentation covers C++ layer builds, persistent storage testing utilities, and integration of third-party libraries such as msgpack-c for serialization and Remotery for CPU/GPU profiling.

Tokens
70K
Snippets
156
Records
377
Agent score
82%

What's inside ArcticDB

  1. What is ArcticDB?

    master
    ArcticDB is a serverless DataFrame database engine designed for the Python Data Science ecosystem. It allows you to store, retrieve, and process DataFrames at scale using commodity object storage (such as S3-compatible storage or Azure Blob Storage). It is designed to require zero additional infrastructure beyond a Python environment and access to object storage.
  2. Explore ArcticDB C++ modules

    master

    The C++ layer is organized into several specialized modules located in cpp/arcticdb/. Detailed documentation for each can be found in their respective .md files:

    • Entity: Core data types, keys, and the type system.
    • Codec: Compression, encoding, and segment formats.
    • Column Store: Columnar data layout and memory management.
    • Pipeline: Read and write data pipelines.
    • Processing: Query processing, clauses, and expressions.
    • Stream: Data streaming and aggregation.
    • Async: Task scheduling and thread pools.
    • Python Bindings: pybind11 bindings for Python integration.
  3. Access ArcticDB Developer Documentation

    master

    The developer documentation for ArcticDB is organized into high-level architecture overviews, C++ layer details, and Python layer details.

    • Architecture: Use ARCHITECTURE.md for a comprehensive overview of the repository structure, C++ and Python layer organization, storage models, and core functionality.
    • C++ Layer: Detailed documentation for the C++ core is located in the cpp/ directory, covering internals like caching, versioning, storage backends, entity types, codecs, column stores, pipelines, query processing, streaming, and async task scheduling.
    • Python Layer: Detailed documentation for the Python interface is located in the python/ directory, covering the Arctic class, the Library V2 API, query processing via QueryBuilder, DataFrame normalization, and storage adapters.
  4. What is ArcticDB and how does it work?

    master

    ArcticDB is a high-performance, embedded analytical (OLAP) DataFrame database designed for the Python Data Science ecosystem.

    Key characteristics:

    • Embedded Engine: It is a Python package that does not require any server infrastructure to function.
    • Optimized for Numerical Data: Designed for massive datasets spanning millions of rows and columns.
    • DataFrame-like API: Provides a familiar interface for researchers and data scientists.
    • Bitemporal Versioning: Supports versioned modifications ("time travel") for point-in-time analysis.
    • Timeseries Optimized: Built as a timeseries database optimized for slicing and dicing billions of rows.
    • Dynamic Schemas: Supports datasets where column sets change over time.
    • Data Discovery: Organizes data into libraries and symbols rather than raw filepaths.
  5. Overview of the ArcticDB C++ Engine Modules

    master

    The C++ layer (cpp/) is the performance-critical core responsible for data storage, compression, and query processing. Key modules include:

    ModulePurpose
    storage/Backend abstraction for S3, Azure, LMDB, MongoDB, and Memory
    version/Version chain management, symbol lists, and snapshots
    pipeline/Data serialization/deserialization pipelines (read/write)
    processing/Query execution including filtering, projection, and aggregation
    codec/Data compression and encoding (LZ4, ZSTD, passthrough)
    column_store/In-memory columnar representation and memory management
    entity/Core domain types like keys, data types, and descriptors
  6. Understand the ArcticDB concurrency model

    master

    ArcticDB is designed for high performance using a lock-free approach for most operations:

    • No locks for reads or writes: ArcticDB does not use locks for symbol reads or writes.
    • Last writer wins: Concurrent writes to the same symbol follow a last-writer-wins policy. This is achieved by writing unique atom keys (data keys, index keys, version keys) first, and then updating the non-unique VERSION_REF key. The last writer to update VERSION_REF wins.
    • Concurrent write caveats: Because of the last-writer-wins policy, parallel writes to the same symbol are not recommended. Specifically, concurrent append() operations may result in rows appearing out of order or one append being dropped.
    • Symbol list: The list_symbols() operation uses a lock-free concurrent data structure. LOCK keys are only utilized during the compaction phase of the symbol list.
    • Async I/O: Read operations utilize parallel segment fetches to improve throughput.
  7. Understand the Encoding and Decoding pipelines

    master

    The codec module manages the transformation of data between raw formats and compressed segments through two distinct paths.

    Write Path (Encoding)

    1. Type Coercion: Ensures consistent data types.
    2. Block Encoding: Splits data into manageable blocks.
    3. Compression: Applies the selected codec (LZ4, ZSTD, etc.).
    4. Segment Assembly: Builds the final segment structure.

    Read Path (Decoding)

    1. Header Parse: Reads metadata from the segment.
    2. Decompression: Uncompresses the data blocks.
    3. Type Promotion: Widens types if necessary to match requested schema.
    4. Raw Data: Returns the usable data to the user.
  8. How libraries and symbols work in ArcticDB

    master

    ArcticDB organizes data into a hierarchy:

    • Libraries: Collections that store multiple symbols. Libraries must be initialized (created) before use.
    • Symbols: Individual tables, typically represented as Pandas DataFrames, stored within a library.

    You can create a library using ac.create_library('name') or use ac.get_library('name', create_if_missing=True) to combine creation and instantiation.

  9. How to perform parallel writes using staged data

    master

    ArcticDB does not support concurrent writers to a single symbol unless the data is written as staged data.

    To use this pattern successfully, you must follow these rules:

    1. Use staged=True: When calling library.write(), set the staged parameter to True. This prevents the written data from being immediately available for reading.
    2. Avoid Overlap: Each unit of staged data must not overlap with any other unit of staged data. Consequently, staged data must be timeseries indexed to ensure distinct time ranges for each parallel writer.
    3. Finalize: Staged data is invisible to readers until library.finalize_staged_data(symbol) is called. This process merges all staged units into the symbol's main data set.

    This pattern is useful for high-throughput ingestion where multiple workers (e.g., Spark executors) need to write to the same symbol simultaneously.

  10. Handle concurrent writers in ArcticDB

    master

    ArcticDB is a client-side library and does not support transactions.

    • Multiple Symbols: Concurrent writers are supported across different symbols within a single library.
    • Single Symbol: Concurrent writes to the same symbol are not supported directly and follow a last-writer-wins policy. The version chain will only show the version from the last writer.
    • Staging: To handle multiple single-symbol concurrent writes, use the staged functionality (see staged documentation).
  11. Use LazyDataFrame for deferred query execution

    master

    A LazyDataFrame allows you to build a query pipeline without executing it immediately. This is useful for optimizing complex operations before triggering a single, efficient data fetch.

    Key Differences from QueryBuilder:

    • LazyDataFrame uses the col("name") function for column references instead of q["name"].
    • Execution is triggered explicitly by calling .collect().

    Example:

    from arcticdb import col
    
    # Read returns a LazyDataFrame when lazy=True
    ldf = lib.read("symbol", lazy=True)
    
    # Build query using col()
    ldf = ldf[col("price") > 100]
    
    # Execute
    result = ldf.collect()
    from arcticdb import col
    ldf = lib.read("symbol", lazy=True)
    ldf = ldf[col("price") > 100]
    result = ldf.collect()
  12. Maintain backwards compatibility in ArcticDB

    master

    When developing for ArcticDB, ensure compatibility across three main areas:

    1. Data on Disk

    ArcticDB is a client-side database. Newer clients might write data formats that older clients cannot read. Any breaking changes to the on-disk format must be documented and, if possible, include version numbers to trigger clear error messages in older clients.

    2. API Stability

    Changes to API signatures, including changes to which exceptions are thrown or the types of those exceptions, are breaking changes. Always describe API changes clearly in Pull Requests, especially for the NativeVersionStore API.

    3. Snapshots

    Symbols are mostly decoupled, but snapshots create dependencies. When deleting keys from storage, ensure they are not required by an existing snapshot. When modifying or deleting a snapshot, ensure that any keys for which that snapshot was the last reference are also cleaned up.