[Rails] Redis的引入和使用方法
Redis是什么?
特点
不是关系型数据库(RDB)。将数据存储在机器的内存中。
*作为对比,在关系型数据库MySQL中,数据存储在文件中。
优势
-
- メモリ上でデータを扱うため処理が早い(HDDとメモリでは数万倍の差がある)
-
- すべての処理が完了しないとロールバックされる機能がデフォである
-
- 直列処理であるため、データの不整合は発生しない
- 複数のDBを持てる
缺点
-
- マシン上のメモリの消費が大きく、データの保存量上限は少ない
メモリ上限に達すると指定したルールに従ってデータが削除される
マシンが落ちたときデータが揮発してしまう
シングルスレッドでの動作であり、並列処理ができない & 1コアしか使えないためCPUのコア数を上げても無駄
マスタ-スレーブ構成が可能だが、非同期であるため不整合が発生する可能性あり
数据的备份措施 de
有两种选择
从快照中恢复
定期的に「Redis Database」ファイルにRedisのスナップショットを作成することで、ある程度の防止が可能ですが、直前のデータは復元できません。
AOF 的以下内容进行释义,只需要一个选项:
从数据库操作日志中备份数据的方法。
由于记录日志会降低数据库操作的执行速度,但可以恢复最近的数据。
应用
-
- セッション管理: RDSでセッション情報を扱うより高速に動作させられる
-
- Webページのキャッシュ
- リアルタイム性を求められる機能(ランキングとか): リスト化した状態で保存して随時ソートを行う
相似的软件Memcached。
嗯,因为没有明显的优点,所以选择Redis似乎是没有错的。
请提供更多上下文,然后我可以准确地为您提供答案。
(Translation: Please provide more context, and I can give you an accurate answer.)
利用步骤
当然,使用Redis需要有相应的服务器和客户端软件。
在搭建本地开发环境时,可以按照以下docker-compose步骤进行。
Redis服务器
docker-compose文件
# redisコンテナはデフォルトで0〜15のインデックスのDBが作成され、リッスンポート6379で起動し、
# /dataに60秒に1回スナップショット(Redis Databaseファイル)を作成するようになっている
redis:
container_name: redis
# dockerホスト起動時にコンテナが起動するよう設定
restart: always
image: "redis:latest"
ports:
- "6379:6379"
volumes:
- "./data/redis:/data"
Redis客户端
Redis的安装和设置
在Gemfile中写明
gem 'redis'
安装
bundle install
③Redis客户端的设置
③-1. 为了在不同的RAILS_ENV环境中切换,需要在config/settings/<環境名>.yml文件中写入以下内容。
# 例. development.yml で ローカルのredisサーバーへ接続する
redis:
host: redis
port: 6379
db: 0 # DBのindex. Redisはデフォで16のDBを持ち、0〜15のindexがある。
在本地创建config/initializers/redis.rb文件,并按照以下配置进行设置。
# RAILS_ENV別のredisクライアント設定読み込み
redis = Settings.redis
# redisクライアントのインスタンスを生成してRedis.currentでアクセスできるようにする
Redis.current = Redis.new(
host: redis.host,
port: redis.port,
db: redis.db
)
动作确认
# 前提: redisコンテナが起動している
# 1. railsサーバーが起動しているコンテナへログイン
docker exec -it <railsコンテナID> bash
# 2. rails console起動
bundle exec rails c
# 3. 適当なキー、値をセットしてみる
Redis.current.set("a", "b")
Redis.current.get("a")
=>
"b" と表示されれば、Redisサーバー & Redisクライアントともに正常に動作している
请参考
使用方式
只需对Redis客户端实例执行键值设置(set)方法(用于写入数据)和获取(get)方法(用于读取数据)。
然而,值可以是以下五种数据类型之一,但每种数据类型应使用不同的方法。
字符串类型
参考: 参考
-
- set
-
- setex
- get
# 保存されるデータ型のイメージ
{'key': "value"}
# set
## 期限なし
Redis.current.set('en', 'Hello')
## 期限あり(秒で設定)
Redis.current.setex('en', 10, 'Hello')
# get
Redis.current.get('en')
=> "Hello" ※setexでセットした場合は、指定した秒数後はnilで返ってくる。
List类型
可以在开头或末尾添加数据。
# 保存されるデータ型のイメージ
{"key": ["value1", "value2",...]}
# set
## 末尾追加
Redis.current.rpush("en", "Hello")
## 先頭追加
Redis.current.lpush("en", "Hello2")
# get
## i番目の値を取得
Redis.current.lindex("en", 0)
=>"Hello2"
## リストのi番目からj番目までの値を配列で取得(先頭インデックスは0)
Redis.current.lrange("en", 0, 1)
=>["Hello2", "Hello"]
集合型
无法将具有相同值的元素注册到值的数组中。
以无序方式保存。
可以使用集合操作方法,感觉更像是为了集合操作而设计的。
# 保存されるデータ型のイメージ
{"key": ["value1", "value2",...]}
# set
## 追加
Redis.current.sadd("en", "Hello")
Redis.current.sadd("en", "Hello2")
Redis.current.sadd("en2", "Hello2")
Redis.current.sadd("en2", "Hello3")
# get
## 全要素を取得
Redis.current.smembers("en")
=>["Hello2", "Hello"]
## 和を出す
Redis.current.sunion("en", "en2")
=>["Hello2", "Hello3", "Hello",]
排序集合类型。不允许注册相同的值。
数组元素按“得分”进行排序,并具有“排名”。可以进行得分/排名范围搜索。
# 保存されるデータ型のイメージ
{"key": [["value1", score1], ["value2", score2]]}
# set
Redis.current.zadd("score_ranking", 10, "user_id_1")
Redis.current.zadd("score_ranking", 500, "user_id_2")
Redis.current.zadd("score_ranking", 600, "user_id_3")
Redis.current.zadd("score_ranking", 1, "user_id_4")
# get
## 特定要素の順位を取得
Redis.current.zrank("score_ranking", "user_id_3")
=>3
## スコア上位iからjまでの値を取得。iは0始まり
Redis.current.zrevrange("score_ranking", 0, 2)
=>["user_id_3", "user_id_2", "user_id_1"]
## スコア上位iからjまでの値とスコアを取得。iは0始まり
Redis.current.zrevrange("score_ranking", 0, 2, with_scores: true)
=> [["user_id_3", 600.0], ["user_id_2", 500.0], ["user_id_1", 10.0]]"user_id_3"], [500, "user_id_2"], [10, "user_id_1"]]
哈希类型
这是一个由键和值组成的哈希表,其中键可以用来进行查找,但值不能用于查找。它类似于关系型数据库的管理方式。
参考: 参考资料
-
- hset
-
- hsetnx
-
- hget
-
- hmset
- hmget
# 保存されるデータ型のイメージ
{"key": {"value_key": value_value}}
# 1つのカラム・値で構成されるレコードをset,getする例
## set
### すでに「"record"」が存在する場合は上書きされる
Redis.current.hset("record", "column_1_key", "column_1_value")
### すでに「"record"」が存在する場合は上書きされない
Redis.current.hsetnx("record", "column_1_key", "column_1_value")
## get
Redis.current.hget("record", "column_1_key")
=>
"column1_value"
# 複数のカラム・値で構成されるレコードをset,getする例
## set
Redis.current.hmset("record",
[
"column1_key", "column1_value",
"column2_key", "column2_value",
]
)
## get
Redis.current.hmget("record", ["column_1_key", "column_2_key"])
=> ["column_1_value", "column2_value"]
可提供以下建议
应用编程
当将ActiveRecord等对象转换为字符串类型并保存到Redis时,可以:
-
- Marshal.dump(<オブジェクト>)
- Marshal.load(<オブジェクト>)
使用它会有很好的效果。
键: “key”,以ActiveRecord类型进行set和get的示例
# set
user = User.first
Redis.current.set("key", Marshal.dump(user))
# get
user_str = Redis.current.get("key")
Marshal.load(user_str)
记事
由于gem“redis”中存在一个类方法“Redis.current”,该方法用于保存Redis客户端实例,因此在每个Rails源文件中使用Redis时应使用该方法。
请参考