Awesome
Redix
Fast, pipelined, resilient Redis client for Elixir.
Redix is a Redis and Valkey client written in pure Elixir with focus on speed, correctness, and resiliency (that is, being able to automatically reconnect to Redis in case of network errors).
This README refers to the main branch of Redix, not the latest released version on Hex. Make sure to check the documentation for the version you're using.
Features
- Idiomatic interface for sending commands to Redis
- Pipelining
- Resiliency (automatic reconnections)
- Pub/Sub
- SSL
- Redis Sentinel
Installation
Add the :redix
dependency to your mix.exs
file. If you plan on connecting to a Redis server over SSL you may want to add the optional :castore
dependency as well:
defp deps do
[
{:redix, "~> 1.1"},
{:castore, ">= 0.0.0"}
]
end
Then, run mix deps.get
in your shell to fetch the new dependencies.
Usage
Redix is simple: it doesn't wrap Redis commands with Elixir functions. It only provides functions to send any Redis command to the Redis server. A Redis command is expressed as a list of strings making up the command and its arguments.
Connections are started via start_link/0,1,2
:
{:ok, conn} = Redix.start_link(host: "example.com", port: 5000)
{:ok, conn} = Redix.start_link("redis://localhost:6379/3", name: :redix)
Commands can be sent using Redix.command/2,3
:
Redix.command(conn, ["SET", "mykey", "foo"])
#=> {:ok, "OK"}
Redix.command(conn, ["GET", "mykey"])
#=> {:ok, "foo"}
Pipelines are just lists of commands sent all at once to Redis for which Redis replies with a list of responses. They can be used in Redix via Redix.pipeline/2,3
:
Redix.pipeline(conn, [["INCR", "foo"], ["INCR", "foo"], ["INCRBY", "foo", "2"]])
#=> {:ok, [1, 2, 4]}
Redix.command/2,3
and Redix.pipeline/2,3
always return {:ok, result}
or {:error, reason}
. If you want to access the result directly and raise in case there's an error, bang! variants are provided:
Redix.command!(conn, ["PING"])
#=> "PONG"
Redix.pipeline!(conn, [["SET", "mykey", "foo"], ["GET", "mykey"]])
#=> ["OK", "foo"]
Resiliency
Redix is resilient against network errors. For example, if the connection to Redis drops, Redix will automatically try to reconnect periodically at a given "backoff" interval. Look at the documentation for the Redix
module and at the "Reconnections" page in the documentation for more information on the available options and on the exact reconnection behaviour.
Redis Sentinel
Redix supports Redis Sentinel out of the box. You can specify a list of sentinels to connect to when starting a Redix
(or Redix.PubSub
) connection. Every time that connection will need to connect to a Redis server (the first time or after a disconnection), it will try to connect to one of the sentinels in order to ask that sentinel for the current primary or a replica.
sentinels = ["redis://sent1.example.com:26379", "redis://sent2.example.com:26379"]
{:ok, primary} = Redix.start_link(sentinel: [sentinels: sentinels, group: "main"])
Terminology
Redix doesn't support the use of the terms "master" and "slave" that are usually used with Redis Sentinel. I don't think those are good terms to use, period. Instead, Redix uses the terms "primary" and "replica". If you're interested in the discussions around this, this issue in the Redis repository might be interesting to you.
Pub/Sub
A Redix.PubSub
process can be started via Redix.PubSub.start_link/2
:
{:ok, pubsub} = Redix.PubSub.start_link()
Most communication with the Redix.PubSub
process happens via Elixir messages (that simulate a Pub/Sub interaction with the pub/sub server).
{:ok, pubsub} = Redix.PubSub.start_link()
Redix.PubSub.subscribe(pubsub, "my_channel", self())
#=> {:ok, ref}
Confirmation of subscriptions is delivered as an Elixir message:
receive do
{:redix_pubsub, ^pubsub, ^ref, :subscribed, %{channel: "my_channel"}} -> :ok
end
If someone publishes a message on a channel we're subscribed to:
receive do
{:redix_pubsub, ^pubsub, ^ref, :message, %{channel: "my_channel", payload: "hello"}} ->
IO.puts("Received a message!")
end
Using Redix in the Real World™
Redix is low-level, but it's still built to handle most things thrown at it. For many applications, you can avoid pooling with little to no impact on performance. Read the "Real world usage" page in the documentation for more information on this and pooling strategies that work better with Redix.
Contributing
To run the Redix test suite you will have to have Redis running locally. Redix requires a somewhat complex setup for running tests (because it needs a few instances running, for pub/sub and sentinel). For this reason, in this repository you'll find a docker-compose.yml
file so that you can use Docker and docker compose to spin up all the necessary Redis instances with just one command. Make sure you have Docker installed and then just run:
docker compose up
Now, you're ready to run tests with the $ mix test
command.
License
Redix is released under the MIT license. See the license file.