Elixir + Phoenix + Amnesia + Multi-node

Jonathan Merriweather
3 min readNov 8, 2016

--

I’ve recently setup Amnesia with multi-node elixir environment. I’ve written up the process for future reference.

Test Project

Lets setup a test phoenix project that we can use to play with Amnesia

# mix phoenix.new blogpost_amnesia --no-ecto

Connect Nodes

Before we get to Amnesia we’ll need to get our nodes talking to each other. I’ll setup two nodes running on the local machine.

To do that we first need to make it so that phoenix will let us specify the port in the dev environment, go to config/dev.exs and change the http setting as follows:

Now that we can launch two instances of phoenix on separate ports, we need tell Elixir to connect the nodes.

To do this we’ll add a sys.config to the root of our project specifying our nodes. The sys.config will tell the Erlang virtual machine to optionally connect to the nodes specified in the sync_nodes_optional list

We should now be able to run two instances of phoenix that are connected

start separate phoenix nodes on Linux
start separate phoenix nodes on Windows

Now we can use Node.list to check that the nodes can see each other

Add Amnesia as a mix dependency

In mix.exs add {:amnesia, “~> 0.2.5”} to the deps list

then run

mix deps.get

Creating an Amnesia database

Now that we have multi-node phoenix setup, lets create an Amnesia database to work with.

Lets create a file called database.ex under the web/models folder

In database.ex paste in the following example database from the Amnesia README

How to create our Amnesia database on both Elixir nodes

There are five steps to create an Amnesia database on multiple nodes

  1. Ensure both nodes are running and able to see each other
  2. Stop Amnesia on both nodes
  3. Create a schema from our database
  4. Start Amnesia on both nodes
  5. Create tables from our database

Ensure both nodes are running and able to see each other

Although it is possible to add nodes to the Amnesia database later, it is much easier to just create the schema and tables with the nodes we require. Lets make life easier and check both nodes are talking:

Stop Amnesia on both nodes

A schema is required if we will be persisting the Amnesia database to disk, to do that we must first stop Amnesia on both nodes.

Create schema from our database

Learn You Some Erlang explains why we need a schema:

To know how to store tables on disk, how to load them, and what other nodes they should be synchronized with, Mnesia needs to have something called a schema

We’ll now go ahead and create the schema, we only need to do this from one of the nodes.

We should now have two new folders in our root directory

Start Amnesia on both nodes

Now that we have a schema we can go ahead and start back up Amnesia

Create tables from our database

Now that we have a schema and Amnesia started again we can create our database tables. In this example I’m going to be using disk copies which means the tables will be stored in RAM as well as persisted to disk. This should only be run from one node.

Done

We’ve now successfully created a multi-node Amnesia database. To confirm that we can run the following in iex:

:mnesia.info

We should get a response as follows:

What next?

I’ll probably post about the following two items when i get a chance:

  1. Creating a new table in an established database
  2. Transforming an existing table. For example, if you need to add an additional attribute to a table

Repo

You can see the repo for this post here: https://github.com/jmerriweather/blogpost_amnesia

References

Chris McCord’s Phoenix Presence Example - simple example of how to connect two nodes https://github.com/chrismccord/phoenix_presence_example

Learn You Some Erlang - Great resource for learning about mnesia http://learnyousomeerlang.com/mnesia

Meh’s Amnesia - mnesia wrapper for Elixir https://github.com/meh/amnesia

--

--