十個正確使用 Redis 的技巧

Redis 在當前的技術社區裏是很是熱門的。歷來自 Antirez 一個小小的我的項目到成爲內存數據存儲行業的標準,Redis已經走過了很長的一段路。隨之而來的一系列最佳實踐,使得大多數人能夠正確地使用 Redis。下面咱們將探索正確使用 Redis 的10個技巧。web

一、中止使用 KEYS *redis

Okay,以挑戰這個命令開始這篇文章,或許並非一個好的方式,但其確實多是最重要的一點。不少時候當咱們關注一個redis實例的統計數據,咱們會快速地輸入」KEYS *」命令,這樣key的信息會很明顯地展現出來。平心而論,從程序化的角度出發每每傾向於寫出下面這樣的僞代碼:數據庫

123 for key in'keys *': doAllTheThings()

可是當你有1300萬個key時,執行速度將會變慢。由於KEYS命令的時間複雜度是O(n),其中n是要返回的keys的個數,這樣這個命令的複雜度就取決於數據庫的大小了。而且在這個操做執行期間,其它任何命令在你的實例中都沒法執行。app

做爲一個替代命令,看一下 SCAN 吧,其容許你以一種更友好的方式來執行… SCAN 經過增量迭代的方式來掃描數據庫。這一操做基於遊標的迭代器來完成的,所以只要你以爲合適,你能夠隨時中止或繼續。工具

二、找出拖慢 Redis 的罪魁禍首測試

因爲 Redis 沒有很是詳細的日誌,要想知道在 Redis 實例內部都作了些什麼是很是困難的。幸運的是 Redis 提供了一個下面這樣的命令統計工具:網站

123456 127.0.0.1:6379> INFO commandstats# Commandstatscmdstat_get:calls=78,usec=608,usec_per_call=7.79cmdstat_setex:calls=5,usec=71,usec_per_call=14.20cmdstat_keys:calls=2,usec=42,usec_per_call=21.00cmdstat_info:calls=10,usec=1931,usec_per_call=193.10

經過這個工具能夠查看全部命令統計的快照,好比命令執行了多少次,執行命令所耗費的毫秒數(每一個命令的總時間和平均時間)spa

只須要簡單地執行 CONFIG RESETSTAT 命令就能夠重置,這樣你就能夠獲得一個全新的統計結果。線程

三、 將 Redis-Benchmark 結果做爲參考,而不要一律而論日誌

Redis 之父 Salvatore 就說過:「經過執行GET/SET命令來測試Redis就像在雨天檢測法拉利的雨刷清潔鏡子的效果」。不少時候人們跑到我這裏,他們想知道爲何本身的Redis-Benchmark統計的結果低於最優結果 。但咱們必需要把各類不一樣的真實狀況考慮進來,例如:

  • 可能受到哪些客戶端運行環境的限制?

  • 是同一個版本號嗎?

  • 測試環境中的表現與應用將要運行的環境是否一致?

Redis-Benchmark的測試結果提供了一個保證你的 Redis-Server 不會運行在非正常狀態下的基準點,可是你永遠不要把它做爲一個真實的「壓力測試」。壓力測試須要反應出應用的運行方式,而且須要一個儘量的和生產類似的環境。

四、Hashes 是你的最佳選擇

以一種優雅的方式引入 hashes 吧。hashes 將會帶給你一種史無前例的體驗。以前我曾看到過許多相似於下面這樣的key結構:

123 foo:first_namefoo:last_namefoo:address

上面的例子中,foo 多是一個用戶的用戶名,其中的每一項都是一個單獨的 key。這就增長了 犯錯的空間,和一些沒必要要的 key。使用 hash 代替吧,你會驚奇地發現居然只須要一個 key :

123456789101112 127.0.0.1:6379> HSET foo first_name "Joe"(integer) 1127.0.0.1:6379> HSET foo last_name "Engel"(integer) 1127.0.0.1:6379> HSET foo address "1 Fanatical Pl"(integer) 1127.0.0.1:6379> HGETALL foo1)"first_name"2)"Joe"3)"last_name"4)"Engel"5)"address"6)"1 Fanatical Pl"127.0.0.1:6379> HGET foo first_name"Joe"

五、設置 key 值的存活時間

不管何時,只要有可能就利用key超時的優點。一個很好的例子就是儲存一些諸如臨時認證key之類的東西。當你去查找一個受權key時——以OAUTH爲例——一般會獲得一個超時時間。這樣在設置key的時候,設成一樣的超時時間,Redis就會自動爲你清除!而再也不須要使用KEYS *來遍歷全部的key了,怎麼樣很方便吧?

六、 選擇合適的回收策略

既然談到了清除key這個話題,那咱們就來聊聊回收策略。當 Redis 的實例空間被填滿了以後,將會嘗試回收一部分key。根據你的使用方式,我強烈建議使用 volatile-lru 策略——前提是你對key已經設置了超時。但若是你運行的是一些相似於 cache 的東西,而且沒有對 key 設置超時機制,能夠考慮使用 allkeys-lru 回收機制。個人建議是先在這裏查看一下可行的方案。

七、若是你的數據很重要,請使用 Try/Except

若是必須確保關鍵性的數據能夠被放入到 Redis 的實例中,我強烈建議將其放入 try/except 塊中。幾乎全部的Redis客戶端採用的都是「發送即忘」策略,所以常常須要考慮一個 key 是否真正被放到 Redis 數據庫中了。至於將 try/expect 放到 Redis 命令中的複雜性並非本文要講的,你只須要知道這樣作能夠確保重要的數據放到該放的地方就能夠了。

八、不要耗盡一個實例

不管何時,只要有可能就分散多redis實例的工做量。從3.0.0版本開始,Redis就支持集羣了。Redis集羣容許你基於key範圍分離出部分包含主/從模式的key。完整的集羣背後的「魔法」能夠在這裏找到。但若是你是在找教程,那這裏是一個再適合不過的地方了。若是不能選擇集羣,考慮一下命名空間吧,而後將你的key分散到多個實例之中。關於怎樣分配數據,在redis.io網站上有這篇精彩的評論。

九、內核越多越好嗎?!

固然是錯的。Redis 是一個單線程進程,即便啓用了持久化最多也只會消耗兩個內核。除非你計劃在一臺主機上運行多個實例——但願只會是在開發測試的環境下!——不然的話對於一個 Redis 實例是不須要2個以上內核的。

十、高可用

到目前爲止 Redis Sentinel 已經通過了很全面的測試,不少用戶已經將其應用到了生產環境中(包括 ObjectRocket )。若是你的應用重度依賴於 Redis ,那就須要想出一個高可用方案來保證其不會掉線。固然,若是不想本身管理這些東西,ObjectRocket 提供了一個高可用平臺,並提供7×24小時的技術支持,有意向的話能夠考慮一下。

若是想深刻體驗LINUX系統的新手,也能夠先下載一個方德Linux軟件中心試用一下。免費下載地址:http://www.nfs-cloud.cn:81/appCenter/open/softcenter

相關文章
相關標籤/搜索