Elixir + Phoenix + Amnesia + Multi-node
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
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
- Ensure both nodes are running and able to see each other
- Stop Amnesia on both nodes
- Create a schema from our database
- Start Amnesia on both nodes
- 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:
- Creating a new table in an established database
- 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