Skip to content
This repository has been archived by the owner on May 2, 2023. It is now read-only.

Commit

Permalink
Merge 3d23035 into e1e6331
Browse files Browse the repository at this point in the history
  • Loading branch information
goncalotomas committed May 9, 2018
2 parents e1e6331 + 3d23035 commit c1b571e
Show file tree
Hide file tree
Showing 48 changed files with 4,631 additions and 3,814 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,4 @@ rebar3.crashdump
tests/
.DS_Store
.idea/
config/fmke.config
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ install:
- make all
- make lint
- make xref
- make dialyzer
before_script:
- epmd -daemon
- sudo sh -c 'echo 0 > /proc/sys/net/ipv6/conf/all/disable_ipv6'
script:
- make test
- make test-multiple-releases
- rebar3 as test coveralls send
# - make bench
after_failure:
Expand Down
25 changes: 2 additions & 23 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
REBAR = rebar3
REBAR=rebar3
BENCH=_build/test/lib/lasp_bench

all: compile rel
Expand Down Expand Up @@ -33,7 +33,6 @@ bench-riak-norm: rel

compile:
${REBAR} as test compile
cd ./_build/test/lib/lasp_bench && rebar3 escriptize

console: rel
./_build/default/rel/fmke/bin/env console
Expand Down Expand Up @@ -87,7 +86,7 @@ shell-riak: rel
./scripts/start_data_store.sh riak
./_build/default/rel/fmke/bin/env console

start:
start: rel
./scripts/start_fmke.sh

start-antidote: select-antidote
Expand Down Expand Up @@ -121,25 +120,5 @@ test: all
rebar3 eunit
rebar3 ct

test-multiple-releases:
rm -rf _build/default/rel
./scripts/start_data_store.sh antidote
./scripts/config/change_http_port.sh 9090
./scripts/config/change_db.sh antidote
./scripts/config/change_db_ports.sh antidote
${REBAR} release -n fmke
./_build/default/rel/fmke/bin/env start
sleep 10
./scripts/config/change_http_port.sh 9190
${REBAR} release -n fmke_test
./_build/default/rel/fmke_test/bin/env_test start
sleep 10
./scripts/populate_fmke.escript "antidote" "../config/benchmark_short.config" "fmke_test@127.0.0.1"
_build/test/lib/lasp_bench/_build/default/bin/lasp_bench config/benchmark_short.config
./scripts/config/change_http_port.sh 9090
./_build/default/rel/fmke/bin/env stop
./_build/default/rel/fmke_test/bin/env_test stop
./scripts/stop_data_store.sh antidote

xref:
rebar3 xref
17 changes: 9 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
# FMKe [![Build Status](https://travis-ci.org/goncalotomas/FMKe.svg?branch=master)](https://travis-ci.org/goncalotomas/FMKe) [![Coverage Status](https://coveralls.io/repos/github/goncalotomas/FMKe/badge.svg?branch=master)](https://coveralls.io/github/goncalotomas/FMKe?branch=master)
# FMKe
![Erlang Version](https://img.shields.io/badge/Erlang%2FOTP-20-brightgreen.svg)
[![Build Status](https://travis-ci.org/goncalotomas/FMKe.svg?branch=master)](https://travis-ci.org/goncalotomas/FMKe)
[![Coverage Status](https://coveralls.io/repos/github/goncalotomas/FMKe/badge.svg?branch=master)](https://coveralls.io/github/goncalotomas/FMKe?branch=master)
![Dialyzer Enabled](https://img.shields.io/badge/dialyzer-enabled-brightgreen.svg)

FMKe is an extendable real world benchmark for distributed key-value stores.
This repository contains code for the application server and a set of scripts for orchestrating deployment and local execution of micro-benchmarks.
Expand Down Expand Up @@ -33,13 +37,10 @@ Firstly, separating the application server from the workload generation componen
We have a generic interface for key-value stores (implemented as an Erlang behaviour) that is well specified, which makes supporting a new database as simple as writing a driver for it. Furthermore, pull requests with new drivers or optimizations for existing ones are accepted and welcomed.

## Supported data stores
- AntidoteDB (using nested CRDTs)
- AntidoteDB (with a normalized data model)
- Riak (using nested CRDTs)
- Redis (with a normalized data model)
### In a future release
- Lasp

- AntidoteDB
- Cassandra
- Redis
- Riak KV

## How the benchmark is deployed
By default FMKe keeps a connection pool to a single database node, and the workload generation is performed by [Lasp Bench][4].
Expand Down
32 changes: 28 additions & 4 deletions config/fmke.config
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,46 @@
%% (1): ["192.168.1.1", "192.168.1.2"]
%% (2): [{192,168,1,1} {192,168,1,2}]
%% (3): "192.168.1.1 192.168.1.2"
%% If you're connecting to multiple nodes on the same port, you can list all of the different addresses here and leave
%% a single entry in the database_ports option (e.g. [8087]).
{database_addresses, ["127.0.0.1"]}.

%% List of ports where FMKe should try to connect at boot time.
%% NOTE: Must use one of the following structures:
%% (1): ["8080", "8081"]
%% (2): [8080, 8081]
%% (3): "8080 8081"
%% If you're connecting to multiple nodes on the same address but on different ports, you can list all of the different
%% ports here and leave a single entry in the database_addresses option (e.g. ["127.0.0.1"]).
{database_ports, [8087]}.

%% Target back end data store. This is required in order for FMKe to load the
%% correct drivers to connect to your desired data store.
%% Currently FMKe supports the following data stores:
%% antidote, riak_kv
%% antidote, riak, redis
%% Please select one of the previous values in the form of an erlang atom
%% (e.g. riak) or string (e.g. "riak")
{target_database, antidote}.
{target_database, riak}.

%% Uses an optimized driver that implements the entire FMKe API (only if implemented).
%% Currently these are available for antidote, riak and redis. You're welcome to implement a new one and submit a
%% pull request!
%% Predictably, this defaults to false, so you only need to specify this option when you want to use an optimized driver
%% implementation.
% {optimized_driver, true}.

%% Changes the data model, if the available drivers support it.
%% For key value stores, we consider the possible values to be nested or non_nested, depending on whether the database
%% keeps references to other objects, or copies of other objects that must be updated on each update to the original.
%% The gen_fmke_kv_driver behaviour specifies the start/1 callback for all drivers implemented with this behaviour, and
%% the argument to the start function is the value of this option. We recommend you also implement the gen_server
%% behaviour and keep it in the state, or put it inside an ETS table (but you must check it's value for each relevant
%% get or put operation).
%% When implementing drivers it might make sense to look at how other previous ones were made and attempt to replicate
%% the logic inside them.
%% NOTE: Usually optimized drivers only support one data model (the one that yields the best performance), so please
%% keep this line commented when measuring performance with optimized drivers.
% {data_model, nested}.

%% When FMKe connects to the database you choose it opens a pool of connections.
%% This parameter configures the connection pool size.
Expand All @@ -28,6 +52,6 @@
%% open 15 connections to each database node.
{connection_pool_size, 30}.

%% The HTTP port to which the FMKe HTTP server binds to. Running on a system
%% reserved port interval (1-2048) will require superuser privileges.
%% The port on which the FMKe HTTP server binds to. Running on a system
%% reserved port (0-1023) will require superuser privileges.
{http_port, 9090}.
15 changes: 9 additions & 6 deletions elvis.config
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@
{elvis_style, macro_names, #{ignore => []}},
{elvis_style, macro_module_names},
{elvis_style, operator_spaces, #{rules => [
{right, ","}, {right, "++"}, {left, "++"}, {right, "--"}, {left, "--"}
{right, "++"}, {left, "++"}, {right, "--"}, {left, "--"}
]}},
{elvis_style, nesting_level, #{level => 3}},
{elvis_style, nesting_level, #{level => 4}},
{elvis_style, god_modules, #{limit => 30, ignore => []}},
{elvis_style, no_if_expression},
{elvis_style, invalid_dynamic_call, #{ignore => [
fmke, fmke_kv_driver, fmke_db_connection
fmke, fmke_db_connection, fmke_pt_adapter, fmke_kv_adapter
]}},
{elvis_style, used_ignored_variable},
{elvis_style, no_behavior_info},
Expand All @@ -27,8 +27,8 @@
% {elvis_style, state_record_and_type, disable},
{elvis_style, state_record_and_type},
{elvis_style, no_spec_with_records},
{elvis_style, dont_repeat_yourself, #{min_complexity => 30}},
{elvis_style, no_debug_call, #{ignore => [fmke_test_utils]}}],
{elvis_style, dont_repeat_yourself, #{min_complexity => 40}},
{elvis_style, no_debug_call, #{ignore => [fmke_test_setup]}}],
%% sequential reporter calls other reporters dynamically
% {elvis_style, invalid_dynamic_call, #{ignore => [oc_sequential_reporter]}}],

Expand All @@ -39,10 +39,13 @@
rules => [{elvis_style, god_modules, #{ignore => [egithub]}},
{elvis_style, dont_repeat_yourself, #{min_complexity => 30}},
{elvis_style, line_length, #{limit => 120}},
{elvis_style, operator_spaces, #{rules => [
{right, "++"}, {left, "++"}, {right, "--"}, {left, "--"}
]}},
%% be a bit more lax on naming for tests
{elvis_style, variable_naming_convention, #{regex => "^_{0,2}([A-Z][0-9a-zA-Z]*)$"}},
{elvis_style, state_record_and_type, disable},
{elvis_style, no_debug_call, #{ignore => [fmke_test_utils]}}],
{elvis_style, no_debug_call, #{ignore => [fmke_test_setup]}}],
ruleset => erl_files
},
#{dirs => ["."],
Expand Down
55 changes: 37 additions & 18 deletions include/fmke.hrl
Original file line number Diff line number Diff line change
@@ -1,43 +1,44 @@
-define (APP, fmke).
-define (OPTIONS, [adapter, connection_pool_size, database_addresses, database_ports, http_port, target_database]).
-define (OPTIONS, [
adapter, connection_pool_size, database_addresses, database_ports, http_port,
target_database, data_model, optimized_driver
]).
-define (DEFAULTS, #{
adapter => fmke_ndm_adapter,
adapter => fmke_kv_adapter,
connection_pool_size => 64,
database_addresses => ["127.0.0.1"],
database_ports => [8087],
http_port => 9090,
target_database => antidote
target_database => riak,
data_model => nested,
optimized_driver => false
}).

-define (TIMEOUT, 60000).
-define(TIMEOUT, 60000).

-define (CONFIG_FILE_PATH, "/config/fmke.config").
-define(CONFIG_FILE_PATH, "/config/fmke.config").
-define(ETS_TABLE_NAME, fmke_ets).

%% TODO move this to an ETS table
-define(SUPPORTED_DBS, [antidote, antidote_norm, riak_kv, riak_kv_norm, redis]).
-define(SUPPORTED_KVS, [antidote, antidote_norm, riak_kv, riak_kv_norm, redis]).

-type id() :: non_neg_integer().
-type field() :: binary().
-type reason() :: term().
-type crdt() :: term().

-record(prescription, {
id :: id()
,patient_id :: id()
,pharmacy_id :: id()
,prescriber_id :: id()
id :: id() | binary()
,patient_id :: id() | binary()
,pharmacy_id :: id() | binary()
,prescriber_id :: id() | binary()
,date_prescribed :: field()
,date_processed = <<"undefined">> :: field()
,drugs :: list(field())
,drugs :: list(string() | binary())
,is_processed = <<"prescription_not_processed">> :: field()
}).

-record(patient, {
id :: id()
,name :: string()
,address :: string()
,prescriptions = [] :: list(#prescription{})
,prescriptions = [] :: list(#prescription{} | key())
% ,treatments=[] :: list(#treatment{})
% ,events=[] :: list(#event{})
}).
Expand All @@ -46,7 +47,7 @@
id :: id()
,name :: string()
,address :: string()
,prescriptions = [] :: list(#prescription{})
,prescriptions = [] :: list(#prescription{} | key())
}).

-record(facility, {
Expand All @@ -63,5 +64,23 @@
,name :: string()
,address :: string()
,speciality :: string()
,prescriptions = [] :: list(#prescription{})
,prescriptions = [] :: list(#prescription{} | key())
}).

-type id() :: non_neg_integer().
-type field() :: binary().
-type reason() :: term().
-type crdt() :: term().
-type app_record() :: #facility{} |
#patient{} |
#pharmacy{} |
#prescription{} |
#staff{}.
-type entity() :: facility | patient | pharmacy | prescription | staff.
-type key() :: binary().

-type facility() :: #facility{}.
-type patient() :: #patient{}.
-type pharmacy() :: #pharmacy{}.
-type prescription() :: #prescription{}.
-type staff() :: #staff{}.
File renamed without changes.
File renamed without changes.
20 changes: 1 addition & 19 deletions rebar.config
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,6 @@
{erl_opts, [no_debug_info, warnings_as_errors]},
{relx, [{dev_mode, false}]}
]},
{test, [
{erl_opts, [debug_info]},
{deps, [
{hackney, "1.9.0"},
{lasp_bench, {git, "https://github.com/lasp-lang/lasp-bench", {tag, "fmke"}}}
]}
]},
{lint, [
{plugins, [
{rebar3_lint, {git, "https://github.com/project-fifo/rebar3_lint.git", {tag, "v0.1.9"}}}
Expand All @@ -57,18 +50,7 @@
{copy, "config/fmke.config", "config/fmke.config"}
]},
{overlay_vars, "config/vars.config"},
{extended_start_script, true}]},

{release, {fmke_test, "0.1.0"}, [fmke], [
{vm_args, "config/vm_test.args"},
{dev_mode, true},
{include_erts, false},
{overlay, [
{copy, "bin/env_test", "bin"},
{copy, "config/fmke.config", "config/fmke.config"}
]},
{overlay_vars, "config/vars_test.config"},
{extended_start_script, true}]}
{extended_start_script, true}]}
]}.

{xref_checks, [
Expand Down
16 changes: 15 additions & 1 deletion scripts/populate_fmke.escript
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
-mode(compile).
-define(ZIPF_SKEW, 1).
-define(NUMTHREADS, 30).
-define(DIVERGENCE_TIMEOUT, 10).
-define(MAX_RETRIES, 10).

-record(fmkeconfig, {
Expand Down Expand Up @@ -171,9 +172,22 @@ add_prescription_rec(Nodes, PrescriptionId, ListPatientIds, FmkConfig, Ops) ->
PharmacyId = rand:uniform(FmkConfig#fmkeconfig.numpharmacies),
PrescriberId = rand:uniform(FmkConfig#fmkeconfig.numstaff),
Node = lists:nth(PrescriptionId rem length(Nodes) + 1, Nodes),
ok = run_op(Node, create_prescription, [PrescriptionId, CurrentId, PrescriberId, PharmacyId, gen_random_date(), gen_random_drugs()]),
OpArgs = [PrescriptionId, CurrentId, PrescriberId, PharmacyId, gen_random_date(), gen_random_drugs()],
Result = run_op(Node, create_prescription, OpArgs)
case divergence_failure(Result) of
false ->
ok;
true ->
timer:sleep(?DIVERGENCE_TIMEOUT * 1000),
ok = run_op(Node, create_prescription, OpArgs)
end,
add_prescription_rec(Nodes, PrescriptionId - 1, Tail, FmkConfig, Ops + 1).

divergence_failure(ok) -> false;
divergence_failure({error, no_such_patient}) -> true;
divergence_failure({error, no_such_pharmacy}) -> true;
divergence_failure({error, no_such_staff}) -> true.

run_op(FmkNode, create_pharmacy, Params) ->
[_Id, _Name, _Address] = Params,
run_rpc_op(FmkNode, create_pharmacy, Params);
Expand Down
2 changes: 2 additions & 0 deletions src/fmke.app.src
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
{applications,
[kernel,
stdlib,
runtime_tools,
tools,
poolboy,
lager,
cowboy,
Expand Down
Loading

0 comments on commit c1b571e

Please sign in to comment.