What is redis and how to use it in rails ...
brew install redis
on OSXbrew services start redis
redis-server /usr/local/etc/redis.conf
(use!)gem install redis
Create a simple app using scaffold Snippet content:text
In this example, redis will be used to load snippets from Rails rather than using a SQL db.
For loading a page that contains many records, it may take a very long time to load, Redis can be used to load the records drastically faster
Once the app is created and migrations are ran, install the following gems:
gem 'rack-mini-profiler'
: displays loading time in upper left corner of browsergem 'faker'
: used to fill in dummy data to create records faster#example of using faker in seed.db
100000.times do
Snippet.create(content: Faker::Lorem.paragraph)
end
bundle install
bundle exec rake db:seed
Change root to snippets#index
Run rails s
Notice the loading time of rack-mini-profiler!
redis-server
redis-server /usr/local/etc/redis.conf
Gemfile
:
gem 'redis'
gem 'redis-rails'
bundle install
config/development.rb
, you can instruct Rails to use redis as a cache store: (or even production.rb
)module nameOfApp
class Application < Rails::Application
config.cache_store = :redis_store, 'redis://localhost:6379/0/cache', {expires_in: 90.minutes}
# redis has 16 databases to choose from (0-15), represents the 0 before cache
# cache represents the namespace
# you can configure host, port and other db:
# Redis.new(:host => '10.0.1.1', :port => 6380, :db => 15)
# Alternatively:
config.cache_store = :redis_store, {
host: 'localhost',
port: 6379,
db: 0,
namespace: 'cache'
}
end
end
#include the controller helper folder, code will be ran inside there
# example SnippetsController.rb
def index
@data = fetch_snippets
end
#helpers/snippets_helper.rb
module SnippetsHelper
def fetch_snippets
snippets = $redis.get("snippets")
if snippets.nil?
#IMPORTANT:
# the first time around snippets will be nil, redis hasn't put anything in yet
snippets = Snippet.all.to_json
#Now redis is inserting the array of snippets in a hash with key "snippets"
# from the database access, so that next time it can just bypass the db and use its store
$redis.set("snippets", snippets)
#Expire the cache every 5 hours
$redis.expire("snippets", 5.hour.to_i)
end
JSON.load snippets
end
end
#Update the views
<% @data.each do |snippet| %>
<%= snippet["content"] %>
<% end %>
JSON.load
after_save
validation on the model being cached:#example of categories being cached
class Category
after_save: :clear_cache
def clear_cache
$redis.del "categories"
end
end
gem 'redis-rails'
# setting a key/value pair
redis.set("key", "value")
# retrieving a value
redis.get("key")
#=> "value"
# in your rails app, view template
<% cache 'word-of-the-hour', :expires_in => Time.now.beginning_of_hour + 1.hour do %>
<%= %w(ruby rails javascript web developer).sample %>
<% end %>
# Every hour, redis will empty the cache and set a new value for the key
redis server
redis-cli
127.0.0.1:6379
, default port is 6379# set key value
set name parm
# get value from key
get name
# => parm
cd
in to the directory where you downloaded redisredis.config
, find section for Snapshotting
, read the info on how to configure
the snapshot after x sec with atleast x amount of changesappendonly
and change no
to yes
redis-server /usr/local/etc/redis.conf
redis2.conf
3780
slaveof
and replace with: slaveof 127.0.0.1 6379
, slave of redis.config
redis2.conf
filemaster-slave relation has started
.conf
filesrequirepass enterpass
, replace enterpass
with a password, make sure slave is updated
with the same password in the location of masterauth
redis-cli -a password
, entering the password
that was set in the .conf
file.set address 435
incr address #increment by 1
# => 436
incrby address 100 #increment by x
#decrement
decr address
decrby address
# For multiple words for a value, USE DOUBLE QUOTES!!
set country "North America"
#getset is used to get a key and then set it, returns original key
getset firstName "Parm"
#set multiple values:
mset street blah city blah2 state blah3 zip "blah4"
#retrieve those values:
mget street city state zip
#check if something exists:
exists street
# returns 1 for yes it exists, 0 else
#delete a key
del street
#expire a key in x sec
exp city 5
#set and expires
set zip "989-899989" ex 9
#creating a hash:
hmset nameofhash key1 value1 key2 value2 ...
#retrieve the hash:
hgetall nameofhash
#retrieve a certain value in the hash:
hget nameofhash key1
#retrieve multiple values
hmget nameofhash key1 key2
#exist?
hexist nameofhash key1
#set another key
hmset nameofhash keyx valuex
#increment
hincrby nameofhash key numtoincrementby
#creates a new list (right push appends to bottom of list)
rpush nameoflist value1 value2 value3 ...
#list the list
lrange nameoflist startindex stopindex
#startindex is usually 0!
# -1 all
# -2 all except the last one
# -3 all except the last 2
#append to the BEGINNING of a list (left push)
lpush nameoflist valuex
#remove (left pop)
lpop nameoflist
#right pop (removes at the end of the list)
rpop nameoflist
#trimming a list
ltrim nameoflist starti stopi
#ex ltrim grocery 0 2
# lrange 0 -1 to see the new list
#creating a set
sadd nameofset value1 value2 value3 value4
#retrieve set
smembers name
#add more values
sadd valuex valauey
#is there?
sismember nameofset value
#returns 0 no, 1 yes
#creating a subset
sadd nameofset:value value_1 value_2 value_3 ...
#retrieve subset
smembers nameofset:value
#creating a new value that has the same sublist as another value
sunionstore nameofset:newvalue nameofset:existingvalue
#remove the last value from the subset
spop nameofset:value
#count of how many values
scard nameofset
#creating a sorted set, helps if keys are integers
zadd nameofset key1 value1 key2 value2 key3 value3 ...
#listing the set
zrange nameofset starti endi
# 0 start, -1 end
# return just the values, to return with key AND values:
zrange nameofset 0 -1 withscores #again 0 is starti and -1 is endi
#reverse the set
zrevrange nameofset starti endi withscores
#get upto a certain range of key
zrangebyscore nameofset -inf integer withscores
#inf = information that will be obtained until the integer value
#retrieve the position of a value
zrank nameofset value
#returns the index or ranking
# IF THEY KEYS ARE NOT INTEGERS, REDIS WOULD SORT THE KEYS ALPHABETICALLY
config
file and search for security, requirepass password
is the main way to secure
redisbind
and notice that redis is binded to 127.0.0.1
= 1 interface, which means
we can only access the redis server through that address!