Skip to content

Instantly share code, notes, and snippets.

@francisco-rojas
Last active August 29, 2015 14:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save francisco-rojas/d9ff7df23aeb09a13171 to your computer and use it in GitHub Desktop.
Save francisco-rojas/d9ff7df23aeb09a13171 to your computer and use it in GitHub Desktop.
Redis Useful Commands

Redis Installation (Ubuntu)

  • 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

Start 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"

Stop Redis Server

To stop redis server just run:

killall redis-server

Check Redis Version

Run:

redis-server -v

Basic Redis Commands

  • 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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment