jemc / jylis

A distributed in-memory database for Conflict-free Replicated Data Types (CRDTs). :seedling: :left_right_arrow:
https://jemc.github.io/jylis
Mozilla Public License 2.0
74 stars 6 forks source link

Replicated data is not synced to disk #10

Closed amclain closed 6 years ago

amclain commented 6 years ago

When using disk persistence and intentionally causing a partition split, I noticed that data written on one side of the split is not synced to disk on the nodes on the other side of the split after the partition has been repaired and replication has completed. This could cause problems if the nodes on one side of a split are restarted during the split, as they would lose the data they had replicated from the other side of the partition. I have set up an example to reproduce the issue.

Steps To Reproduce

version: "3"
services:
  db1:
    image: jemc/jylis
    ports:
      - "6379:6379"
    volumes:
      - ./data1:/data
    command:
      - "--disk-dir=/data"
      - "--addr=db1:9999:db1"

  db2:
    image: jemc/jylis
    ports:
      - "6382:6379"
    volumes:
      - ./data2:/data
    command:
      - "--disk-dir=/data"
      - "--addr=db2:9999:db2"
      - "--seed-addrs=db1:9999:db1"
    links:
      - db1
      - db3

  db3:
    image: jemc/jylis
    ports:
      - "6383:6379"
    command:
      - "--addr=db3:9999:db3"
      - "--seed-addrs=db1:9999:db1"
    links:
      - db1

  cli1:
    image: redis:4.0-alpine
    restart: "no"
    command: redis-cli -h db1
    links:
      - db1

  cli2:
    image: redis:4.0-alpine
    restart: "no"
    command: redis-cli -h db2
    links:
      - db2

  cli3:
    image: redis:4.0-alpine
    restart: "no"
    command: redis-cli -h db3
    links:
      - db3
$ mkdir data1
$ mkdir data2
db2:
  image: jemc/jylis
  ports:
    - "6382:6379"
  volumes:
    - ./data2:/data
  command:
    - "--disk-dir=/data"
    - "--addr=db2:9999:db2"
  #   - "--seed-addrs=db1:9999:db1"
  # links:
  #   - db1
  #   - db3
jemc commented 6 years ago

Thanks for the very detailed steps to reproduce.

I'll make sure this is fixed and that we have a regression test for it before the 1.0 version.

jemc commented 6 years ago

Just to check though, considering my comment here: https://github.com/jemc/jylis/pull/11#discussion_r194225412

Have you confirmed that setting up one-directional links in docker-compose actually allows Jylis to establish a bidirectional link between nodes? Note that each node in the cluster needs to be able to connect to the declared addr of each other node.

I haven't read through the entire steps to reproduce in this ticket yet, but having only uni-directional links between nodes could potentially explain some issues with partition tolerance

I can check this myself a bit later if I haven't heard back from you by then.

amclain commented 6 years ago

Have you confirmed that setting up one-directional links in docker-compose actually allows Jylis to establish a bidirectional link between nodes?

Yes, the links are bidirectional. Adding the links in both directions results in an error: ERROR: Circular dependency between db3 and db2

amclain commented 6 years ago

I noticed something else as well: The replicated data is being stored on disk after replication and there is a PDAT command in the file with the MVREG command following it. Maybe that's being skipped over when the file is read?