mirror of
https://github.com/zoo-apps/papers.git
synced 2026-10-30 14:56:54 +00:00
81 lines
2.4 KiB
TeX
81 lines
2.4 KiB
TeX
\section{Architecture}
|
|
|
|
|
|
\subsection{Components}
|
|
|
|
\begin{description}
|
|
\item[\texttt{hanzoai/replicate}] Litestream-based WAL streaming
|
|
daemon. Watches SQLite WAL, ships frames to S3. Runs as a
|
|
sidecar container sharing the data volume with the primary
|
|
service container.
|
|
|
|
\item[\texttt{hanzoai/age}] X25519 + ChaCha20-Poly1305 file
|
|
encryption. Used for encrypting WAL snapshots and segments
|
|
at rest in S3. Compatible with \texttt{luxfi/age} (same
|
|
wire format).
|
|
|
|
\item[\texttt{hanzoai/s3}] S3-compatible object storage. Deployed
|
|
as a ClusterIP service within the Zoo K8s cluster
|
|
(\texttt{s3.zoo.svc.cluster.local:9000}). Backed by
|
|
DigitalOcean Spaces or MinIO depending on environment.
|
|
|
|
\item[ConfigMap] Shared \texttt{replicate-config} ConfigMap
|
|
containing the Litestream YAML configuration. All services
|
|
reference the same ConfigMap; pod identity (\texttt{POD\_NAME})
|
|
provides per-replica S3 path namespacing.
|
|
\end{description}
|
|
|
|
\subsection{Data Flow}
|
|
|
|
\begin{verbatim}
|
|
Service writes to SQLite
|
|
-> WAL frames written to shared PVC
|
|
-> Replicate sidecar reads WAL
|
|
-> Frames uploaded to S3 (1s interval)
|
|
-> Optional: age encryption before upload
|
|
|
|
Pod restart:
|
|
-> Init container runs replicate restore
|
|
-> Fetches latest snapshot + WAL segments
|
|
-> Reconstructs SQLite database
|
|
-> Primary container starts with warm data
|
|
\end{verbatim}
|
|
|
|
\subsection{K8s Sidecar Pattern}
|
|
|
|
Each service pod contains three components:
|
|
|
|
\begin{enumerate}
|
|
\item \textbf{Init container} (\texttt{replicate-restore}): Runs
|
|
\texttt{replicate restore -if-db-not-exists -if-replica-exists}
|
|
to restore from S3 on cold start. No-op if database already
|
|
exists on the PVC.
|
|
|
|
\item \textbf{Primary container}: The service binary (e.g.,
|
|
\texttt{zoo-bridge}, future Base-powered services). Reads and
|
|
writes \texttt{/app/data/data.db}.
|
|
|
|
\item \textbf{Sidecar container} (\texttt{replicate}): Runs
|
|
\texttt{replicate replicate} to continuously stream WAL changes
|
|
to S3. Shares the \texttt{/app/data} volume with the primary.
|
|
\end{enumerate}
|
|
|
|
\subsection{S3 Path Layout}
|
|
|
|
\begin{verbatim}
|
|
s3://zoo-data/
|
|
{pod-name}/
|
|
generations/
|
|
{generation-id}/
|
|
snapshots/
|
|
{index}.snapshot.lz4
|
|
wal/
|
|
{index}.wal.lz4
|
|
\end{verbatim}
|
|
|
|
Each pod (e.g., \texttt{zoo-bridge-0}, \texttt{zoo-bridge-1})
|
|
replicates to a distinct prefix. The \texttt{POD\_NAME}
|
|
environment variable is injected via the Kubernetes downward API
|
|
(\texttt{metadata.name} fieldRef).
|
|
|