RAKUS Developers Blog

株式会社ラクスのエンジニアブログ

セッション管理としてRedisを使用する

f:id:ntthuat:20170926225716p:plain

はじめに

みなさん こんにちは、Thuatと申します。今年ラクスに入社しました1年目です。 この記事ではセッション管理としてRedisを使用するケースを紹介します。

Redisとは?

Redis は簡単に言うと、メモリ上のKey-Valueストアです。 メモリ上にデータを格納しますので高速に動作します。
以下はインストールから簡単なデータの登録・取得までの手順になります。

Redisをインストールする

$ wget http://download.redis.io/releases/redis-4.0.1.tar.gz
$ tar xzf redis-4.0.1.tar.gz
$ cd redis-4.0.1
$ make

Redisサーバーを起動する

$ src/redis-server
33507:C 25 Sep 23:21:32.201 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
33507:C 25 Sep 23:21:32.202 # Redis version=4.0.1, bits=64, commit=00000000, modified=0, pid=33507, just started
33507:C 25 Sep 23:21:32.202 # Warning: no config file specified, using the default config. In order to specify a config file use src/redis-server /path/to/redis.conf
33507:M 25 Sep 23:21:32.203 * Increased maximum number of open files to 10032 (it was originally set to 256).
                _._                                                  
           _.-``__ ''-._                                             
      _.-``    `.  `_.  ''-._           Redis 4.0.1 (00000000/0) 64 bit
  .-`` .-```.  ```\/    _.,_ ''-._                                   
 (    '      ,       .-`  | `,    )     Running in standalone mode
 |`-._`-...-` __...-.``-._|'` _.-'|     Port: 6379
 |    `-._   `._    /     _.-'    |     PID: 33507
  `-._    `-._  `-./  _.-'    _.-'                                   
 |`-._`-._    `-.__.-'    _.-'_.-'|                                  
 |    `-._`-._        _.-'_.-'    |           http://redis.io        
  `-._    `-._`-.__.-'_.-'    _.-'                                   
 |`-._`-._    `-.__.-'    _.-'_.-'|                                  
 |    `-._`-._        _.-'_.-'    |                                  
  `-._    `-._`-.__.-'_.-'    _.-'                                   
      `-._    `-.__.-'    _.-'                                       
          `-._        _.-'                                           
              `-.__.-'                                               

33507:M 25 Sep 23:21:32.206 # Server initialized
33507:M 25 Sep 23:21:32.206 * DB loaded from disk: 0.000 seconds
33507:M 25 Sep 23:21:32.206 * Ready to accept connections

Redisのポートはデフォルトで6379になります。

クライアントからGET/SETする

Redisにあらかじめ組込まれているクライアントツールからデータをGET/SETしてみましょう。
シンタックスは以下になります。
set key value
get key

$ src/redis-cli
127.0.0.1:6379> set key1 10000
OK
127.0.0.1:6379> get key1
"10000"
127.0.0.1:6379> 

ValueJSONでも保存できます。

127.0.0.1:6379> set user_info '{"username":"taro", "age":20}'
OK
127.0.0.1:6379> get user_info
"{\"username\":\"taro\", \"age\":20}"
127.0.0.1:6379>

Redisは メモリ上にデータを格納しますので、デフォルトはサーバーを停止、再起動した場合は、データが失われます。 Redisはどのような時に利用すればよいでしょうか。 最適なユースケースはキャッシュやセッション管理です。

セッション管理としてRedisを使用する

セッションとは?

セッションはクライアントとサーバの通信の状態をWebサーバー上に保持されます。クライアントはセッションIDをURLやクッキー経由でサーバに渡します。 Key-Value構造としてメモリ、ファイル又はDBに格納します。KeyはセッションID、Valueはセッションに保存したいデータです。
デフォルトではセッションは Webサーバーのメモリ上に保持されます。 Webサーバー単独でセッション管理を行う場合はWebサーバーのロードバランサを構成できません。 セッションをDBに格納する設定にすると、ロードバランサを構成することができますが、パフォーマンスに影響します。
セッションについては、
セッション管理の周辺知識まとめ – PAYFORWARD
を参照ください。

Redisを使ってセッションを管理する

データをセッションではなくて Redisで管理する方法を紹介します。
Redisにはセッションのようにタイムアウト時間を設定できます。タイムアウト時間を超えた場合はRedisに保存したデータが自動的に削除されます。

以下の機能をJavaで実現してみます。

JavaでのRedisクライアントは多くありますが一番人気はJedisです。
https://github.com/xetorthio/jedis/wiki/Getting-started

プロジェクトのLibrariesにjedis-2.9.0.jarを追加してください。
http://search.maven.org/remotecontent?filepath=redis/clients/jedis/2.9.0/jedis-2.9.0.jar

jedis-2.9.0.jar を追加する

f:id:ntthuat:20171009185454p:plain:w600

フォルダの構成は以下のようになります

f:id:ntthuat:20171011232101p:plain:w300

Userクラスを作成します。

package jp.co.jedis;

public class User {
    private String username;
    private String address;

    public User(String username, String address) {
        this.username = username;
        this.address  = address;
    }
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String getAddress() {
        return address;
    }
    public void setAddress(String address) {
        this.address = address;
    }

    @Override
    public String toString() {
        return "{'username':'"+this.username + "' , 'address':'"+ this.address + "'}";
    }

}


UserActionクラスを作成します。 ユーザーのデータをRedisに保存するためのクラスです。
3分後、自動にExpireされるように設定します。
KeyはユニークなUUID、ValueJSONでのユーザーのデータです。

package jp.co.jedis;

import java.util.UUID;

import redis.clients.jedis.Jedis;

public class UserAction {
    private static final int TIMEOUT = 3*60; //3分
    public static void main(String[] args) {
        String userToken = UUID.randomUUID().toString();
        System.out.println("user token: " + userToken);
        Jedis jedis = new Jedis("localhost");
        User user = new  User("tanaka", "Tokyo-shibuya");
        //3分後、無効になる
        jedis.setex(userToken, TIMEOUT, user.toString());
        jedis.close();

    }

}


Eclipseで実行してみましょう。

f:id:ntthuat:20171012000341p:plain:w600


Redisのクライアントで確認しましょう。

127.0.0.1:6379> get a62a05d0-1efe-4d09-99f1-4289ff1511a6   -> 3分以内の場合
"{'username':'tanaka' , 'address':'Tokyo-shibuya'}"

127.0.0.1:6379> get a62a05d0-1efe-4d09-99f1-4289ff1511a6  -> 3分以上の場合
(nil)
127.0.0.1:6379> 

a62a05d0-1efe-4d09-99f1-4289ff1511a6 は生成されたKey、ユニークなUUIDです。

セッション管理としてRedisを使用するメリットは以下になります。

  • メモリ上に格納するのでパフォーマンスがよい

  • Webサーバーの負荷が減る

  • 別サーバーでセッション管理するので、Webサーバーのロードバランサを問題なく構成することができる
    ロードバランサを構成するには以下のような構成となります。

f:id:ntthuat:20171013001755p:plain:w700

最後に

セッション管理としてRedisを使用する方法やJavaでRedisにアクセスする方法を紹介しました。 Redisはまだたくさんオプションがあります。
例えば接続数ハンドル、トランザクションクラスターなどをもっと知りたい方は https://github.com/xetorthio/jedis/wiki を参照ください。

参考資料

セッション管理の周辺知識まとめ – PAYFORWARD

Redis

Home · xetorthio/jedis Wiki · GitHub

Copyright © RAKUS Co., Ltd. All rights reserved.