Logical Time in Distributed Computing
Origins and Significance of Logical Time
Foundational Research: The concept of logical time originated from the seminal 1978 paper by Leslie Lamport titled ‐‐Time, Clocks, and the Ordering of Events in a Distributed System,‑‑ published in Communications of the ACM.
Continued Relevance: The topic remains a central interest in distributed computing. A notable recent contribution is the paper ‐‐Capturing Causality in Distributed Systems‑‑ by Raynal and Singhal.
Lamport's Recognition: Leslie Lamport's original paper received the PODC Influential Paper Award in 2000.
Applications of Logical Time
Parallel Computations: Used in visualizations produced by parallel computations to maintain event order.
Banker System Algorithm: Logical time is essential for the implementation of the banker system algorithm in distributed environments.
Replicated Data Consistency: Used in efficient solutions for the Replicated Log and Replicated Dictionary problems, specifically the work of Wuu and Bernstein.
Background and Distributed System Model
System Composition: A distributed computation consists of a set of processes that cooperate and compete to achieve a common goal.
Communication Constraints: These processes do not share common global memory and communicate solely by passing messages over a communication network.
Event Classification: Actions within a process are modeled as three types of events: * Internal Events: These occur within a single process and affect only that process. Logic dictates that events at a process are linearly ordered by their occurrence. * Message Send Events: Signify the flow of information leaving a process. * Message Receive Events: Signify the intake of information from another process.
Causal Dependency: Send and receive events establish a causal dependency from the sender process to the receiver process.
Causality and the Happen‐Before Relation
Causal Precedence Relation: This is a formal concept used for reasoning, analyzing, and drawing inferences about distributed computations. It helps programmers and the system itself solve problems by knowing the relation between processes.
Absence of Physical Time: Distributed systems have no built‐in physical time and can only approximate it. Because interactions occur in sporadic "spurts," logical clocks are used to accurately capture causality.
Asynchronous Processes: Programs are composed of independent, asynchronous processes: . These processes do not share a global clock.
Spontaneity: Each process can execute an event spontaneously. When sending a message, a process does not wait for delivery to complete.
Internal Sequencing: Each process produces a sequence of events . These are totally ordered by sequencing: * (Read: " happens before "). * The relation is transitive: for all i < j.
Inter‐Process Causality: For every message exchanged between two processes and : * If and , then .
Event Ordering Summary: * Local events are totally ordered. * Causality‐linked events are totally ordered. * Unrelated events are unordered or concurrent (). * For any two events and , one of three conditions must hold: (i) , (ii) , or (iii) .
Logical Clock Conditions
Clock Assignment: Every event is assigned a timestamp according to a specific protocol.
Clock Consistency Condition: A system satisfies this if: * If , then C(e_1) < C(e_2), where is the timestamp of event .
Strong Clock Consistency Condition: A clock is strongly consistent if it also satisfies the converse: * If C(e_1) < C(e_2), then .
Scalar Logical Clocks (Lamport Clocks)
Protocol Implementation: * Rule 1 (R1): Before executing any event (send, receive, or internal), process increments its clock: (where d > 0, usually ). * Rule 2 (R2): Every message carries the clock value of the sender at the time of sending (). Upon receiving a message, process performs: * . * Execute Rule 1 (increment). * Deliver the message.
Properties: * The logical clock is monotonically increasing. * It satisfies the clock consistency condition. * It does not necessarily satisfy the strong clock consistency condition (e.g., C(e_1) < C(e_2) does not prove ).
Vector Logical Clocks
Structure: Each process out of processes maintains an integer vector . * is the local logical clock of . * is 's latest knowledge of 's local time.
Protocol Rules: * Local Update: Before an event, . * Message Piggybacking: The sender attaches its current vector clock to the message . * Reception Update: Process updates its vector: * For . * .
Strong Consistency: Vector clocks are strongly consistent. * e_1 \rightarrow e_2 \iff vt(e_1) < vt(e_2).
Vector Comparison Logic: * V_1 < V_2 if for all , AND there exists at least one such that V_1[k] < V_2[k]. * Example 1: , V_2 = {2, 3, 4, 5} \implies V_1 < V_2. * Example 2: , V_2 = {2, 2, 4, 4} \implies V_1 < V_2. * Example 3: , Unordered/Concurrent.
Matrix Logical Time
Development: Proposed by Michael and Fischer in 1982.
Structure: Process maintains an matrix . * is the local logical clock of . * Row corresponds to the vector clock of . * is the latest knowledge has regarding 's local clock (). * represents what knows about 's knowledge of 's local clock.
Protocol Rules: * Local Event: . * Reception from : 1. Update 's knowledge of others via message matrix : For . 2. Update transitive knowledge for all processes: For , for . 3. .
Comparison Logic: * M_1 < M_2 if for all , AND there exists some such that M_1[k, p] < M_2[k, p]. * Provides strong consistency to determine causal relations.
Replicated Dictionary Problem (Wuu and Bernstein)
The Problem: A dictionary is replicated across multiple nodes over an unreliable network. Nodes must maintain independent views that are eventually consistent.
Approach: Unlike standard databases using serializability/locking, Wuu and Bernstein propose a logic‐based algorithm.
Operations: * : Can be issued by only one node. * : Can be issued by multiple nodes. Invoked at only if is currently in internal view .
Dictionaries and History: * : The unique insertion event. * event: An event deleting . * Logic: is in view iff and there exists no event such that .
The Log: Each node maintains a log of events. Each log entry contains: (operation, time, nodeID). Example:
(add a, 3, 2).
Wuu and Bernstein Solutions
Trivial Fault-Tolerant Solution: * Every event adds a record to local log . * Every message includes the entire log . * Reception involves applying all events in the log to the dictionary view . * Drawbacks: Logs grow unboundedly; excessive communication, computation, and storage costs.
Improved Solution using Matrix Time: * Uses matrix clocks to purge records seen by all participants. * The hasrec Predicate:
boolean hasrec(Ti, eR, k)returns true ifTi[k, eR.node] > eR.time. This determines if process has already seen record . * Node Initialization: Dictionary view , Partial Log , all matrix values = 0.Operational Rules for Improved Solution: * On locally issuing insert/delete: Update matrix clock, add event to , update . * On sending to node : Create subset of containing only entries where
hasrec(Ti, eR, k)is false. Send and matrix clock to node . * On receiving from node : 1. Extract subset from received log wherehasrec(Ti, eR, i)is false (new events for node ). 2. Update based on . 3. Update matrix clock . 4. Add to those records from the received log wherehasrec(Ti, eR, j)is false for at least one participant . This ensures the record is kept until everyone has seen it.Result: Efficiently minimizes log size in messages and memory while remaining fault‐tolerant and ensuring eventual consistency.