Upgrade to Pro — share decks privately, control downloads, hide ads and more …



Barrel is a database Benoit wrote from scratch over the past two years that can be embedded in an Erlang or Elixir application like Mnesia. With Barrel, you can easily bring and keep a view (complete or partial) of your data inside your application and replicate it between your different machines.
This talk will describe how you can use Barrel to quickly create your own peer-to-peer data platform with different storage and replication strategies

Benoit Chesneau

June 01, 2018

More Decks by Benoit Chesneau

Other Decks in Technology


  1. benoît chesneau craftsman working on P2P and custom data endpoints

    solution enki multimedia: the corporate interface member of the Erlang Industrial User Group about me
  2. 1. Does my service do only one thing? 2. Is

    my service autonomous? 3. Does this service own its own data? a good micro-service?
  3. sharing data update 
 and query microservice standard solution: client

    call a webservices to query and update the data problem: if connection is slow or absent the micro- service stops cloud 
  4. sharing data microservice local storage replicated always available eventually consistent

 storage update 
 and query synchronize local 
  5. library embedded in your Erlang application(*) available as a micro-service

    via HTTP(1,2) operation friendly (Wombat, OpenCensus) platform (*) including elixir or life
  6. simple API (P1 version): 
 save_doc(s), fetch_doc(s), delete_doc(s), .... multi

    storage backend: ordered Key/Value stores with snapshot support multi-backend
  7. MVCC over ETS writes are done via a single process

    garbage collection is handled in background via a process https://gitlab.com/barrel-db/memstore memory storage InternalKey(user_key="Key1", seqno=10, Type=Put) | Value = "KEY1_VAL2" InternalKey(user_key="Key1", seqno=9, Type=Put) | Value = "KEY1_VAL1" InternalKey(user_key="Key2", seqno=16, Type=Put) | Value = "KEY2_VAL2" InternalKey(user_key="Key2", seqno=15, Type=Delete) | Value = "KEY2_VAL1" InternalKey(user_key="Key3", seqno=7, Type=Delete) | Value = "KEY3_VAL1" InternalKey(user_key="Key4", seqno=5, Type=Put) | Value = "KEY4_VAL1"
  8. persisted on disk using rocksdb dirty NIF https://gitlab.com/barrel-db/erlang-rocksdb.git pure Erlang

    disk storage over leveled (https:// github.com/martinsumner/leveled ) ? disk storage
  9. automatic indexing {"headquarters:"belgium" } has path /headquarters/belgium {"exports": [{"city": “Moscow"},

    {"city": Athens"}]} has path 
 /exports/[]/city/Moscow and /exports/[]/city/Athens.

  10. a revision tree: conflict is stored on a new branch

    (based on hash histories https://dl.acm.org/ citation.cfm?id=851951 ) revision id : (level)-hash(Doc, Parent, Deleted) a winning when the leaf
 is not a deleted tombstone longest branch is the winner all revisions are replicated multiple revisions
  11. List or subscribe on document changes changes are received as

 {changes, Stream, Changes, LastSeq} Changes are received by batch at an interval set during subscription filter changes changes stream
  12. { <<"id">> : <<"someid">>, <<"seq">> : 1,
 <<"rev">> : <<"1-...">>,

    <<"doc">> : #{} } change sequence document Id revision of the document change document
  13. p2p

  14. every peers fork the master, updates are offline peers pull

    and merge from the main server peers keeps a partial view of the database (filtered replication) replication scenarios
  15. released in Q2 platform tested with partisan (but not only)

    nat traversal support:
 https://github.com/benoitc/erlang-nat find & aggregate
  16. ?