您好,登錄后才能下訂單哦!
一、Redis介紹
Redis是由意大利人Salvatore Sanfilippo(網名:antirez)開發的一款內存高速緩存數據庫。Redis全稱為:Remote Dictionary Server(遠程數據服務),該軟件使用C語言編寫,Redis是一個key-value存儲系統,它支持豐富的數據類型,如:string、list、set、zset(sorted set)、hash。和Memcache類似,但很大程度補償了Memcache的不足,它支持存儲的value類型相對更多,包括string、list、set、zset和hash。這些數據類型都支持push/pop、add/remove及取交集并集和差集及更豐富的操作。在此基礎上,Redis支持各種不同方式的排序。
Redis以內存作為數據存儲介質,所以讀寫數據的效率極高,遠遠超過數據庫。以設置和獲取一個256字節字符串為例,它的讀取速度可高達110000次/s,寫速度高達81000次/s。Redis的存儲分為內存存儲、磁盤存儲和log文件三部分,重啟后,Redis可以從磁盤重新將數據加載到內存中,這些可以通過配置文件對其進行配置,正因為這樣,Redis才能實現持久化。因為Redis交換數據快,所以在服務器中常用來存儲一些需要頻繁調取的數據,這樣可以大大節省系統直接讀取磁盤來獲得數據的I/O開銷,更重要的是可以極大提升速度。
Memcache只能將數據緩存到內存中,無法自動定期寫入硬盤,一斷電或重啟,內存清空,數據丟失。所以Memcache的應用場景適用于緩存無需持久化的數據.
Redis從它的許多競爭繼承來的三個主要特點:
1.Redis數據庫完全在內存中,使用磁盤僅用于持久性。
2.相比許多鍵值數據存儲,Redis擁有一套較為豐富的數據類型。
3.Redis可以將數據復制到任意數量的從服務器。
4、Redis能支持超過 100K+ 每秒的讀寫頻率
5、單個value限制是1GB,memcached為1M數據
Redis優勢
異常快速:Redis的速度非常快,每秒能執行約11萬集合,每秒約81000+條記錄。
支持豐富的數據類型:Redis支持最大多數開發人員已經知道像列表,集合,有序集合,散列數據類型。這使得它非常容易解決各種各樣的問題,因為我們知道哪些問題是可以處理通過它的數據類型更好。
操作都是原子性:所有Redis操作是原子的,這保證了如果兩個客戶端同時訪問的Redis服務器將獲得更新后的值。
多功能實用工具:Redis是一個多實用的工具,可以在多個用例如緩存,消息,隊列使用(Redis原生支持發布/訂閱),任何短暫的數據,應用程序,如Web應用程序會話,網頁命中計數等。
二、Redis的安裝
[root@localhost app]# ls redis-3.2.8.tar.gz [root@localhost app]# tar zxvf redis-3.2.8.tar.gz [root@localhost app]# cd redis-3.2.8 [root@localhost redis-3.2.8]# yum -y install gcc gcc-c++ [root@localhost redis-3.2.3]# make #make MALLOC=libc 如果在make的時候不指定內存管理方式,會報錯的: zmalloc.h:50:31: 致命錯誤:jemalloc/jemalloc.h:沒有那個文件或目錄。 malloc是管理內存碎片的。 Hint: It's a good idea to run 'make test' ;) make[1]: Leaving directory `/app/redis-3.2.3/src' [root@localhost redis-3.2.3]#
在執行完make之后,在最后的程序中會輸出(t's a good idea to run 'make test'),它建議我們執行make test進行測試,那么接下來我們就輸入make test,檢查測試,是否出現問題,如出現如圖所示:則說明測試沒有問題:
[root@localhost redis-3.2.3]# cd src/ [root@localhost src]# make test You need tcl 8.5 or newer in order to run the Redis test make: *** [test] Error 1 [root@localhost src]# cd /app/ [root@localhost app]# wget [root@localhost app]# tar zxvf tcl8.6.1-src.tar.gz [root@localhost app]# cd tcl8.6.1/unix/ [root@localhost unix]# ./configure [root@localhost unix]# make && make install [root@localhost unix]# cd /app/redis-3.2.3/ [root@localhost redis-3.2.3]# make clean [root@localhost redis-3.2.3]# make [root@localhost redis-3.2.3]# cd src/ [root@localhost src]# make test 215 seconds - integration/replication-3 212 seconds - integration/replication-4 98 seconds - unit/hyperloglog 151 seconds - unit/obuf-limits \o/ All tests passed without errors! Cleanup: may take some time... OK [root@localhost src]# make install #make PREFIX=/app/redis install 注意PREFIX大寫 Hint: It's a good idea to run 'make test' ;) INSTALL install INSTALL install INSTALL install INSTALL install INSTALL install [root@localhost src]#
注意:這里很可能會在make test 這步出現以下錯誤:
錯誤一
!!! WARNING The following tests failed: *** [err]: Test replication partial resync: ok psync (diskless: yes, reconnect: 1) in tests/integration/replication-psync.tcl Expected condition '[s -1 sync_partial_ok] > 0' to be true ([s -1 sync_partial_ok] > 0) Cleanup: may take some time... OK make: *** [test] Error 1 [root@localhost src]#
有2個方法可以避免:
1、在解壓目錄中修改 tests/integration/replication-psync.tcl,把 after 100 改成 after 500,這個參數貌似是等待的毫秒數
[root@localhost redis-3.2.3]# vim tests/integration/replication-psync.tcl if ($reconnect) { for {set j 0} {$j < $duration*10} {incr j} { after 500 # catch {puts "MASTER [$master dbsize] keys, SLAVE [$slave dbsize] keys"} [root@localhost redis-3.2.3]#
2、用taskset來make test
taskset -c 1 make test
錯誤二
[exception]: Executing test client: NOREPLICAS Not enough good slaves to write.. NOREPLICAS Not enough good slaves to write. ...... Killing still running Redis server 63439 Killing still running Redis server 63486 Killing still running Redis server 63519 Killing still running Redis server 63546 Killing still running Redis server 63574 Killing still running Redis server 63591 I/O error reading reply ...... "createComplexDataset $r $ops" (procedure "bg_complex_data" line 4) invoked from within "bg_complex_data [lindex $argv 0] [lindex $argv 1] [lindex $argv 2] [lindex $argv 3]" (file "tests/helpers/bg_complex_data.tcl" line 10) Killing still running Redis server 21198 make: *** [test] Error 1 [root@localhost src]# vim ../tests/integration/replication-2.tcl start_server {tags {"repl"}} { start_server {} { test {First server should have role slave after SLAVEOF} { r -1 slaveof [srv 0 host] [srv 0 port] after 10000 #修改成10000 s -1 role } {slave}
錯誤三
[err]: Slave should be able to synchronize with the master in tests/integration/replication-psync.tcl Replication not started.
這個錯誤我重新make test就可以了,只遇到過一次
三、redis的配置
啟動:
[root@localhost src]# redis-server ../redis.conf _._ _.-``__ ''-._ _.-`` `. `_. ''-._ Redis 3.2.3 (00000000/0) 64 bit .-`` .-```. ```\/ _.,_ ''-._ ( ' , .-` | `, ) Running in standalone mode |`-._`-...-` __...-.``-._|'` _.-'| Port: 6379 | `-._ `._ / _.-' | PID: 35217 `-._ `-._ `-./ _.-' _.-' |`-._`-._ `-.__.-' _.-'_.-'| | `-._`-._ _.-'_.-' | http://redis.io `-._ `-._`-.__.-'_.-' _.-' |`-._`-._ `-.__.-' _.-'_.-'| | `-._`-._ _.-'_.-' | `-._ `-._`-.__.-'_.-' _.-' `-._ `-.__.-' _.-' `-._ _.-' `-.__.-' 35217:M 29 Mar 11:30:21.454 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128. 35217:M 29 Mar 11:30:21.454 # Server started, Redis version 3.2.3 35217:M 29 Mar 11:30:21.454 # WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect. 35217:M 29 Mar 11:30:21.454 * The server is now ready to accept connections on port 6379 ^C35217:signal-handler (1490758240) Received SIGINT scheduling shutdown... 35217:M 29 Mar 11:30:40.180 # User requested shutdown... 35217:M 29 Mar 11:30:40.180 * Saving the final RDB snapshot before exiting. 35217:M 29 Mar 11:30:40.191 * DB saved on disk 35217:M 29 Mar 11:30:40.191 * Removing the pid file. 35217:M 29 Mar 11:30:40.191 # Redis is now ready to exit, bye bye... [root@localhost src]#
這里直接執行Redis-server 啟動的Redis服務,是在前臺直接運行的(效果如上圖),也就是說,執行完該命令后,如果Lunix關閉當前會話,則Redis服務也隨即關閉。正常情況下,啟動Redis服務需要從后臺啟動,并且指定啟動配置文件。
編輯conf文件,將daemonize屬性改為yes(表明需要在后臺運行)
[root@localhost src]# vim ../redis.conf daemonize yes [root@localhost src]# redis-server ../redis.conf [root@localhost src]# netstat -anotp|grep :6379 tcp 0 0 127.0.0.1:6379 0.0.0.0:* LISTEN 35415/redis-server off (0.00/0/0) [root@localhost src]# redis-cli shutdown #停止redis服務 [root@localhost src]# netstat -anotp|grep :6379
配置
為了方便管理,將Redis文件中的conf配置文件和常用命令移動到統一文件中
[root@localhost app]# mkdir -p redis6379/{log,conf,data,bin} [root@localhost src]# cp redis-server redis-benchmark redis-cli mkreleasehdr.sh redis-check-aof /app/redis6379/bin/ [root@localhost src]# cp ../redis.conf /app/redis6379/conf/ [root@localhost src]# pwd /app/redis-3.2.3/src [root@localhost src]# cd /app/redis6379/bin/ [root@localhost bin]# redis-server ../conf/redis.conf [root@localhost bin]# netstat -antp|grep :6379 tcp 0 0 127.0.0.1:6379 0.0.0.0:* LISTEN 36334/redis-server [root@localhost bin]# cp /etc/sysctl.conf{,.bak} [root@localhost bin]# vim /etc/sysctl.conf vm.overcommit_memory = 1 [root@localhost bin]# sysctl -p
redis-benchmark redis性能檢測工具
測試Redis的讀寫性能:
[root@localhost bin]# ./redis-benchmark -h localhost -p 6979 -c 100 -n 100000 #100個并發連接,100000個請求 ...... ====== MSET (10 keys) ====== 100000 requests completed in 0.94 seconds #100000個請求完成于 0.94 秒 100 parallel clients #每個請求有100個并發客戶端 3 bytes payload #每次寫入3字節 keep alive: 1 #保持1個連接 99.92% <= 1 milliseconds 100.00% <= 1 milliseconds 106609.80 requests per second #每秒106609.80次查詢
參數:
-h 設置檢測主機IP地址,默認為127.0.0.1
-p 設置檢測主機的端口號,默認為6379
-s<socket> 服務器套接字(壓倒主機和端口)
-c 并發連接數
-n 請求數
-d 測試使用的數據集的大小/字節的值(默認3字節)
-k 1:表示保持連接(默認值)0:重新連接
-r SET/GET/INCR方法使用隨機數插入數值,設置10則插入值為rand:000000000000 - rand:000000000009
-P 默認為1(無管道),當網絡延遲過長時,使用管道方式通信(請求和響應打包發送接收)
-q 簡約信息模式,只顯示查詢和秒值等基本信息。
--csv 以CSV格式輸出信息
-l 無線循環插入測試數據,ctrl+c停止
-t<tests> 只運行<tests>測試逗號分隔的列表命令,如:-t ping,set,get
-I 空閑模式。立即打開50個空閑連接和等待。
redis-check-rdb 檢查rbd日志的工具
redis-check-dump 檢查本地數據庫文件
redis-check-dump dump.rdb
redis-sentinel Redis集群的管理工具 監控多個master-slave集群,發現master宕機后能進行自動切換
redis-check-aof 檢查aof日志的工具
redis-check-aof appendonly.aof
--fix參數為修復log文件
redis-cli Redis命令行操作工具
參數:
-h 設置檢測主機IP地址,默認為127.0.0.1
-p 設置檢測主機的端口號,默認為6379
-s<socket> 服務器套接字(壓倒主機和端口)
-a 連接到Master服務器時使用的密碼
-r 執行指定的N次命令,eg:redis-cli -r 3 info 重復執行info命令三次-i 執行命令后等待N秒,如–i 0.1 info(執行后等0.1秒),eg:redis-cli -r 100 -i 1 info | grep used_memory_human
-n 指定連接N號ID數據庫,如 –n 3(連接3號數據庫)
-x 從控制臺輸入的信息中讀取最后一個參數,eg:cat testStr.txt | redis-cli -x set testStr讀取testStr.txt文件所有內容設置為testStr的值-d 定義多個定界符為默認輸出格式(默認: \n)
--raw 使用原數據格式返回輸出內容
--latency 進入一個不斷延時采樣的特殊模式
--slave 模擬一個從服務器到主服務器的命令顯示反饋
--pipe 使用管道協議模式
--bigkeys 監聽顯示數據量大的key值,--bigkeys -i 0.1
--help 顯示命令行幫助信息
--version 顯示版本號
[root@localhost bin]# ./redis-cli -h 10.15.97.136 -p 6979 -a ywbz97.136 info #查看info信息 [root@localhost bin]# ./redis-cli -h 10.15.97.136 -p 6979 -a ywbz97.136 Warning: Using a password with '-a' option on the command line interface may not be safe. 10.15.97.136:6979> keys \* #查看所有鍵值信息 (empty list or set) 10.15.97.136:6979> [root@localhost bin]# ./redis-cli -h 10.15.97.136 -p 6979 -a ywbz97.136 -n 15 #登陸15號數據庫 [root@localhost bin]# ./redis-cli -h 10.15.97.136 -p 6979 -a ywbz97.136 info|grep "\<used_memory\>" #過濾查詢used_memory屬性 Warning: Using a password with '-a' option on the command line interface may not be safe. used_memory:902799 [root@localhost bin]#
當used_memory_rss接近maxmemory或者used_memory_peak超過maxmemory時,要加大maxmemory 負責性能下降。
maxmemory:
不要用比設置的上限更多的內存。一旦內存使用達到上限,Redis會根據選定的回收策略(參見:maxmemmory-policy:內存策略設置)刪除key。如果因為刪除策略問題Redis無法刪除key,或者策略設置為 "noeviction",Redis會回復需要更多內存的錯誤信息給命令。例如,SET,LPUSH等等。但是會繼續合理響應只讀命令,比如:GET。在使用Redis作為LRU緩存,或者為實例設置了硬性內存限制的時候(使用 "noeviction" 策略)的時候,這個選項還是滿有用的。當一堆slave連上達到內存上限的實例的時候,響應slave需要的輸出緩存所需內存不計算在使用內存當中。當請求一個刪除掉的key的時候就不會觸發網絡問題/重新同步的事件,然后slave就會收到一堆刪除指令,直到數據庫空了為止。slave連上一個master的話,建議把master內存限制設小點兒,確保有足夠的系統內存用作輸出緩存。(如果策略設置為"noeviction"的話就不無所謂了),設置最大內存,達到最大內存設置后,Redis會先嘗試清除已到期或即將到期的Key,當此方法處理后,任到達最大內存設置,將無法再進行寫入操作。
設置內存分配策略vm.overcommit_memory = 1 ;否則Redis腳本在重啟或停止redis時,將會報錯,并且不能自動在停止服務前同步數據到磁盤上
/proc/sys/vm/overcommit_memory可選值:0、1、2。
0, 表示內核將檢查是否有足夠的可用內存供應用進程使用;如果有足夠的可用內存,內存申請允許;否則,內存申請失敗,并把錯誤返回給應用進程。
1, 表示內核允許分配所有的物理內存,而不管當前的內存狀態如何。
2, 表示內核允許分配超過所有物理內存和交換空間總和的內存
值得注意的一點是,redis在dump數據的時候,會fork出一個子進程,理論上child進程所占用的內存和parent是一樣的,比如parent占用的內存為8G,這個時候也要同樣分配8G的內存給child,如果內存無法負擔,往往會造成redis服務器的down機或者IO負載過高,效率下降。所以這里比較優化的內存分配策略應該設置為 1(表示內核允許分配所有的物理內存,而不管當前的內存狀態如何)
redis服務關閉后,緩存數據會自動dump到硬盤上,硬盤地址為redis.conf中的配置項dbfilename dump.rdb所設定
redis配置文件簡介
[root@localhost conf]# vim redis.conf # 1k => 1000 bytes # 1kb => 1024 bytes # 1m => 1000000 bytes # 1mb => 1024*1024 bytes # 1g => 1000000000 bytes # 1gb => 1024*1024*1024 bytes # # units are case insensitive so 1GB 1Gb 1gB are all the same. #當配置中需要配置內存大小時,可以使用 1k, 5GB, 4M 等類似的格式,其內存單位轉換方式如下(不區分大小寫,比如 1gb 1Gb 1GB 1gB均可) daemonize yes #是否以后臺進程運行,默認為no pidfile /var/run/redis_6379.pid #如以后臺進程運行,需指定一個pid路徑,默認為/var/run/redis.pid port 6379 #監聽端口,默認為6379 # unixsocket /tmp/redis.sock #指定用來監聽連接的unxi套接字的路徑。這個沒有默認值,所以如果不指定的話,Redis就不會通過unix套接字來監聽。 # unixsocketperm 700 timeout 300 #超時時間,當客戶端在這段時間內沒有發出任何指令,那么關閉該連接,默認為0(秒),永不超時 loglevel notice #日志記錄等級,有4個可選值,debug適用于開發和測試,verbose更詳細信息,notice適用于生產環境,warning只記錄警告或錯誤信息 logfile /app/redis6379/log/redis.log #日志記錄方式,默認值為stdout # syslog-enabled no #是否將日志輸出到系統日志 # syslog-ident redis #設置linux系統日志syslog的標示符,若是"syslog-enabled=no",則這個選項無效。 # syslog-facility local0 #設置syslog的facility,必須是USER或者是 LOCAL0-LOCAL7之間的值。 slave-serve-stale-data yes #當slave與master之間的連接斷開或slave正在與master進行數據同步時,如果有slave請求,當設置為yes時,slave仍然響應請求,此時可能有問題,如果設置no時,slave會返回"SYNC with master in progress"錯誤信息。但INFO和SLAVEOF命令除外。 databases 16 #可用數據庫數,默認值為16, ############### 快照方式 ############### save 900 1 #900秒(15分鐘)內至少有1個key被改變,則快照 save 300 10 #300秒(5分鐘)內至少有10個key被改變 ,則快照 save 60 10000 #60秒內至少有10000個key被改變,則快照,如果不需要寫磁盤,則把所有 "save" 設置注釋掉 rdbcompression yes #存儲至本地數據庫時是否壓縮數據,默認為yes,如果你希望保存子進程節省點 cpu ,你就設置它為 no ,不過這個數據集可能就會比較大 dbfilename dump.rdb #本地數據庫文件名,默認值為dump.rdb rdbchecksum yes #是否校驗rdb文件 dir /app/redis6379/data #本地數據庫存放路徑,默認值為 ./ 工作目錄 tcp-keepalive 60 #tcp 心跳包,推薦一個合理的值就是60秒,防止死的 peers ############### 主從復制 ############### # slaveof <masterip> <masterport> #slaveof 10.0.0.12 6379 #當本機為從服務時,設置主服務的IP及端口 # masterauth <master-password> #masterauth justin #當master設置密碼認證,slave用此選項指定master認證密碼 # repl-ping-slave-period 10 #Slaves在一個預定義的時間間隔內發送ping命令到server, 默認為10秒。可以通過 repl_ping_slave_period 來設置 # repl-timeout 60 #設置主從復制大塊數據I/O、向master請求數據和ping響應的過期時,這個值一定要比repl-ping-slave-period大,否則master和slave之間的傳輸過期時間比預想的要短。 # requirepass foobared # requirepass justin #設置redis密碼 # maxclients 10000 #設置最大同時連接客戶端數量,0為不限制,這個關系到Redis進程能夠打開的文件描述符數量,一旦達到這個限制,Redis會關閉所有新連接并發送錯誤"達到最大用戶數上限(max number of clients reached)" # maxmemory <bytes> #指定Redis最大內存限制,Redis在啟動時會把數據加載到內存中,達到最大內存后,Redis會先嘗試清除已到期或即將到期的Key,當此方法處理后,仍然到達最大內存設置,將無法再進行寫入操作,但仍然可以進行讀取操作。Redis新的vm機制,會把Key存放內存,Value會存放在swap區 appendonly no #指定是否在每次更新操作后進行日志記錄,Redis在默認情況下是異步的把數據寫入磁盤,如果不開啟,可能會在斷電時導致一段時間內的數據丟失。因為 redis本身同步數據文件是按上面save條件來同步的,所以有的數據會在一段時間內只存在于內存中。默認為no # maxmemory-policy noeviction #如果達到maxmemory值,采用此策略,可以采取的動作,volatile-lru :默認策略,只對設置過期時間的key進行LRU算法刪除,allkeys-lru :刪除不經常使用的key,volatile-random :隨機刪除即將過期的key,allkeys-random :隨機刪除一個key,volatile-ttl :刪除即將過期的key,noeviction :不過期,寫操作返回報錯。 # maxmemory-samples 5 #默認隨機選擇5個key,從中淘汰最不經常用的 appendfilename "appendonly.aof" #更新日志文件名,默認值為appendonly.aof appendfsync everysec #更新日志條件,共有3個可選值。no表示等操作系統進行數據緩存同步到磁盤,always表示每次更新操作后手動調用fsync()將數據寫到磁盤,everysec表示每秒同步一次 no-appendfsync-on-rewrite no #日志文件即將增長到指定百分比時,redis通過調用BGREWRITEAOF是否自動重寫AOF日志文件。 really-use-vm yes vm-enabled yes #是否使用虛擬內存,默認值為no,VM機制將數據分頁存放,由Redis將訪問量較少的頁即冷數據swap到磁盤上,訪問多的頁面由磁盤自動換出到內存中 vm-swap-file /tmp/redis.swap #虛擬內存文件路徑,默認值為/tmp/redis.swap,不可多個Redis實例共享 vm-max-memory 0 #vm大小限制。0:不限制,建議60-80% 可用內存大小。將所有大于vm-max-memory的數據存入虛擬內存,無論vm-max-memory設置多小,所有索引數據都是內存存儲的(Redis的索引數據 就是keys),也就是說,當vm-max-memory設置為0的時候,其實是所有value都存在于磁盤。默認值為0 vm-page-size 32 #根據緩存內容大小調整,默認32字節。Redis swap文件分成了很多的page,一個對象可以保存在多個page上面,但一個page上不能被多個對象共享,vm-page-size是要根據存儲的 數據大小來設定的,作者建議如果存儲很多小對象,page大小最好設置為32或者64bytes;如果存儲很大大對象,則可以使用更大的page,如果不 確定,就使用默認值 vm-pages 134217728 #page數。每 8 page,會占用1字節內存。設置swap文件中的page數量,由于頁表(一種表示頁面空閑或使用的bitmap)是在放在內存中的,,在磁盤上每8個pages將消耗1byte的內存。 vm-page-size #vm-pages 等于 swap 文件大小 vm-max-threads 4 #vm 最大io線程數。注意: 0 標志禁止使用vm,設置訪問swap文件的線程數,最好不要超過機器的核數,如果設置為0,那么所有對swap文件的操作都是串行的,可能會造成比較長時間的延遲。默認值為4 include /path/to/local.conf #指定包含其它的配置文件,可以在同一主機上多個Redis實例之間使用同一份配置文件,而同時各個實例又擁有自己的特定配置文件
maxmemory <bytes> 設置最大內存,maxmemory是bytes字節類型,注意轉換,如果設置了maxmemory,一般都要設置過期策略,默認策略maxmemory-policy volatile-lru對設置過期時間的key進行LRU(Least Recently Used 近期最少使用算法)算法刪除,如果set時候沒有加上過期時間就會導致數據寫滿maxmemory,此時將無法再進行寫入操作。
volatile-lru -> 根據LRU算法生成的過期時間來刪除。
allkeys-lru -> 根據LRU算法刪除任何key。
volatile-random -> 根據過期設置來隨機刪除key。
allkeys->random -> 無差別隨機刪。
volatile-ttl -> 根據最近過期時間來刪除(輔以TTL)
noeviction -> 誰也不刪,直接在寫操作時返回錯誤。
maxmemory 16777216 #設置最大內存16GB,一般推薦Redis設置內存為最大物理內存的四分之三。
Redis使用超過設置的最大值,在debug模式下的頁面,提示錯誤:OOM command not allowed when used memory > ‘maxmemory’.
redis的持久化方式分兩種
1.rdb模式
其實就是對內存中的東西按一些策略定期做snapshot,也就是快照,rdb保存的是二進制文件,是redis的默認方式。
save <seconds> <changes> #100秒內至少有10個key值發生改變才做持久化 save 100 10 #最新的快照保存失敗時停止寫操作 stop-writes-on-bgsave-error yes #做快照時是不是需要做壓縮 rdbcompression yes #數據校驗,保證數據正確性 rdbchecksum yes #快照的文件名 dbfilename dump.rdb #存放快照的目錄 dir /var/lib/redis
2.Append only file(AOF)的方式
它將每一步操作的命令強制保存到磁盤上,持久性比較好,但對于寫比較頻繁的情況不適合,不推薦。 配置如下:
appendonly no #append only file的名稱,默認為appendonly.aof appendfilename "appendonly.aof" #在日志重寫時,不進行命令追加操作,而只是將其放在緩沖區里,避免與命令的追加造成DISK IO上的沖突。 no-appendfsync-on-rewrite yes
強制同步數據到磁盤: redis-cli save 或 redis-cli -p 6380 save (根據端口號指定某臺服務器同步)
info命令查看Redis內存使用情況
[root@localhost redis6379]# cd bin/ [root@localhost bin]# ./redis-cli 127.0.0.1:6379> info # Server redis_version:3.2.3 redis_git_sha1:00000000 redis_git_dirty:0 redis_build_id:9f41557dffea5d14 redis_mode:standalone os:Linux 2.6.32-642.el6.x86_64 x86_64 arch_bits:64 #64位系統 multiplexing_api:epoll # Redis 所使用的事件處理機制 gcc_version:4.4.7 process_id:1381 #當前服務器進程id run_id:94e9454ecd837dc2b3fc6e41499ecc058679daae #Redis 服務器的隨機標識符(用于 Sentinel 和集群) tcp_port:6379 uptime_in_seconds:723584 #正常工作時間(秒) uptime_in_days:8 #正常工作天數 hz:10 lru_clock:16736529 executable:/app/redis6379/bin/redis-server config_file:/app/redis6379/conf/redis.conf # Clients connected_clients:1 #客戶端連接數 connected_slaves:0 #從服務器連接數 client_longest_output_list:0 #當前連接的客戶端當中,最長的輸出列表 client_biggest_input_buf:0 #當前連接的客戶端當中,最大輸入緩存 blocked_clients:0 #正在等待阻塞命令(BLPOP、BRPOP、BRPOPLPUSH)的客戶端的數量 # Memory used_memory:289912 #由Redis分配器分配的內存總量(edis數據占用的內存),以字節(byte)為單位 used_memory_human:283.12K #以人類可讀的格式返回Redis分配的內存總量,重點關注 used_memory_rss:1196032 #從操作系統的角度,返回Redis已分配的內存總量(redis占用的物理內存)。這個值和top、ps等命令的輸出一致。 used_memory_rss_human:1.14M used_memory_peak:289912 #redis使用物理內存的峰值(以字節為單位) used_memory_peak_human:283.12K total_system_memory:505806848 total_system_memory_human:482.38M used_memory_lua:37888 # Lua 引擎所使用的內存大小(以字節為單位) used_memory_lua_human:37.00K maxmemory:0 maxmemory_human:0B maxmemory_policy:noeviction mem_fragmentation_ratio:4.13 #內存碎片率,used_memory_rss和used_memory之間的比率 mem_allocator:jemalloc-4.0.3 #內存分配器版本,在編譯時指定的Redis所使用的內存分配器。可以是libc、jemalloc或者tcmalloc。 #在理想情況下, used_memory_rss 的值應該只比 used_memory 稍微高一點兒。 #當 rss > used ,且兩者的值相差較大時,表示存在(內部或外部的)內存碎片。內存碎片的比率可以通過 mem_fragmentation_ratio 的值看出。 #當 used > rss 時,表示 Redis 的部分內存被操作系統換出到交換空間了,在這種情況下,操作可能會產生明顯的延遲。當 Redis 釋放內存時,分配器可能會,也可能不會,將內存返還給操作系統。如果 Redis 釋放了內存,卻沒有將內存返還給操作系統,那么 used_memory 的值可能和操作系統顯示的 Redis 內存占用并不一致。查看 used_memory_peak 的值可以驗證這種情況是否發生。 # Persistence RDB 和 AOF 的相關信息 loading:0 rdb_changes_since_last_save:0 rdb_bgsave_in_progress:0 #后臺異步保存數據的進程數 rdb_last_save_time:1492407953 rdb_last_bgsave_status:ok rdb_last_bgsave_time_sec:-1 rdb_current_bgsave_time_sec:-1 aof_enabled:1 #是否開啟純累加模式 aof_rewrite_in_progress:0 aof_rewrite_scheduled:0 aof_last_rewrite_time_sec:-1 aof_current_rewrite_time_sec:-1 aof_last_bgrewrite_status:ok aof_last_write_status:ok aof_current_size:0 aof_base_size:0 aof_pending_rewrite:0 aof_buffer_length:0 aof_rewrite_buffer_length:0 aof_pending_bio_fsync:0 aof_delayed_fsync:0 # Stats 一般統計信息 total_connections_received:1 #接受到的總連接數 total_commands_processed:1 #服務器處理的命令數量 instantaneous_ops_per_sec:0 total_net_input_bytes:31 total_net_output_bytes:5935693 instantaneous_input_kbps:0.00 instantaneous_output_kbps:0.00 rejected_connections:0 sync_full:0 sync_partial_ok:0 sync_partial_err:0 expired_keys:0 #失效key的總數量 evicted_keys:0 #已刪除的key的總數量 keyspace_hits:0 #Key命中次數 keyspace_misses:0 #Key未命中次數 pubsub_channels:0 #訂閱信息 pubsub_patterns:0 latest_fork_usec:0 #最近子進程 migrate_cached_sockets:0 # Replication 主/從復制信息 role:master #master為主服務器slave為從服務器 connected_slaves:0 master_repl_offset:0 repl_backlog_active:0 repl_backlog_size:1048576 repl_backlog_first_byte_offset:0 repl_backlog_histlen:0 # CPU used_cpu_sys:386.43 #Cpu使用率 used_cpu_user:218.25 used_cpu_sys_children:0.00 used_cpu_user_children:0.00 #commandstats Redis 命令統計信息 # Cluster Redis 集群信息 cluster_enabled:0 # Keyspace 數據庫相關的統計信息 db0:keys=2,expires=0,avg_ttl=0 #1號數據庫保存的key數量,及超時時間 127.0.0.1:6379>
將Redis配置成服務
[root@localhost conf]# cp /usr/local/redis-3.2.8/utils/redis_init_script /etc/rc.d/init.d/redis [root@localhost conf]# cat /etc/rc.d/init.d/redis #!/bin/bash #chkconfig: 2345 10 90 #description: Redis server is an open source, advanced key-value store. # source function library source /etc/rc.d/init.d/functions port="6379" pidfile="/var/run/redis_$port.pid" lockfile="/var/lock/subsys/redis-server" rootpath="/app/redis$port" config="$rootpath/conf/redis.conf" binpath="$rootpath/bin" [ -r "$SYSCONFIG" ] && source "$SYSCONFIG" reids_status(){ status -p $pidfile redis-server } start() { if [ -e $pidfile ];then echo "Redis Server aleady running......" exit 1 else echo -n "Starting Redis Server......" $binpath/redis-server $config value=$? [ $value -eq 0 ] && touch $lockfile && echo "OK" return $value fi } stop() { echo -n "Stop Redis Server......" killproc redis-server # $binpath/redis-cli save && $binpath/redis-cli shutdown value=$? [ $value -eq 0 ] && rm -rf $lockfile $pidfile return $value } restart() { stop start } case "$1" in start) start ;; stop) stop ;; restart) restart ;; status) reids_status ;; *) echo $"Usage: $0 {start|stop|restart|status}" esac [root@localhost conf]# chkconfig --add redis [root@localhost conf]# chkconfig --level 2345 redis on [root@localhost conf]# chmod +x /etc/rc.d/init.d/redis
三、redis的測試
[root@localhost src]# redis-cli #redis-cli -h host -p port -a password 127.0.0.1:6379> set justin "WeChat ID:ityunwei2017" #向redis中插入鍵值對數據,鍵為justin,值為WeChat ID:ityunwei2017 OK 127.0.0.1:6379> get justin #根據鍵取值 "WeChat ID:ityunwei2017" 127.0.0.1:6379> exists justin #查看鍵是否存在 (integer) 1 127.0.0.1:6379> exists justin1 (integer) 0 127.0.0.1:6379> del justin #刪除當前key (integer) 1 127.0.0.1:6379> exists justin (integer) 0 127.0.0.1:6379> keys * #查看所有鍵 127.0.0.1:6379> dbsize #鍵總數 127.0.0.1:6379> 127.0.0.1:6379> quit [root@localhost src]# redis-benchmark -h 127.0.0.1 -p 6379 -n 10 -c 50
redis-benchmark -h 127.0.0.1 -p 6379 -n 10 -c 50 向redis服務器發送10個請求,每個請求附帶50個并發客戶端,-n 接請求數,-c 接并發數
Redis并沒有自己實現內存池,沒有在標準的系統內存分配器上再加上自己的東西。所以系統內存分配器的性能及碎片率會對Redis造成一些性能上的影響。Redis在編譯時,會先判斷是否使用tcmalloc,如果是,會用tcmalloc對應的函數替換掉標準的libc中的函數實現。其次會判斷jemalloc是否使得,最后如果都沒有使用才會用標準的libc中的內存管理函數。
從最新的版本中,jemalloc已經作為源碼包的一部分包含在源碼包中,所以可以直接被使用。而如果你要使用tcmalloc的話,是需要自己安裝的。
與標準的glibc庫的malloc相比,TCMalloc在內存的分配上效率和速度要高得多,可以在很大程度上提高MySQL服務器在高并發情況下的性能,降低系統負載。
tcmalloc(Thread-Caching Malloc)是google-proftools( http://code.google.com/p/gperftools/downloads/list)中的一部分,所以我們實際上需要安裝google-proftools。64位操作系統需先安裝libunwind庫(32位操作系統不要安裝)
libunwind庫為基于64位CPU和操作系統的程序提供了基本的堆棧輾轉開解功能,其中包括用于輸出堆棧跟蹤的API、用于以編程方式輾轉開解堆棧的API以及支持C++異常處理機制的API。
編譯環境
[root@justin ~]# yum -y install gcc gcc+ gcc-c++ openssl openssl-devel pcre pcre-devel
安裝tcmalloc包
wget http://download.savannah.gnu.org/releases/libunwind/libunwind-0.99-alpha.tar.gz
tar zxvf libunwind-0.99-alpha.tar.gz
cd libunwind-0.99-alpha/
CFLAGS=-fPIC ./configure
make CFLAGS=-fPIC
make CFLAGS=-fPIC install
安裝google-preftools包
wget http://google-perftools.googlecode.com/files/google-perftools-1.8.1.tar.gz
tar zxvf google-perftools-1.8.1.tar.gz
cd google-perftools-1.8.1/
./configure --disable-cpu-profiler --disable-heap-profiler --disable-heap-checker --disable-debugalloc --enable-minimal
make && make install
sudo echo "/usr/local/lib" > /etc/ld.so.conf.d/usr_local_lib.conf #如果沒有這個文件,自己建一個
sudo /sbin/ldconfig
cd /usr/local/lib
ln -sv libtcmalloc_minimal.so.4.1.2 libtcmalloc.so
安裝Redis包
cd redis-4.11
make PREFIX=/opt/redis USE_TCMALLOC=yes FORCE_LIBC_MALLOC=yes
make install
對于tcmalloc,jemalloc和libc對應的三個內存分配器。其性能和碎片率如何,可以使用Redis自帶的redis-benchmark寫入等量數據進行測試
1、測試數據都是小數據,也就是說單條數據并不大時,采用tcmalloc時碎片率是最低的,為1.01,jemalloc為1.02,而libc的分配器碎片率為1.31
2、設置benchmark的-d參數,將value值調整為1k大小,采用tcmalloc時碎片率是最低的,為1.02,jemalloc為1.01,而libc的分配器碎片率為1.04
四、Redis配置多實例
多實例比較簡單,通過不通配置文件就可以生成不通的實例,這里我們生成100歌實例為例
先將默認的配置文件配置好,例如端口、日志名稱、數據文件名等改成帶有端口號表示的(根據自己的愛好來定義)
[root@localhost ~]# vim /app/redis/etc/redis.conf ... port 6979 pidfile /var/run/redis_6979.pid logfile /app/redis/logs/redis_6979.log dbfilename 6979.rdb ... [root@localhost ~]# for n in `seq 8000 8099`;do cp redis.conf redis$n.conf && sed -i "s/6379/$n/g" redis$n.conf;done [root@localhost ~]# for n in `seq 8000 8099`;do /app/redis/bin/redis-server /app/redis/etc/redis$n.conf;done
五、Redis主從配置
Redis的主從復制功能非常強大,一個master可以擁有多個slave,而一個slave又可以擁有多個slave,如此下去,形成了強大的多級服務器集群架構。
1、redis主不需要特別配置,按照正常配置即可
2、redis從,需要在配置文件里指定redis主
我這里在一臺主機上配置多實例做為主從
[root@localhost etc]# vim redis6380.conf # slaveof <masterip> <masterport> slaveof 127.0.0.1 6379 # masterauth <master-password> 如果master設置了驗證密碼,還需配置masterauth masterauth justin
啟動master、slave的redis執行info命令查看結果:
master
[root@localhost etc]# ../bin/redis-cli -h 127.0.0.1 -p 6379 -a justin 127.0.0.1:6379> info # Replication role:master #主 connected_slaves:3 #3個從連接信息 slave0:ip=127.0.0.1,port=6380,state=online,offset=2314790043,lag=1 slave1:ip=127.0.0.1,port=6381,state=online,offset=2314790043,lag=1 slave2:ip=127.0.0.1,port=6382,state=online,offset=2314790043,lag=1 master_replid:10f3abe30f7ff3991dd6a15ccccd4ebdce1bb35a master_replid2:0000000000000000000000000000000000000000 master_repl_offset:2314790043 second_repl_offset:-1 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:2313741468 repl_backlog_histlen:1048576
slave
[root@localhost etc]# ../bin/redis-cli -p 6380 127.0.0.1:6380> info # Replication role:slave #從 master_host:127.0.0.1 master_port:6379 master_link_status:up #狀態為UP說明和主連接上了,否則為down master_last_io_seconds_ago:1 #距離最后一次的連接時間 master_sync_in_progress:0 #同步主服務器進程數 slave_repl_offset:2320002171 slave_priority:100 slave_read_only:1 connected_slaves:0 master_replid:10f3abe30f7ff3991dd6a15ccccd4ebdce1bb35a master_replid2:0000000000000000000000000000000000000000 master_repl_offset:2320002171 second_repl_offset:-1 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:2318953596 repl_backlog_histlen:1048576
此時在master里set個值,在slave里get就可以得到該值說明配置成功
slave:6380 master:6379
[root@localhost bin]# ./redis-cli -p 6380 -a abcdef 127.0.0.1:6380> keys * (empty list or set) 127.0.0.1:6380> quit [root@localhost bin]# ./redis-cli -p 6379 -a 123456 127.0.0.1:6379> keys * (empty list or set) 127.0.0.1:6379> set justin 51cto OK 127.0.0.1:6379> get justin "51cto" 127.0.0.1:6379> quit [root@localhost bin]# ./redis-cli -p 6379 -a 123456 127.0.0.1:6379> keys * 1) "justin" 127.0.0.1:6379> quit [root@localhost bin]# ./redis-cli -p 6380 -a abcdef 127.0.0.1:6380> keys * 1) "justin" 127.0.0.1:6380> set justin1 51cto #Slave不可以寫,只可以讀 (error) READONLY You can't write against a read only slave. 127.0.0.1:6380> quit [root@localhost bin]# ./redis-cli -p 6379 -a 123456 127.0.0.1:6379> del justin (integer) 1 127.0.0.1:6379> keys * (empty list or set) 127.0.0.1:6379> exit [root@localhost bin]# ./redis-cli -p 6380 -a abcdef 127.0.0.1:6380> keys * (empty list or set) 127.0.0.1:6380>
六、最大緩存設置
示例:maxmemory 100mb
單位:mb,gb。
默認不限制,如果有新的數據添加,超過最大內存,則會使redis崩潰,設置最好為物理內存的3/4,或者比例更小,因為redis復制數據等其他服務時,也是需要緩存的。以防緩存數據過大致使redis崩潰,造成系統出錯不可用。設置maxmemory之后,配合的要設置緩存數據回收策略。
當maxmemory限制到達的時候,Redis將采取的準確行為是由maxmemory-policy配置指令配置的。
(1)、noeviction:當到達內存限制時返回錯誤。當客戶端嘗試執行命令時會導致更多內存占用(大多數寫命令,除了DEL和一些例外)。
(2)、allkeys-lru:回收最近最少使用(LRU)的鍵,為新數據騰出空間。
(3)、volatile-lru:回收最近最少使用(LRU)的鍵,但是只回收有設置過期的鍵,為新數據騰出空間。
(4)、allkeys-random:回收隨機的鍵,為新數據騰出空間。
(5)、volatile-random:回收隨機的鍵,但是只回收有設置過期的鍵,為新數據騰出空間。
(6)、volatile-ttl:回收有設置過期的鍵,嘗試先回收離TTL最短時間的鍵,為新數據騰出空間。
如果數據呈現冪律分布,也就是一部分數據訪問頻率高,一部分數據訪問頻率低,則使用allkeys-lru,如果數據呈現平等分布,也就是所有的數據訪問頻率都相同,則使用allkeys-random。
redis啟動時日志的幾個報警錯誤
1、The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128
TCP backlog設置值,511沒有成功,因為 /proc/sys/net/core/somaxconn這個設置的是更小的128;baklog參數實際控制的是已經3次握手成功的還在accept queue的大小。
echo 511 > /proc/sys/net/core/somaxconn (將其寫入/etc/rc.local文件中)
2、overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to/etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
overcommit_memory參數設置為0!在內存不足的情況下,后臺程序save可能失敗。建議在文件 /etc/sysctl.conf 中將overcommit_memory修改為1。
echo "vm.overcommit_memory=1" > /etc/sysctl.conf
3、you have Transparent Huge Pages (THP) support enabled in your kernel. This will create latency and memory usage issues with Redis. To fix thisissue run the command 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' as root, and add it to your /etc/rc.local in order to retain thesetting after a reboot. Redis must be restarted after THP is disabled.
使用的是透明大頁,可能導致redis延遲和內存使用問題。執行 echo never > /sys/kernel/mm/transparent_hugepage/enabled 修復該問題。
echo never > /sys/kernel/mm/transparent_hugepage/enabled (將其寫入/etc/rc.local文件中)
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。