Redis
mruby
mrubyDay 2

mruby-redisでランキングを実装

More than 2 years have passed since last update.
  1. はじめに
    今回はmruby-redisでランキングを実装します。RedisはKVS(キーバリューストア)のインメモリーデータベースです。キーは文字列で、値には様々な型を保存することができます

  2. 値の型
    値の型にはString,Hash,List,Set, Sorted Setの5種類が使用出来ます
    • String 文字列
    • Hash 連想配列。複数の要素を格納出来、文字列のキーに対して、値を設定できます
    • List 複数の要素が格納でき、順序があります
    • Set ユニークな値のみ格納できる集合です
    • Sorted Set ユニークな値のみ格納し、与えられたスコアによってソートされます

  3. mruby-redisでランキングを実装
    mruby-redisはmrubyからRedisにアクセスするMGEMです。今回はSorted Setを使用してランキングを実装します

  4. mruby-redisのインストール
    まず、mrubyをダウンロードします

    $ git clone https://github.com/mruby/mruby
    

    build_config.rbに以下を追加します

    MRuby::Build.new do |conf|
    
      # ...(省略)...
    
      conf.gem :git => 'https://github.com/matsumoto-r/mruby-redis.git'
    end
    

ビルドします

```text
$ rake
```
  1. redis-serverを起動
    redis-serverをローカルにインストールし、起動してください

  2. ランキング
    ユーザーID, スコアを追加すると、スコアが高い順にソートして表示します。ランキングを実装したranking.rbは以下の通りになります

    ranking.rb
    host     = "127.0.0.1"
    port     = 6379
    database = 0
    
    redis = Redis.new(host, port)
    redis.select(database)
    
    # データの挿入/更新
    #redis.zadd(high-score", score, user_id)
    redis.zadd("high-score", 400, "lion")
    redis.zadd("high-score", 650, "cat")
    redis.zadd("high-score", 800, "dog")
    redis.zadd("high-score", 700, "bug")
    
    # データの順位を返す
    high_score_list = redis.zrevrange("high-score", 0, -1)
    puts "rank name score"
    puts "---------------------"
    high_score_list.each do |name|
      puts "#{redis.zrevrank("high-score", name) + 1}: #{name} #{redis.zscore("high-score", name)}"
    end
    
    redis.close
    

    実行結果は以下の通りになります

    $ mruby ranking.rb
    rank name score
    ---------------------
    1: dog 800
    2: bug 700
    3: cat 650
    4: lion 400
    
  3. mruby-redisのメソッド解説
    Redis#select(データベース)は0から15あるデータベースを選びます。ここでは0を選んでいます
    Redis#zadd(キー名, スコア, ユーザーID)でキー名のSorted SetにスコアとユーザーIDを対で追加します
    Redis#zrevrange(キー名, 開始インデックス, 終了インデックス) はスコアにしたがって、降順にSorted Setを返します。返す範囲を開始インデックと終了インデックスで指定します。開始インデックスが0から始まります。また、末尾からは-1,-2となります。 redis.zrevrange("high-score", 0, -1)はスコアの降順にすべての要素を返すことになりますちなみに昇順はRedis#zrange(キー名, 開始インデックス, 終了インデックス)となります
    Redis#zrevrank(キー名, ユーザーID)は降順のランクを返します。ランクのはじめは0です。ちなみに昇順のランクはRedis#zrank(キー名, ユーザーID)となります
    Redis#zscore(キー名, ユーザーID)でスコアを返します

  4. おわりに
    RedisでSorted Setを使用して、ランキングを実装してみました。Sorted Setは、Redis#zaddするたびにソートされますので、リアルタイムランキングに有用です