Skip to content

Commit

Permalink
v2
Browse files Browse the repository at this point in the history
  • Loading branch information
albertzak committed May 28, 2020
1 parent 4a39c2a commit d3a7d1e
Show file tree
Hide file tree
Showing 14 changed files with 140 additions and 48 deletions.
2 changes: 1 addition & 1 deletion glossary.tex
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
\newacronym{edn}{edn}{Extensible Data Notation}
\newacronym{CQRS}{CQRS}{Command Query Responsibility Segregation}
\newacronym{CRDT}{CRDT}{Conflict-free Replicated Data Type}
\newacronym{OT}{OT}{Operational Transform}
\newacronym{OT}{OT}{Operational Transformation}
\newacronym{lvar}{lvar}{logic variable}
\newacronym{HTTP}{HTTP}{Hypertext Transfer Protocol}
\newacronym{CALM}{CALM}{Consistency as Logical Monotonicity}
Expand Down
Binary file added images/Source.sketch
Binary file not shown.
Binary file added images/dbvalue.pdf
Binary file not shown.
Binary file added images/namespaces.pdf
Binary file not shown.
Binary file added images/pubsub.pdf
Binary file not shown.
46 changes: 43 additions & 3 deletions lit.bib
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@ @inproceedings{calderwood15cqrs
}

@inproceedings{meijer2006linq,
title={Linq: reconciling object, relations and xml in the. net framework},
title={{LINQ}: {Reconciling} object, relations and {XML} in the {.NET} framework},
author={Meijer, Erik and Beckman, Brian and Bierman, Gavin},
booktitle={Proceedings of the 2006 ACM SIGMOD international conference on Management of data},
booktitle={Proceedings of the 2006 {ACM SIGMOD} international conference on Management of data},
pages={706--706},
year={2006}
}
Expand Down Expand Up @@ -353,7 +353,7 @@ @book{may1973historylog
title={A History of Marine Navigation. With a Chapter on Modern Developments by Leonard Holder},
author={May, William Edward and Holder, Leonard},
year={1973},
publisher={G. T. Foulis & Co. Ltd., Henley-on-Thames, Oxfordshire}
publisher={G. T. Foulis \& Co. Ltd., Henley-on-Thames, Oxfordshire}
}

@article{zubeck1997implementing,
Expand Down Expand Up @@ -754,4 +754,44 @@ @article{decker2000semantic
pages={63--73},
year={2000},
publisher={IEEE}
}


@book{jungnickel2018feasibility,
title={On the feasibility of multi-leader replication in the early tiers},
author={Jungnickel, Tim},
volume={11},
year={2018},
publisher={Universit{\"a}tsverlag der TU Berlin}
}

@inproceedings{brewer2000towards,
title={Towards robust distributed systems},
author={Brewer, Eric A},
booktitle={{PODC}},
volume={7},
year={2000},
organization={Portland, OR}
}

@article{gilbert2002brewer,
title={Brewer's conjecture and the feasibility of consistent, available, partition-tolerant web services},
author={Gilbert, Seth and Lynch, Nancy},
journal={{ACM SIGACT} News},
volume={33},
number={2},
pages={51--59},
year={2002},
publisher={{ACM} New York, NY, USA}
}

@article{abadi2012consistency,
title={Consistency tradeoffs in modern distributed database system design: CAP is only part of the story},
author={Abadi, Daniel},
journal={Computer},
volume={45},
number={2},
pages={37--42},
year={2012},
publisher={IEEE}
}
4 changes: 2 additions & 2 deletions sections/abstract.tex
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

\section*{Abstract}

Growing customer demands lead to increased incidental complexity of data-intensive distributed applications. Relational Database Management Systems (RDBMS), especially those implementing Structured Query Language (SQL) possess performant but destructive-by-default write semantics. Modeling domains such as healthcare in classic RDBMS leads to an explosion in the number of columns and tables. Their structure has to be known in advance, discouraging an explorative development process. Requirements of real time collaboration, auditability of changes, and evolution of the schema push the limit of established paradigms.
Growing customer demands lead to increased incidental complexity of data-intensive distributed applications. Relational Database Management Systems (RDBMS), especially those implementing Structured Query Language (SQL) possess performant but destructive-by-default write semantics. Modeling domains such as healthcare in classic RDBMS leads to an explosion in the number of columns and tables. Their structure has to be known in advance, discouraging an explorative development process. Requirements of real time collaboration and auditability of changes push the limit of established paradigms.

The core of the data layer presented in this thesis is a simple relational model based on facts in the form of Entity-Attribute-Value (EAV) triples. A central append-only immutable log accretes these facts via assertions and retractions. Transactions guarantee atomicity/consistency/isolation/durability (ACID) and are themselves first-class queryable entities carrying arbitrary meta facts, realizing strict bitemporal auditability of all changes by keeping two timestamps: transaction time $t_x$ and valid time $t_v$. Changes are replicated to clients which subscribe to the result of a query. Multiple incrementally maintained indices (EAVT, AEVT, AVET, VAET) grant efficient direct access to tuples, regarding the database analogous to a combined graph, column, and document store. The database itself is an immutable value which can be passed within the program and queried locally.
The core of the data layer presented in this thesis is a simple relational model based on facts in the form of Entity-Attribute-Value (EAV) triples. A central append-only immutable log accretes these facts via assertions and retractions. Transactions guarantee atomicity/consistency/isolation/durability (ACID) and are themselves first class queryable entities carrying arbitrary meta facts, realizing strict bitemporal auditability of all changes by keeping two timestamps: transaction time $t_x$ and valid time $t_v$. Changes are replicated to clients which subscribe to the result of a query. Multiple incrementally maintained indices (EAVT, AEVT, AVET, VAET) grant efficient direct access to tuples, regarding the database analogous to a combined graph, column, and document store. The database itself is an immutable value which can be passed within the program and queried locally.

This work demonstrates the feasibility of implementing various desirable features in less than 400 lines of Clojure: bitemporality, audit logging, transactions, server-client reactivity, consistency criteria, derived facts, and a simple relational query language based on Datalog.
16 changes: 11 additions & 5 deletions sections/conclusion.tex
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,20 @@
\section{Future Work}

\paragraph{Safe concurrent editing.}
A distributed system expects connection loss and simultaneous conflicting edits. It should be possible to define a schema that selects one of many built-in conflict resolution strategies specific to the domain requirements of each attribute. A per-field specifiable tradeoff as dictated by the \gls{cap} theorem of C and A must propagate to the clients and dictate the possible operations on the data item in question given the current network conditions \cite{emerick2014api}.
A distributed system expects connection loss and simultaneous conflicting edits. Especially when distributing state not just within the data center, but towards clients which thereby become (limited) database peers and are free to perform queries and writes at any time, the question arises of how such distribution can be achieved safely over (very) unreliable networks with partitions lasting for e.g. days. While theorems such as CAP and PACELC fundamentally stake out the playing field, common current data layers preempt the designer's choices and appear to make austere and conservative decisions in favor of consistency requiring coordination where not strictly needed, thus unnecessarily limiting availability.

Conflict-free replicated data types (CRDTs) and \gls{OT} are concepts which appear to provide various composable consistency primitives for robust replication \cite{weilbach2015replikativ, weilbach2016decoupling}, generally trading space efficiency for the ability to perform arbitrary \emph{merges} via an idempotent, associative, and commutative function. The result is that partitioned nodes can safely to continue to perform changes while guaranteeing that the resulting states can be reconciled later. A variety of commonly used data types have been implemented in a conflict-free variant. Since some of them may grow extremely quickly compared to their unsafe twins, garbage collection and epochal compaction of such data types remain areas of active research.

A \gls{DRP} approach by \cite{margara2014we} focuses strongly on selectable consistency guarantees, while \gls{CRDT} and \gls{OT} are recently discovered concepts which appear to provide composable consistency primitives for robust replication \cite{weilbach2015replikativ, weilbach2016decoupling}.
In a system like the one presented in this work, it should at least be possible to define a schema that specifies a distribution tradeoff for each attribute as dictated by the \gls{CAP} theorem. These constraints must propagate to the clients and elicit the data layer to restrict the possible operations on the data item in question given the current network conditions \cite{emerick2014api}.

The Braid protocol \cite{braid19} is an in-progress draft of a proposed \gls{IETF} standard to add history, editing, and subscription semantics to HTTP resources. It aims to standardize the representation and synchronization of arbitrary web application state. Braid can allow simultaneous editing of the same resource by different clients and servers and can guarantee a consistent resulting state via selectable \emph{merge types} implementing various CRDTs and OTs.
Going forward, the same schema could also select one of many built-in conflict resolution strategies (built on CRDTs or similar) specific to the domain requirements of each attribute. This is the approach taken by the Braid \cite{braid19} protocol, an in-progress draft of a proposed \gls{IETF} standard to add history, editing, and subscription semantics to HTTP resources. It aims to standardize the representation and synchronization of arbitrary web application state. Braid can allow simultaneous editing of the same resource by different clients and servers and can guarantee a consistent resulting state via selectable \emph{merge types} implementing various CRDTs and OTs.

Relaxing the design goal of full auditability of every change via bitemporal transactions, the described system could provide a more useful and vastly more efficient notion of history concerning simultaneous editing of full-text values (e.g. medical notes) when represented as a mutably updatable CRDT value within a fact.

Lastly, the entire immutable log described in this work could be constructed as a conflict-free data type. Clients could converge values of the database with no coordination, because then only the latest commits would need to be transmitted between clients, forgoing the need of a server. However, the publication/subscription mechanism would have to be redesigned completely, and a decentralized immutable database implemented as a CRDT would require tackling clock synchronization if the resulting system were to have a notion of bitemporality.


\cleardoublepage
\paragraph{(Temporal) logic constraints.} An ideal programming environment would let the programmer "use logic to express what is true, use logic to check whether something is true, [and] use logic to find out what is true \cite{sicp}". Research by \cite{alvaro2010dedalus,alvaro2011consistency} explores temporal extensions to Datalog and a domain-specific language for describing time-dependent behavior of distributed systems.

\paragraph{Full stack laziness.} A fully lazy distributed data structure would allow transparent access and local caching of all facts for which the client passes access rules set up by the server. Such a design would also allow transparent querying of past facts, possibly aided by hints from the programmer as to where (on client or server) the query should be executed.
Expand All @@ -24,8 +30,8 @@ \section{Future Work}
\cleardoublepage
\section{Conclusion}

Easy things are easy, hard things are hard. This thesis set out to redesign and implement the entire data layer using a combination of non-mainstream ideas. From data representation in EAV facts, to the database being an immutable value to be passed around and queried locally, to only accreting facts via assertion and retraction, yet keeping ACID guarantees, to having functions stored as values inside the database which derive new facts or act as constraints, to a replication mechanism where clients subscribe to the live-updating result set of a query, to pulling out simple values directly from the database by reaching into its index structures, or asking complex questions with a pattern matching query language.
Easy things are easy, hard things are hard. This thesis set out to redesign and implement the entire data layer using a combination of non-mainstream ideas. From data representation in EAV facts, to the database being an immutable value to be passed around and queried locally, to only accreting facts via assertion and retraction, requiring no schema yet keeping ACID guarantees, to having functions stored as values which derive new facts or act as constraints on the database value, to a replication mechanism where clients subscribe to the live-updating result set of a query, to pulling out simple values directly from the database value by reaching into its index structures, or asking complex questions with a pattern matching query language.

The resulting implementation in less than 400 lines is impressively tight yet appears to map nicely to the initial design, mostly thanks to the incredibly expressive Clojure language and its built-in immutable data structures. While all of the mentioned features are implemented to a degree that is just enough to experiment with, almost all of the more complicated aspects were left simply left out of the design: There is no expectation of performance, efficiency, scale, security, safety, testing, or any implied suitability for usage in the real world or with more than just a handful of sample facts. The proof-of-concept fixates on the easy parts of that utopian data layer design which were almost trivial to implement, and barely covers any truly complex minutiae. In particular, the implementation of the query language turned out to be harder than anticipated, despite cutting out almost all but the most basic pattern matching features of a real Datalog.
The resulting implementation in less than 400 lines is impressively tight yet appears to map nicely to the initial design, mostly thanks to the incredibly expressive Clojure language and its built-in immutable data structures. While all of the mentioned features are implemented to a degree that is just enough to experiment with, almost all of the more complicated aspects were simply left out of the design: There is no expectation of performance, efficiency, scale, security, safety, testing, or any implied suitability for usage in the real world or with more than just a handful of sample facts. The proof-of-concept fixates on the easy parts of that utopian data layer design which were almost trivial to implement, and barely covers any truly complex minutiae. In particular, the implementation of the query language turned out to be harder than anticipated, despite cutting out almost all but the most basic pattern matching features of a real Datalog.

Yet the formidable degree to which the presented ideas appear to mesh together, supported by considerable amount of related work, gives a sound impression of the general direction of this and similar designs for better data layers.
4 changes: 2 additions & 2 deletions sections/design.tex
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ \subsection{Query language}\label{sec:query_language}

The query language of the system is a greatly simplified language modeled after the pattern matching relational query language used in Datomic, which is in turn a Lisp variant of the Datalog \cite{abiteboul1988datalog} language expressed in of Clojure's \gls{edn}.

The choice of language is arbitrary -- any relational language would suffice -- and the core of the database does not depend on any query language capabilities Modeling the language after the one used in Datomic was chosen because because not only has the edn notation become a de-facto standard for other EAV databases like Crux, EVA, and Datascript, but because the shape of each query clause maps naturally to the representation of a fact in canonical EAV order.
The choice of language is arbitrary -- any relational language would suffice -- and the core of the database does not depend on any query language capabilities Modeling the language after the one used in Datomic was chosen because not only has the edn notation become a de-facto standard for other EAV databases like Crux, EVA, and Datascript, but because the shape of each query clause maps naturally to the representation of a fact in canonical EAV order.

See listing~\ref{lst:example_query} for an query consisting of four query clauses (the \lisp{:where} part) performing an implicit join, and a final projection (\lisp{:find}) to extract the values bound to the \emph{\gls{lvar}} symbols \lisp{?name} and \lisp{?location}. For example, the query clause \lisp{[?p :name ?name]} applied to the fact \lisp{[:person/123 :name "Hye-mi"]} would result in \emph{binding} the lvar \lisp{?p} to the value \lisp{:person/123}, and the lvar \lisp{?name} to the value \lisp{"Hye-mi"}. Other clauses are bound likewise. Note that multiple occurrences of the same lvar prompt \emph{unification} with the same value, creating an implicit \emph{join}. The order of the query clauses has no semantic meaning.

Expand All @@ -85,7 +85,7 @@ \subsection{Query language}\label{sec:query_language}
\paragraph{Temporal and bitemporal queries.}
As stated in section~\ref{sec:nongoals}, the (bi-)temporal aspects of the described system are secondary -- they are to be used for infrequent auditing purposes. Consequently, the design of the indexing and query mechanisms can be greatly simplified be forgoing bitemporal indexing strategies such as \cite{nascimento1995ivtt}.

As the query function simply takes a database as a \emph{value}, a \emph{filtering function} can be applied the the database beforehand. The \lisp{keep} function in listing~\ref{lst:queryfilter} returns a structurally shared and lazy copy of the database filtered by arbitrary bounds of the relevant timestamps $t_x$ and $t_v$.
As the query function simply takes a database as a \emph{value}, a \emph{filtering function} can be applied to the database beforehand. The \lisp{keep} function in listing~\ref{lst:queryfilter} returns a structurally shared and lazy copy of the database filtered by arbitrary bounds of the relevant timestamps $t_x$ and $t_v$.

\begin{lstlisting}[label={lst:queryfilter},caption=Applying a temporal filter before querying,morekeywords={keep,q,<,>}]
(q (keep
Expand Down
2 changes: 1 addition & 1 deletion sections/design_problems.tex
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ \subsection{Problems}

\paragraph{\gls{SQL}.}
Despite the widespread use of SQL, it is not, in any version, an accurate reflection of the relational model \cite{codd1990relational} \cite{tarpit}.
Modeling domains in common \gls{RDBMS} requires distinguishing between entity and relationship \cite{chen1976entity}. A system in which choosing the structure for the data involves setting up "routes" between data instances (such as from a particular employee to a particular department) is access path dependent. A pure relational systems would need no problematic distinction between entity and relationship \cite{tarpit}.
Modeling domains in common \gls{RDBMS} requires distinguishing between entity and relationship \cite{chen1976entity}. Access path dependence requires an upfront decision about the "routes" between data, such as from a particular room to a particular building. A pure relational systems would need no problematic distinction between entity and relationship \cite{tarpit}.

SQL within the application's main programming language is usually treated as a second class citizen by resorting to concatenation of strings with a thin layer of sanitization. (Microsoft's LINQ \cite{meijer2006linq} is a notable exception.) Features such as materialized views are cumbersome to use because the language lacks powerful means of abstraction and composition \cite{sicp} which would enable recursively composing complex queries out of smaller queries.

Expand Down
Loading

0 comments on commit d3a7d1e

Please sign in to comment.