22
技術社區[雲棲]
《Redis官方教程》-FAQ
為什麼Redis不同於其他的鍵值存儲數據庫?
有兩個主要原因:
- Redis發展方向不同與其他鍵值數據庫,它能包含很多複雜數據類型,對這些數據類型操作都是原子的。Redis數據類型與基本數據結構強相關,直接暴露給程序員,沒有增加抽象層。
- Redis是一個內存數據庫,而不是持久化在硬盤數據庫中,因此為了實現高速讀寫,數據集大小不能超過內存。內存數據庫另一個優點是,內存數據庫相對於硬盤數據庫非常容易操作複雜數據結構,因此Redis的可以做很多事情,很少有內部的複雜性。與此同時兩款磁盤存儲格式(RDB和AOF)不需要支持隨機訪問,因此他們是緊湊的,而且總是以追加形式生成(甚至AOF日誌輪換也是一個追加操作,因為新版本是由內存中的副本生成)。
Redis內存使用情況?
舉幾個例子(所有數據基於64位實例)
- 一個空實例大約占用1M內存
- 1百萬簡單字符串鍵值對大約占用100M內存
- 1百萬哈希表鍵值對,每個對象有5個屬性,大約占用200M內存
為了測試你的用例,使用redis-benchmark工具生成隨機數據集,使用INFO memory命令檢查使用內存空間。
存儲相同的鍵,64位係統比32位係統使用更多的內存,鍵值很小情況下更明顯。這是因為64位係統指針占用8字節。但是64位係統優點是可以配置更多內存(校對注:32位操作係統支持的內存最多為2的32次方,就是4G),因此為了運行大型Redis服務器,64位係統或多或少都是需要的。另一種方案是使用分片。
我喜歡Redis的高性能操作和特性,但是不喜歡所有內容都在內存中,我不能創建一個比內存更大數據集。有計劃改變嗎?
過去為了允許數據集超過RAM大小,Redis開發人員嚐試使用虛擬內存和其他係統,但是我們非常高興可以把一件事情做好:數據服務由內存提供,磁盤用於存儲數據。所以現在沒有計劃為Redis創建磁盤後端,畢竟Redis大部分特性都是基於其當前架構設計的。
你的真正問題並不是所需的總內存,而是你需要劃分你的數據集到多個Redis實例上,為了獲取更多信息請閱讀本文檔中的分區頁麵。
同時使用Redis和磁盤數據庫,是不是一個好想法?
是的,一個通用的設計方案是,在非常頻繁的寫小的數據時采用Redis(並且你需要使用Redis數據結構給你的問題建立高效模型),以及將大數據存儲到SQL數據庫或者最終一致性磁盤數據庫中。
有沒有方法降低Redis內存使用率?
如果可以的話使用Redis 32位實例。另外,還要善於使用哈希表,列表,有序集合和整數集,因為在特殊情況下Redis使用這些數據類型可以更緊湊存儲一些元素。可以在內存優化頁麵獲取更多信息。
Redis內存不足時會發生什麼?
Redis要麼被Linux內核OOM殺掉,拋出錯誤崩潰,要麼開始變得卡頓。隨著現代操作係統malloc方法通常都不返回NULL,而是服務器開始交換,因此Redis性能降低,因此你可能會觀察到一些錯誤現象。
INFO命令返回Redis使用內存總量,因此你可以編寫腳本監控Redis服務器內存臨界值。
Redis內置保護措施允許用戶在配置文件中使用maxmemory選項,設置Redis最大占用內存。如果達到此限製,Redis將開始返回錯誤給寫命令(但是將繼續接受隻讀命令),或者當最大內存限製達到時也可以配置為驅逐鍵,在這種情況下Redis作為緩存使用。
在Linux係統中,即使我有很多空閑內存,後台保存失敗報fork錯誤!
精辟答案:echo 1 > /proc/sys/vm/overcommit_memory
詳細回答:
Redis後台保存模式依賴現代操作係統的寫時拷貝技術。Redis fork(創建一個子進程)是父進程精確拷貝。子進程存儲數據到磁盤並且最終退出。從理論上講,子進程應該和父進程使用同樣多內存,作為父進程副本,但是得益於多數現代操作係統實現的寫時複製技術,父進程和子進程共享內存頁。內存頁在父進程或子進程改變時將被複製。當子進程保存時,理論上所有頁麵都可能改變,Linux無法提前告知子進程需要多少內存,因此如果overcommit_memory設置為0,fork將會失敗除非有足夠的空閑RAM真正複製父進程內存頁.結果是,如果你有3G Redis數據集,隻有2G可用內存將會失敗。
overcommit_memory設置為1,意味著Linux 使用更樂觀方式fork,這確實是你所期望的Redis。
“理解虛擬機內存 (校對注:有興趣可以翻譯此文在並發網發表)”是紅帽經典文章,可以了解Linux虛擬內存怎麼工作,overcommit_memory和overcommit_ratio的替代品。這篇文章校正了proc(5)用戶手冊對overcommit_memory1和2配置正確含義。
Redis磁盤快照是不是原子操作?
是的,當服務器不在執行命令時,Redis後台保存進程總是被創建,因此每個命令在RAM中是原子的,並且在磁盤快照過程也是原子的。
Redis是單線程的,我怎麼利用多CPU/核?
CPU基本不可能成為的Redis的瓶頸,因為通常Redis受限於內存或網絡。例如使用Pipelining,Redis運行在普通的Linux係統上,每秒可以處理50萬請求,所以如果你的應用程序主要使用O(N) 或者 O(log(N))命令,幾乎不會使用太多的CPU。
然而為了最大限度利用CPU,你可以在一台機器上啟動多個Redis實例,並把它們設置為不同服務器。某些時候單個機器是不夠的,所以如果你想使用多個CPU,你可以提前考慮使用分片。
關於使用多Redis實例,你可以在Partitioning page找到更多的信息
單個Redis實例最多可以存儲多少鍵?哈希表、列表、集合和有序集合最大可以包含多少元素?
Redis最大可以處理2^32鍵,實踐測試每個實例最少可以處理2.5億鍵。
每個哈希表、列表、集合和有序集合可以容納2^32元素。
換句話說,Redis極限容量就是係統可用內存。
為什麼我的從實例與主實例擁有不同數量鍵?
如果你使用有生存周期的鍵,這就是正常現象。這就導致主從實例鍵的數量不一致原因。
- 主實例在第一次與從實例同步時生成RDB文件。
- RDB文件不包含已經過期的鍵,但是已經過期的鍵仍然在內存中。
- 盡管這些鍵從邏輯上說已經過期失效,但是還在Redis主實例內存中,他們並不被識別為存在的,當增量或訪問這些鍵時這些鍵會被回收。盡管從邏輯上說這些鍵不是數據集一部分,但是INFO和DBSIZE命令結果包含這些信息。
- 當從實例讀取主實例生成的RDB文件時,過期鍵不會被載入。
為很多鍵設置過期屬性,通常為用戶提供了在從實例上存儲更少鍵,但是實際上實例內容沒有邏輯區別。
Redis實際含義是什麼?
Redis是遠程數據字典服務器(REmote DIctionary Server)。
你為什麼啟動Redis項目?
最初啟動Redis,是為了擴大LLOOGG。但是當我完成了基本服務端工作後,我喜歡把這個想法分享給其他人,然後Redis轉變成開源項目。
最後更新:2017-05-22 09:32:01