Redis 是 BSD 授權的開源軟體,屬於 NoSQL 家族成員之一,是 in-memory 的 key-value 資料庫,基於資料存在記憶體的特性,其存取速度比硬碟快許多,常被應用在需要快取 (Cache) 的場合,也可使用在 Database 及簡單的 Message broker,與 Memcached 比,穩定性更好
以下擷取自 Wiki 介紹
Redis是一個使用ANSI C編寫的開源、支援網路、基於記憶體、可選永續性的鍵值對儲存資料庫。根據月度排行網站DB-Engines.com的資料,Redis是最流行的鍵值對儲存資料庫
(謎之聲,有興趣想知道記憶體與硬碟的速度差異,可 Google 下,題外話,之前會用 RAM disk 在上面執行作業系統、軟體等,速度有感提升
由於資料是儲存在 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-cli
# 在終端機輸入
redis-server
# 在終端機輸入
redis-benchmark
# 進入 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
...
...
...
從 info
的 config_file
這欄,可看到 redis.conf
檔案路徑,該檔案內的註解很詳細,Google 下也有相關參數設定說明可參考
SET
設定 key-value
GET
從 key 取 value
127.0.0.1:6379> SET river 'hi'
OK
127.0.0.1:6379> GET river
"hi"
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"
針對指定 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" => "不知寫什麼"
# }
會在許多場景看到 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/
備註:之後文章修改更新,以個人部落格為主