Committer
Committer is a Go implementation of the Two-Phase Commit (2PC) and Three-Phase Commit (3PC) protocols for distributed systems.
Architecture
The system consists of two types of nodes: Coordinator and Cohorts. The Coordinator is responsible for initiating and managing the commit protocols (2PC or 3PC), while the Cohorts participate in the protocol by responding to the coordinator's requests. The communication between nodes is handled using gRPC, and the state of each node is managed using a state machine.
Atomic Commit Protocols
Two-Phase Commit (2PC)
The Two-Phase Commit protocol ensures atomicity in distributed transactions through two distinct phases:
Phase 1: Voting Phase (Propose)
- Coordinator sends a
PROPOSErequest to all cohorts with transaction data - Each Cohort validates the transaction locally and responds:
ACK(Yes) - if ready to commitNACK(No) - if unable to commit
- Coordinator waits for all responses
Phase 2: Commit Phase
- If all cohorts voted
ACK:- Coordinator sends
COMMITto all cohorts - Each Cohort commits the transaction and responds with
ACK
- Coordinator sends
- If any cohort voted
NACK:- Coordinator sends
ABORTto all cohorts - Each Cohort aborts the transaction
- Coordinator sends
Three-Phase Commit (3PC)
The Three-Phase Commit protocol extends 2PC with an additional phase to reduce blocking scenarios:
Phase 1: Voting Phase (Propose)
- Coordinator sends
PROPOSErequest to all cohorts - Cohorts respond with
ACK/NACK(same as 2PC)
Phase 2: Preparation Phase (Precommit)
- If all cohorts voted
ACK:- Coordinator sends
PRECOMMITto all cohorts - Cohorts acknowledge they're prepared to commit
- Timeout mechanism: If cohort doesn't receive
COMMITwithin timeout, it auto-commits
- Coordinator sends
- If any cohort voted
NACK:- Coordinator sends
ABORTto all cohorts
- Coordinator sends
Phase 3: Commit Phase
- Coordinator sends
COMMITto all cohorts - Cohorts perform the actual commit operation
Configuration
All configuration parameters can be set using command-line flags:
| Flag | Description | Default | Example |
|---|---|---|---|
role |
Node role: coordinator or cohort |
cohort |
-role=coordinator |
nodeaddr |
Address of the current node | localhost:3050 |
-nodeaddr=localhost:3051 |
coordinator |
Coordinator address (required for cohorts) | "" |
-coordinator=localhost:3050 |
committype |
Commit protocol: two-phase or three-phase |
three-phase |
-committype=two-phase |
timeout |
Timeout (ms) for unacknowledged messages (3PC only) | 1000 |
-timeout=500 |
dbpath |
Path to the BadgerDB database on the filesystem | ./badger |
-dbpath=/tmp/badger |
cohorts |
Comma-separated list of cohort addresses | "" |
-cohorts=localhost:3052,3053 |
whitelist |
Comma-separated list of allowed hosts | 127.0.0.1 |
-whitelist=192.168.0.1,192.168.0.2 |
Usage
Running as a Cohort
./committer -role=cohort -nodeaddr=localhost:3001 -coordinator=localhost:3000 -committype=three-phase -timeout=1000 -dbpath=/tmp/badger/cohort
Running as a Coordinator
./committer -role=coordinator -nodeaddr=localhost:3000 -cohorts=localhost:3001 -committype=three-phase -timeout=1000 -dbpath=/tmp/badger/coordinator
Hooks System
The hooks system allows you to add custom validation and business logic during the Propose and Commit stages without modifying the core code. Hooks are executed in the order they were registered, and if any hook returns false, the operation is rejected.
// Default usage (with built-in default hook) committer := commitalgo.NewCommitter(database, "three-phase", wal, timeout) // With custom hooks metricsHook := hooks.NewMetricsHook() validationHook := hooks.NewValidationHook(100, 1024) auditHook := hooks.NewAuditHook("audit.log") committer := commitalgo.NewCommitter(database, "three-phase", wal, timeout, metricsHook, validationHook, auditHook, ) // Dynamic registration committer.RegisterHook(myCustomHook)
Testing
Run Functional Tests
Testing with Example Client
- Compile executables:
- Run the coordinator:
make run-example-coordinator
- Run a cohort in another terminal:
- Start the example client:
Or directly:
go run ./examples/client/client.go
Contributions
Contributions are welcome! Feel free to submit a PR or open an issue if you find bugs or have suggestions for improvement.
License
This project is licensed under the Apache License.
