# AtlasKV

AtlasKV is a distributed key-value store designed for low-latency reads, durable writes, and predictable horizontal scaling. Data is partitioned across the cluster using consistent hashing and replicated to multiple nodes for fault tolerance.

AtlasKV is suitable for service metadata, session state, feature flags, caches that require persistence, and other workloads built around simple key-based access.

> AtlasKV is under active development. Test failure scenarios and backup procedures before running production workloads.

## Features

- Replicated storage with configurable replication factors
- Automatic partitioning and cluster rebalancing
- Strongly consistent writes through Raft consensus
- Linearizable and stale read modes
- Persistent storage with write-ahead logging
- Time-to-live support for expiring keys
- Compare-and-swap operations
- HTTP and gRPC APIs
- Prometheus-compatible metrics
- Graceful node replacement and rolling upgrades
- Optional TLS and token-based authentication

## Requirements

- Linux or macOS
- Go 1.23 or later when building from source
- At least three nodes for a fault-tolerant deployment

## Installation

### Prebuilt binary

Download the appropriate release archive, extract it, and install the binary:

```bash
tar -xzf atlaskv_1.4.0_linux_amd64.tar.gz
sudo install -m 0755 atlaskv /usr/local/bin/atlaskv
atlaskv version
```

### Build from source

```bash
git clone https://github.com/example/atlaskv.git
cd atlaskv
make build
sudo install -m 0755 ./bin/atlaskv /usr/local/bin/atlaskv
```

### Docker

```bash
docker run --rm \
  -p 7400:7400 \
  -p 7401:7401 \
  -v atlaskv-data:/var/lib/atlaskv \
  ghcr.io/example/atlaskv:1.4.0
```

## Quick Start

Start a single-node development server:

```bash
atlaskv server \
  --node-id node-1 \
  --data-dir ./data \
  --listen-client 127.0.0.1:7400 \
  --listen-peer 127.0.0.1:7401 \
  --bootstrap
```

Write a value:

```bash
curl -X PUT http://127.0.0.1:7400/v1/kv/users/alice \
  -H 'Content-Type: application/json' \
  -d '{"value":"active"}'
```

Read it:

```bash
curl http://127.0.0.1:7400/v1/kv/users/alice
```

Delete it:

```bash
curl -X DELETE http://127.0.0.1:7400/v1/kv/users/alice
```

## Usage

### Keys and values

Keys are UTF-8 strings up to 1 KiB. Values are opaque byte sequences up to 10 MiB. When using the HTTP API, binary values must be base64-encoded.

Create or replace a value:

```bash
curl -X PUT http://localhost:7400/v1/kv/config/theme \
  -H 'Content-Type: application/json' \
  -d '{"value":"dark"}'
```

Create a key that expires after 60 seconds:

```bash
curl -X PUT http://localhost:7400/v1/kv/sessions/abc123 \
  -H 'Content-Type: application/json' \
  -d '{"value":"user-42","ttl":"60s"}'
```

Perform a conditional update:

```bash
curl -X PUT http://localhost:7400/v1/kv/config/theme \
  -H 'Content-Type: application/json' \
  -H 'If-Match: "7"' \
  -d '{"value":"light"}'
```

The `ETag` returned by a read contains the current revision. A conditional write fails with `412 Precondition Failed` when the revision has changed.

### Command-line client

The distribution includes an `atlaskv` client:

```bash
atlaskv put app/maintenance false
atlaskv get app/maintenance
atlaskv delete app/maintenance
```

Specify a remote endpoint with `--endpoint` or the `ATLASKV_ENDPOINT` environment variable:

```bash
export ATLASKV_ENDPOINT=https://kv.example.com:7400
export ATLASKV_TOKEN=replace-me

atlaskv get app/maintenance
```

### Starting a cluster

Start the first node:

```bash
atlaskv server --config /etc/atlaskv/node-1.yaml --bootstrap
```

Start the remaining nodes with the first node as a seed:

```bash
atlaskv server --config /etc/atlaskv/node-2.yaml \
  --join http://10.0.0.11:7401

atlaskv server --config /etc/atlaskv/node-3.yaml \
  --join http://10.0.0.11:7401
```

Verify cluster health:

```bash
atlaskv cluster status --endpoint http://10.0.0.11:7400
```

A three-node cluster tolerates the loss of one node. A five-node cluster tolerates the loss of two nodes.

## Configuration

AtlasKV accepts a YAML configuration file through `--config`. Command-line flags override file values.

```yaml
node:
  id: node-1
  data_dir: /var/lib/atlaskv

network:
  client_address: 0.0.0.0:7400
  peer_address: 0.0.0.0:7401
  advertise_client_address: 10.0.0.11:7400
  advertise_peer_address: 10.0.0.11:7401

cluster:
  replication_factor: 3
  partitions: 256
  rebalance_concurrency: 2

storage:
  engine: pebble
  sync_writes: true
  wal_dir: /var/lib/atlaskv/wal
  compaction_interval: 30m
  max_value_size: 10MiB

consistency:
  default_read: linearizable
  write_timeout: 5s
  election_timeout: 1s

security:
  authentication:
    enabled: true
    token_file: /etc/atlaskv/tokens
  tls:
    enabled: true
    certificate: /etc/atlaskv/tls/server.crt
    private_key: /etc/atlaskv/tls/server.key
    client_ca: /etc/atlaskv/tls/clients.crt

observability:
  log_level: info
  log_format: json
  metrics_address: 0.0.0.0:9090
```

### Important settings

| Setting | Default | Description |
| --- | --- | --- |
| `cluster.replication_factor` | `3` | Number of replicas maintained for each partition |
| `cluster.partitions` | `256` | Number of logical partitions in the cluster |
| `storage.sync_writes` | `true` | Flushes committed writes to durable storage before acknowledging them |
| `storage.max_value_size` | `10MiB` | Maximum accepted value size |
| `consistency.default_read` | `linearizable` | Default read mode: `linearizable` or `stale` |
| `consistency.write_timeout` | `5s` | Maximum time allowed for a write to reach quorum |
| `security.authentication.enabled` | `false` | Requires a bearer token for client requests |
| `observability.metrics_address` | `127.0.0.1:9090` | Address exposing Prometheus metrics |

The partition count cannot be changed after cluster creation. Increasing the replication factor triggers background replication and may temporarily increase disk and network usage.

## Operations

Check node health:

```bash
curl http://localhost:7400/healthz
```

Check quorum readiness:

```bash
curl http://localhost:7400/readyz
```

Create a snapshot:

```bash
atlaskv snapshot create \
  --endpoint http://localhost:7400 \
  --output backup.snapshot
```

Restore a snapshot into an empty data directory:

```bash
atlaskv snapshot restore \
  --input backup.snapshot \
  --data-dir /var/lib/atlaskv
```

Prometheus metrics are exposed at `/metrics` on the configured metrics address.

## Security

Production clusters should use TLS for both client and peer traffic. Keep peer ports inaccessible from public networks, rotate access tokens regularly, and store certificates and token files outside the data directory with restrictive permissions.

AtlasKV does not encrypt data files at rest. Use encrypted disks or filesystem-level encryption when required.

## Development

Run the unit tests:

```bash
make test
```

Run integration tests:

```bash
make test-integration
```

Start a local three-node cluster:

```bash
make dev-cluster
```

## License

AtlasKV is licensed under the Apache License 2.0. See `LICENSE` for details.