iT邦幫忙

第 12 屆 iT 邦幫忙鐵人賽

DAY 23
0
自我挑戰組

Ruby on Rails 與它們相關的東西系列 第 23

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

前言

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 背後運作原理、處理機制等,網路上有許多資料可以參考,不在這一一描述


如何安裝

在終端機輸入

# MacOS、Linux 原生不支援這指令

# MacOS 安裝指令
brew install redis

在 Ruby on Rails 專案的 Gemfile 加入

# Gemfile

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

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

常用指令介紹

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

# 在終端機輸入

redis-cli

開啟 redis server

# 在終端機輸入

redis-server

redis 性能測試

# 在終端機輸入

redis-benchmark

查看 redis 資訊 (information)

# 進入 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

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

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

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 (文件有針對每個指令提供範本與說明)

操作範例

# 終端機輸入,進入 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

# 終端機輸入
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/

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


上一篇
Day22 - Ruby on Rails 中的 Race Condition
下一篇
Day24 - Ruby on Rails 中的 Resque 的介紹與應用
系列文
Ruby on Rails 與它們相關的東西31

尚未有邦友留言

立即登入留言