Ruby on rails x Redisでsessionを高速化しよう!

#今日の目標

NoSQLデータベースについて学ぶ

今回は
Amazon Web Services	Amazon ElastiCache for Redis　または
Microsoft Azure	Azure Redis Cache　を利用する前の予習段階としてごく簡単なアプリケーションでRedisの設定を学習したメモ書きです。

##Redisとは

Redisはメモリ上にデータを保存する超高速のデータベースの一種、データをメモリ上に保存するタイプのインメモリ型の`KVS(Key Value Store)`です。

KVSとは、主としてキーとバリューのシンプルなデータを保存するタイプのデータベースのことで、RDB(Relational Database)のような複雑なデータは扱えない反面、**高速に動作するという特徴**があります。

**データの永続化を目的とする場合は向いていません**。

###RailsでRedisを使うメリットとは？
Redisは**シンプルでかつ高速なデータベース**であるため、

- キャッシュ(Rails.cache)
- Ruby on Rails のセッションデータ

- 大量データ送信データ(Active Job)

などの一時的なデータ保存先としてRedisを利用すると**Railsを高速化**することができます！

さらに、セッションデータの場合は、Redisへ変更することでセッションハイジャックなどの**セキュリティリスクを軽減**できます！

![rails_redis_5](https://user-images.githubusercontent.com/41051390/81182981-846b5500-8fe9-11ea-8018-1a14d511f3d5.png)


#Redisをインストールしてみよう

Redis のインストール

```
$ brew install redis
```

```
(base) USERnoMacBookea:~ user$ brew install redis
Updating Homebrew...
==> Auto-updated Homebrew!
Updated 1 tap (homebrew/services).
No changes to formulae.


==> Downloading https://homebrew.bintray.com/bottles/redis-5.0.8.mojave.bottle.tar.gz
==> Downloading from https://akamai.bintray.com/c7/c72def1c78f6c24c02d47de80a0b5ae5ef67640a42a38d040c503429eb02d3b1?__gda__=exp=1588749665~hmac=c2fa7998accdcd9eaee8924e58ca7815a1
######################################################################## 100.0%
==> Pouring redis-5.0.8.mojave.bottle.tar.gz
==> Caveats
To have launchd start redis now and restart at login:
  brew services start redis
Or, if you don't want/need a background service you can just run:
  redis-server /usr/local/etc/redis.conf
==> Summary
🍺  /usr/local/Cellar/redis/5.0.8: 13 files, 3.1MB

```
##Redis サーバーの起動

```
$ redis-server
```
[![Image from Gyazo](https://i.gyazo.com/275fb3e944a0890a189a2b6607522812.png)](https://gyazo.com/275fb3e944a0890a189a2b6607522812)


これでローカル環境で Redis を使えるようになります。

ターミナルで新規タブを立ち上げRedis に接続する

```
$ redis-cli
127.0.0.1:6379>
```
##Redis を使ってみる
redis-cli で Redisサーバーに接続したあとに下記のように操作してみます。

SET を使って Key と Value を設定しデータを保存する
GET で Key を指定して Value を取得する
quit で redis-cli を終了

```
(base) USERnoMacBookea:~ user$ redis-cli
127.0.0.1:6379> SET mykey "Hello"
OK
127.0.0.1:6379> GET mykey
"Hello"
127.0.0.1:6379> quit

```

#RailsにRedisを導入してみる
環境
ruby 2.5.1
rails 5.2.4

##Rails アプリの作成

ここではとあるページにRedisから値を取り出して表示するだけの簡単なアプリケーションを作ります。

```
rails _5.2.4_ new redis_sample
```

### gem redis-rails のインストール

```
gem 'redis-rails'
```
```
$ bundle install
```
config/application.rbに以下を記載

```ruby:config/application.rb
config.cache_store = :redis_store, 'redis://localhost:6379/0/cache', { expires_in: 90.minutes }
```
config/application.rb に書いていますが、実際は環境毎に参照する Redis サーバーは違うと思うので、config/enviroments/◯◯.rb に書くとよいかと

###サンプルページの作成

```ruby:config/initializers/redis.rb
Redis.current = Redis.new
```
ローカル環境なので Redis.new しか書いていませんが、下記のように host と port を指定できるので、AWSのElastiCacheのRedisなどを使う場合はそれぞれを指定する必要があります。

```ruby:app/controller/redis_controller
class RedisController < ApplicationController
  def show
    Redis.current.set('mykey', 'Hello')
  end
end
```
config/initializers/redis.rb で定義した Redis.current に対して値を保存します。

```erb:app/view/redis/show.html.erb
<%= Redis.current.get('mykey') %>
```

ビューでcontrollerで保存した値が取り出せるか確認してみましょう。

[![Image from Gyazo](https://i.gyazo.com/092602c2ba75615566d56b6a63ae1d5f.png)](https://gyazo.com/092602c2ba75615566d56b6a63ae1d5f)

redisから値が取り出せることが確認できました。


## Railsのセッション管理をRedisにしてみる

config/initializers/session_store.rbを作成します。（Rails 5.0ではデフォルトですが5.2以降の場合は作成してください)

```ruby:config/initializers/session_store.rb
Rails.application.config.session_store :redis_store, {
  servers: [
    {
      host: "localhost",  # Redisのサーバー名
      port: 6379,         # Redisのサーバーのポート
      db: 0,              # データベースの番号(0 ~ 15)の任意
      namespace: "session"  # 名前空間。"session:セッションID"の形式
    },
  ],
  expire_after: 90.minutes # 保存期間
}

```
rails cで確認します

```
$ bin/rails c
```
```
>redis = Redis.new(url: 'redis://localhost:6379/0') # Redisに接続
    
# セッションを保存しているデータベースを選択
> redis.select 0
=> "OK
 
# Redisのセッションデータをクリア
> redis.flushdb
=> "OK"
 
# キーの一覧を取得
> redis.keys　
=> []
```

今回のサンプルアプリではセッションをくんでいないため　redis.keys => []となりますが
Railsアプリケーションからセッションに保存する操作をすると以下のようにredis.keysで内容が確認できると思います。

```
# キーの一覧を取得
> redis.keys
=> ["session:de7b87c3c487b3622c8a505c5e1ce69a", "session:7d12e83552cd35bb1e082480fbaee71d"]
 
# 保存データの中身を確認
> redis.get "session:de7b87c3c487b3622c8a505c5e1ce69a"
=> "\u0004\b{\u0006I\"\u0010_csrf_token\u0006:\u0006EFI\"13u/SxOI4lsxx836eIAKj8yOnViUXGcAMF02kvvDQFB8=\u0006;\u0000F"
```
以上でセッションデータのRedis接続は完了です。

Redisは、メモリ上にデータを保存する超高速のデータベースの一種です。

Ruby on Railsのセッション管理データの保存先をRedisにすると、高速化だけでなくセキュリティー強化にもなるため、ぜひ活用してみてください。

##参考
## Redis キャッシュの有効化

クエリの結果をキャッシュしてDBアクセスの回数を減らして負荷を軽減するという方法
こちらの記事でサンプルアプリを作成することができます。

[Railsでクエリ結果をキャッシュしてDB負荷を軽減する](https://qiita.com/yamashun/items/bf9a3d29de749cf18f2e)