1.redis簡介
REmote DIctionary Server(Redis)是一個由Slvatore Sanfilippo 寫的key-value內存中的數據結構存儲系統,並且是開源(BSD許可)的,它可以用作數據庫、緩存和消息中間件。
2.redis組成
它支持多種類型的數據結構,如字符串(string),散列(hashes),列表(lists),集合(sets),有序集合(sorted sets)與範圍查詢,bitmaps,hyperloglogs和地理空間(geospatial)索引半徑查詢;
redis內置了複製(replication),LUA腳本(LUA scriptiong),LRU驅動事件(LRU eviction),事務(transactions)和不同級別的磁盤持久化(persistence);
並通過Redis哨兵(Sentinel)和自動分區(Cluster)提供高可用性(high availablility).
3.redis優點
性能很高:redis支持超過100k每秒的讀取頻率;
豐富數據類型:redis支持二進制的String,Lisst,Hashes,Sets及Ordered Sets等數據類型操作;
原子:Redis的所有操作都是原則性的,同時Redis還支持對幾個操作全並後的原則性執行;
豐富的特性:redis還支持publiss/subscribe,通知,key過期等等特性,redis支持異機主從複製
4.redis應用場景
redis最佳使用場景的全部是數據in-memory
redis更多場景是作爲Memecached的替代品來使用
當需要除key/value之外的更多數據類型支持時,使用redis更合適
當存儲的數據不能被提出時,使用redis更合適
5.redis小結
5.1redis數據庫小結
提高了DB的可拓展性,只需要將新加的數據放到新加的服務器上就可以了
提高了DB的可用性,隻影響到需要訪問的shard服務器上的數據的用戶
提高了DB的可維護性,對系統的升級和配置可以按shard一個個來搞,對服務產生的影響較小
小的數據庫存的查詢壓力小,查詢更快,性能更好
5.2redis應用小結
要進行Master-slave的配置,出現服務故障時可以支持切換
在master側禁用數據持久化,只需在slave上配置數據持久化
物理內存+虛擬內存不足,這個dump一致死着,時間久了機器掛掉,這個情況下就是災難
當Redis物理內存使用超過內存總容量的3/5時就會開始比較危險了,就開始做swap,內存碎片
當達到最大內存時,回清空帶有過期時間的key,即使key未過期時間
redis與DB同步寫的問題,先寫DB,後寫redis,因爲內存基本上沒問題
6.redis部署搭建
在redis的官方網站(http://www.redis.io)下載最新的穩定版本redis 操作命令如下:
6.1、獲取redis安裝包,並解壓
wget http://download.redis.io/releases/redis-3.0.7.tar.gz tar xzf redis-3.0.7.tar.gz
6.2、進入目錄,並查看說明文件README
cd redis-3.0.7 less README
6.3、配置redis安裝包
make MANIFESTO=jemalloc && \ make PREFIX=/application/redis-3.0.7 install
6.4、創建軟連接
ln -s /application/redis-3.0.7/ /application/redis
6.5、配置環境語言
LANG=en_US.UTF-8
6.6、查看redis命令的目錄
tree /application/redis/bin/ 執行結果如下: /application/redis/bin/ ├── redis-benchmark ├── redis-check-aof ├── redis-check-dump ├── redis-cli ├── redis-sentinel -> redis-server └── redis-server 命令執行完成後,會在/applicaion/redis/bin/目錄下生成5個可執行文件,分別是: redis-benchmark redis-check-aof redis-check-dump redis-cli redis-sentinel redis-server 它們的作用如下: 命令 說明 redis-server Redis服務器的daemon啓動程序 redis-cli Redis命令行操作工具,當然也可以用telnet跟其純文本協議來操作 redis-benchmark Redis性能測試工具,測試Redis在你的系統及你的配置下的讀寫 redis-check-aof 更新日誌檢查 redis-check-dump 用語本地數據庫的檢查
7.配置並啓動redis服務
a. 配置環境變量,命令如下
echo ' PATH=/application/redis/bin/:$PATH' >> /etc/profile source /etc/profile
查看執行結果如下:
tail -1 /etc/profile 提示:PATH=/application/redis/bin/:$PATH
查看是否被導入到全局路徑下
which redis-server
執行結果如下
/application/redis/bin/redis-server
b. 查看命令幫助
[root@mysql01 ~]# redis-server --help Usage: ./redis-server [/path/to/redis.conf] [options] ./redis-server - (read config from stdin) ./redis-server -v or --version ./redis-server -h or --help ./redis-server --test-memory <megabytes> Examples: ./redis-server (run the server with default conf) ./redis-server /etc/redis/6379.conf ./redis-server --port 7777 ./redis-server --port 7777 --slaveof 127.0.0.1 8888 ./redis-server /etc/myredis.conf --loglevel verbose Sentinel mode: ./redis-server /etc/sentinel.conf --sentinel
c. 啓動redis服務 操作命令:
cp ~/redis-3.0.7/redis.conf /application/redis /#安裝包內含有redis的默認配置文件 a) echo vm.overcommit_memory=1 >> /etc/sysctl.conf b) sysctl vm.overcommit_memory=1 或執行echo vm.overcommit_memory=1 >>/proc/sys/vm/overcommit_memory redis-server /application/redis/conf/redis.conf & 提示:啓動後會出現夯住的命令行,但是其實只要回車就好,因爲此處回車後臺執行 提示:查看端口是否存在確定redis是否啓動成功 [root@mysql01 ~]# netstat -lntup|grep -w 6379 tcp 0 0 0.0.0.0:6379 0.0.0.0:* LISTEN 5896/redis-server * tcp 0 0 :::6379 :::* LISTEN 5896/redis-server *
d. 關閉redis
redis-cli shutdown 或者 killall redis-server
8.redis主配置文件詳解
[root@dbserver ~]# grep -vE "#|^$" /application/redis/redis.conf 1.redis默然不是以守護進程的方式運行,可以通過該配置修改,使用yes啓用守護進程 daemonize yes 2.當redis以守護進程方式運行時,redis默認會把pid寫入/var/run/redis.pid文件,可以通過pidfile指定 pidfile /var/run/redis.pid 3.指定redis監聽端口,默認端口爲6379,爲了安全一般修改端口 port 6397 4.在高併發環境下需要一個backlog值來避免慢客戶端連接問題。注意Linux內核默默地將這個值減少到/proc/sys/net/core/somaxconn的值,所以需要確認增大aomaxconn和tcp_max_syx_backlog兩個值來表達想要的效果。 tcp-backlog 511 5.綁定主機地址 bind 127.0.0.1 6.當客戶端閒置多長時間後關閉連接,如果指定爲0,表示關閉功能 timeout 0 7.tcp連接保活策略,可以通過tcp-keepalive配置項來進行設置,單位爲妙,假如設置爲60秒,則server端會每60秒向連接空閒的客戶端發起一次ACK請求,以檢查客戶端是否已經掛掉,對於無響應的客戶端則會關閉其連接,所以關閉一個連接最長需要120秒的時間,如果設置爲0.則不進行保活檢測。一般合理值爲60秒 tcp-keepalive 0 8.指定日誌級別,redis總共支持四個級別:debug/verbose/notice/warning,默認爲verbose.debug記錄很多信息,用於開發與測試;verbose:很多精簡的有用信息,不像debug會記錄那麼多;notice普通的verbose,常用於生產環境;warning只有非常重要或者嚴重的信息會記錄到日誌 loglevel notice 9.指定日誌文件名,也可以使用“stdout”來強制讓redis把日誌信息寫到標準輸出上,默認爲標準輸出,如果配置redis爲守護進程的方式運行,而這裏又配置爲日誌記錄方式爲標準輸出,則日誌將會發給/dev/null logfile "" 10.設置數據庫的數量,默認數據爲0,可以使用select<dbid>命令在連接上指定數據庫ID databases 16 11.指定在多長時間內,有多少次更新操作,就講數據同步到數據文件,可以多個條件配合 save <seconds> <changes> redis默認配置文件中提供了三個條件: save 900 1 save 300 10 save 60 10000 分別表示900秒(15分鐘)內1個更改,300秒(5分鐘)內有10個更改以及60秒內有10000個更改。 12.如果開啓了RDB快照功能,那麼在redis持久化數據到磁盤時如果出現失敗,默認情況下,redis會停止接受所有的寫請求,這樣做的好處在於可以讓用戶很明確的知道內存中的數據和磁盤上的數據已經存在不一致了,如果redis不顧這種不一致,一意孤行的繼續接受請求,就可能會引起一些災難性的的後果,如果下一次RDB持久化成功,redis會自動回覆接受請求,當然,如果不在乎這種數據不一致或者有其他的手段發現和控制這種不一致的話,你完全可以關閉這個功能,以便在快照寫入失敗時,也能確保redis繼續接受新的請求。 stop-writes-on-bgsave-error yes 13.當導出到.rdb數據庫時是否用LZF壓縮字符串對象,默認設置爲“yes”如果想節省CPU的話,可以把這個設置爲“no",但是如果有壓縮的key卻沒有壓縮的話,那數據文件會變得更大。 rdbcompression yes 14.因爲版本5的RDB有一個CRC64算法的效驗和放在了文件的最後。這將使文件格式更加可靠但在生產和加載RDB文件時,這有一個性能消耗(大約10%),所以可以關掉它來獲取最好的新能,生成的關閉效驗的RDB文件有一0的效驗和,它將告訴加載代碼跳過檢查 rdbchecksum yes 15.數據庫的文件名及存放路徑 dbfilename dump.rdb 16.工作目錄,本地數據庫會寫到這個目錄下,文件名是上面的“dbfilename”的值,累加文件也放這裏,注意你這裏指定的必須是目錄,不是文件名。 dir ./ 17.當一個slave失去和master的連接,或者同步正在進行中,slave的行爲有兩種可能:1)如果slave-server-stale-data設置爲“yes”(默認值),slave會繼續響應客戶端請求,可能是正常數據,也可能是還沒獲得值的空數據。 2)如果slave-server-stale-data設置爲“no”,slave會回覆“正在從master同步(SYNC with master in progress)”來處理各種請求,除了INFO和SLAVEOF命令。 slave-serve-stale-data yes 18.可以配置slave實例是否接受寫操作。可寫的slave實例可能對存儲臨時數據比較有用(因爲寫入slave#的數據在同master同步之後將很容易被刪除),但是如果客戶端由於配置錯誤在寫入時也可能產生一些問題,從Redis2.6默認所有的slave爲只讀,注意:只讀slave不是爲了暴露給互聯網上不可信的客戶端而設計的,它只是一個防止實例誤用的保護層。一個只讀的slave支持所有的管理命令比如config,debug等。爲了限制你可以用“rename-command”來,隱藏所有的管理和危險命令來增強只讀slave的安全性 slave-read-only yes 19.複製集同步策略:磁盤或者socket,新slave連接或者老slave重新連接時候不能只接收不同,得做一個全同步。需要一個新的RDB文件dump出來,然後從master傳到slave。可能有兩種情況:1)基於硬盤(disk-backed):master創建一個新的進程dump RDB,完事兒之後由父進程(即主進程)增量傳給slave;2)基於socket(diskless):master創建一個新進程直接dump RDB到slave的socket,不經過主進程,不經過硬盤。基於硬盤的話,RDB文件創建後,一旦創建完畢,可以同時服務更多的slave。基於socket的話,新slave來了後,得排隊(如果超出了repl-diskless-sync-delay還沒來),完事兒一個再進行下一個。當用diskless的時候,master等待一個repl-diskless-sync-dely的秒數,如果沒slave來的話,就直接傳,後來的得排隊等了,否則就可以一起傳,disk較慢,並且網絡較快的時候,可以用diskless(默認用disk-based) repl-diskless-sync no 20.設置成0的話,傳輸開始ASAP repl-diskless-sync-delay 5 21.是否在slave套接字發送SYNC之後禁用TCP_NODELAY?如果選擇yes redis將使用更少的TCP包和帶寬來向slave發送數據,但是這將使數據傳輸到slave上有延遲,Linux內核的默認會達到40毫秒,如果選中了no數據傳輸到slave的延遲將會減少但要使用更多的帶寬默認我們會爲低延遲做優化,但高流量情況或主從之間的跳數過多時,把這個選項設置爲yes是個不錯的選擇。 repl-disable-tcp-nodelay no 22.slave的優先級是一個整數展示在redis的info輸出中,如果master不再正常工作了,sentinel將用它來選擇一個slave提升=升爲master。優先級數字小的slave會優先考慮提升爲master,所以例如有三個slave優先級分別爲10,100,25,sentinel將挑選優先級最小數字爲10的slave,0作爲一個特殊的優先級,標示這個slave不能作爲master,所以一個優先級爲0的slave永遠不會被sentinel挑選提升爲master,默認優先級爲100 slave-priority 100 23.要求客戶端在處理任何命令時都要驗證身份和密碼,這個功能在有你不信任的其它客戶端能夠訪問redis服務器的環境裏非常有用,爲了向後兼容的話這段應該註釋掉。而且大多數人不需要身份證(例如:它們運行在自己的服務器上)警告:因爲redis太快了,所以外面的人可以嘗試每秒150k的密碼來試圖破解密碼。這意味着你需要一個高強度的密碼,否則容易破解太容易了 requirepass 898redis 24.默認情況下,redis是異步的把數據導出到磁盤上。這種模式在很多應用裏已經足夠好,但redis進程出問題或斷電時可能造成一段時間的寫操作丟失(這取決於配置的save指令)。AOF是一種提供了更可靠的替代持久化模式,例如使用默認的數據寫入文件策略,在遇到像服務器斷電或單寫情況下redis自身進程出現問題但操作系統仍正常運行等突發事件時,redis能丟失1秒的寫操作,AOF和RDB持久化能同時啓動並且不會有問題。如果AOF開啓,那麼在啓動時redis將加載AOF文件,它更能保證數據的可靠性 appendonly no 25.追加加文件名字,默認appendonly.aof appendfilename "appendonly.aof" 26.fsync()系統調用告訴操作系統把數據寫到磁盤上,而不是等更多的數據進入輸出緩衝區。有些操作系統會真的把數據馬上刷到磁盤上;有些則會快速去嘗試這麼做。 redis支持三種不同的模式: no:不要立刻刷,只有操作系統需要刷的時候再刷。比較快; always:每次寫操作都立刻寫入到AOF文件。慢,但是最安全 everysec:每秒寫一次。折中方案。 默認的“everysec”通常來說能在速度和數據安全性之間取得比較好的平衡。根據你的理解來決定,如果你能放寬該配置爲“no”來獲取更好的性能(但如果你能忍受一些數據丟失,可以考慮使用默認的快照持久化模式),或者相反,用“always”會比較慢但比everysec要更安全。 appendfsync everysec 27.如果AOF的同步策略設置成“always”或者“everysec”,並且後臺的存儲進程(後臺存儲進程或寫入AOF日誌)會產生很多磁盤I/0開銷。某些Linux的配置下會使redis因爲fsync()系統調用而阻塞很久。注意,目前對這個情況還沒有完美修正,甚至不同線程的fsync()會阻塞我們同步的write(2)調用。爲了緩解這個問題,可以用下面這個選項。它可以在BGSAVE或BGREWRITEAOF處理時組織fsync().這就意味着如果有子進程在進行保存操作,那麼redis就處於“不可同步”的狀態。這實際上是說,在最差的情況下可能會丟掉30秒鐘的日誌數據(默認Linux設定)如果把這個設置成yes帶來了延遲問題,就保持no,這是保存持久數據的最安全的方式。 no-appendfsync-on-rewrite no 28.自動重寫AOF文件,如果AOF日誌文件增大到指定百分比,redis能夠通過BGREWRITEAOF自動重寫AOF日誌文件。工作原理:redis記住上次重寫AOF文件的大小(如果重啓還沒有寫操作,就直接啓動時的AOF大小)這個基準大小和當前大小做比較。如果當前大小超過指定比例,就會觸發重寫操作,還需要指定被重寫日誌的最小尺寸,這樣避免了打到指定百分比但尺寸仍然很小的情況還要重寫。指定百分比爲0會禁用AOF自動重寫特徵。 auto-aof-rewrite-percentage 100 auto-aof-rewrite-min-size 64mb 29.AOF文件可能在尾部是不完整的(上次system關閉有問題,尤其是mount ext4文件系統時沒有加上data=ordered選項。只會發生在OS死時,redis自己死不會不完整)。那redis重啓時load進內存的時候就有問題了。發生的時候,可以選擇redis啓動報錯,或者load儘量多正常的數據。如果aof-load-truncated是yes,會自動發佈一個log給客戶端然後load(默認)如果是no,用戶必須手動redis-check-aof修復AOF文件纔可以。 aof-load-truncated yes 30.如果達到最大時間限制(毫秒),redis會記個log,然後返回error,當一個腳本超過了最大時限,只有script kill 和shutdown nosave可以用,第一個可以殺沒有調用了write,只能用第二個命令殺,設置成0或者負值,時限就無限。 lua-time-limit 5000 31.redis慢查詢日誌可以記錄超過指定時間的查詢。運行時間不包括各種I/O時間,例如:連接客戶端,發送響應數據等,而只計算命令執行的實際時間(這只是線程阻塞而無法同時爲其它請求服務的命令執行階段)可以爲慢查詢日誌配置;兩個參數:一個指明redis的超時時間(單位爲微妙)來記錄超過時間的命令,另一個是慢查詢日誌長度。當一個新的命令被寫進日誌的時候,最老的那個記錄從隊列中移除,下面的時間單位是微妙,所以1000000就是1秒。注意,負數時間會禁用慢查詢日誌,而0則會強制記錄所有命令。 slowlog-log-slower-than 10000 32.這個長度沒有限制,只是要主要會消耗內存。可以通過slowlog reset來回收內存 slowlog-max-len 128 33.默認情況下禁用延遲監控,因爲它基本上是不需要的,單位爲毫秒 latency-monitor-threshold 0 34.redis能通知pub/Sub客戶端關於鍵空間發生的事件例如:如果鍵空間事件通知被開啓,並且客戶端對0號數據庫的鍵foo執行del命令時,將通過Pub/Sub發佈兩條消息: PUBLISH_keyspace@0_:foo del PUBLISH_keyevent@0_:del foo 可以在下表中選擇redis要通知的事件類型。事件類型由單個字符來標示: K 鍵空間通知,以_keyspace@<db>_爲前綴 E 鍵事件通知,以_keyevent@<db>_爲前綴 g DEL,EXPIRE,RENAME等類型無關的通用命令的通知。。。 $ String命令 l List命令 s Set命令 h Hash命令 z 有序集合命令 x 過期事件(每次key過期時生成) e 驅逐事件(當key在內存滿了被清楚時生成) A g$lshzce的別名,因此“AKE”意味着所有的事件 notify-keyspace-events帶一個由0到多個字符組成的字符串參數。空字符串意思是通知被禁用。例子:啓用list和通用事件通知:notify-keyspace-events Elg 例子2:爲了獲取過期key的通知訂閱名字爲_keyevent@_:expired的頻道,用以下配置notify-keyspace-events Ex 默認所用的通知被禁用,因爲用戶通常不需要該特性,並且該特性會有性能耗損。注意所用的通知被禁用,因爲用戶通常不需要該特性,並且該特性會有性能耗損。注意如果你不指定至少k或E之一,不會發送任何事件。 notify-keyspace-events "" 35.當有大量數據時,適合用哈希編碼(這會需要更多的內存),元素數量上限不能超過給定限制。redis hash是value內部爲一個hashmap,如果該map的成員數比較少,則會採用類似一維線性的緊湊格式來存儲該map,即省去了大量指針的內存開銷,如果2個條件任意一個條件超過設置值都會轉換成真正的hashmap,當value這個map內部不超過多少個成員時會採用線性緊湊格式存儲,默認是64,即value內部有64個一下的成員就是使用線性緊湊存儲,超過該值自動轉成正在的hashmap hash-max-ziplist-entries 512 36.當value這個map內部的每個成員值不超過多少字節就會採用線性緊湊存儲來節省空間。 hash-max-ziplist-value 64 37.與hash-max-zipmap-entries哈希相類似,數據元素較少的情況下,可以用另一種方式來編碼從而節省大量空間。list數據類型多少節點一下會採用去指針的緊湊存儲格式 list-max-ziplist-entries 512 38.list數據類型節點值小小於多少字節會採用緊湊格式 list-max-ziplist-value 64 39.還有這樣一種特殊編碼的情況:數據全是64位無符號整形數字構成的字符串。下面這個配置就是用來限制這種情況下使用這種編碼的最大上限的。 set-max-intset-entries 512 40.與第一、第二種情況類似,有序序列可以用一種特別的編碼方式來處理,可節省大量空間。這種編碼只適合長度和元素都符合下面限制的有序序列: zset-max-ziplist-entries 128 zset-max-ziplist-value 64 41.關於Hyperloglogs稀疏表示限制設置,如果其值大於16000,則仍然採用稠密表示,因爲這時稠密表示更能有效使用內存,建議值爲3000 hll-sparse-max-bytes 3000 42. 哈希刷新,每100個CPU毫秒會拿出1個毫秒來刷新Redis的主哈希表(頂級鍵值映射表)。redis所用的哈希表實現(見dict.c)採用延遲哈希刷新機制:你對一個哈希表操作越多,哈希刷新操作就越頻繁;反之,如果服務器非常不活躍那麼也就是用點內存保存哈希表而已。默認是每秒鐘進行10次哈希表刷新,用來刷新字典,然後儘快釋放內存。建議:如果對延遲比較在意的話就用 "activerehashing no",每個請求延遲2毫秒不太好嘛。如果你不太在意延遲而希望儘快釋放內存的話就設置 activerehashing yes 43. 客戶端的輸出緩衝區的限制,可用於強制斷開那些因爲某種原因從服務器讀取數據的速度不夠快的客戶端,(一個常見的原因是一個發佈/訂閱客戶端消費消息的速度無法趕上生產它們的速度)可以對三種不同的客戶端設置不同的限制: normal -> 正常客戶端slave -> slave和 MONITOR 客戶端pubsub -> 至少訂閱了一個pubsub channel或pattern的客戶端,下面是每個client-output-buffer-limit語法: client-output-buffer-limit <class><hard limit> <soft limit> <soft seconds>一旦達到硬限制客戶端會立即被斷開,或者達到軟限制並持續達到指定的秒數(連續的)。例如,如果硬限制爲32兆字節和軟限制爲16兆字節/10秒,客戶端將會立即斷開如果輸出緩衝區的大小達到32兆字節,或客戶端達到16兆字節並連續超過了限制10秒,就將斷開連接。默認normal客戶端不做限制,因爲他們在不主動請求時不接收數據(以推的方式),只有異步客戶端,可能會出現請求數據的速度比它可以讀取的速度快的場景。pubsub和slave客戶端會有一個默認值,因爲訂閱者和slaves以推的方式來接收數據,把硬限制和軟限制都設置爲0來禁用該功能 client-output-buffer-limit normal 0 0 0 client-output-buffer-limit slave 256mb 64mb 60 client-output-buffer-limit pubsub 32mb 8mb 60 44.redis調用內部函數來執行許多後臺任務,如關閉客戶端超時的連接,清除未被請求過得過期key等等。不是所有的任務都以相同的頻率執行,但redis依照指定的“hz”值來執行檢查任務。默認情況下,“hz”的被設定爲10.提高該值將在redis空閒時使用更多的CPU時,但同時當有多個key同時到期會使redis的反應更靈敏,以及超時可以更精確的處理。範圍是1到500之間,但是值超過100通常不是一個好主意。大多數用戶應該使用10這個默認值,只有在非常低的延遲要求時有必要提高到100. hz 10 45.當一個子進程重寫AOF文件時,如果啓用下面的選項,則文件沒生成32M數據會被同步。爲了增量式的寫入硬盤並且避免大的延遲高峯這個指令是非常有用的 aof-rewrite-incremental-fsync yes