第一次接觸 Redis 時,是工作上需要撈取後端同事儲存在上面的資料,當時天真的我都覺得為什麼資料不全部放在資料庫(Mysql, MariaDB)就好?這樣我都去同一個資料源撈就好XD
事實上,後端在開發時會儲存許多不同類型的資料,並不是所有的資料都適合儲存在資料庫中(疑?那不然要存在哪裡?),依照不同的使用場景會儲存在不同的地方,redis 就是其中一個地方~
使用場景
讓我們簡單想像一個情境,假設現在後端開發一個「登入系統」,就是我們最常見的讓使用者輸入「帳號」及「密碼」、做一個登入的動作!
那可想而知一定要有個地方去儲存使用者帳號對應的密碼,所以我們先簡單地都放進 mysql 資料庫吧~
再多想一步
把所有帳號密碼都丟進資料庫這樣真的好嗎?假設今天這個系統有很多使用者、而且大家都頻繁地上線登入,這樣就代表資料庫會被頻繁地查詢。如果帳號一多,資料庫一定會被查到炸掉,所以這樣是不行滴~
Redis cache 的妙用
為什麼資料庫頻繁地被查會炸掉呢?其實資料庫儲存結構是在電腦「硬碟」上,除了搜尋資料速度比較慢之外、頻繁地去硬碟掃資料也容易造成鎖死lock 的情形,而 redis 的 cache快取 儲存方式就恰恰解決了這個問題。
快取簡單的想像就是將資料儲存在電腦「記憶體」中,如果資料是頻繁要去查詢的,存在記憶體中可以讓電腦快速地找到。更白話一點就是如果這些資料是 已經 查詢過的,就先把它們保留在一個小角落,等到有新的請求是要求看已經查詢過的資料,就可以用極快的速度從小角落拿出來、而不用再去倉庫(資料庫)中翻箱倒櫃重新找出來一次。
這個小角落,其實就是 Redis 啦~~
實作情境
今天我們一樣來寫個 python 程式模擬登入系統:現在有許多使用者輸入了「帳號」,而網站收到了帳號會去尋找對應的「密碼」,步驟如下:
- 先嘗試從 redis 拿取密碼X。如果找到密碼就回傳值。
- 如果 步驟1 拿不到密碼,就去 mysql 裡面找。如果找到密碼 X 就在回傳後、寫一筆到 redis 中;
- 如果 步驟2 在 mysql 也找不到密碼,就寫一筆到 mysql 中、並同時也寫一筆到 redis 中,最後回傳密碼。
感覺上很複雜,簡單想就是不管怎樣查資料一定會先從 redis 查,如果查不到才會去 mysql 查。如果連 mysql 都查不到代表一開始沒有建檔,所以要寫一筆進去 mysql 中,中間查詢的過程也都會另外寫一筆到 redis 做快速查詢。
準備工作
首先我們需要安裝好 Redis 與 Mysql,macOS 可以簡單使用 HomeBrew 安裝就好,今天重點先擺在 python實作部分,詳細安裝可自行google關鍵字:「安裝 mysql redis」,都有很多詳細資訊~
安裝好 mysql 後,我們先進入 mysql server 後,並在 localhost 建立一個 database: test
,然後建立一張表 tb_user
專門用來記錄帳號密碼表。可參考以下程式碼:
小~小~的背景知識
或許你又會想問:「咦我們現在又沒有真正的使用者申請,怎麼做到模擬的密碼?」,這篇因為只是要模擬而已,假設我有100個使用者,那我就會隨機在 1-100 之間挑一個數當作帳號,然後把該帳號輸入 sha-256雜湊函數,將函數輸出的值當作密碼。
有在接觸區塊鏈的讀者應該不陌生,沒聽過的讀者也不用緊張,可以把它想像成是一個輸入字串、最後輸出會是長度32的字串,而且是一對一的關係,就很像「帳號」對應「密碼」的關係~
例如我輸入一個字串"a",sha256就會吐一個字串"0cc175b9c0f1b6a831c399e269772661",其他輸入字串都不可能得到跟字串"a"一樣的結果。python 中有 hashlib 這個函式可以操作,大家可以先參考下面的程式碼玩玩看:
# 字串 "a" 輸出結果
0cc175b9c0f1b6a831c399e269772661
正式開始
首先
我們先使用 python 連入本地端的 redis 與 mysql:
再來我們寫一個計時器,當作之後函數運行的 decorator ,讓我們可以對函數的運行進行計時,方便之後做運行速度的比較~
模擬 redis + mysql 查詢
進入重頭戲,我們來實作上面一開始所說的,先使用 redis 當快取緩存、如果查不到資料再去 mysql 裡面查詢。
一開始的參數設定,我預設有 100 位使用者
、並且 隨機重複查詢 10000 次
,另外在一開始會先把 redis 與 mysql 的資料做清除,為了測試的公平性~
模擬只用 mysql 查詢
對照組我們就每次查詢都只去 mysql 查詢,如果沒有查到就在 mysql 寫一筆:
速度運行大PK
程式碼都刻完,現在我們寫一個腳本來呼叫函數執行吧~
用肉眼看好像 redis + mysql 的程式碼複雜許多,到底誰會比較快呢?
執行腳本的結果:
我們發現,搭配 redis 的速度快上許多,尤其是如果短時間隨機查詢到了 100000 次時,如果只用 mysql 查詢竟然要超過一分鐘。這個如果是大型網站,絕對會被使用者靠北到不行XD
詳細的程式碼一樣放在我的 github,有興趣的讀者可以自行下載玩玩看