Redis
是 Remote Dictionary Server
的簡寫,意思為遠端字典Server。
字典Dictionary 即是Key-Value
對照表。
Redis存放資料的速度極快,是物理層面上的快,因為Redis對記憶體(Memory)進行操作。
用以下數量級打個比方,會比較有感覺
假如磁碟(Disk、Storage)
的讀寫速度是1、容量10000。
那麼...
記憶體(Mem、RAM)
的讀寫速度會是100、容量是100,
CPU快取(Cache)
的讀寫速度是10000、容量是1。
之前提到的MySQL資料庫是對硬碟進行讀寫,
Redis將資料存放於記憶體中的特點為:讀寫速度比存放於磁碟快、但容量較小,且資料在斷電就揮發(Volatile)不見了(若沒及時寫進磁碟中的話)
若有短時間內大量存取的需求,卻又不想如此頻繁的對硬碟讀寫,這種場合可以使用Redis資料庫
暫時存放資料,等一段時間後再一齊寫入硬碟裡。
Redis與MySQL
同樣是資料庫,分成Server端與Client端,只是存放資料的形式不同。
到Github下載 .msi安裝檔案,
接著下一步、勾選加入PATH環境變數
預設會將Redis Server開啟成一項 Windows服務
Server端有了,再來啟動一個CMD
來執行 Client端
$ redis-cli
用Homebrew
來快速方便的安裝
$ brew install redis
啟動Redis Server 端
$ redis-server
再另外起一個Terminal來執行Client
$ redis-cli
把container命名為redis_test
$ docker run --name redis_test -d -p 6379:6379 redis
執行Client端
$ docker exec -it redis_test /bin/bash
# redis-cli
(要結束Redis的話)
$ docker container rm -f redis_test
(如果Windows上出現 the input device is not a TTY. If you are using mintty, try prefixing the command with 'winpty'
的錯誤,將terminal改用CMD再試一次。)
Redis Server端預設使用 6379 port
。
成功啟動Redis Server後的畫面,直接畫一個Redis的圖樣出來。
此時對Client端下指令:
PING
PONG (乒乓球?)
如同在Go語言中 用指令操作map結構
一般,非常的簡便。
> SET test 123
> GET test
隨便設幾個Key-Value
來玩玩吧~
是不是忘記自己下過哪些變數名稱了、怕怕的?
可利用KEYS指令,透過 pattern
(正規表達式) 來查詢。
> KEYS *
Keys指令的時間複雜度為O(n)
,會佔用Redis單線程、卡到後面讀寫指令,
在程式開發、測試時可以使用,但在大型正式運行的伺服器中千萬別使用KEYS
相關指令,
查詢時若大批的資料湧進會造成堵塞、炸裂。建議改用SCAN
指令來查詢。
在當前的Redis資料庫中進行迭代。
一開始先下SCAN 0
,之後看他回傳的數值 接著繼續SCAN迭代下去。
> SCAN 0
此時若第一個回傳值為"15"
> SCAN 15
持續步驟直到第一個回傳值為"0"
忘記這個Key對應到的是甚麼物件類型了?
查詢test的類型
> TYPE test
Redis鍵值資料庫中也有分格式,常用到的格式有:
Score
分數來排序,是個極度有趣的格式。所有的指令在 Redis官網 都有詳細記載,真的夭壽多。
以下會快速導覽、稍微熟悉一下Redis指令用法。
雖然是字串,但實際上可以放數字。
設置 test1的值為123
> SET test1 123
設置 test1的值為字串
> SET test1 "Hello Redis"
此筆資料10秒後自動過期(Expired)、刪除。免費的倒數計時器,天殺的太方便啦
> SET test1 "123" EX 10
test1加1、test1減1
> INCR test1
> DECR test1
test1加50、test1減50
> INCRBY test1 50
> DECRBY test1 50
返回test1字串的長度
> STRLEN test1
透過append在字尾新增字串hello,接著返回字串總長度
> APPEND test "hello"
> GET test1
將a塞入list1之中
> LPUSH list1 hello
LPUSH
: 往左側(頭)塞入元素a,若無list1則自動建立一個新的
RPUSH
: 往右側(尾)塞入元素a,若無list1則自動建立一個新的
LPUSHX
:若無list1則塞入失敗,不會自動建立
一次塞多個值進list1
> LPUSH list1 b c d a a a
將list1最左側(頭)的元素POP彈出
> LPOP list1
看 list1 之中 第0到100的元素(含0含100)
> LRANGE list1 0 100
若要查看所有元素可使用:LRANGE list1 0 -1
。 Index -1 代表最後一個項目
Hash
即為 一組Key對應到一組Value
HSET 設 hash1表裡面的 h1
鍵 值為123
> HSET hash1 h1 123
HMSET 設置hashmap
(一次設多個HSET)
> HMSET hash1 h2 234 h3 345 h4 456
取得hash1表中的 h1
的值
> HGET hash1 h1
取得hash1表中全部的鍵值
> HGETALL hash1
在Redis中 不支援巢狀Hash(hash中不能再設hash),
可以用Serialize
或 將兩個Hash Table
當成 key:value 對應來達成
或者使用ReJSON
(Redis JSON),可方便儲存Json格式
Set 集合
裡面的內容,是唯一且不重複的。
譬如學生的 學號
> SADD set1 "S00001"
> SADD set1 "S00002" "S00003" "S00004" "S00005" ...
> SCARD set1
返回集合總數量
> SDIFF set1
返回、列出不同的Set
有Score 分數
的集合。
可以想像成:考完期中考的學生,各自都會對應到一個分數。
分數可重複,學生不能重複
S00001 拿到了99分
S00002 拿到了3分
S00003 也拿到了3分
> ZADD exam 99 "S00001"
> ZADD exam 3 "S00002"
> ZADD exam 3 "S00003"
若加上XX
的話,只會更新已存在的值,若無鍵 則不會新增。
老師也想來考試,但沒有在名單上 不給你考勒~
> ZADD exam XX 100 "Teacher"
改成NX
則相反:只新增鍵、不會更新已存在的
查看來考試的學生數量
> ZCARD exam
查看S00001
的分數
> ZSCORE exam S00001
有幾個人分數落在0~10分的
> ZCOUNT exam 0 20
印出所有人的 排名(從低分印到高分)
> ZRANGE exam 0 -1
印所有人的 排名與分數(從低分印到高分)
> ZRANGE exam 0 -1 WITHSCORES
把 S00001
的分數+3分,直接變102分突破天際啦!
> ZINCRBY exam 3 S00001
程式可以辦到很多事情嘛,我們一樣可以透過 Golang程式 來模擬 Redis Client端的執行。
而在golang github社群中有兩個主流的Redis函式庫。
Oh My God!
這兩個命名真的非常像,一個把go放前面、一個把go放後面,常常搞混...
在這裡會介紹go-redis
這一個星星數稍微多一點點的項目。
(希望不會發生哪天星星數被追過去了...這樣還要改文章)