Redis 是一個基於內存的高性能key-value數據庫。 (有空再補充,有理解錯誤或不足歡迎指正)html
Redis本質上是一個Key-Value類型的內存數據庫,很像memcached,整個數據庫通通加載在內存當中進行操做,按期經過異步操做把數據庫數據flush到硬盤上進行保存。由於是純內存操做,Redis的性能很是出色,每秒能夠處理超過 10萬次讀寫操做,是已知性能最快的Key-Value DB。 Redis的出色之處不只僅是性能,Redis最大的魅力是支持保存多種數據結構,此外單個value的最大限制是1GB,不像 memcached只能保存1MB的數據,所以Redis能夠用來實現不少有用的功能,比方說用他的List來作FIFO雙向鏈表,實現一個輕量級的高性 能消息隊列服務,用他的Set能夠作高性能的tag系統等等。另外Redis也能夠對存入的Key-Value設置expire時間,所以也能夠被看成一 個功能增強版的memcached來用。 Redis的主要缺點是數據庫容量受到物理內存的限制,不能用做海量數據的高性能讀寫,所以Redis適合的場景主要侷限在較小數據量的高性能操做和運算上。node
Redis經過Key-Value的單值不一樣類型來區分, 如下是支持的類型: Strings Lists Sets 求交集、並集 Sorted Set hashesmysql
Redis爲了達到最快的讀寫速度將數據都讀到內存中,並經過異步的方式將數據寫入磁盤。因此redis具備快速和數據持久化的特徵。若是不將數據放在內存中,磁盤I/O速度爲嚴重影響redis的性能。在內存愈來愈便宜的今天,redis將會愈來愈受歡迎。 若是設置了最大使用的內存,則數據已有記錄數達到內存限值後不能繼續插入新值。git
redis利用隊列技術將併發訪問變爲串行訪問,消除了傳統數據庫串行控制的開銷github
當你的key很小而value很大時,使用VM的效果會比較好.由於這樣節約的內存比較大. 當你的key不小時,能夠考慮使用一些很是方法將很大的key變成很大的value,好比你能夠考慮將key,value組合成一個新的value. vm-max-threads這個參數,能夠設置訪問swap文件的線程數,設置最好不要超過機器的核數,若是設置爲0,那麼全部對swap文件的操做都是串行的.可能會形成比較長時間的延遲,可是對數據完整性有很好的保證.redis
本身測試的時候發現用虛擬內存性能也不錯。若是數據量很大,能夠考慮分佈式或者其餘數據庫算法
redis支持主從的模式。原則:Master會將數據同步到slave,而slave不會將數據同步到master。Slave啓動時會鏈接master來同步數據。sql
這是一個典型的分佈式讀寫分離模型。咱們能夠利用master來插入數據,slave提供檢索服務。這樣能夠有效減小單個機器的併發訪問數量數據庫
經過增長Slave DB的數量,讀的性能能夠線性增加。爲了不Master DB的單點故障,集羣通常都會採用兩臺Master DB作雙機熱備,因此整個集羣的讀和寫的可用性都很是高。 讀寫分離架構的缺陷在於,無論是Master仍是Slave,每一個節點都必須保存完整的數據,若是在數據量很大的狀況下,集羣的擴展能力仍是受限於單個節點的存儲能力,並且對於Write-intensive類型的應用,讀寫分離架構並不適合。數組
爲了解決讀寫分離模型的缺陷,能夠將數據分片模型應用進來。
能夠將每一個節點當作都是獨立的master,而後經過業務實現數據分片。
結合上面兩種模型,能夠將每一個master設計成由一個master和多個slave組成的模型。
volatile-lru:從已設置過時時間的數據集(server.db[i].expires)中挑選最近最少使用的數據淘汰
volatile-ttl:從已設置過時時間的數據集(server.db[i].expires)中挑選將要過時的數據淘汰
volatile-random:從已設置過時時間的數據集(server.db[i].expires)中任意選擇數據淘汰
allkeys-lru:從數據集(server.db[i].dict)中挑選最近最少使用的數據淘汰
allkeys-random:從數據集(server.db[i].dict)中任意選擇數據淘汰
no-enviction(驅逐):禁止驅逐數據
1. 使用Redis有哪些好處?
(1) 速度快,由於數據存在內存中,相似於HashMap,HashMap的優點就是查找和操做的時間複雜度都是O(1)
(2) 支持豐富數據類型,支持string,list,set,sorted set,hash
(3) 支持事務,操做都是原子性,所謂的原子性就是對數據的更改要麼所有執行,要麼所有不執行
(4) 豐富的特性:可用於緩存,消息,按key設置過時時間,過時後將會自動刪除
2. redis常見性能問題和解決方案:
(1) Master最好不要作任何持久化工做,如RDB內存快照和AOF日誌文件
(2) 若是數據比較重要,某個Slave開啓AOF備份數據,策略設置爲每秒同步一次
(3) 爲了主從複製的速度和鏈接的穩定性,Master和Slave最好在同一個局域網內
(4) 儘可能避免在壓力很大的主庫上增長從庫
(5) 主從複製不要用圖狀結構,用單向鏈表結構更爲穩定,即:Master <- Slave1 <- Slave2 <- Slave3...
這樣的結構方便解決單點故障問題,實現Slave對Master的替換。若是Master掛了,能夠馬上啓用Slave1作Master,其餘不變。
3. MySQL裏有2000w數據,redis中只存20w的數據,如何保證redis中的數據都是熱點數據
相關知識:redis 內存數據集大小上升到必定大小的時候,就會施行數據淘汰策略。redis 提供 6種數據淘汰策略:
voltile-lru:從已設置過時時間的數據集(server.db[i].expires)中挑選最近最少使用的數據淘汰
volatile-ttl:從已設置過時時間的數據集(server.db[i].expires)中挑選將要過時的數據淘汰
volatile-random:從已設置過時時間的數據集(server.db[i].expires)中任意選擇數據淘汰
allkeys-lru:從數據集(server.db[i].dict)中挑選最近最少使用的數據淘汰
allkeys-random:從數據集(server.db[i].dict)中任意選擇數據淘汰
no-enviction(驅逐):禁止驅逐數據
4. Redis 常見的性能問題都有哪些?如何解決?
1).Master寫內存快照,save命令調度rdbSave函數,會阻塞主線程的工做,當快照比較大時對性能影響是很是大的,會間斷性暫停服務,因此Master最好不要寫內存快照。
2).Master AOF持久化,若是不重寫AOF文件,這個持久化方式對性能的影響是最小的,可是AOF文件會不斷增大,AOF文件過大會影響Master重啓的恢復速度。Master最好不要作任何持久化工做,包括內存快照和AOF日誌文件,特別是不要啓用內存快照作持久化,若是數據比較關鍵,某個Slave開啓AOF備份數據,策略爲每秒同步一次。
3).Master調用BGREWRITEAOF重寫AOF文件,AOF在重寫的時候會佔大量的CPU和內存資源,致使服務load太高,出現短暫服務暫停現象。
4). Redis主從複製的性能問題,爲了主從複製的速度和鏈接的穩定性,Slave和Master最好在同一個局域網內
1.redis是什麼
2.redis的做者何許人也
3.誰在使用redis
4.學會安裝redis
5.學會啓動redis
6.使用redis客戶端
7.redis數據結構 – 簡介
8.redis數據結構 – strings
9.redis數據結構 – lists
10.redis數據結構 – 集合
11.redis數據結構 – 有序集合
12.redis數據結構 – 哈希
13.聊聊redis持久化 – 兩種方式
14.聊聊redis持久化 – RDB
15.聊聊redis持久化 – AOF
16.聊聊redis持久化 – AOF重寫
17.聊聊redis持久化 – 如何選擇RDB和AOF
18.聊聊主從 – 用法
19.聊聊主從 – 同步原理
20.聊聊redis的事務處理
21.教你看懂redis配置 – 簡介
22.教你看懂redis配置 -通用
23.教你看懂redis配置 – 快照
24.教你看懂redis配置 – 複製
25.教你看懂redis配置 – 安全
26.教你看懂redis配置 -限制
27.教你看懂redis配置 – 追加模式
28.教你看懂redis配置 – LUA腳本
29.教你看懂redis配置 – 慢日誌
30.教你看懂redis配置 – 事件通知
31.教你看懂redis配置 – 高級配置
【redis是什麼】
redis是一個開源的、使用C語言編寫的、支持網絡交互的、可基於內存也可持久化的Key-Value數據庫。
redis的官網地址,很是好記,是redis.io。(特地查了一下,域名後綴io屬於國家域名,是british Indian Ocean territory,即英屬印度洋領地)
目前,Vmware在資助着redis項目的開發和維護。
【redis的做者何許人也】
開門見山,先看照片:
是否是出乎了你的意料,嗯,高手總會有些地方不同凡響的。
這位即是redis的做者,他叫Salvatore Sanfilippo,來自意大利的西西里島,如今居住在卡塔尼亞。目前供職於Pivotal公司。
他使用的網名是antirez,若是你有興趣,能夠去他的博客逛逛,地址是antirez.com,固然也能夠去follow他的github,地址是http://github.com/antirez。
【誰在使用redis】
Blizzard、digg、stackoverflow、github、flickr …
【學會安裝redis】
從redis.io下載最新版redis-X.Y.Z.tar.gz後解壓,而後進入redis-X.Y.Z文件夾後直接make便可,安裝很是簡單。
make成功後會在src文件夾下產生一些二進制可執行文件,包括redis-server、redis-cli等等:
【學會啓動redis】
啓動redis很是簡單,直接./redis-server就能夠啓動服務端了,還能夠用下面的方法指定要加載的配置文件:
默認狀況下,redis-server會以非daemon的方式來運行,且默認服務端口爲6379。
有關做者爲何選擇6379做爲默認端口,還有一段有趣的典故,英語好的同窗能夠看看做者這篇博文中的解釋。
【使用redis客戶端】
咱們直接看一個例子:
【redis數據結構 – 簡介】
redis是一種高級的key:value存儲系統,其中value支持五種數據類型:
1.字符串(strings)
2.字符串列表(lists)
3.字符串集合(sets)
4.有序字符串集合(sorted sets)
5.哈希(hashes)
而關於key,有幾個點要提醒你們:
1.key不要太長,儘可能不要超過1024字節,這不只消耗內存,並且會下降查找的效率;
2.key也不要過短,過短的話,key的可讀性會下降;
3.在一個項目中,key最好使用統一的命名模式,例如user:10000:passwd。
【redis數據結構 – strings】
有人說,若是隻使用redis中的字符串類型,且不使用redis的持久化功能,那麼,redis就和memcache很是很是的像了。這說明strings類型是一個很基礎的數據類型,也是任何存儲系統都必備的數據類型。
咱們來看一個最簡單的例子:
字符串類型的用法就是這麼簡單,由於是二進制安全的,因此你徹底能夠把一個圖片文件的內容做爲字符串來存儲。
另外,咱們還能夠經過字符串類型進行數值操做:
看,在遇到數值操做時,redis會將字符串類型轉換成數值。
因爲INCR等指令自己就具備原子操做的特性,因此咱們徹底能夠利用redis的INCR、INCRBY、DECR、DECRBY等指令來實現原子計數的效果,假如,在某種場景下有3個客戶端同時讀取了mynum的值(值爲2),而後對其同時進行了加1的操做,那麼,最後mynum的值必定是5。很多網站都利用redis的這個特性來實現業務上的統計計數需求。
【redis數據結構 – lists】
redis的另外一個重要的數據結構叫作lists,翻譯成中文叫作「列表」。
首先要明確一點,redis中的lists在底層實現上並非數組,而是鏈表,也就是說對於一個具備上百萬個元素的lists來講,在頭部和尾部插入一個新元素,其時間複雜度是常數級別的,好比用LPUSH在10個元素的lists頭部插入新元素,和在上千萬元素的lists頭部插入新元素的速度應該是相同的。
雖然lists有這樣的優點,但一樣有其弊端,那就是,鏈表型lists的元素定位會比較慢,而數組型lists的元素定位就會快得多。
lists的經常使用操做包括LPUSH、RPUSH、LRANGE等。咱們能夠用LPUSH在lists的左側插入一個新元素,用RPUSH在lists的右側插入一個新元素,用LRANGE命令從lists中指定一個範圍來提取元素。咱們來看幾個例子:
lists的應用至關普遍,隨便舉幾個例子:
1.咱們能夠利用lists來實現一個消息隊列,並且能夠確保前後順序,沒必要像MySQL那樣還須要經過ORDER BY來進行排序。
2.利用LRANGE還能夠很方便的實現分頁的功能。
3.在博客系統中,每片博文的評論也能夠存入一個單獨的list中。
【redis數據結構 – 集合】
redis的集合,是一種無序的集合,集合中的元素沒有前後順序。
集合相關的操做也很豐富,如添加新元素、刪除已有元素、取交集、取並集、取差集等。咱們來看例子:
對於集合的使用,也有一些常見的方式,好比,QQ有一個社交功能叫作「好友標籤」,你們能夠給你的好友貼標籤,好比「大美女」、「土豪」、「歐巴」等等,這時就可使用redis的集合來實現,把每個用戶的標籤都存儲在一個集合之中。
【redis數據結構 – 有序集合】
redis不但提供了無需集合(sets),還很體貼的提供了有序集合(sorted sets)。有序集合中的每一個元素都關聯一個序號(score),這即是排序的依據。
不少時候,咱們都將redis中的有序集合叫作zsets,這是由於在redis中,有序集合相關的操做指令都是以z開頭的,好比zrange、zadd、zrevrange、zrangebyscore等等
老規矩,咱們來看幾個生動的例子:
//新增一個有序集合myzset,並加入一個元素baidu.com,給它賦予的序號是1:
【redis數據結構 – 哈希】
最後要給你們介紹的是hashes,即哈希。哈希是從redis-2.0.0版本以後纔有的數據結構。
hashes存的是字符串和字符串值之間的映射,好比一個用戶要存儲其全名、姓氏、年齡等等,就很適合使用哈希。
咱們來看一個例子:
有關hashes的操做,一樣很豐富,須要時,你們能夠從這裏查詢。
【聊聊redis持久化 – 兩種方式】
redis提供了兩種持久化的方式,分別是RDB(Redis DataBase)和AOF(Append Only File)。
RDB,簡而言之,就是在不一樣的時間點,將redis存儲的數據生成快照並存儲到磁盤等介質上;
AOF,則是換了一個角度來實現持久化,那就是將redis執行過的全部寫指令記錄下來,在下次redis從新啓動時,只要把這些寫指令從前到後再重複執行一遍,就能夠實現數據恢復了。
其實RDB和AOF兩種方式也能夠同時使用,在這種狀況下,若是redis重啓的話,則會優先採用AOF方式來進行數據恢復,這是由於AOF方式的數據恢復完整度更高。
若是你沒有數據持久化的需求,也徹底能夠關閉RDB和AOF方式,這樣的話,redis將變成一個純內存數據庫,就像memcache同樣。
【聊聊redis持久化 – RDB】
RDB方式,是將redis某一時刻的數據持久化到磁盤中,是一種快照式的持久化方法。
redis在進行數據持久化的過程當中,會先將數據寫入到一個臨時文件中,待持久化過程都結束了,纔會用這個臨時文件替換上次持久化好的文件。正是這種特性,讓咱們能夠隨時來進行備份,由於快照文件老是完整可用的。
對於RDB方式,redis會單首創建(fork)一個子進程來進行持久化,而主進程是不會進行任何IO操做的,這樣就確保了redis極高的性能。
若是須要進行大規模數據的恢復,且對於數據恢復的完整性不是很是敏感,那RDB方式要比AOF方式更加的高效。
雖然RDB有很多優勢,但它的缺點也是不容忽視的。若是你對數據的完整性很是敏感,那麼RDB方式就不太適合你,由於即便你每5分鐘都持久化一次,當redis故障時,仍然會有近5分鐘的數據丟失。因此,redis還提供了另外一種持久化方式,那就是AOF。
【聊聊redis持久化 – AOF】
AOF,英文是Append Only File,即只容許追加不容許改寫的文件。
如前面介紹的,AOF方式是將執行過的寫指令記錄下來,在數據恢復時按照從前到後的順序再將指令都執行一遍,就這麼簡單。
咱們經過配置redis.conf中的appendonly yes就能夠打開AOF功能。若是有寫操做(如SET等),redis就會被追加到AOF文件的末尾。
默認的AOF持久化策略是每秒鐘fsync一次(fsync是指把緩存中的寫指令記錄到磁盤中),由於在這種狀況下,redis仍然能夠保持很好的處理性能,即便redis故障,也只會丟失最近1秒鐘的數據。
若是在追加日誌時,剛好遇到磁盤空間滿、inode滿或斷電等狀況致使日誌寫入不完整,也沒有關係,redis提供了redis-check-aof工具,能夠用來進行日誌修復。
由於採用了追加方式,若是不作任何處理的話,AOF文件會變得愈來愈大,爲此,redis提供了AOF文件重寫(rewrite)機制,即當AOF文件的大小超過所設定的閾值時,redis就會啓動AOF文件的內容壓縮,只保留能夠恢復數據的最小指令集。舉個例子或許更形象,假如咱們調用了100次INCR指令,在AOF文件中就要存儲100條指令,但這明顯是很低效的,徹底能夠把這100條指令合併成一條SET指令,這就是重寫機制的原理。
在進行AOF重寫時,仍然是採用先寫臨時文件,所有完成後再替換的流程,因此斷電、磁盤滿等問題都不會影響AOF文件的可用性,這點你們能夠放心。
AOF方式的另外一個好處,咱們經過一個「場景再現」來講明。某同窗在操做redis時,不當心執行了FLUSHALL,致使redis內存中的數據所有被清空了,這是很悲劇的事情。不過這也不是世界末日,只要redis配置了AOF持久化方式,且AOF文件尚未被重寫(rewrite),咱們就能夠用最快的速度暫停redis並編輯AOF文件,將最後一行的FLUSHALL命令刪除,而後重啓redis,就能夠恢復redis的全部數據到FLUSHALL以前的狀態了。是否是很神奇,這就是AOF持久化方式的好處之一。可是若是AOF文件已經被重寫了,那就沒法經過這種方法來恢復數據了。
雖然優勢多多,但AOF方式也一樣存在缺陷,好比在一樣數據規模的狀況下,AOF文件要比RDB文件的體積大。並且,AOF方式的恢復速度也要慢於RDB方式。
若是你直接執行BGREWRITEAOF命令,那麼redis會生成一個全新的AOF文件,其中便包括了能夠恢復現有數據的最少的命令集。
若是運氣比較差,AOF文件出現了被寫壞的狀況,也沒必要過度擔心,redis並不會貿然加載這個有問題的AOF文件,而是報錯退出。這時能夠經過如下步驟來修復出錯的文件:
1.備份被寫壞的AOF文件
2.運行redis-check-aof –fix進行修復
3.用diff -u來看下兩個文件的差別,確認問題點
4.重啓redis,加載修復後的AOF文件
【聊聊redis持久化 – AOF重寫】
AOF重寫的內部運行原理,咱們有必要了解一下。
在重寫即將開始之際,redis會建立(fork)一個「重寫子進程」,這個子進程會首先讀取現有的AOF文件,並將其包含的指令進行分析壓縮並寫入到一個臨時文件中。
與此同時,主工做進程會將新接收到的寫指令一邊累積到內存緩衝區中,一邊繼續寫入到原有的AOF文件中,這樣作是保證原有的AOF文件的可用性,避免在重寫過程當中出現意外。
當「重寫子進程」完成重寫工做後,它會給父進程發一個信號,父進程收到信號後就會將內存中緩存的寫指令追加到新AOF文件中。
當追加結束後,redis就會用新AOF文件來代替舊AOF文件,以後再有新的寫指令,就都會追加到新的AOF文件中了。
【聊聊redis持久化 – 如何選擇RDB和AOF】
對於咱們應該選擇RDB仍是AOF,官方的建議是兩個同時使用。這樣能夠提供更可靠的持久化方案。
【聊聊主從 – 用法】
像MySQL同樣,redis是支持主從同步的,並且也支持一主多從以及多級從結構。
主從結構,一是爲了純粹的冗餘備份,二是爲了提高讀性能,好比很消耗性能的SORT就能夠由從服務器來承擔。
redis的主從同步是異步進行的,這意味着主從同步不會影響主邏輯,也不會下降redis的處理性能。
主從架構中,能夠考慮關閉主服務器的數據持久化功能,只讓從服務器進行持久化,這樣能夠提升主服務器的處理性能。
在主從架構中,從服務器一般被設置爲只讀模式,這樣能夠避免從服務器的數據被誤修改。可是從服務器仍然能夠接受CONFIG等指令,因此仍是不該該將從服務器直接暴露到不安全的網絡環境中。若是必須如此,那能夠考慮給重要指令進行重命名,來避免命令被外人誤執行。
【聊聊主從 – 同步原理】
從服務器會向主服務器發出SYNC指令,當主服務器接到此命令後,就會調用BGSAVE指令來建立一個子進程專門進行數據持久化工做,也就是將主服務器的數據寫入RDB文件中。在數據持久化期間,主服務器將執行的寫指令都緩存在內存中。
在BGSAVE指令執行完成後,主服務器會將持久化好的RDB文件發送給從服務器,從服務器接到此文件後會將其存儲到磁盤上,而後再將其讀取到內存中。這個動做完成後,主服務器會將這段時間緩存的寫指令再以redis協議的格式發送給從服務器。
另外,要說的一點是,即便有多個從服務器同時發來SYNC指令,主服務器也只會執行一次BGSAVE,而後把持久化好的RDB文件發給多個下游。在redis2.8版本以前,若是從服務器與主服務器因某些緣由斷開鏈接的話,都會進行一次主從之間的全量的數據同步;而在2.8版本以後,redis支持了效率更高的增量同步策略,這大大下降了鏈接斷開的恢復成本。
主服務器會在內存中維護一個緩衝區,緩衝區中存儲着將要發給從服務器的內容。從服務器在與主服務器出現網絡瞬斷以後,從服務器會嘗試再次與主服務器鏈接,一旦鏈接成功,從服務器就會把「但願同步的主服務器ID」和「但願請求的數據的偏移位置(replication offset)」發送出去。主服務器接收到這樣的同步請求後,首先會驗證主服務器ID是否和本身的ID匹配,其次會檢查「請求的偏移位置」是否存在於本身的緩衝區中,若是二者都知足的話,主服務器就會向從服務器發送增量內容。
增量同步功能,須要服務器端支持全新的PSYNC指令。這個指令,只有在redis-2.8以後才具備。
【聊聊redis的事務處理】
衆所周知,事務是指「一個完整的動做,要麼所有執行,要麼什麼也沒有作」。
在聊redis事務處理以前,要先和你們介紹四個redis指令,即MULTI、EXEC、DISCARD、WATCH。這四個指令構成了redis事務處理的基礎。
1.MULTI用來組裝一個事務;
2.EXEC用來執行一個事務;
3.DISCARD用來取消一個事務;
4.WATCH用來監視一些key,一旦這些key在事務執行以前被改變,則取消事務的執行。
紙上得來終覺淺,咱們來看一個MULTI和EXEC的例子:
在上面的例子中,咱們看到了QUEUED的字樣,這表示咱們在用MULTI組裝事務時,每個命令都會進入到內存隊列中緩存起來,若是出現QUEUED則表示咱們這個命令成功插入了緩存隊列,在未來執行EXEC時,這些被QUEUED的命令都會被組裝成一個事務來執行。
對於事務的執行來講,若是redis開啓了AOF持久化的話,那麼一旦事務被成功執行,事務中的命令就會經過write命令一次性寫到磁盤中去,若是在向磁盤中寫的過程當中剛好出現斷電、硬件故障等問題,那麼就可能出現只有部分命令進行了AOF持久化,這時AOF文件就會出現不完整的狀況,這時,咱們可使用redis-check-aof工具來修復這一問題,這個工具會將AOF文件中不完整的信息移除,確保AOF文件完整可用。
有關事務,你們常常會遇到的是兩類錯誤:
1.調用EXEC以前的錯誤
2.調用EXEC以後的錯誤
「調用EXEC以前的錯誤」,有多是因爲語法有誤致使的,也可能時因爲內存不足致使的。只要出現某個命令沒法成功寫入緩衝隊列的狀況,redis都會進行記錄,在客戶端調用EXEC時,redis會拒絕執行這一事務。(這時2.6.5版本以後的策略。在2.6.5以前的版本中,redis會忽略那些入隊失敗的命令,只執行那些入隊成功的命令)。咱們來看一個這樣的例子:
而對於「調用EXEC以後的錯誤」,redis則採起了徹底不一樣的策略,即redis不會理睬這些錯誤,而是繼續向下執行事務中的其餘命令。這是由於,對於應用層面的錯誤,並非redis自身須要考慮和處理的問題,因此一個事務中若是某一條命令執行失敗,並不會影響接下來的其餘命令的執行。咱們也來看一個例子:
好了,咱們來講說最後一個指令「WATCH」,這是一個很好用的指令,它能夠幫咱們實現相似於「樂觀鎖」的效果,即CAS(check and set)。
WATCH自己的做用是「監視key是否被改動過」,並且支持同時監視多個key,只要還沒真正觸發事務,WATCH都會盡職盡責的監視,一旦發現某個key被修改了,在執行EXEC時就會返回nil,表示事務沒法觸發。
【教你看懂redis配置 – 簡介】
咱們能夠在啓動redis-server時指定應該加載的配置文件,方法以下:
接下來,咱們就來說解下redis配置文件的各個配置項的含義,注意,本文是基於redis-2.8.4版本進行講解的。
redis官方提供的redis.conf文件,足有700+行,其中100多行爲有效配置行,另外的600多行爲註釋說明。
在配置文件的開頭部分,首先明確了一些度量單位:
能夠看出,redis配置中對單位的大小寫不敏感,1GB、1Gb和1gB都是相同的。由此也說明,redis只支持bytes,不支持bit單位。
redis支持「主配置文件中引入外部配置文件」,很像C/C++中的include指令,好比:
若是你看過redis的配置文件,會發現仍是頗有條理的。redis配置文件被分紅了幾大塊區域,它們分別是:
1.通用(general)
2.快照(snapshotting)
3.複製(replication)
4.安全(security)
5.限制(limits)
6.追加模式(append only mode)
7.LUA腳本(lua scripting)
8.慢日誌(slow log)
9.事件通知(event notification)
下面咱們就來逐一講解。
【教你看懂redis配置 -通用】
默認狀況下,redis並非以daemon形式來運行的。經過daemonize配置項能夠控制redis的運行形式,若是改成yes,那麼redis就會以daemon形式運行:
當以daemon形式運行時,redis會生成一個pid文件,默認會生成在/var/run/redis.pid。固然,你能夠經過pidfile來指定pid文件生成的位置,好比:
默認狀況下,redis會響應本機全部可用網卡的鏈接請求。固然,redis容許你經過bind配置項來指定要綁定的IP,好比:
redis的默認服務端口是6379,你能夠經過port配置項來修改。若是端口設置爲0的話,redis便不會監聽端口了。
有些同窗會問「若是redis不監聽端口,還怎麼與外界通訊呢」,其實redis還支持經過unix socket方式來接收請求。能夠經過unixsocket配置項來指定unix socket文件的路徑,並經過unixsocketperm來指定文件的權限。
當一個redis-client一直沒有請求發向server端,那麼server端有權主動關閉這個鏈接,能夠經過timeout來設置「空閒超時時限」,0表示永不關閉。
TCP鏈接保活策略,能夠經過tcp-keepalive配置項來進行設置,單位爲秒,假如設置爲60秒,則server端會每60秒向鏈接空閒的客戶端發起一次ACK請求,以檢查客戶端是否已經掛掉,對於無響應的客戶端則會關閉其鏈接。因此關閉一個鏈接最長鬚要120秒的時間。若是設置爲0,則不會進行保活檢測。
redis支持經過loglevel配置項設置日誌等級,共分四級,即debug、verbose、notice、warning。
redis也支持經過logfile配置項來設置日誌文件的生成位置。若是設置爲空字符串,則redis會將日誌輸出到標準輸出。假如你在daemon狀況下將日誌設置爲輸出到標準輸出,則日誌會被寫到/dev/null中。
若是但願日誌打印到syslog中,也很容易,經過syslog-enabled來控制。另外,syslog-ident還可讓你指定syslog裏的日誌標誌,好比:
並且還支持指定syslog設備,值能夠是USER或LOCAL0-LOCAL7。具體能夠參考syslog服務自己的用法。
對於redis來講,能夠設置其數據庫的總數量,假如你但願一個redis包含16個數據庫,那麼設置以下:
這16個數據庫的編號將是0到15。默認的數據庫是編號爲0的數據庫。用戶可使用select <DBid>來選擇相應的數據庫。
【教你看懂redis配置 – 快照】
快照,主要涉及的是redis的RDB持久化相關的配置,咱們來一塊兒看一看。
咱們能夠用以下的指令來讓數據保存到磁盤上,即控制RDB快照功能:
舉例來講:
save 300 10 //表示每5分鐘且至少有10個key改變,就觸發一次持久化
save 60 10000 //表示每60秒至少有10000個key改變,就觸發一次持久化
若是你想禁用RDB持久化的策略,只要不設置任何save指令就能夠,或者給save傳入一個空字符串參數也能夠達到相同效果,就像這樣:
若是用戶開啓了RDB快照功能,那麼在redis持久化數據到磁盤時若是出現失敗,默認狀況下,redis會中止接受全部的寫請求。這樣作的好處在於可讓用戶很明確的知道內存中的數據和磁盤上的數據已經存在不一致了。若是redis不顧這種不一致,獨斷獨行的繼續接收寫請求,就可能會引發一些災難性的後果。
若是下一次RDB持久化成功,redis會自動恢復接受寫請求。
固然,若是你不在意這種數據不一致或者有其餘的手段發現和控制這種不一致的話,你徹底能夠關閉這個功能,以便在快照寫入失敗時,也能確保redis繼續接受新的寫請求。配置項以下:
對於存儲到磁盤中的快照,能夠設置是否進行壓縮存儲。若是是的話,redis會採用LZF算法進行壓縮。若是你不想消耗CPU來進行壓縮的話,能夠設置爲關閉此功能,可是存儲在磁盤上的快照會比較大。
在存儲快照後,咱們還可讓redis使用CRC64算法來進行數據校驗,可是這樣作會增長大約10%的性能消耗,若是你但願獲取到最大的性能提高,能夠關閉此功能。
咱們還能夠設置快照文件的名稱,默認是這樣配置的:
最後,你還能夠設置這個快照文件存放的路徑。好比默認設置就是當前文件夾:
【教你看懂redis配置 – 複製】
redis提供了主從同步功能。
經過slaveof配置項能夠控制某一個redis做爲另外一個redis的從服務器,經過指定IP和端口來定位到主redis的位置。通常狀況下,咱們會建議用戶爲從redis設置一個不一樣頻率的快照持久化的週期,或者爲從redis配置一個不一樣的服務端口等等。
若是主redis設置了驗證密碼的話(使用requirepass來設置),則在從redis的配置中要使用masterauth來設置校驗密碼,不然的話,主redis會拒絕從redis的訪問請求。
當從redis失去了與主redis的鏈接,或者主從同步正在進行中時,redis該如何處理外部發來的訪問請求呢?這裏,從redis能夠有兩種選擇:
第一種選擇:若是slave-serve-stale-data設置爲yes(默認),則從redis仍會繼續響應客戶端的讀寫請求。
第二種選擇:若是slave-serve-stale-data設置爲no,則從redis會對客戶端的請求返回「SYNC with master in progress」,固然也有例外,當客戶端發來INFO請求和SLAVEOF請求,從redis仍是會進行處理。
你能夠控制一個從redis是否能夠接受寫請求。將數據直接寫入從redis,通常只適用於那些生命週期很是短的數據,由於在主從同步時,這些臨時數據就會被清理掉。自從redis2.6版本以後,默認從redis爲只讀。
只讀的從redis並不適合直接暴露給不可信的客戶端。爲了儘可能下降風險,可使用rename-command指令來將一些可能有破壞力的命令重命名,避免外部直接調用。好比:
從redis會週期性的向主redis發出PING包。你能夠經過repl_ping_slave_period指令來控制其週期。默認是10秒。
在主從同步時,可能在這些狀況下會有超時發生:
1.以從redis的角度來看,當有大規模IO傳輸時。
2.以從redis的角度來看,當數據傳輸或PING時,主redis超時
3.以主redis的角度來看,在回覆從redis的PING時,從redis超時
用戶能夠設置上述超時的時限,不過要確保這個時限比repl-ping-slave-period的值要大,不然每次主redis都會認爲從redis超時。
咱們能夠控制在主從同步時是否禁用TCP_NODELAY。若是開啓TCP_NODELAY,那麼主redis會使用更少的TCP包和更少的帶寬來向從redis傳輸數據。可是這可能會增長一些同步的延遲,大概會達到40毫秒左右。若是你關閉了TCP_NODELAY,那麼數據同步的延遲時間會下降,可是會消耗更多的帶寬。(若是你不瞭解TCP_NODELAY,能夠到這裏來科普一下)。
咱們還能夠設置同步隊列長度。隊列長度(backlog)是主redis中的一個緩衝區,在與從redis斷開鏈接期間,主redis會用這個緩衝區來緩存應該發給從redis的數據。這樣的話,當從redis從新鏈接上以後,就沒必要從新全量同步數據,只須要同步這部分增量數據便可。
若是主redis等了一段時間以後,仍是沒法鏈接到從redis,那麼緩衝隊列中的數據將被清理掉。咱們能夠設置主redis要等待的時間長度。若是設置爲0,則表示永遠不清理。默認是1個小時。
咱們能夠給衆多的從redis設置優先級,在主redis持續工做不正常的狀況,優先級高的從redis將會升級爲主redis。而編號越小,優先級越高。好比一個主redis有三個從redis,優先級編號分別爲十、100、25,那麼編號爲10的從redis將會被首先選中升級爲主redis。當優先級被設置爲0時,這個從redis將永遠也不會被選中。默認的優先級爲100。
假如主redis發現有超過M個從redis的鏈接延時大於N秒,那麼主redis就中止接受外來的寫請求。這是由於從redis通常會每秒鐘都向主redis發出PING,而主redis會記錄每個從redis最近一次發來PING的時間點,因此主redis可以瞭解每個從redis的運行狀況。
上面這個例子表示,假若有大於等於3個從redis的鏈接延遲大於10秒,那麼主redis就再也不接受外部的寫請求。上述兩個配置中有一個被置爲0,則這個特性將被關閉。默認狀況下min-slaves-to-write爲0,而min-slaves-max-lag爲10。
【教你看懂redis配置 – 安全】
咱們能夠要求redis客戶端在向redis-server發送請求以前,先進行密碼驗證。當你的redis-server處於一個不太可信的網絡環境中時,相信你會用上這個功能。因爲redis性能很是高,因此每秒鐘能夠完成多達15萬次的密碼嘗試,因此你最好設置一個足夠複雜的密碼,不然很容易被黑客破解。
這裏咱們經過requirepass將密碼設置成「芝麻開門」。
redis容許咱們對redis指令進行改名,好比將一些比較危險的命令改個名字,避免被誤執行。好比能夠把CONFIG命令改爲一個很複雜的名字,這樣能夠避免外部的調用,同時還能夠知足內部調用的須要:
咱們甚至能夠禁用掉CONFIG命令,那就是把CONFIG的名字改爲一個空字符串:
但須要注意的是,若是你使用AOF方式進行數據持久化,或者須要與從redis進行通訊,那麼更改指令的名字可能會引發一些問題。
【教你看懂redis配置 -限制】
咱們能夠設置redis同時能夠與多少個客戶端進行鏈接。默認狀況下爲10000個客戶端。當你沒法設置進程文件句柄限制時,redis會設置爲當前的文件句柄限制值減去32,由於redis會爲自身內部處理邏輯留一些句柄出來。
若是達到了此限制,redis則會拒絕新的鏈接請求,而且向這些鏈接請求方發出「max number of clients reached」以做迴應。
咱們甚至能夠設置redis可使用的內存量。一旦到達內存使用上限,redis將會試圖移除內部數據,移除規則能夠經過maxmemory-policy來指定。
若是redis沒法根據移除規則來移除內存中的數據,或者咱們設置了「不容許移除」,那麼redis則會針對那些須要申請內存的指令返回錯誤信息,好比SET、LPUSH等。可是對於無內存申請的指令,仍然會正常響應,好比GET等。
須要注意的一點是,若是你的redis是主redis(說明你的redis有從redis),那麼在設置內存使用上限時,須要在系統中留出一些內存空間給同步隊列緩存,只有在你設置的是「不移除」的狀況下,纔不用考慮這個因素。
對於內存移除規則來講,redis提供了多達6種的移除規則。他們是:
1.volatile-lru:使用LRU算法移除過時集合中的key
2.allkeys-lru:使用LRU算法移除key
3.volatile-random:在過時集合中移除隨機的key
4.allkeys-random:移除隨機的key
5.volatile-ttl:移除那些TTL值最小的key,即那些最近才過時的key。
6.noeviction:不進行移除。針對寫操做,只是返回錯誤信息。
不管使用上述哪種移除規則,若是沒有合適的key能夠移除的話,redis都會針對寫請求返回錯誤信息。
LRU算法和最小TTL算法都並不是是精確的算法,而是估算值。因此你能夠設置樣本的大小。假如redis默認會檢查三個key並選擇其中LRU的那個,那麼你能夠改變這個key樣本的數量。
最後,咱們補充一個信息,那就是到目前版本(2.8.4)爲止,redis支持的寫指令包括了以下這些:
【教你看懂redis配置 – 追加模式】
默認狀況下,redis會異步的將數據持久化到磁盤。這種模式在大部分應用程序中已被驗證是頗有效的,可是在一些問題發生時,好比斷電,則這種機制可能會致使數分鐘的寫請求丟失。
如博文上半部分中介紹的,追加文件(Append Only File)是一種更好的保持數據一致性的方式。即便當服務器斷電時,也僅會有1秒鐘的寫請求丟失,當redis進程出現問題且操做系統運行正常時,甚至只會丟失一條寫請求。
咱們建議你們,AOF機制和RDB機制能夠同時使用,不會有任何衝突。對於如何保持數據一致性的討論,請參見本文。
咱們還能夠設置aof文件的名稱:
fsync()調用,用來告訴操做系統當即將緩存的指令寫入磁盤。一些操做系統會「當即」進行,而另一些操做系統則會「儘快」進行。
redis支持三種不一樣的模式:
1.no:不調用fsync()。而是讓操做系統自行決定sync的時間。這種模式下,redis的性能會最快。
2.always:在每次寫請求後都調用fsync()。這種模式下,redis會相對較慢,但數據最安全。
3.everysec:每秒鐘調用一次fsync()。這是性能和安全的折衷。
默認狀況下爲everysec。有關數據一致性的揭祕,能夠參考本文。
當fsync方式設置爲always或everysec時,若是後臺持久化進程須要執行一個很大的磁盤IO操做,那麼redis可能會在fsync()調用時卡住。目前還沒有修復這個問題,這是由於即便咱們在另外一個新的線程中去執行fsync(),也會阻塞住同步寫調用。
爲了緩解這個問題,咱們可使用下面的配置項,這樣的話,當BGSAVE或BGWRITEAOF運行時,fsync()在主進程中的調用會被阻止。這意味着當另外一路進程正在對AOF文件進行重構時,redis的持久化功能就失效了,就好像咱們設置了「appendsync none」同樣。若是你的redis有時延問題,那麼請將下面的選項設置爲yes。不然請保持no,由於這是保證數據完整性的最安全的選擇。
咱們容許redis自動重寫aof。當aof增加到必定規模時,redis會隱式調用BGREWRITEAOF來重寫log文件,以縮減文件體積。
redis是這樣工做的:redis會記錄上次重寫時的aof大小。假如redis自啓動至今尚未進行太重寫,那麼啓動時aof文件的大小會被做爲基準值。這個基準值會和當前的aof大小進行比較。若是當前aof大小超出所設置的增加比例,則會觸發重寫。另外,你還須要設置一個最小大小,是爲了防止在aof很小時就觸發重寫。
若是設置auto-aof-rewrite-percentage爲0,則會關閉此重寫功能。
【教你看懂redis配置 – LUA腳本】
lua腳本的最大運行時間是須要被嚴格限制的,要注意單位是毫秒:
若是此值設置爲0或負數,則既不會有報錯也不會有時間限制。
【教你看懂redis配置 – 慢日誌】
redis慢日誌是指一個系統進行日誌查詢超過了指定的時長。這個時長不包括IO操做,好比與客戶端的交互、發送響應內容等,而僅包括實際執行查詢命令的時間。
針對慢日誌,你能夠設置兩個參數,一個是執行時長,單位是微秒,另外一個是慢日誌的長度。當一個新的命令被寫入日誌時,最老的一條會從命令日誌隊列中被移除。
單位是微秒,即1000000表示一秒。負數則會禁用慢日誌功能,而0則表示強制記錄每個命令。
慢日誌最大長度,能夠隨便填寫數值,沒有上限,但要注意它會消耗內存。你可使用SLOWLOG RESET來重設這個值。
【教你看懂redis配置 – 事件通知】
redis能夠向客戶端通知某些事件的發生。這個特性的具體解釋能夠參見本文。
【教你看懂redis配置 – 高級配置】
有關哈希數據結構的一些配置項:
有關列表數據結構的一些配置項:
有關集合數據結構的配置項:
有關有序集合數據結構的配置項:
關因而否須要再哈希的配置項:
關於客戶端輸出緩衝的控制項:
有關頻率的配置項:
有關重寫aof的配置項
至此,redis的入門內容就結束了,內容實在很多,但相對來講都很基礎,本文沒有涉及redis集羣、redis工做原理、redis源碼、redis相關LIB庫等內容,後續會陸續奉獻,你們敬請期待:)
謝謝!