📢 この記事は gemini-3-flash-preview によって翻訳されました
Redisの基礎:この記事
Redis分散キャッシュ:
https://blog.yexca.net/ja/archives/225/
Redisはメモリベースのkey-value構造のデータベースで、インターネット技術の分野で最も広く使われているストレージミドルウェアなんだ。
Redisはメモリにデータを保存するから読み書きのパフォーマンスがすごく高くて、ホットデータ(商品情報、ニュース、お知らせとか)の保存に向いているよ。C言語で開発されたオープンソースの高性能なキーバリューストアで、扱える値(value)の型が豊富なことから「構造化されたNoSQL(Not Only SQL)」データベースとも呼ばれているんだ。
NoSQLは非リレーショナルデータベースの総称で、リレーショナルデータベースを置き換えるものではなく、それを補完するものとして使われるよ。
リレーショナルデータベース (RDBMS):
非リレーショナルデータベース (NoSQL):
Redisのダウンロード・インストールと実行
ダウンロード先:
Windows版は解凍するだけで使えるよ。Linux版の手順はこんな感じ:
- 解凍する:
tar -zxvf redis-4.0.0.tar.gz -C /usr/local - 依存環境をインストールする:
yum install gcc-c++ - インストールディレクトリに入ってコンパイルする:
make - redisのsrcディレクトリに入ってインストールする:
make install
関連ファイルの解説:
- /usr/local/redis-4.0.0/src/redis-server:Redisサーバーの起動スクリプト
- /usr/local/redis-4.0.0/src/redis-cli:Redisクライアントのスクリプト
- /usr/local/redis-4.0.0/redis.conf:Redisの設定ファイル
サーバーの起動について。Windows版を例にすると、起動コマンドはこれ:
1
| redis-server.exe redis.windows.conf
|
デフォルトのポート番号は6379で、パスワードは設定されていないよ。起動したらクライアントで接続できる。
redis-cli.exe を使って接続するよ。
1
| redis-cli.exe -h ip -p port -a password
|
省略した場合は 127.0.0.1:6379 が使われるよ。
設定ファイル (redis.windows.conf) を書き換えてパスワードを設定することもできる。
書き換えた後は再起動すれば有効になるよ。
Github:
https://github.com/qishibo/AnotherRedisDesktopManager
ダウンロードしてインストールしたら、新規接続を作成して情報を入力すれば接続できるよ。
Dockerでのデプロイ
イメージのプル
設定ファイルの取得。対応するバージョンをダウンロードして中身を取り出せばOK。Linuxなら redis.conf だね。
Redisのデータマッピング用フォルダを作成する。例えばこんな感じ:
1
2
| mkdir /home/redis
mkdir /home/redis/data
|
設定ファイルを修正して、デプロイ先のサーバーに送る。例えば Windows から Linux へ scp で送るなら:
1
| scp pathOfFile root@IP:/PathOfFile
|
起動
1
| docker run -p 6379:6379 --name redis -v /home/redis/redis.conf:/etc/redis/redis.conf -v /home/redis/data:/data -d redis redis-server /etc/redis/redis.conf
|
参考資料:
https://cloud.tencent.com/developer/article/1670205
Redisのデータ型
Redisのキー(key)は文字列型だけど、バリュー(value)にはよく使われる5つのデータ型があるよ。
- 文字列 (string):普通の文字列
- ハッシュ (hash):連想配列みたいなもの
- リスト (list):挿入順に並ぶ。重複要素OK
- セット (set):順序のない集合。重複要素NG
- ソート済みセット (sorted set/zset):各要素にスコア (score) が紐付いていて、スコア順に並ぶ

Redisのよく使うコマンド
Redisはコマンドの大文字・小文字を区別しないよ。
文字列操作のよく使うコマンド:
1
2
3
4
5
6
7
8
| # 指定したキーの値をセット
SET key value
# 指定したキーの値を取得
GET key
# 指定したキーの値をセットし、有効期限をseconds秒に設定
SETEX key seconds value
# キーが存在しない場合のみ、値をセット
SETNX key value
|
hashは文字列型のフィールド(field)と値(value)のマップで、オブジェクトを保存するのにぴったりなんだ。よく使うコマンド:
1
2
3
4
5
6
7
8
9
10
| # ハッシュ表 key の field に value をセット
HSET key field value
# ハッシュ表に保存されている指定フィールドの値を取得
HGET key field
# ハッシュ表に保存されている指定フィールドを削除
HDEL key field
# ハッシュ表にある全フィールドを取得
HKEYS key
# ハッシュ表にある全値を取得
HVALS key
|
リストは単純な文字列のリストで、挿入順に並ぶよ。よく使うコマンド:
1
2
3
4
5
6
7
8
9
10
11
| # 1つまたは複数の値をリストの先頭に挿入
LPUSH key value1 [value2]
# リストの指定範囲の要素を取得
LRANGE key start stop
# リストの最後の要素を取り出して取得
RPOP key
# リストの長さを取得
LLEN key
# リストの最後の要素を取り出して取得。
# リストが空なら要素が見つかるかタイムアウトするまでブロックする
BRPOP key1 [key2] timeout
|
キュー(Queue)みたいに、先入れ先出し(FIFO)の動きだね。
セットは文字列型の順序のない集合で、メンバーは一意だよ。よく使うコマンド:
1
2
3
4
5
6
7
8
9
10
11
12
| # 集合に1つまたは複数のメンバーを追加
SADD key member1 [member2]
# 集合の全メンバーを返す
SMEMBERS key
# 集合のメンバー数を取得
SCARD key
# 指定した全集合の積集合(共通部分)を返す
SINTER key2 [key2]
# 指定した全集合の和集合を返す
SUNION key1 [key2]
# 集合から1つまたは複数のメンバーを削除
SREM key member1 [member2]
|
ソート済みセットは文字列要素の集合で、各メンバーに double 型のスコアが紐付いているよ。よく使うコマンド:
1
2
3
4
5
6
7
8
| # ソート済みセットに1つまたは複数のメンバーを追加
ZADD key score1 member1 [score2 member2]
# インデックス範囲で指定した範囲のメンバーを返す
ZRANGE key start stop [WITHSCORES]
# 指定したメンバーのスコアに increment を加算
ZINCRBY key increment member
# ソート済みセットから1つまたは複数のメンバーを削除
ZREM key member1 [member2]
|
各データ型専用のコマンド以外に、どの型でも使える共通コマンドもあるよ:
1
2
3
4
5
6
7
8
| # パターン(pattern)に一致する全キーを探す
KEYS pattern # patternには * とかが使える
# 指定したキーが存在するか確認
EXISTS key
# キーに保存されている値の型を返す
TYPE key
# キーが存在すれば削除
DEL key
|
JavaでRedisを操作する
JDBCを使ってMySQLを操作するのと同じように、RedisもJava用のクライアントを使って操作する必要があるんだ。
RedisのJavaクライアントはたくさんあるけど、有名なのはこのあたり:
- Jedis
- Lettuce
- Spring Data Redis
Jedisはカプセル化が一番しっかりしていて、Redisのコマンドと同じ感覚で使えるから公式でも推奨されているよ。Lettuceはスレッド呼び出しの扱いが上手くてパフォーマンスが良いのが特徴。Springはこれらのクライアントを統合してSpring Data Redisを提供していて、Spring Bootプロジェクトなら専用のStarter(spring-boot-starter-data-redis)も用意されているよ。
Spring Data Redis
Spring Data RedisはSpringプロジェクトの一部で、簡単な設定だけでRedisサーバーにアクセスできるように、低レイヤーのライブラリを高度にカプセル化してくれているんだ。SpringプロジェクトでRedisを楽に扱いたいならこれを使おう。サイト:
https://spring.io/projects/spring-data-redis
Mavenの依存関係:
1
2
3
4
| <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
|
Spring Data Redisでは、RedisTemplate という高度にカプセル化されたクラスが提供されていて、操作のタイプごとに専用のインターフェースにまとめられているよ:
- ValueOperations:string型のデータ操作
- SetOperations:set型のデータ操作
- ZSetOperations:zset型のデータ操作
- HashOperations:hash型のデータ操作
- ListOperations:list型のデータ操作
Redisデータソースの設定(設定ファイル):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| # application
spring:
profiles:
active: dev
redis:
host: ${sky.redis.host}
port: ${sky.redis.port}
password: ${sky.redis.password}
database: ${sky.redis.database}
# -dev
sky:
redis:
host: localhost
port: 6379
password: 123456
# どのデータベースを使うか。指定しない場合は 0
database: 10
|
Redisはデフォルトで16個のデータベース(0-15)を持っていて、設定でその数を変更することもできるよ。
設定クラスを書いて、RedisTemplateオブジェクトを作成する:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| @Configuration
@Slf4j
public class RedisConfiguration {
@Bean
public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory){
log.info("Redisオブジェクトの作成を開始します");
RedisTemplate redisTemplate = new RedisTemplate();
// redisの接続ファクトリをセット
redisTemplate.setConnectionFactory(redisConnectionFactory);
// redisキーのシリアライザをセット
redisTemplate.setKeySerializer(new StringRedisSerializer());
return redisTemplate;
}
}
|
この設定クラスは必須じゃないんだ。SpringBootが自動で RedisTemplate を自動構成してくれるけど、デフォルトのシリアライザが JdkSerializationRedisSerializer だから、Redisに保存されたデータが元のデータと少し違って見えることがあるんだよね。
文字列型のデータ
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| @SpringBootTest
public class RedisTest {
@Autowired
private RedisTemplate redisTemplate;
@Test
public void testString(){
// set
redisTemplate.opsForValue().set("name", "Tom");
// get
String name =(String) redisTemplate.opsForValue().get("name");
System.out.println(name);
// setex
redisTemplate.opsForValue().set("code", "1234", 2, TimeUnit.MINUTES);
// setnx
redisTemplate.opsForValue().setIfAbsent("lock","1");
redisTemplate.opsForValue().setIfAbsent("lock","2");
}
}
|
ハッシュ型のデータ
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| @Test
public void testHash(){
HashOperations hashOperations = redisTemplate.opsForHash();
// hset
hashOperations.put("100", "name", "Jerry");
hashOperations.put("100", "age", "20");
// hget
String name =(String) hashOperations.get("100", "name");
System.out.println(name);
// hkeys
Set keys = hashOperations.keys("100");
System.out.println(keys);
// hvals
List values = hashOperations.values("100");
System.out.println(values);
// hdel
hashOperations.delete("100", "name");
}
|
リスト型のデータ
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| @Test
public void testList(){
ListOperations listOperations = redisTemplate.opsForList();
// lpush
listOperations.leftPushAll("mylist", "a", "b", "c");
listOperations.leftPush("mylist", "d");
// lrange
List mylist = listOperations.range("mylist", 0, -1);
System.out.println(mylist);
// rpop
listOperations.rightPop("mylist");
// llen
Long size = listOperations.size("mylist");
System.out.println(size);
}
|
セット型のデータ
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
| @Test
public void testSet(){
SetOperations setOperations = redisTemplate.opsForSet();
// sadd
setOperations.add("set1","a","b","c","d");
setOperations.add("set2","a","b","x","y");
// smembers
Set members = setOperations.members("set1");
System.out.println(members);
// scard
Long size = setOperations.size("set1");
System.out.println(size);
// sinter
Set intersect = setOperations.intersect("set1", "set2");
System.out.println(intersect);
// sunion
Set union = setOperations.union("set1", "set2");
System.out.println(union);
// srem
setOperations.remove("set1", "a", "b");
}
|
ソート済みセット型のデータ
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| @Test
public void testZset(){
ZSetOperations zSetOperations = redisTemplate.opsForZSet();
// zadd
zSetOperations.add("zset1", "a", 10);
zSetOperations.add("zset1", "b", 12);
zSetOperations.add("zset1", "c", 9);
// zrange
Set zset = zSetOperations.range("zset1", 0, -1);
System.out.println(zset);
// zincrby
zSetOperations.incrementScore("zset1", "c", 10);
// zrem
zSetOperations.remove("zset1", "a", "b");
}
|
共通コマンドの操作
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| @Test
public void testCommon(){
// keys
Set keys = redisTemplate.keys("*");
System.out.println(keys);
// exists
Boolean name = redisTemplate.hasKey("name");
System.out.println(name);
// type
for (Object key : keys) {
DataType type = redisTemplate.type(key);
System.out.println(type.name());
}
// del
redisTemplate.delete("set2");
}
|