Redis To Go
Last updated January 23, 2020
Table of Contents
RedisToGo is an add-on for providing functionality for Redis with graphs, backups, persistence and fine-tuned Redis. We currently support over 53,000 Redis instances, we’re here to help you rock your app with Redis goodness.
Redis is a key-value store similar to memcached, but non-volatile; it supports lists, hashes, sets, and ordered sets.
Adding Redis to an application provides benefits, you may be using RedisToGo to power simple Resque or Sidekiq jobs, or using the raw power of Redis 2.6 Lua Scripting to do some crazy fast operations. Redis can be used a database, but it’s often used as a complementary datastore. With over 140 commands, the possibilities are endless.
RedisToGo is accessible via an API and has supported client libraries for Java, Ruby, Python, Node.js, Clojure, GoLang.
Provisioning the add-on
RedisToGo can be attached to a Heroku application via the CLI:
A list of all plans available can be found here.
$ heroku addons:create redistogo
-----> Adding RedisToGo to fat-unicorn-1337... done, v18 (free)
Once RedisToGo has been added a ADDON_CONFIG_NAME
setting will be available in the app configuration. This can be confirmed using the heroku config:get
command.
$ heroku config --app fat-unicorn-1337 | grep REDISTOGO_URL
REDISTOGO_URL => redis://redistogo:44ec0bc04dd4a5afe77a649acee7a8f3@drum.redistogo.com:9092/
After installing RedisToGo the application should be configured to fully integrate with the add-on.
Using with Rails 2.3.3
For Rails 2.3.3 and higher, update the config/environment.rb
to include the
redis
gem.
config.gem 'redis'
If using Rails 3, update the Gemfile:
gem 'redis'
Setup the Redis connection information for development in
config/environments/development.rb
ENV["REDISTOGO_URL"] = 'redis://username:password@my.host:6389'
Configure Redis in config/initializers/redis.rb
for versions before Rails 4
uri = URI.parse(ENV["REDISTOGO_URL"])
REDIS = Redis.new(:host => uri.host, :port => uri.port, :password => uri.password)
If you are running Rails 4 then run the following
uri = URI.parse(ENV["REDISTOGO_URL"])
REDIS = Redis.new(:url => uri)
Test that it works in the console.
$ rails console
>> REDIS.set("foo", "bar")
"OK"
>> REDIS.get("foo")
"bar"
Using Redis from Java
There are several Java libraries available for connecting to Redis, including Jedis and JRedis. This guide will shows to use Jedis from both a generic Java application and a Spring configured application.
Add Jedis to dependencies
Include the Jedis library in your application by adding the following dependency to pom.xml
:
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.0.0</version>
</dependency>
Use Redis in your Java application
The connection information for the Redis Service provisioned by Redis To Go is stored as a URL in the REDISTOGO_URL
config var. You can create a Jedis connection pool from this URL string with the following code snippet:
try {
URI redisURI = new URI(System.getenv("REDISTOGO_URL"));
JedisPool pool = new JedisPool(new JedisPoolConfig(),
redisURI.getHost(),
redisURI.getPort(),
Protocol.DEFAULT_TIMEOUT,
redisURI.getUserInfo().split(":",2)[1]);
} catch (URISyntaxException e) {
// URI couldn't be parsed. Handle exception
}
Now you can use this pool to perform Redis operations. For example:
Jedis jedis = pool.getResource();
try {
/// ... do stuff here ... for example
jedis.set("foo", "bar");
String foobar = jedis.get("foo");
jedis.zadd("sose", 0, "car"); jedis.zadd("sose", 0, "bike");
Set<String> sose = jedis.zrange("sose", 0, -1);
} finally {
/// ... it's important to return the Jedis instance to the pool once you've finished using it
pool.returnResource(jedis);
}
(example taken directly from Jedis docs).
Using Redis with Spring
Use the following Java Configuration class to set up a JedisPool
instance as a singleton Spring bean:
@Configuration
public class SpringConfig {
@Bean
public JedisPool getJedisPool() {
try {
URI redisURI = new URI(System.getenv("REDISTOGO_URL"));
return new JedisPool(new JedisPoolConfig(),
redisURI.getHost(),
redisURI.getPort(),
Protocol.DEFAULT_TIMEOUT,
redisURI.getUserInfo().split(":",2)[1]);
} catch (URISyntaxException e) {
throw new RuntimeException("Redis couldn't be configured from URL in REDISTOGO_URL env var:"+
System.getenv("REDISTOGO_URL"));
}
}
}
or the following XML configuration file:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:annotation-config/>
<context:property-placeholder/>
<bean id="jedisURI" class="java.net.URI">
<constructor-arg value="${REDISTOGO_URL}"/>
</bean>
<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig"/>
<bean id="jedisPool" class="redis.clients.jedis.JedisPool">
<constructor-arg index="0" ref="jedisPoolConfig"/>
<constructor-arg index="1" value="#{ @jedisURI.getHost() }"/>
<constructor-arg index="2" value="#{ @jedisURI.getPort() }"/>
<constructor-arg index="3" value="#{ T(redis.clients.jedis.Protocol).DEFAULT_TIMEOUT }"/>
<constructor-arg index="4" value="#{ @jedisURI.getUserInfo().split(':',2)[1] }"/>
</bean>
</beans>
Sample Java code
To see a complete, working example, check out the sample code in github. The readme explains more about the example.
Install Redis in Python
The redis-py module is the best way to access Redis from Python.
To install it, use pip:
$ pip install redis
And to have your application depend on it, add the following to requirements.txt
:
$ pip freeze | grep redis
redis==2.4.13
Using from Python
Example store.py
:
import os
import redis
redis_url = os.getenv('REDISTOGO_URL', 'redis://localhost:6379')
redis = redis.from_url(redis_url)
Using with bottlepy
redistogo_url = os.getenv('REDISTOGO_URL', None)
if redistogo_url == None:
redis_url = '127.0.0.1:6379'
else:
redis_url = redistogo_url
redis_url = redis_url.split('redis://redistogo:')[1]
redis_url = redis_url.split('/')[0]
REDIS_PWD, REDIS_HOST = redis_url.split('@', 1)
redis_url = "%s?password=%s" % (REDIS_HOST, REDIS_PWD)
session_opts = { 'session.type': 'redis', 'session.url': redis_url, 'session.data_dir': './cache/', 'session.key': 'appname', 'session.auto': True, }
Deploying to Heroku
To use Redis To Go on Heroku, install the redistogo add-on:
$ heroku addons:create redistogo
Test that it works from the Heroku console:
$ heroku run python
Python 2.7.2 (default, Oct 31 2013, 16:22:04)
>>> from store import redis
>>> redis.set('answer', 42)
True
>>> redis.get('answer')
'42'
Using as a Django cache
Redis can also be used with the Django cache backend.
To do so, install the Django :
$ pip install django-redis-cache
Then, add the following to your settings.py
file:
import os
import urlparse
redis_url = urlparse.urlparse(os.environ.get('REDISTOGO_URL', 'redis://localhost:6959'))
CACHES = {
'default': {
'BACKEND': 'redis_cache.RedisCache',
'LOCATION': '%s:%s' % (redis_url.hostname, redis_url.port),
'OPTIONS': {
'DB': 0,
'PASSWORD': redis_url.password,
}
}
}
Using with Node.js
When node_redis connects to a Redis instance on your local machine it assumes the default port and host information, so instantiating the client is as simple as this:
var redis = require("redis").createClient();
That works just fine in development, but we need it to authenticate to Redis To Go in production. To handle both cases I just check for the existence of the REDISTOGO_URL
, like so:
if (process.env.REDISTOGO_URL) {
// TODO: redistogo connection
} else {
var redis = require("redis").createClient();
}
Everything should still work fine in development, but we still need to implement the Redis To Go connection. To do this we need to extract the port, hostname, and authentication string from REDISTOGO_URL using Node’s built-in url lib:]
// inside if statement
var rtg = require("url").parse(process.env.REDISTOGO_URL);
var redis = require("redis").createClient(rtg.port, rtg.hostname);
redis.auth(rtg.auth.split(":")[1]);
For some reason Node’s url lib won’t split up the auth section’s username and password, so that’s what is going on in the rtg.client.auth.split(":")[1]
that is passed to the auth command.
Redis-related entries I have in my package.json are hiredis (0.1.10)
and redis (0.6.0)
.
GoLang
We recommend using redigo to connect to RedisToGo.
Redis 3.2
All new RedisToGo instances run with 3.2.12 as default. Higher versions are not available at this time. If you have any questions about this, please feel free to contact Support@RedisToGo.com.
Lua
Lua is the business. In short Lua lets you run application code on the server.
Redis Sentinel
We can offer Redis Sentinel configured HA environments for high volume accounts. Please contact support@redistogo.com for more information and a consultation.
Monitoring & Logging
We offer monitoring and logging on a per account basis. We’ll inform our customers when they start to reach memory and connection limits.
If you’re using Redis for resque
we recommend using Airbrake, please read this blog post for more instructions on setting up error
Dashboard
For more information on the features available within the RedisToGo dashboard please see the docs at redistogo.com/documentation .
The RedisToGo dashboard allows you to view config, display graphs, retrieve backups.
The dashboard can be accessed via the CLI:
$ heroku addons:open redistogo
Opening RedisToGo for fat-unicorn-1337…
or by visiting the Heroku Dashboard and selecting the application in question. Select RedisToGo from the Add-ons menu.
Troubleshooting
Why am I hitting my connection limit with one Dyno?
This is often caused by customers using the nano
free plan. One connection is used by one worker, but often other connections can be made to Redis. We would recommend upgrading to our lowest plan to see if this solves the issue. Otherwise we would recommend setting a hard limit on your application code.
Migrating between plans
Application owners should carefully manage the migration timing to ensure proper application function during the migration process.
WARNING: Upgrades from ‘nano’ to Mini will lose data. If you would like to keep data please e-mail support@redistogo.com
Use the heroku addons:upgrade
command to migrate to a new plan.
$ heroku addons:upgrade redistogo:mini
-----> Upgrading RedisToGo:newplan to fat-unicorn-1337... done, v18 ($49/mo)
Your plan has been updated to: RedisToGo:newplan
This may fail if the server is full, if this happens please e-mail support@redistogo.com and we can help you out.
Removing the add-on
RedisToGo can be removed via the CLI.
This will destroy all associated data and cannot be undone!
$ heroku addons:destroy redistogo
-----> Removing RedisToGo from fat-unicorn-1337... done, v20 (free)
Before removing RedisToGo a data export can be performed by going to the backups tab of RedisToGo https://redistogo.com/heroku/resources/[instance-ID]/backups
this will offer a download a .rdb
, backup file.
Support
All RedisToGo support and runtime issues should be submitted via on of the Heroku Support channels. We recommend CC:ing support@redistogo.com for urgent issues.
We are available on twitter, and you can keep up-to-date on status issues at status.redistogo.com