你必須很努力

Day23 - Ruby on Rails 中的 Redis 的介紹與應用

2020/09/28
字數統計: 1.5k閱讀時間: 6 min

前言

RedisBSD 授權的開源軟體,屬於 NoSQL 家族成員之一,是 in-memory 的 key-value 資料庫,基於資料存在記憶體的特性,其存取速度比硬碟快許多,常被應用在需要快取 (Cache) 的場合,也可使用在 Database 及簡單的 Message broker,與 Memcached 比,穩定性更好

以下擷取自 Wiki 介紹

Redis是一個使用ANSI C編寫的開源、支援網路、基於記憶體、可選永續性的鍵值對儲存資料庫。根據月度排行網站DB-Engines.com的資料,Redis是最流行的鍵值對儲存資料庫

(謎之聲,有興趣想知道記憶體與硬碟的速度差異,可 Google 下,題外話,之前會用 RAM disk 在上面執行作業系統、軟體等,速度有感提升


特色

  1. 效能好 (與 database 比)、穩定性高 (與 Memcached 比)
  2. 資料是儲存在 Memory (記憶體)
  3. Single Thread I/O Multiplex

由於資料是儲存在 Memory 上,Memory 特性為斷電 (或關機、重開機) 會造成資料遺失,Redis 可以設定資料同步到硬碟,但如果剛好遇到同步前就斷電的話,資料就掰掰惹,或遇到 CPU、Memory 接近滿載,同時又有大量資料需要透過 Redis 處理,也可能會遇到資料遺失。

Redis 是 Single Thread,這點非常重要,不論 Server CPU Core (核心) 為幾核,1 個 Redis 只會使用到 1 個 CPU Core (核心),無法同時運算多個 request,當有 1 個 request 佔用 CPU 太久時,會導致無法回應其他 connection request 而造成後面塞車。

(謎之聲,Redis 背後運作原理、處理機制等,網路上有許多資料可以參考,不在這一一描述


如何安裝

在終端機輸入

1
2
3
4
# MacOS、Linux 原生不支援這指令

# MacOS 安裝指令
brew install redis

在 Ruby on Rails 專案的 Gemfile 加入

1
2
3
4
5
# Gemfile

gem 'redis', '~> 4.2', '>= 4.2.2'

# 以 Rails 6.0.3.3 為例,預設 Gemfile 中,是註解,取消註解,再 bundle 即可

常用指令介紹

進入 Redis 終端機 (Command-Line Interface) 畫面

1
2
3
# 在終端機輸入

redis-cli

開啟 redis server

1
2
3
# 在終端機輸入

redis-server

redis 性能測試

1
2
3
# 在終端機輸入

redis-benchmark

查看 redis 資訊 (information)

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
# 進入 redis-cli 後,輸入

info


# Server
redis_version:6.0.8
redis_git_sha1:00000000
redis_git_dirty:0
redis_build_id:25b38681eed52ae
redis_mode:standalone
os:Darwin 19.6.0 x86_64
arch_bits:64
multiplexing_api:kqueue
atomicvar_api:atomic-builtin
gcc_version:4.2.1
process_id:1552
run_id:1ea27ec21bc37fea806bb2ccf213132176f
tcp_port:6379
uptime_in_seconds:15272
uptime_in_days:0
hz:10
configured_hz:10
lru_clock:7122746
executable:/usr/local/opt/redis/bin/redis-server
config_file:/usr/local/etc/redis.conf
io_threads_active:0

...
...
...

設定 Redis 相關參數(配置)

infoconfig_file 這欄,可看到 redis.conf 檔案路徑,該檔案內的註解很詳細,Google 下也有相關參數設定說明可參考

SET, GET

SET 設定 key-value

GET 從 key 取 value

1
2
3
4
127.0.0.1:6379> SET river 'hi'
OK
127.0.0.1:6379> GET river
"hi"

HSET, HGET

HSET 設定 hash key-value

HGET 取 hash key 的 value

1
2
3
4
5
6
127.0.0.1:6379> HSET order1 name 'order_name' price 500 note 'nothing'
(integer) 3
127.0.0.1:6379> HGET order1 note
"nothing"
127.0.0.1:6379> HGET order1 price
"500"

INCR, DECR

針對指定 key 的 value 進行數字加減

INCR 針對 key 的 value +1

DECR 針對 key 的 value -1

備註: 若 value 型別不是數字,會回 (error) WRONGTYPE Operation against a key holding the wrong kind of value

1
2
3
4
5
6
127.0.0.1:6379> SET num '4'
OK
127.0.0.1:6379> DECR num
(integer) 3
127.0.0.1:6379> INCR num
(integer) 4

更多指令請參考官方commands (文件有針對每個指令提供範本與說明)

操作範例

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
# 終端機輸入,進入 Redis Command-Line Interface
redis-cli

# ---

127.0.0.1:6379> ping # 測試連線是否正常,回傳 PONG 代表正常
PONG
127.0.0.1:6379> set river 'https://riverye.com/' # 設定 key 是 "river", value 是 "https://riverye.com/"
OK
127.0.0.1:6379> get river # 讀取 key "river"
"https://riverye.com/"
127.0.0.1:6379> del river # 刪除 key "river"
(integer) 1
127.0.0.1:6379> get river
(nil)
127.0.0.1:6379> set say hi EX 5 # 設定 key "set" 存在 5 秒, EX 為設定期限 (單位是秒)
OK
127.0.0.1:6379> get say # 上面設定好,在 5 秒內查詢
"hi"
127.0.0.1:6379> get say # 5 秒後,讀取 key "say" ,會變 nil
(nil)
127.0.0.1:6379> hmset order name 'order_name' price 999 note '不知寫什麼' # 設定 雜湊表 "order"
OK
127.0.0.1:6379> hgetall order # 讀取 雜湊表 "order"
1) "name"
2) "order_name"
3) "price"
4) "999"
5) "note"
6) "\xe4\xb8\x8d\xe7\x9f\xa5\xe5\xaf\xab\xe4\xbb\x80\xe9\xba\xbc"
127.0.0.1:6379>

rails console 操作 Redis

1
2
3
4
5
6
7
8
9
10
11
12
# 終端機輸入
rails c

# ---

r = Redis.new
r.hgetall("order")
# {
# "name" => "order_name",
# "price" => "999",
# "note" => "不知寫什麼"
# }

示範在 Rails console 操作 Redis

參考資料

  1. 深入分析Redis特点及应用场景
  2. Redis系列 - C#存取Redis (上)
  3. 資料庫的好夥伴:Redis
  4. Redis資料庫看這一篇文章就夠了
  5. Redis常见面试题连环问,你能回答到第几问?(上)
  6. Redis常见面试题连环问,你能回答到第几问?(中)
  7. Redis常见面试题连环问,你能回答到第几问?(下)

小結

會在許多場景看到 Redis 出沒,全端與後端必備技能之一,舉個例子來說,之前在處理不同頁面皆要顯示同資訊「未處理訂單數量」,是透過打 API 詢問未處理的訂單資訊,接著與 Database 比對該訂單名稱是否被建立過、訂單的商品數量與 Database 中商品庫存是否足夠...等,由 worker 處理,經過一連串處理後,才能計算出實際「未處理訂單數量」,另個頁面是儀表板頁面,只需顯示「未處理訂單數量」,這時透過 Redis 處理,將計算結果存在 Redis ,另個頁面直接取值顯示即可

上述例子為實際應用過的情境之一,若對 Redis 還不熟悉也不用太緊張,上方參考連結的文章,由淺入深的排序,可以從數字 1 開始往下看,過程中搭配實際操作練習,會更快上手喔


鐵人賽文章連結:https://ithelp.ithome.com.tw/articles/10245246
medium 文章連結:https://link.medium.com/V8n6I2TQ79
本文同步發布於 小菜的 Blog https://riverye.com/

備註:之後文章修改更新,以個人部落格為主

原文連結:https://riverye.com/2020/09/28/Day23-Ruby-on-Rails-中的-Redis-的介紹與應用/

發表日期:2020-09-28

更新日期:2020-09-28

CATALOG
  1. 1. 前言
  2. 2. 特色
  3. 3. 如何安裝
  4. 4. 常用指令介紹
    1. 4.0.1. 進入 Redis 終端機 (Command-Line Interface) 畫面
    2. 4.0.2. 開啟 redis server
    3. 4.0.3. redis 性能測試
    4. 4.0.4. 查看 redis 資訊 (information)
    5. 4.0.5. 設定 Redis 相關參數(配置)
  5. 4.1. SET, GET
  6. 4.2. HSET, HGET
  7. 4.3. INCR, DECR
  • 5. 操作範例
    1. 5.0.1. 示範在 Rails console 操作 Redis
  • 6. 參考資料
  • 7. 小結