Connect to the server
Connect your Ruby application to a Redis database
Basic connection
Create a Redis object with the host, port, and database number of your server. The
defaults are localhost, port 6379, and database 0. If you don't pass a host, port, socket
path, or URL, the client uses the URL in the REDIS_URL environment variable, if it's set.
require "redis"
r = Redis.new(host: "localhost", port: 6379, db: 0)
Store and retrieve a string to test the connection.
r.set("foo", "bar")
# => "OK"
r.get("foo")
# => "bar"
To connect as an access control list (ACL)
user, pass username and password:
r = Redis.new(
host: "localhost",
port: 6379,
username: "default", # use your Redis user
password: "secret", # use your Redis password
)
You can also pass the connection details as a redis:// URL. If you pass other options
with url, such as password, those options override the values in the URL.
r = Redis.new(url: "redis://default:secret@localhost:6379/0")
The client URL-decodes the username and password, so you must URL-encode any special
characters in them, such as @, :, /, or +:
require "uri"
password = URI.encode_www_form_component("p@ss/word+1")
r = Redis.new(url: "redis://default:#{password}@localhost:6379")
To connect through a Unix socket, pass the socket path in path, or use a unix:// URL:
r = Redis.new(path: "/var/run/redis/redis.sock")
r = Redis.new(url: "unix:///var/run/redis/redis.sock")
Connect to a Redis cluster
Cluster support is in the separate redis-clustering gem:
gem install redis-clustering
Create a Redis::Cluster object with a list of cluster nodes. The list doesn't need to
include every node, because the client discovers the rest of the cluster from the nodes
you list.
require "redis-clustering"
rc = Redis::Cluster.new(nodes: [
"redis://localhost:16379",
"redis://localhost:16380",
"redis://localhost:16381",
])
rc.set("foo", "bar")
# => "OK"
rc.get("foo")
# => "bar"
To send read-only commands to replicas, set replica: true. Use replica_affinity to
choose a replica: :random (the default) picks a random replica, :random_with_primary
picks from the replicas and the primary, and :latency picks the replica with the lowest
latency. Replication is asynchronous, so a replica can return stale data.
rc = Redis::Cluster.new(
nodes: ["redis://localhost:16379"],
replica: true,
replica_affinity: :latency,
)
Connect to Redis Sentinel
To connect through Redis Sentinel,
pass sentinels and name to Redis.new. Set name to the name of the primary that the
Sentinels monitor. The client asks the Sentinels for the current address of the primary.
require "redis"
SENTINELS = [
{ host: "localhost", port: 26379 },
{ host: "localhost", port: 26380 },
{ host: "localhost", port: 26381 },
]
r = Redis.new(name: "mymaster", sentinels: SENTINELS)
r.set("foo", "bar")
# => "OK"
r.get("foo")
# => "bar"
The Sentinels and the data nodes have separate credentials, and neither inherits the
other's. Set sentinel_password (and sentinel_username, if your Sentinels use ACL users)
for the Sentinels, and username and password for the primary and replicas:
r = Redis.new(
name: "mymaster",
sentinels: SENTINELS,
sentinel_password: "sentinel-secret", # use your Sentinel password
username: "default", # use your Redis user
password: "secret", # use your Redis password
)
The Sentinel connections use your other options, such as the timeouts and ssl.
To connect to a replica, set role: :replica. The client connects to a random replica.
Replication is asynchronous, so a replica can return stale data, and writes fail with
Redis::ReadOnlyError.
replica = Redis.new(name: "mymaster", sentinels: SENTINELS, role: :replica)
replica.get("foo")
# => "bar"
redis-rb doesn't listen for failover announcements from the Sentinels. After a failover, the client keeps using the old primary until Sentinel reconfigures it as a replica and it starts rejecting writes. The client then reconnects to the new primary. Any writes that the old primary accepts during that time are lost.
Connect to your production Redis with TLS
When you deploy your application, use Transport Layer Security (TLS) and follow the Redis security guidelines.
Set ssl: true, or use a rediss:// URL, and pass the TLS settings in ssl_params. Set
ca_file to the certificate authority (CA) certificate that signed the server's
certificate:
r = Redis.new(
url: "rediss://default:[email protected]:6379",
ssl_params: { ca_file: "./redis_ca.pem" },
)
If the server requires clients to authenticate with a certificate, also pass the client
certificate and private key in cert and key:
r = Redis.new(
host: "my-redis.example.com",
port: 6379,
username: "default", # use your Redis user
password: "secret", # use your Redis password
ssl: true,
ssl_params: {
ca_file: "./redis_ca.pem",
cert: OpenSSL::X509::Certificate.new(File.read("./redis_user.crt")),
key: OpenSSL::PKey.read(File.read("./redis_user_private.key")),
},
)
r.set("foo", "bar")
# => "OK"
r.get("foo")
# => "bar"
cert and key also accept file paths, such as cert: "./redis_user.crt". If you use the
hiredis driver, cert and key must be file paths.
Connect with a connection pool
A Redis object holds a single connection, and a lock serializes access to it. You can
share one object between threads safely, but each thread waits for the others to finish
their commands. To run commands from several threads in parallel, use a pool of Redis
objects from the connection_pool gem:
gem install connection_pool
Create a ConnectionPool and call with to check out a connection for a block of
commands:
require "connection_pool"
require "redis"
pool = ConnectionPool.new(size: 5, timeout: 5) do
Redis.new(host: "localhost", port: 6379)
end
pool.with do |r|
r.set("foo", "bar")
r.get("foo")
end
# => "bar"
ConnectionPool::Wrapper wraps a pool in an object that you call like a Redis object.
Each method call checks out a connection for that call only, so consecutive calls can run on
different connections. Use with when several commands must run on the same connection.
redis = ConnectionPool::Wrapper.new(size: 5, timeout: 5) do
Redis.new(host: "localhost", port: 6379)
end
redis.set("foo", "bar")
redis.get("foo")
# => "bar"
See Connection pools and multiplexing for more information.
Timeouts and reconnection
The connect, read, and write timeouts default to 1 second. Set timeout to change all
three, or set connect_timeout, read_timeout, and write_timeout individually. All
values are in seconds.
r = Redis.new(
host: "localhost",
port: 6379,
connect_timeout: 0.5,
read_timeout: 2.0,
write_timeout: 2.0,
)
After a connection error, the client reconnects and retries the command once by default.
Set reconnect_attempts to an Integer to change the number of retries, or to an Array
of delays in seconds to wait before each retry:
r = Redis.new(host: "localhost", port: 6379, reconnect_attempts: [0.05, 0.25, 1.0])
A retry can run a command twice: if the connection fails after the server runs a command
but before the client reads the reply, the client sends the command again. For commands
that aren't idempotent, such as INCR or LPUSH, set reconnect_attempts: 0, or run them
inside without_reconnect:
r.without_reconnect do
r.incr("counter")
end
Protocol
Starting with redis-rb 6.0, the client uses
RESP3 (Redis serialization
protocol version 3) by default. If the server doesn't support RESP3, the client falls
back to RESP2 and prints a warning. To use RESP2, set protocol: 2:
r = Redis.new(host: "localhost", port: 6379, protocol: 2)