サイトアイコン 協栄情報ブログ

【初心者向け】Amazon EC2でRedisを使ってみる

redis-handsonアイキャッチ画像


この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので十分ご注意ください。

わたしはPythonで書かれたWebフレームワークのFlaskを使い、Webアプリを作成しています。ログイン機能を実装したところ、ログイン状態を維持できない問題にぶちあたりました。

 

その解決策として、ログインのセッションデータを外部ストアに保存する必要がありました。

 

外部ストアに保存する方法の選択肢として、Redis、Memcached、データベースが考えられます。AWSの学習をする際に"Redis"がちょくちょく出てきていて興味があったので、"Redisで試してみよう"と思い立ったのです。

 

今回は「Amazon EC2を利用してRedisの簡単な使い方」と、「Flaskで作成したアプリのログインセッションデータをRedisに保存する方法」を紹介します。

 

 

Redisを使ってみよう

■Redisとは

Redis(Remote Dictionary Server)は、高速なインメモリデータストアです。

 

通常はキーと値として保存・使用されますが、リスト、セット、ハッシュ、ソート済みセット、ビットマップなど、さまざまなデータ型をサポートしています。一般的には、キャッシュ、セッションストア、パブ/サブメッセージング、リアルタイムのアナリティクスなど、多くの用途で利用されます。

 

 

Redisのメリット

 

 

Redisのデメリット

 

AWSのページにRedisについて詳しく載っています。詳しく知りたい方はぜひ。

 

 

■前提条件

今回の記事ではRedisについて知るために、ハンズオンを3つ用意しました。ハンズオンの前提条件は以下の通りです。

 

 

 

※ハンズオンではPythonやhtmlのソースコードが出てきますが、あくまでRedisの紹介ですのでコード説明は省きます。

 

 

■ハンズオン1:Redisを使ってみる

ハンズオン1では、Amazon EC2にRedisをインストールして、[redis-cli]を使い、キーと値を保存・参照してみます。

 

 

↓EC2インスタンスに接続し、以下のコマンドを実行します。
sudo dnf install -y redis6

 

 

インストールが完了したら、起動します。以下のコマンドを順に実行してください。
sudo systemctl start redis6
sudo systemctl enable redis6
systemctl status redis6

 
【実行結果】

[ec2-user@ip-10-0-1-41 ~]$ systemctl status redis6
● redis6.service - Redis persistent key-value database
     Loaded: loaded (/usr/lib/systemd/system/redis6.service; enabled; preset: disable>
    Drop-In: /etc/systemd/system/redis6.service.d
             └─limit.conf
     Active: active (running) since Sun 2023-09-10 00:40:50 UTC; 55s ago
   Main PID: 25082 (redis6-server)     Status: "Ready to accept connections"
      Tasks: 5 (limit: 9349)
     Memory: 2.1M
        CPU: 36ms
     CGroup: /system.slice/redis6.service
             └─25082 "/usr/bin/redis6-server 127.0.0.1:6379"

Sep 10 00:40:50 ip-10-0-1-41.ap-southeast-1.compute.internal systemd[1]: Starting red>
Sep 10 00:40:50 ip-10-0-1-41.ap-southeast-1.compute.internal systemd[1]: Started redi>lines 1-15/15 (END)

 

[actiove(running)]になっていたら、起動しています。

 

↓それではRedisを使ってみましょう。Redisサーバを操作する方法はいくつかありますが、まずは"redis6-cli"ツールを使ってみます。以下のコマンドを実行してください。
redis6-cli

 

 

↓キーと値を保存します。
SET mykey "Hello, Redis!"

 

 

↓保存した値を取り出します。
GET mykey

 

 

キーと値の保存・参照の仕方はシンプルでわかりやすいですね。

 

ハンズオン1は以上です。

 

 

■ハンズオン2:PythonでRedisを使ってみる

ハンズオン2はPythonでRedisを操作するコードを使って、Redisにキーと値を保存し、指定したキーの値を表示してみます。

 

 

↓"Python"をインストールします。環境によってはすでにインストール済みかもしれません。
sudo dnf install -y python3-pip python3-devel

 

 

↓PythonでRedisを扱うためのパッケージをインストールします。
pip install redis

 

 

↓インストールが完了したら、Pythonファイルを保存するディレクトリを作成します。
mkdir test_redis/

 

 

↓ディレクトリを作成したら、実行ファイルを作成します。コマンドとソースコードは以下を利用してください。
sudo vim test_redis/test_redis.py

 
【ソースコード(test_redis.py)】

import redis

# Redisに接続
r = redis.Redis(host='localhost', port=6379, db=0)

# データのセット
r.set('my_key', 'Hello from Python!')

# データの取得
value = r.get('my_key')
print(value.decode('utf-8'))

 

 

↓ソースコードを入力したら、[Esc]キーを押し、以下のコマンドで保存してエディターを終了します。
:wq

 

 

↓ディレクトリを移動し、pyファイルを実行しましょう。
cd test_redis/
python3 test_redis.py

 

 

キー"my_key"を指定して、値"Hello from Python!"が返ってきました。

 

ハンズオン2は以上です。

 

■ハンズオン3:Redis×Flaskを使ってみる

さいごに、WebフレームワークのFlaskを利用して、redisにセッションデータを保存してみます。Flaskについてはこちら

 

ハンズオン2の続きから始めますので、カレントディレクトリに注意してください。

 

 

↓必要なパッケージをインストールします。
pip install Flask Flask-Session

 

 

↓htmlファイルを置くディレクトリを作成し、htmlファイルも作成していきます。
mkdir templates/
sudo vim templates/login.html

 

【ソースコード(login.html)】

<!DOCTYPE html>
<html>
<head>
    <title>Login</title>
</head>
<body>
{% with messages = get_flashed_messages() %}
  {% if messages %}
    {% for message in messages %}
      <p>{{ message }}</p>
    {% endfor %}
  {% endif %}
{% endwith %}
    <h1>Login</h1>
    <form method="POST" action="/login">
        <label for="username">Username:</label>
        <input type="text" id="username" name="username" required><br><br>

        <label for="password">Password:</label>
        <input type="password" id="password" name="password" required><br><br>

        <input type="submit" value="Login">
    </form>
</body>
</html>

 

 

 

[Esc]キーを押し、以下のコマンドで保存してエディターを終了します。
:wq

 

↓Flaskを実行するファイルを作成し、以下のソースコードを貼り付けましょう。
sudo vim app.py

 

【ソースコード(app.py)】

from flask import Flask, request, render_template, redirect, session, url_for
from redis import Redis
from flask_session import Session

app = Flask(__name__)
app.secret_key = 'your_secret_key'
app.config['SESSION_TYPE'] = 'redis'
app.config['SESSION_PERMANENT'] = False
app.config['SESSION_USE_SIGNER'] = True
app.config['SESSION_KEY_PREFIX'] = 'your_prefix'
app.config['SESSION_REDIS'] = Redis(host='localhost', port=6379, db=0)

# セッションのセットアップ
Session(app)

# ダミーのユーザーデータ
users = {
    'user1': 'password1',
    'user2': 'password2'
}

# ログインページ
@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        username = request.form['username']
        password = request.form['password']

        if users.get(username) == password:
            session['username'] = username
            return redirect(url_for('dashboard'))
        else:
            return 'ログインに失敗しました'

    return render_template('login.html')

# ダッシュボード(ログインが必要なページ)
@app.route('/dashboard')
def dashboard():
    if 'username' in session:
        username = session['username']
        return f'こんにちは、{username}さん! <a href="/about">ログイン継続チェック</a> <a href="/logout">ログアウト</a>'
    else:
        return 'ログインしてください。'

# /about ページ(ログインが必要)
@app.route('/about')
def about():
    if 'username' not in session:
        return f'ログインが必要です。 <a href="/login">ログイン</a>'
    username = session['username']  # 'username'をセッションから取得
    print('username:', username)
    return f'{username}さん!、ログイン継続中です! <a href="/logout">ログアウト</a>'

# ログアウト
@app.route('/logout')
def logout():
    if 'username' in session:
        session.pop('username')
    return redirect(url_for('login'))

if __name__ == '__main__':
    app.run(debug=False, host='0.0.0.0')

 

 

 

[Esc]キーを押し、以下のコマンドで保存してエディターを終了します。
:wq

 

↓準備が整いましたので、Webアプリを起動しましょう。WARNINGが表示されますが、問題ないので進めてください。
python3 app.py

 

 

↓ブラウザからWebアプリにアクセスします。アクセスできない場合は、セキュリティグループのインバウンドルールとパブリックIPアドレスを確認してください。
http://<EC2インスタンスパブリックIPアドレス>:5000/login

 

 

↓ダミーのユーザーデータを用意していますので、Usename: user1、Password: password1 でログインしてみてください。

 

 

ログインできましたでしょうか。
 

 

↓今回はログインしたユーザーのセッションデータをRedisに保存するのが目的です。ログインしていなければアクセスできないページを用意してありますので、確認してみましょう。[ログイン接続チェック]をクリックしてください。

 

 

Usernameが表示され、ログイン継続中と出ました。

 

↓しかし、本当にRedisにセッションデータが保存されているのか気になりますよね。確認してみましょう。コマンドラインに戻り、[Ctrl + c]でWebアプリを一旦止めます

 

 

↓[redis6-cli]を実行し、以下のコマンドを実行します。
keys *

 

 

↓いくつかデータが保存されていますが、今回のFlaskアプリのキー名は[your_prefix]から始まるデータです。

 

 

↓値を確認してみます
GET <キー名>
例)GET your_prefixc8b8431a-d59f-4235-bf2c-75ed3ab77d93

 

 

値の中にusernameとuser1が入っているのが確認できました。

 

↓もう一度、Webアプリを起動し、以下のページにアクセスしてください。セッションデータが保持されているので、アクセスできるかと思います。
http://<EC2インスタンスパブリックIPアドレス>:5000/about

 

 

↓[ログアウト]をクリックしてください。

 

↓それでは、もう一度redisのデータを確認してみます。[redis6-cli]→[keys *]を実行します。

 

 

さきほどまであった、[your_prefixxxxxxxxxxxxxxxxxx]というキーが消えていますね。ログアウトしたことで、セッションデータが消えました。

 

今回のハンズオンは以上です。

 

 

まとめ:【初心者向け】Amazon EC2でRedisを使ってみる

Webアプリケーションを作成していて、各実行プロセスがユーザーのログイン情報を保持できずに困っていました。

 

解決策は外部ストアを利用することで、外部ストアの選択肢のひとつに今回紹介したRedisがあったのです。AWSの認定資格で"Amazon ElastiCache for Redis"ってしょうちゅう出てきますよね。

 

今回のハンズオンを通して、"Redis"の動きや操作がなんとなくわかった気がします。

 

 

参考リンク:RedisFlask – クイックスタート
 

 

↓ほかの協栄情報メンバーもPythonに関する記事を公開しています。ぜひ参考にしてみてください。

 

■【簡単】Pythonで始めるwebアプリ開発入門【Flask】(齊藤弘樹)
https://cloud5.jp/saitou-intro-flask/

 

■天気予報情報をスクレイピング(Python)で、LINE NotifyによりLINE通知の構築(INAMURA)
https://cloud5.jp/web-scraping_line-notify/

 

■Pythonでlxmlを用いてhtmlから情報取得(zhangzy)
https://cloud5.jp/python-ixml/

 

■仮想環境作成ツール”virtualenv”を使ってみる(齊藤弘樹)
https://cloud5.jp/saitou-howtouse-virtualenv/

 

■【初学者向け】PCにPythonを学習するための環境を整える part1【Windows編】(齊藤弘樹)
https://cloud5.jp/saitou-python-install/
 

モバイルバージョンを終了