- sudo apt-get install -y python-software-properties
- sudo add-apt-repository -y ppa:rwky/redis
- sudo apt-get update
- sudo apt-get install -y redis-server
For development
redis-server
works fine but for production environments you should use a configuration file. In order to start Redis with a configuration file use the full path of the configuration file as first argument:
redis-server /etc/redis/redis.conf
The first thing to do in order to check if Redis is working properly is sending a PING command using redis-cli:
redis-cli ping
PONG
Running redis-cli followed by a command name and its arguments will send this command to the Redis instance running on localhost at port 6379. You can change the host and port used by redis-cli, just try the --help option to check the usage information.
Another interesting way to run redis-cli is without arguments: the program will start in interactive mode, you can type different commands and see their replies.
$ redis-cli
redis 127.0.0.1:6379> ping
PONG
redis 127.0.0.1:6379> set mykey somevalue
OK
redis 127.0.0.1:6379> get mykey
"somevalue"
To stop redis server just run:
killall redis-server
Run:
redis-server -v
- sadd: Add member to the set stored at key. If member is already a member of this set, no operation is performed. If key does not exist, a new set is created with member as its sole member.
- srem: Remove member from the set stored at key. If member is not a member of this set, no operation is performed.
- smembers: Returns all the members of the set value stored at key.
- sinter: Returns the members of the set resulting from the intersection of all the given sets.
- scard: Returns the set cardinality (number of elements) of the set stored at key.
- sismember: Returns if member is a member of the set stored at key.
- multi: Marks the start of a transaction block. Subsequent commands will be queued for atomic execution using EXEC.
Examples:
#####Twitter like relationships
class User < ActiveRecord::Base
# follow a user
def follow!(user)
$redis.multi do
$redis.sadd(self.redis_key(:following), user.id)
$redis.sadd(user.redis_key(:followers), self.id)
end
end
# unfollow a user
def unfollow!(user)
$redis.multi do
$redis.srem(self.redis_key(:following), user.id)
$redis.srem(user.redis_key(:followers), self.id)
end
end
# users that self follows
def followers
user_ids = $redis.smembers(self.redis_key(:followers))
User.where(:id => user_ids)
end
# users that follow self
def following
user_ids = $redis.smembers(self.redis_key(:following))
User.where(:id => user_ids)
end
# users who follow and are being followed by self
def friends
user_ids = $redis.sinter(self.redis_key(:following), self.redis_key(:followers))
User.where(:id => user_ids)
end
# does the user follow self
def followed_by?(user)
$redis.sismember(self.redis_key(:followers), user.id)
end
# does self follow user
def following?(user)
$redis.sismember(self.redis_key(:following), user.id)
end
# number of followers
def followers_count
$redis.scard(self.redis_key(:followers))
end
# number of users being followed
def following_count
$redis.scard(self.redis_key(:following))
end
# helper method to generate redis keys
def redis_key(str)
"user:#{self.id}:#{str}"
end
end
> %w[Alfred Bob].each{|name| User.create(:name => name)}
=> ['Alfred', 'Bob']
> a, b = User.all
=> [#<User id: 1, name: "Alfred">, #<User id: 2, name: "Bob">]
> a.follow!(b)
=> [1, 1]
> a.following?(b)
=> true
> b.followed_by?(a)
=> true
> a.following
=> [#<User id: 2, name: "Bob">]
> b.followers
=> [#<User id: 1, name: "Alfred">]
> a.friends
=> []
> b.follow!(a)
=> [1, 1]
> a.friends
=> [#<User id: 2, name: "Bob">]
> b.friends
=> [#<User id: 1, name: "Alfred">]
#####High Score Table
- zadd: Adds the member with the specified score to the sorted set stored at key. If member is already a member of the sorted set, the score is updated and the element reinserted at the right position to ensure the correct ordering. If key does not exist, a new sorted set with the specified member as sole member is created.
- zrevrank: Returns the rank of member in the sorted set stored at key, with the scores ordered from high to low. The rank (or index) is 0-based, which means that the member with the highest score has rank 0. zrevrange Returns the specified range of elements in the sorted set stored at key. The elements are considered to be ordered from the highest to the lowest score. Descending lexicographical order is used for elements with equal score.
- zscore: Returns the score of member in the sorted set at key.
We can construct a simple high score table using Redis sorted sets:
class User < ActiveRecord::Base
# log high score
def scored(score)
if score > self.high_score
$redis.zadd("highscores", score, self.id)
end
end
# table rank
def rank
$redis.zrevrank("highscores", self.id) + 1
end
# high score
def high_score
$redis.zscore("highscores", self.id).to_i
end
# load top 3 users
def self.top_3
$redis.zrevrange("highscores", 0, 2).map{|id| User.find(id)}
end
end
> a, b, c, d = User.limit(4)
=> [#<User id: 1, name: "Alfred">, #<User id: 2, name: "Bob">, #<User id: 3, name: "Charlie">, #<User id: 4, name: "Derek"">]
> a.scored 100
=> true
> b.scored 500
=> true
> c.scored 25
=> true
> d.scored 10000
=> true
> d.high_score
=> 10000
> d.rank
=> 1
> c.rank
=> 4
> c.scored 5000000
=> false
> c.high_score
=> 5000000
> c.rank
=> 1
> User.top_3
=> [#<User id: 3, name: "Charlie">, #<User id: 4, name: "Derek">, #<User id: 2, name: "Bob">]
###References