沒看redis入門指南這本書以前,我是經過別人的博客和手冊來學習redis的,所獲得的知識零零碎碎,最近兩個星期看完了入門指南這本書get到了許多知識,因而打算分享一篇學習筆記。php
提示 Redis 對於鍵的命名並無強制的要求,但比較好的實踐是用「對象類型:對象ID:對象屬性」來命名一個鍵,如使用鍵user:1:friends來存儲ID爲1的用戶的好友列表。對於多個單詞則推薦使用「.」分隔,一方面是沿用之前的習慣(Redis之前版本的鍵名不能包含空格等特殊字符),另外一方面是在 redis-cli 中容易輸入,無需使用雙引號包裹。另外爲了往後維護方便,鍵的命名必定要有意義,如 u:1:f的可讀性顯然不如user:1:friends好.html
例如:文章ID爲1的這篇文章的觀看量要如何命名?redis
$key = "article:1:view";
複製代碼
ps:雖然採用較短的名稱能夠節省存儲空間,但因爲鍵值的長度每每遠遠大於鍵名的長度,因此這部分的節省大部分狀況下並不如可讀性來得重要。數據庫
Redis中的事務(transaction)是一組命令的集合。事務同命令同樣都是 Redis 的最小執行單位,一個事務中的命令要麼都執行,要麼都不執行。事務的應用很是廣泛,如銀行轉帳過程當中A給B匯款,首先系統從A的帳戶中將錢划走,而後向B的帳戶增長相應的金額。這兩個步驟必須屬於同一個事務,要麼全執行,要麼全不執行。不然只執行第一步,錢就憑空消失了,這顯然讓人沒法接受。緩存
redis> MULTI
OK
redis> SADD "user:1:following" 2
QUEUED
redis> SADD "user:2:followers" 1
QUEUED
redis> EXEC
1) (integer) 1
2) (integer) 1
複製代碼
上面的代碼演示了事務的使用方式。首先使用MULTI命令告訴Redis:「下面我發給你的命令屬於同一個事務,你先不要執行,而是把它們暫時存起來。」Redis回答:「OK。」安全
然後咱們發送了兩個 SADD命令來實現關注和被關注操做,能夠看到 Redis 遵照了承諾,沒有執行這些命令,而是返回QUEUED表示這兩條命令已經進入等待執行的事務隊列中了。網絡
當把全部要在同一個事務中執行的命令都發給 Redis 後,咱們使用 EXEC 命令告訴Redis將等待執行的事務隊列中的全部命令(即剛纔全部返回QUEUED的命令)按照發送順序依次執行。EXEC 命令的返回值就是這些命令的返回值組成的列表,返回值順序和命令的順序相同。app
Redis保證一個事務中的全部命令要麼都執行,要麼都不執行。若是在發送EXEC命令前客戶端斷線了,則 Redis 會清空事務隊列,事務中的全部命令都不會執行。而一旦客戶端發送了EXEC命令,全部的命令就都會被執行,即便此後客戶端斷線也不要緊,由於Redis中已經記錄了全部要執行的命令。性能
有些狀況下會不適合使用事務來保證數據操做的原子性,這時候就要用到腳本。學習
使用腳本的好處有以下幾點: (1)減小網絡開銷:若是五條命令最多須要向Redis發送5次請求,而使用腳本功能完成一樣的操做只須要發送一個請求便可,減小了網絡往返時延。
(2)原子操做:Redis 會將整個腳本做爲一個總體執行,中間不會被其餘命令插入。換句話說在編寫腳本的過程當中無需擔憂會出現競態條件,也就無需使用事務。事務能夠完成的全部功能均可以用腳原本實現。
(3)複用:客戶端發送的腳本會永久存儲在 Redis 中,這就意味着其餘客戶端(能夠是其餘語言開發的項目)能夠複用這一腳本而不須要使用代碼完成一樣的邏輯。
當使用Redis存儲非臨時數據時,通常須要打開AOF持久化來下降進程停止致使的數據丟失。AOF能夠將Redis執行的每一條寫命令追加到硬盤文件中,這一過程顯然會下降Redis 的性能,可是大部分狀況下這個影響是能夠接受的,另外使用較快的硬盤能夠提升AOF的性能。
雖然每次執行更改數據庫內容的操做時,AOF都會將命令記錄在AOF文件中,可是事實上,因爲操做系統的緩存機制,數據並無真正地寫入硬盤,而是進入了系統的硬盤緩存。在默認狀況下系統每30秒會執行一次同步操做,以便將硬盤緩存中的內容真正地寫入硬盤,在這30秒的過程當中若是系統異常退出則會致使硬盤緩存中的數據丟失。通常來說啓用AOF持久化的應用都沒法容忍這樣的損失,這就須要Redis在寫入AOF文件後主動要求系統將緩存內容同步到硬盤中。在 Redis 中咱們能夠經過 appendfsync 參數設置同步的時機:
# appendfsync always
appendfsync everysec
# appendfsync no
複製代碼
默認狀況下Redis採用everysec規則,即每秒執行一次同步操做。always表示每次執行寫入都會執行同步,這是最安全也是最慢的方式。no表示不主動進行同步操做,而是徹底交由操做系統來作(即每30秒一次),這是最快但最不安全的方式。通常狀況下使用默認值everysec就足夠了,既兼顧了性能又保證了安全。
看完書中的redis內部編碼優化,我仍是挺不解的,直到看到一篇博客才恍然大悟。