A consistent distributed data store.

Doozer

logo

Build Status

What Is It?

Doozer is a highly-available, completely consistent store for small amounts of extremely important data. When the data changes, it can notify connected clients immediately (no polling), making it ideal for infrequently-updated data for which clients want real-time updates. Doozer is good for name service, database master elections, and configuration data shared between several machines. See When Should I Use It?, below, for details.

See the mailing list to discuss doozer with other users and developers.

Quick Start

  1. Download doozerd

  2. Unpack the archive and put doozerd in your PATH

  3. Repeat for doozer

  4. Start a doozerd with a WebView listening on :8080

     $ doozerd -w ":8080"
    
  5. Set a key and read it back

     $ echo "hello, world" | doozer add /message
     $ doozer get /message
     hello, world
    
  6. Open http://localhost:8080 and see your message

doozer web view

How Does It Work?

Doozer is a network service. A handful of machines (usually three, five, or seven) each run one doozer server process. These processes communicate with each other using a standard fully-consistent distributed consensus algorithm. Clients dial in to one or more of the doozer servers, issue commands, such as GET, SET, and WATCH, and receive responses.

(insert network diagram here)

Each doozerd process has a complete copy of the datastore and serves both read and write requests; there is no distinguished "master" or "leader". Doozer is designed to store data that fits entirely in memory; it never writes data to permanent files. A separate tool provides durable storage for backup and recovery.

When Should I Use It?

Here are some example scenarios:

  1. Name Service

    You have a set of machines that serve incoming HTTP requests. Due to hardware failure, occasionally one of these machines will fail and you replace it with a new machine at a new network address. A change to DNS data would take time to reach all clients, because the TTL of the old DNS record would cause it to remain in client caches for some time.

    Instead of DNS, you could use Doozer. Clients can subscribe to the names they are interested in, and they will get notified when any of those names’ addresses change.

  2. Database Master Election

    You are deploying a MySQL system. You want it to have high availability, so you add slaves on separate physical machines. When the master fails, you might promote one slave to become the new master. At any given time, clients need to know which machine is the master, and the slaves must coordinate with each other during failover.

    You can use doozer to store the address of the current master and all information necessary to coordinate failover.

  3. Configuration

    You have processes on several different machines, and you want them all to use the same config file, which you must occasionally update. It is important that they all use the same configuration.

    Store the config file in doozer, and have the processes read their configuration directly from doozer.

What can I do with it?

We have a detailed description of the data model.

For ways to manipulate or read the data, see the protocol spec.

Try out doozer's fault-tolerance with some fire drills.

Similar Projects

Doozer is similar to the following pieces of software:

Hacking on Doozer

License and Authors

Doozer is distributed under the terms of the MIT License. See LICENSE for details.

Doozer was created by Blake Mizerany and Keith Rarick. Type git shortlog -s for a full list of contributors.

Comments
  • A new Doozerd fails to join a cluster

    A new Doozerd fails to join a cluster

    Using the firedrill and master branch as an example, if step 4 (start a forth) is run after the store revision number has passed the -hist parameter, the new instance panics with TOO_LATE

    It's also easy to reproduce by setting a low -hist on the first instance and waiting to start another until the pulse has made rev > hist.

    The stack trace begins:

    panic: TOO_LATE
    
    goroutine 1 [running]:
    doozer/peer.cloner.VisitFile(0xf840051410, 0xf840001960, 0xf840019d60, 0xa, 0xf84004e3f0, ...)
        /home/dcoates/code/doozerd/src/pkg/peer/peer.go:298 +0xc0
    doozer/peer.(*cloner).VisitFile(0xf840019a60, 0xf840019d60, 0xf80000000a, 0xf84004e3f0, 0x1, ...)
        /home/dcoates/code/doozerd/src/pkg/peer/peer.go:0 +0x8b
    github.com/ha/doozer.walk(0xf840001960, 0x8f, 0xf840019d60, 0xf80000000a, 0xf84004e3f0, ...)
        /home/dcoates/code/doozer/walk.go:23 +0x64
    

    It appears that the Clean in clean.go (line 352) on the store initiated by a goroutine in peer.go (line 62) is causing the Get in peer.go (line 296) to return ErrTooLate because the rev of some path (in my case /ctl/cal/0 at rev 5) is less than st.head

    This seems like a bug, but I may be misunderstanding.

    What is the proper way to add a new doozerd to a cluster after the rev has passed hist? This seems like a pretty basic operation to do if an instance crashes.

  • Cannot run on Mac OS X 10.7

    Cannot run on Mac OS X 10.7

    I've downloaded this binary: https://github.com/downloads/ha/doozerd/doozerd-0.8-darwin-amd64.tar.gz Unpacked, chmodded and tried to run. Getting following error:

    ./doozerd
    libcgo: thread-local storage 0x108 not at %gs:0x8a0 - x=0 y=0
    [1]    21635 abort      ./doozerd
    
  • add SELF transaction type

    add SELF transaction type

    it allows you to deterministically identify a running node... this has been helpful for our use of doozerd at bitly particularly in scripts for cluster setup and daemon instantiation

    ready for review @kr

    matching pull request for client code on https://github.com/ha/doozer coming up

  • make 4ad/doozerd the primary repository

    make 4ad/doozerd the primary repository

    Currently, 4ad/doozerd compiles against go1 and is more actively maintained. A support ticket to Github made by @ha could "flip" the fork status of the ha/doozerd and 4ad/doozerd.

    Similarly, with ha/doozer and 4ad/doozer, I believe.

    This would make it more clear to new users which repo is more available (and might help clear up the strong google juice ha/doozerd has over 4ad's).

  • V0.8 go r59

    V0.8 go r59

    this makes doozer compile with go r59. Two types of problems occured to me:

    1.) some function signatures changed 2.) the provided generated protobuffer files did not work for me, i.e. I removed *.pb.go files from the repository and added them to be removed when clean is called -- they get auto generated when all.sh is executed.

  • Can't compile - missing pretty.go

    Can't compile - missing pretty.go

    I get this error when running make.sh:

    package github.com/ha/doozer
        imports code.google.com/p/goprotobuf/proto
        imports github.com/kr/pretty.go
        imports github.com/kr/pretty.go
        imports github.com/kr/pretty.go: no Go source files in .go/src/github.com/kr/pretty.go
    
  • fix for issue #5 (web interface issues)

    fix for issue #5 (web interface issues)

    the problem seemed to be that the server would infinite loop due to nop events having rev == -3... this commit prevents the state of rev in the websocket loop from ever going backwards.

    ready for review @kr

  • 0.8 (everything) and current master (web view) not working on Mac OS 10.8

    0.8 (everything) and current master (web view) not working on Mac OS 10.8

    When compiling from today's master, I get the same issue originally reported as #32: the web view doesn't work (can't connect). When using the 0.8 packages in downloads, both 32 and 64 bit binaries give the same result on my machine:

    $ doozerd
    libcgo: thread-local storage 0x108 not at %gs:0x8a0 - x=0 y=0
    Abort trap: 6
    

    Almost the same result as root:

    $ sudo doozerd
    libcgo: thread-local storage 0x108 not at %gs:0x8a0 - x=0 y=0
    

    And it's the same trying to use the help command:

    $ doozerd --help
    libcgo: thread-local storage 0x108 not at %gs:0x8a0 - x=0 y=0
    Abort trap: 6
    

    Do you need more information?

  • Go 1.1 compatibility, prevent hanging tests

    Go 1.1 compatibility, prevent hanging tests

    This includes a few changes:

    1. General test fixes to get everything running on go1.1 (chiefly, removing explicit allocations of *net.UDPAddr.
    2. server.ListenAndServe aborts on all non-temporary network errors, not just syscall.EINVAL. This was a cause of randomly hanging tests with quiet logging. When the listen socket was closed from a defer() statement in the tests, it would enter an infinite failure loop, attempting to log the error message -- which, when using ioutil.Discard, was not guaranteed to trigger the scheduler, resulting in 100% CPU usage from the serve goroutine and a hanging process.
    3. Change conensensus.triggers.Less() to consider both timestamp and sequence number. The current implementation depends on undefined behaviour in container/heap which differs between go1.0.3 and go1.1.

    I'd appreciate feedback on 2 and 3: though all tests pass with the changes, I could imagine consequences that aren't covered by the tests.

  • Update hacking.md  to point to http://localhost:8000 instead of http://localhost:8080

    Update hacking.md to point to http://localhost:8000 instead of http://localhost:8080

    By default, doozerd web starts up at http://localhost:8000, But the documentation (hacking.md) was pointing it to the wrong URL (http://localhost:8080)

  • 0.8.0-darwin-amd64 web process closed

    0.8.0-darwin-amd64 web process closed

    I followed the main README to get a feel for doozerd. The web process returns just: closed retrying in 2s [Try now]

    I can get and set messages successfully:

    $ doozerd -w ":8080"
    $ echo "hello, world" | doozer add /message
    81
    $ doozer get /message
    hello, world
    
  • unable to detect version control system for code.google.com

    unable to detect version control system for code.google.com

    package code.google.com/p/goprotobuf/proto: unable to detect version control system for code.google.com/ path
    package code.google.com/p/go.net/websocket: unable to detect version control system for code.google.com/ path
    

    these two libs are not hosted in code.google.com code.google.com/p/goprotobuf/proto ==> github.com/golang/protobuf/proto code.google.com/p/go.net/websocket ==> golang.org/x/net/websocket

    So to change all files

    import "code.google.com/p/goprotobuf/proto"  to  import "github.com/golang/protobuf/proto"
    import "code.google.com/p/go.net/websocket"  to  import "golang.org/x/net/websocket"
    
    

    Also: cause it import itself ha/doozerd & ha/doozer so need to change the directories ${GOPATH}/src/github.com/ha/doozer & ${GOPATH}/src/github.com/ha/doozerd all files import like above

  • dependency on code.google.com/p/goprotobuf/proto

    dependency on code.google.com/p/goprotobuf/proto

    I pulled down code... running ./all.sh I get: package github.com/ha/doozer imports code.google.com/p/goprotobuf/proto: unable to detect version control system for code.google.com/ path

    I made changes in the files, replace the code.google.com with proper git hub imports in: modified: .travis.yml modified: consensus/m.pb.go modified: consensus/m_test.go modified: consensus/manager.go modified: consensus/manager_test.go modified: consensus/run.go modified: consensus/run_test.go modified: doc/hacking.md modified: doc/proto.md modified: server/conn.go modified: server/msg.pb.go modified: server/server_test.go modified: server/txn.go modified: web/web.go

    I can't find any more references, but somewhere I the code is still looking for code.google.com, preventing build.

  • Web ui doesn't seem to work v0.8

    Web ui doesn't seem to work v0.8

    Downloaded the prepacked binary (v0.8 amd64)

    executed the following commands:

    doozerd
    ps aux | grep doozerd
    doozerd 9660 james    6u  0000     0,9        0     6343 anon_inode
    doozerd 9660 james    7u  IPv6 4737813      0t0      UDP localhost:8046 
    doozerd 9660 james    8u  IPv6 4737814      0t0      TCP localhost:8000 (LISTEN)
    doozerd 9660 james    9r   CHR     1,9      0t0     1034 /dev/urandom
    

    Browsed to localhost:8000/ page just constantly trys to reconnect to the events web socket. and the socket closes immediately prior to hand shaking.

    Attempted to add a piece a data:

    echo "hello, world" | doozer add /message
    

    same deal. Also tried starting with doozerd -w ":8080" and browsing to 8080, same problem.

    what am I missing?

    Note: encountering same issue on v0.7, pretty sure I'm doing something wrong but have no clue what, lack of build instructions/requirements are also make it extremely difficult to manually build and debug.

  • service bind port traffic

    service bind port traffic

    My Node.js app is on the same machine with Doozerd.Node.js App it dynamic allocate port to bind, but when it get one free port then the doozerd service(here is account_service) bind to that port, then node.js app bind failed.

Related tags
Consistelancer - Consistent hashing load balancer for Kubernetes

Setup minikube start kubectl apply -f k8s-env.yaml skaffold dev # test locks ku

Sep 28, 2022
A simple distributed key-value store by using hashicorp/raft

raftkv This repository holds a simple distributed key-value store by using hashicorp/raft. raftkv provides gRPC and HTTP APIs. Please take a look API

Nov 30, 2022
In memory Key/Value store in go using gRPC.
In memory Key/Value store in go using gRPC.

In memory cache, using gRPC Contents About Running Server Local Docker Kubernetes Example Helm Terraform API Add Get GetByPrefix GetAllItems DeleteKey

Dec 26, 2022
Use Consul to do service discovery, use gRPC +kafka to do message produce and consume. Use redis to store result.
Use  Consul to do service discovery, use gRPC +kafka to do message produce and consume. Use redis to store result.

目录 gRPC/consul/kafka简介 gRPC+kafka的Demo gRPC+kafka整体示意图 限流器 基于redis计数器生成唯一ID kafka生产消费 kafka生产消费示意图 本文kafka生产消费过程 基于pprof的性能分析Demo 使用pprof统计CPU/HEAP数据的

Jul 9, 2022
A shazam like tool to store songs fingerprints and retrieve them
A shazam like tool to store songs fingerprints and retrieve them

musig ?? A shazam-like tool that allows you to compute song's fingerprints and reverse lookup song names. It's more or less an implementation of the s

Dec 12, 2022
OpenDILab RL Object Store

Introduction Decision AI Store Installation Prerequisites Linux Python >= 3.6 pip install . Quick Start Start Etcd Server di_store etcd_server ./conf/

Jan 6, 2023
Project Kebe is the open-source Snap Store implementation.

Introduction Kebe intends to be a full replacement for the Snap Store. Quickstart Once you have an environment setup (for instance using https://githu

Nov 9, 2022
A pizza store design using NATS pub sub queue.
A pizza store design using NATS pub sub queue.

A pizza store design using NATS pub sub queue.

Oct 12, 2022
Backend implementation using go, proto3 and gRPC for a mock online store

Backend implementation using go, proto3 and gRPC for a mock online store Ricardo RICO URIBE Tasks I - Order service The current system exposes a produ

Oct 10, 2021
Consul K/V Store Implementation For Go
Consul K/V Store Implementation For Go

Consul K/V Store Implementation For Go Enables Consul to be used as a configuration source in go applications Dynamic Configuration with Consul's Key/

Jun 7, 2022
Inventory: Task 1 : Online Store

Task 1 : Online Store ### Q1: Describe what you think happened that caused those bad reviews during our 12.12 event and why it happened. Answer : You

Dec 6, 2021
Data Connector is a Google Sheets Add-on that lets you import (and export) data to/from Google Sheets

Data Connector Data Connector is a Google Sheets Add-on that lets you import (and export) data to/from Google Sheets. Our roadmap: Connect to JSON/XML

Jul 30, 2022
A cloud native distributed streaming network telemetry.
A cloud native distributed streaming network telemetry.

Panoptes Streaming Panoptes Streaming is a cloud native distributed streaming network telemetry. It can be installed as a single binary or clustered n

Sep 27, 2022
Go language interface to the Libcircle distributed-queue API

Circle Description The Circle package provides a Go interface to the Libcircle distributed-queue API. Despite the name, Circle has nothing to do with

Oct 24, 2022
Distributed RTC System by pure Go and Flutter
Distributed RTC System by pure Go and Flutter

ION is a distributed real-time communication system, the goal is to chat anydevice, anytime, anywhere! Distributed Real-time Communication System ION

Jan 2, 2023
Golang implementation of Sliding Window Algorithm for distributed rate limiting.
Golang implementation of Sliding Window Algorithm for distributed rate limiting.

slidingwindow Golang implementation of Sliding Window Algorithm for distributed rate limiting. Installation $ go get -u github.com/RussellLuo/slidingw

Dec 27, 2022
Antenna RPC is an RPC protocol for distributed computing, it's based on QUIC and Colfer. its currently an WIP.

aRPC - Antenna Remote Procedure Call Antenna remote procedure call (aRPC) is an RPC protocol focused on distributed processing and HPC. aRPC is implem

Jun 16, 2021
A Lightweight VPN Built on top of Libp2p for Truly Distributed Networks.
A Lightweight VPN Built on top of Libp2p for Truly Distributed Networks.

Hyprspace A Lightweight VPN Built on top of Libp2p for Truly Distributed Networks. demo.mp4 Table of Contents A Bit of Backstory Use Cases A Digital N

Dec 29, 2022
🌐 (Web 3.0) Pastebin built on IPFS, securely served by Distributed Web and Edge Network.
🌐 (Web 3.0) Pastebin built on IPFS, securely served by Distributed Web and Edge Network.

pastebin-ipfs 简体中文 (IPFS Archivists) Still in development, Pull Requests are welcomed. Pastebin built on IPFS, securely served by Distributed Web and

Jan 1, 2023