public memo

エンジニア向け小ネタ書き溜め用。公開日記だけど親切な文章とは程遠いかもしれない。

言語別 Redis 接続方法まとめ

2016-10-31 by MasakiMisawa
Tweet
このエントリーをはてなブックマークに追加
Pocket
LINEで送る

仕事では結構前から使っていたのですが、最近プライベートな小規模開発でも Redis を使う機会が増えてきました。
イマイチな点もありますが、正しく使えば便利なデータストアなので、一度各言語別の接続方法をまとめておきます。

前準備

まずは、接続先のRedisサーバを用意する必要があるので、ローカル環境用のRedisサーバを用意します。
(AWSのElastiCacheなど、接続先が既に存在する場合はこの手順は不要です)

【Mac】
homebrewでインストールするのが管理的にも楽ですね。

mac redis install
ZSH
1
brew install redis

インストールしたらコンソールからredisサーバを起動。

redis-server-start
ZSH
1
redis-server

起動したRedisサーバに接続し、テストデータを入れてみて接続確認します。

redis-connect-check
ZSH
1
2
3
4
5
6
7
redis-cli -h localhost
localhost:6379> set test-key test-value
OK
localhost:6379> get test-key
"test-value"
localhost:6379> del test-key
(integer) 1

-h の後が接続先のホスト名になるので、ElastiCacheに繋ぐ場合などはEndPointのURLに置き換えてください。
(デフォルトがlocalhostなのでローカル環境では -h オプションは不要です)

【Windows】
Redis自体がWindows環境をサポートしていないようなのでMSOpenTeckを利用して使うそうです。
試していませんが、こちらとか参照して進めれば使えるようになるはず!

環境が用意できたところで、各言語別の接続方法をざっと書いていきます。
(とりあえず5つほど書きますが、要望があればその他の言語も追記します)
Ruby
Java
Python
Node.js
PHP

Ruby

接続用ライブラリに redis を使用するので事前に用意しておきます。

ruby-redis-setup
ZSH
1
gem install redis

* permission error で拒否される場合は、sudo をつけて実行で対処します

後は、以下のように自由に操作するだけです。

ruby-redis-sample
Ruby
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
require 'redis'
 
# ここはそれぞれの環境に合わせて書き換える
REDIS_HOST_NAME = "localhost"
REDIS_PORT_NO = 6379
 
redis = Redis.new(:host => REDIS_HOST_NAME, :port => REDIS_PORT_NO)
 
# 操作は基本的にRedisのコマンド名をそのまま使用
 
# String
redis.set("string-key", "string-value")
 
# List
redis.rpush("list-key", "list-value1")
redis.rpush("list-key", "list-value2")
 
# Set
redis.sadd("set-key", "set-value1")
redis.sadd("set-key", "set-value2")
 
# Sortedset
redis.zadd("sortedset-key", [[10, "value1"], [20, "value2"]])
 
# Hash
redis.hset("hash-key", "member-name", "hash-value")
redis.hset("hash-key", "member-name2", "hash-value2")

Sortedsetに追加するzaddの書き方に少し癖があるぐらいで、後は環境の用意含めて非常に楽です。

Java

接続用ライブラリに Jedis を使用するのでmavenのpom.xmlに以下のように書いて用意しておきます。
以下の例では2016年10月時点での最新バージョンの2.9.0を落としていますが、バージョンは最新のものに書き換えてください。

pom.xml
1
2
3
4
5
6
<!-- https://mvnrepository.com/artifact/redis.clients/jedis -->
<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>2.9.0</version>
</dependency>

後は、以下のように自由に操作するだけです。

java-redis-sample
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
package java.redis.sample;
 
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
 
public class JavaRedisSample {
    
    // ここはそれぞれの環境に合わせて書き換える
    private static final String REDIS_HOST_NAME = "localhost";
    private static final int REDIS_PORT_NO = 6379;
 
 
    public static void main(String... args) {
 
        JedisPool pool = new JedisPool(REDIS_HOST_NAME, REDIS_PORT_NO);
        Jedis jedis = null;
 
        try {
            jedis = pool.getResource();
 
            // 操作は基本的にRedisのコマンドをそのまま使用
 
            // String
            jedis.set("string-key", "string-value");
 
            // List
            jedis.rpush("list-key", "list-value1");
            jedis.rpush("list-key", "list-value2");
 
            // Set
            jedis.sadd("set-key", "set-value1");
            jedis.sadd("set-key", "set-value2");
 
            // Sortedset
            jedis.zadd("sortedset-key", 10, "value1");
            jedis.zadd("sortedset-key", 20, "value2");
 
            // Hash
            jedis.hset("hash-key", "member-name", "hash-value");
            jedis.hset("hash-key", "member-name2", "hash-value2");
 
            // 最後に必ずpoolにインスタンスを返す
            pool.returnResource(jedis);
        } catch (Exception e) {
            // 接続障害などで落ちた場合もインスタンスを閉じる
            if (jedis != null) {
                jedis.close();
            }
        }
 
    }
}

Redisのコマンドをそのまま書くだけなので非常にシンプルです。
poolを使ってインスタンスを管理する場合は、必ずインスタンスを閉じるのを徹底しないとpoolの枯渇が起こるので注意ですね。

Python

接続用ライブラリに redis を使用するので事前に用意しておきます。

python-redis-setup
ZSH
1
pip install redis

* pip が未インストールの場合は、公式からDL or 使用するpythonを brew install python で落としてきた方に変更のどちらかで対処します

後は、以下のように自由に操作するだけです。

python-redis-sample
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# -*- coding: utf-8 -*-
 
import redis
 
# ここはそれぞれの環境に合わせて書き換える
REDIS_HOST_NAME = "localhost"
REDIS_PORT_NO = 6379
 
r = redis.Redis(host = REDIS_HOST_NAME, port = REDIS_PORT_NO)
 
# 操作は基本的にRedisのコマンド名をそのまま使用
 
# String
r.set("string-key", "string-value")
 
# List
r.rpush("list-key", "list-value1")
r.rpush("list-key", "list-value2")
 
# Set
r.sadd("set-key", "set-value1")
r.sadd("set-key", "set-value2")
 
# Sortedset
r.zadd("sortedset-key", value1 = 10, value2 = 20)
 
# Hash
r.hset("hash-key", "member-name", "hash-value")
r.hset("hash-key", "member-name2", "hash-value2")

PythonもSortedsetの入れ方に特徴がありますね。

Node.js

接続用ライブラリに redis を使用するので事前に用意しておきます。

node-redis-setup
ZSH
1
npm install redis

* npm が未インストールの場合は、homebrew の brew install node で対処します

後は、以下のように自由に操作するだけです。

node-redis-sample
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// ここはそれぞれの環境に合わせて書き換える
const REDIS_HOST_NAME = 'localhost';
const REDIS_PORT_NO = 6379;
 
var redis = require('redis'),
    client = redis.createClient(REDIS_PORT_NO, REDIS_HOST_NAME);
 
client.on("error", function (err) {
    // Redis接続時エラーの処理を記載する場合はここに書く
});
 
// 操作は基本的にRedisのコマンド名をそのまま使用
 
// String
client.set("string-key", "string-value")
 
// List
client.rpush("list-key", "list-value1")
client.rpush("list-key", "list-value2")
 
// Set
client.sadd("set-key", "set-value1")
client.sadd("set-key", "set-value2")
 
// Sortedset
client.zadd("sortedset-key", 10, "value1")
client.zadd("sortedset-key", 20, "value2")
 
// Hash
client.hset("hash-key", "member-name", "hash-value")
client.hset("hash-key", "member-name2", "hash-value2")

書き方はNode.jsが一番オーソドックスかもしれません。
constがIE10以下ではサポートされていません問題については、今回は一旦抜きで…

PHP

接続用ライブラリに phpredis を使用するので事前に用意しておきます。
用意の仕方は色々ありますが、使用しているPHPバージョンに応じたFormulaをhomebrewでインストールするのが早いです。
以下の例ではMacにデフォルトで入っているPHP5.5用のphp-redisを落としていますが、各自の環境に合わせて数字部分を変えてください。

php-redis-setup
ZSH
1
brew install php55-redis

* .bash_profile(.zshrc) にhomebrewで落としたPHPのパスを通さないと使えるようにならないので忘れずに行うようにしましょう

ZSH
1
echo export PATH=$(brew --prefix)/bin:$PATH >> ~/.bash_profile(.zshrc)

後は、以下のように自由に操作するだけです。

php-redis-sample
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<?php
// ここはそれぞれの環境に合わせて書き換える
define('REDIS_HOST_NAME', 'localhost');
define('REDIS_PORT_NO', 6379);
 
$redis = new Redis();
$redis->connect(REDIS_HOST_NAME, REDIS_PORT_NO);
 
// 操作は基本的にRedisのコマンド名をそのままキャメルケースにして使用
 
// String
$redis->set("string-key", "string-value");
 
// List
$redis->rPush("list-key", "list-value1");
$redis->rPush("list-key", "list-value2");
 
// Set
$redis->sAdd("set-key", "set-value1");
$redis->sAdd("set-key", "set-value2");
 
// Sortedset
$redis->zAdd("sortedset-key", 10, "value1");
$redis->zAdd("sortedset-key", 20, "value2");
 
// Hash
$redis->hset("hash-key", "member-name", "hash-value");
$redis->hset("hash-key", "member-name2", "hash-value2");
?>

redisコマンドをキャメルケースで書くのは個人的に少し違和感が…
後、phpredisの用意は、composerで用意した方が楽かもしれません。

必要とするライブラリや細かい文法が若干違うだけで、基本的にはどの言語も一緒ですね。
今回載せたのは基本コマンドだけですが、もちろんRedisのその他コマンドも使用可能なので公式リファレンスを見て色々試してみてください。
また、全言語共通して接続の詳細設定を設定する事も可能なので、指定したい場合は別途confファイルを用意して設定して下さい。

Redisの適切な使用用途について

RedisはオンメモリのKVSという特性上、その他のデータストアと比較して非常に高速であったりと便利な部分もある反面、保存可能容量が少ないことや、キーに入ったデータの管理が難しいこと、そもそも揮発性なのでいつ消えてもおかしくない(データの永続化は可能)などの難しい側面もあります。
メインのデータストアとして使うのではなく、あくまでもキャッシュDBとして考えるのが良さそうです。

最後に、色々使ってみて感じた個人的に適切だと思う使い方についていくつか書いて終わりにします。

1. メインDBから取得すると時間がかかる重い取得処理のキャッシュDBとして使用

メインDBから取得することも可能なものの、取得に時間がかかり毎回取りにいくのはパフォーマンス的に厳しいデータのキャッシュ保存先として使う方法です。
履歴系テーブルに保存されたデータのユーザ毎のカウント数や最終更新日時などを入れておく使い方で、おそらくこの用途が一番多くRedisで使われていそうです。

example.

user-id-1: {
login-count: 3,
last-login-time: ‘2016-10-31 01:12:126’,
footprint-count: 123,
last-footprint-time: ‘2016-10-31 02:04:257’
}

上記のようなデータの持たせ方をしておき、user-id-の後の1の部分を各ユーザのIDで置き換える感じです。

redis-use-example-cache
Ruby
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
require 'redis'
 
# ここはそれぞれの環境に合わせて書き換える
REDIS_HOST_NAME = "localhost"
REDIS_PORT_NO = 6379
 
redis = Redis.new(:host => REDIS_HOST_NAME, :port => REDIS_PORT_NO)
 
begin
login_count = redis.hget("user-id-1", "login-count")
rescue Redis::CannotConnectError => e
# Redisコネクションエラー時処理をここに書く(ログ出力など)
end
 
if login_count.nil?
# Redisからデータ取得ができない場合は、メインDBへのデータ取得処理を行う
end

取得処理はこんな感じでしょうか。
大事なのは、Redisからデータが取得できなかった場合(接続エラーなども含む)には必ずメインDBから取得処理を追加で行うようにしておき、取得速度の観点以外でRedisに依存しないようにしておく事ですね。

2. 各ジャンル別ランキング管理用DBとして使用

Redisには Sortedset というランキング管理に非常に向いたデータ型が存在するので、ジャンル別の売上数ランキングや評価レートランキングなどに使う方法です。

example.

ganle-book-sales: {
book-name-a: 2,
book-name-b: 0,
book-name-c: 3,
book-name-d: 1
}

ganle-book-rate: {
book-name-a: 3.5,
book-name-b: 0,
book-name-c: 4.0,
book-name-d: 2.5
}

キーをもっと細かくすれば小分類毎のランキングなども作れますし、普通にやろうとすると非常に重そうなランキング表示もRedisなら楽々です。

redis-use-sample-ranking
ZSH
1
zrevrange ganle-book-sales 0 100

スコアの降順に最大100件取得したいなら、こんな感じです。
一点注意なのは、挿入処理のバグやRedis障害発生などでデータが壊れても大丈夫なようにレプリケーション設定は必ずやっておきたいです。
AWSのElasticacheを採用するユーザが多いのは、バックアップや自動フェールオーバーも楽に設定できたりな耐障害性の面が大きい気がします。

3. サーバ監視など、サービス本体とは分離させた形で使用

サービス本体がRedisに依存してしまうのはできるだけ避けたいところですが、仮にRedisが止まってもサービス本体に影響が出ない形で使用するならば選択肢の一つとして有ではないでしょうか。
サーバ監視が止まってしまうのはそれはそれで怖いですが、Redis自身への監視を別に用意しておけばRedisが止まってしまう発生頻度を考えても良い選択肢だと個人的には思います。
代表的なサーバ監視のSensu&UchiwaがRedisを使っているのも大きいです。

長くなってしまいましたが、冒頭で書いた通り適切な使い方をすれば重宝するデータストアなので今後も使っていきたいです。

Tweet
このエントリーをはてなブックマークに追加
Pocket
LINEで送る

カテゴリー: Redis タグ: Java, Node.js, PHP, Python, Redis, Ruby

profile

profile_img Web系のソフトウェアエンジニアです。
野球観戦(横浜DeNAベイスターズ)、格闘ゲーム、カメラ、ランニング、愛犬、インテリア、美味しいものの食べ歩き、などなどが好き。

  • twitter MasakiMisawa
  • facebook MisawaMasaki
  • github MasakiMisawa
  • instagram masakimisawa
  • follow us in feedly

search

recent entry

  • M1 MacでAppleシリコンとIntelプロセッサのバイナリ管理を分離して共存させる
  • M1 MacでtfenvからTerraform1.0.2未満のダウンロードに失敗する問題を無理矢理解決する
  • GitHub ActionsからAWS利用時に永続的クレデンシャル情報を渡さないようにする
  • TerraformでAuroraのエンジンバージョンアップグレードをする時は、対象リソースをクラスターだけに絞る
  • CloudWatch Logsに出力されたエラーログ本文のSlackへの転送

category

  • AWS (17)
    • ACM (1)
    • AWS CLI (1)
    • Chatbot (2)
    • CloudWatchAlarm (1)
    • CloudWatchLogs (1)
    • CodeBuild (3)
    • DynamoDB (1)
    • IAM (1)
    • Kinesis (2)
    • Lambda (5)
    • OpenId Connect (1)
    • RDS (1)
    • S3 (2)
    • SNS (2)
    • SSM (2)
    • STS (1)
  • CI (2)
  • GCP (1)
    • PageSpeedInsights (1)
  • Git (3)
    • GitHub (2)
      • GitHub Actions (1)
  • M1 Mac (2)
  • Python (2)
  • Redis (1)
  • selenium (1)
  • Slack (3)
  • Terraform (3)
  • その他 (1)

archive

  • 2022年2月 (3)
  • 2021年1月 (1)
  • 2020年12月 (1)
  • 2020年11月 (1)
  • 2020年9月 (2)
  • 2020年8月 (1)
  • 2020年7月 (1)
  • 2020年6月 (1)
  • 2020年5月 (2)
  • 2020年4月 (1)
  • 2020年3月 (1)
  • 2020年1月 (1)
  • 2019年1月 (1)
  • 2017年12月 (1)
  • 2017年9月 (1)
  • 2017年8月 (1)
  • 2017年7月 (1)
  • 2017年2月 (1)
  • 2016年10月 (1)

tag cloud

ACM Aurora AWS AWS CLI Billing CI CloudWatchAlarm CloudWatch Logs CodeBuild Code Format Docker DynamoDB EC2 env find firehose Git GitHub GitHub Actions Homebrew husky IAM Role Java kinesis KinesisFirehose Lambda lint-staged M1 Mac Node.js OpenId Connect PHP Python RDS Redis RI S3 Selenium Slack SNS SSM Terraform tfenv セッションマネジャー リモートワーク 生産性

Copyright © 2025 public memo.