Redis安装与源码调试
linux版本:64位CentOS 6.5
Redis版本:redis-3.0.6? (更新到2016年1月22日)
Redis官網(wǎng):http://redis.io/
Redis常用命令:http://redis.io/commands
1.安裝Redis
# wget?http://download.redis.io/releases/redis-3.2.6.tar.gz
#?tar xzf redis-3.2.6.tar.gz
#?cd redis-3.2.6
#?make &&?make install
如果報(bào)錯(cuò)
zmalloc.h:50:31: error: jemalloc/jemalloc.h: No such file or directory
zmalloc.h:55:2: error: #error "Newer version of jemalloc required"
make[1]: *** [adlist.o] Error 1
make[1]: Leaving directory `/data0/src/redis-2.6.2/src'
make: *** [all] Error 2
解決辦法是:
make MALLOC=libc
注意:Redis并沒(méi)有自己實(shí)現(xiàn)內(nèi)存池,沒(méi)有在標(biāo)準(zhǔn)的系統(tǒng)內(nèi)存分配器上再加上自己的東西。
redis-2.4以上自帶jemalloc,你不需要加任何參數(shù),通過(guò)zmalloc.c源碼中我們可以看到,Redis在編譯時(shí),會(huì)先判斷是否使用tcmalloc,如果是,會(huì)用tcmalloc對(duì)應(yīng)的函數(shù)替換掉標(biāo)準(zhǔn)的libc中的函數(shù)實(shí)現(xiàn)。其次會(huì)判斷jemalloc是否使得,最后如果都沒(méi)有使用才會(huì)用標(biāo)準(zhǔn)的libc中的內(nèi)存管理函數(shù)。所以用tcmalloc優(yōu)化請(qǐng)謹(jǐn)慎使用,這兩著分配器碎片率相差不大,建議用自帶jemalloc。
# make USE_TCMALLOC=yes
參考:利用TCMalloc替換Nginx和Redis默認(rèn)glibc庫(kù)的malloc內(nèi)存分配
為了調(diào)試需要修改CFLAGS參數(shù)
# make?CFLAGS="-g?-O0"?
make命令執(zhí)行完成后,會(huì)在src目錄下生成5個(gè)可執(zhí)行文件,分別是redis-server、redis-cli、redis-benchmark、redis-check-aof、redis-check-dump,它們的作用如下:
redis-server:Redis服務(wù)器的daemon啟動(dòng)程序
redis-cli:Redis命令行操作工具。當(dāng)然,你也可以用telnet根據(jù)其純文本協(xié)議來(lái)操作
redis-benchmark:Redis性能測(cè)試工具,測(cè)試Redis在你的系統(tǒng)及你的配置下的讀寫(xiě)性能
redis-check-aof:更新日志檢查?
redis-check-dump:用于本地?cái)?shù)據(jù)庫(kù)檢查?
為什么沒(méi)用標(biāo)準(zhǔn)的Linux安裝三板斧呢?官方維基是這樣說(shuō)的:Redis can run just fine without a configuration file (when executed without a config file a standard configuration is used). With thedefault configuration Redis will log to the standard output so you can check what happens. Later, you canchange the default settings.
也可以make install,這樣就是把可運(yùn)行文件復(fù)制到/usr/local/bin里而已。
make之后,會(huì)出現(xiàn)一句提示:
Hint: To run 'make test' is a good idea ;)
-----------------------------------------------------------------
其實(shí)不測(cè)試,一般都可以用。但是既然人家建議了,咱們就走一下make test吧。
運(yùn)行#make test
報(bào)錯(cuò),提示沒(méi)有You need 'tclsh8.5' in order to run the Redis test
然后到Tcl的官方網(wǎng)站http://www.tcl.tk/下載8.5版本
然后安裝tcl8.5:
(configure和make的位置比較特殊,在安裝目錄的unix下,所以下面是tcl官方安裝法)
#tar xvzf tcl8.5.12-src.tar.gz
#cd tcl8.5.13/unix/
#./configure
#make
#make test
#make install
注:當(dāng)然,也可以簡(jiǎn)單一點(diǎn),用 yum install tcl 來(lái)安裝。
好了,安裝好tcl之后,可以去redis目錄下運(yùn)行make test了,這次正常跑通。提示:
\o/ All tests passed without errors!
Cleanup: may take some time... OK
說(shuō)明redis安裝正常。可以運(yùn)行。
-----------------------------------------------------------------
安裝
# make install
2.運(yùn)行Redis
redis-server被放到了src文件夾下。
啟動(dòng)Redis服務(wù)端
# /usr/redis-3.2.6/src/redis-server
如果沒(méi)有更改daemonize no配置,會(huì)看見(jiàn)運(yùn)行的信息。
說(shuō)明:下面是2.8.17的啟動(dòng)界面:
注釋:
▲redis的默認(rèn)端口號(hào)是6379,(據(jù)redis的作者antirez的博文說(shuō),6379在是手機(jī)按鍵上MERZ對(duì)應(yīng)的號(hào)碼,而MERZ取自意大利歌女Alessia Merz的名字。而MERZ長(zhǎng)期以來(lái)被antirez及其朋友當(dāng)作愚蠢的代名詞。)
▲Redis有兩種存儲(chǔ)方式,默認(rèn)是snapshot方式,實(shí)現(xiàn)方法是定時(shí)將內(nèi)存的快照(snapshot)持久化到硬盤(pán),這種方法缺點(diǎn)是持久化之后如果出現(xiàn)crash則會(huì)丟失一段數(shù)據(jù)。因此在完美主義者的推動(dòng)下作者增加了aof方式。aof即append only mode,在寫(xiě)入內(nèi)存數(shù)據(jù)的同時(shí)將操作命令保存到日志文件。
redis.conf配置文件
就在根目錄下
################################ GENERAL ###################################### By default Redis does not run as a daemon. Use 'yes' if you need it.
# Note that Redis will write a pid file in /var/run/redis.pid when daemonized.
daemonize yes# When running daemonized, Redis writes a pid file in /var/run/redis.pid by
# default. You can specify a custom pid file location here.
pidfile /var/run/redis.pid# Accept connections on the specified port, default is 6379.
# If port 0 is specified Redis will not listen on a TCP socket.
port 6380# TCP listen() backlog.
以后臺(tái)形式運(yùn)行Redis
需要讀取配置文件方式啟動(dòng)
注意,默認(rèn)復(fù)制過(guò)去的redis.conf文件的daemonize參數(shù)為no,所以redis不會(huì)在后臺(tái)運(yùn)行,我們可以修改redis.conf文件,這個(gè)文件就是解壓后的redis根目錄下
daemonize yes
If you want to provide your redis.conf, you have to run it using an additional
parameter (the path of the configuration file):
??? % cd src
??? % ./redis-server /path/to/redis.conf
# /usr/redis-3.2.6/src/redis-server /usr/redis-3.2.6/redis.conf
查看redis進(jìn)程
#ps aux |grep redis
啟動(dòng)多個(gè)redis實(shí)例
拷貝默認(rèn)的redis.conf改為redis6383.conf,打開(kāi)redis6383.conf配置文件,找到port 6379這行,把6379改為6383
# /usr/redis-2.8.17/src/redis-server
啟動(dòng)特定配置文件
# /usr/redis-2.8.17/src/redis-server /usr/redis-2.8.17/redis6383.conf
按照默認(rèn)配置文件啟動(dòng)
#?/usr/redis-3.0.6/src/redis-server /usr/redis-3.0.6/redis.conf
調(diào)用服務(wù):
默認(rèn)的redis-cli是啟動(dòng)6379端口,如果需要連接指定服務(wù)器和端口需要這樣
# /usr/redis-3.2.6/src/redis-cli -h 127.0.0.1 -p 6380
連接默認(rèn)機(jī)器端口
#?/usr/redis-2.8.17/src/redis-cli
新增
redis> set foo bar
獲取
redis> get foo"bar"
刪除
redis>del foo
模糊查找
redis>keys f*
redis>keys f?o?
查看info信息
輸入# info命令,可以看出內(nèi)存碎片率:mem_fragmentation_ratio=2.59
默認(rèn)使用的是jemalloc內(nèi)存分配器
3.配置 Redis
redis的配置文件在你的安裝目錄里。名為:redis.conf。
簡(jiǎn)單說(shuō)幾點(diǎn)redis.conf:
redis默認(rèn)不是用守護(hù)進(jìn)程的,如果需要更改,把daemonize no改成daemonize yes。(測(cè)試的時(shí)候可以不改,看看打印信息。)
如果對(duì)redis默認(rèn)6379端口不爽的,可以更改port 6379
如果想把數(shù)據(jù)文件放到一個(gè)指定文件夾,更改dir /opt/data/
默認(rèn)是dir ./ 也就是默認(rèn)放到安裝目錄下。
連接超時(shí)時(shí)間,timeout 300,沒(méi)什么改頭……
dir 是數(shù)據(jù)文件路徑。默認(rèn)在安裝目錄下。
*下面的配置二選一,詳見(jiàn)本文注釋部分2。
###### SNAPSHOTTING ######內(nèi)存快照方式:
默認(rèn)的內(nèi)存快照策略是,
在900秒(15分鐘)內(nèi),至少有1次數(shù)據(jù)變更;
或者300秒內(nèi),有至少10次數(shù)據(jù)變更;
或者60秒內(nèi),有至少1000次數(shù)據(jù)變更;時(shí)間+數(shù)據(jù)變更次數(shù),共同影響內(nèi)存快照的出現(xiàn)。
###### APPEND ONLY MODE ###### AOF方式
appendfsync everysec 每秒同步。這里可以注釋掉,打開(kāi)下面的選項(xiàng)appendfsync no
其余的配置,conf里面的注釋寫(xiě)的挺清楚,我就不多廢話(huà)了。大家看著自己配就行了。
?
可以拷貝配置文件到etc
mkdir /etc/redis?
cp redis.conf /etc/redis/redis.conf?
mkdir? /var/lib/redis?
1. redis.conf 配置參數(shù):
#是否作為守護(hù)進(jìn)程運(yùn)行?
daemonize yes?
#如以后臺(tái)進(jìn)程運(yùn)行,則需指定一個(gè)pid,默認(rèn)為/var/run/redis.pid?
pidfile redis.pid?
#綁定主機(jī)IP,默認(rèn)值為127.0.0.1?
#bind 127.0.0.1?
#Redis默認(rèn)監(jiān)聽(tīng)端口?
port 6379?
#客戶(hù)端閑置多少秒后,斷開(kāi)連接,默認(rèn)為300(秒)?
timeout 300?
#日志記錄等級(jí),有4個(gè)可選值,debug,verbose(默認(rèn)值),notice,warning?
loglevel verbose?
#指定日志輸出的文件名,默認(rèn)值為stdout,也可設(shè)為/dev/null屏蔽日志?
logfile stdout?
#可用數(shù)據(jù)庫(kù)數(shù),默認(rèn)值為16,默認(rèn)數(shù)據(jù)庫(kù)為0?
databases 16?
#保存數(shù)據(jù)到disk的策略?
#當(dāng)有一條Keys數(shù)據(jù)被改變是,900秒刷新到disk一次?
save 900 1?
#當(dāng)有10條Keys數(shù)據(jù)被改變時(shí),300秒刷新到disk一次?
save 300 10?
#當(dāng)有1w條keys數(shù)據(jù)被改變時(shí),60秒刷新到disk一次?
save 60 10000?
#當(dāng)dump .rdb數(shù)據(jù)庫(kù)的時(shí)候是否壓縮數(shù)據(jù)對(duì)象?
rdbcompression yes?
#本地?cái)?shù)據(jù)庫(kù)文件名,默認(rèn)值為dump.rdb?
dbfilename dump.rdb?
#本地?cái)?shù)據(jù)庫(kù)存放路徑,默認(rèn)值為 ./?
dir /var/lib/redis/?
########### Replication #####################?
#Redis的復(fù)制配置?
# slaveof <masterip> <masterport> 當(dāng)本機(jī)為從服務(wù)時(shí),設(shè)置主服務(wù)的IP及端口?
# masterauth <master-password> 當(dāng)本機(jī)為從服務(wù)時(shí),設(shè)置主服務(wù)的連接密碼?
#連接密碼?
# requirepass foobared?
#最大客戶(hù)端連接數(shù),默認(rèn)不限制?
# maxclients 128?
#最大內(nèi)存使用設(shè)置,達(dá)到最大內(nèi)存設(shè)置后,Redis會(huì)先嘗試清除已到期或即將到期的Key,當(dāng)此方法處理后,任到達(dá)最大內(nèi)存設(shè)置,將無(wú)法再進(jìn)行寫(xiě)入操作。?
# maxmemory <bytes>?
maxmemory 2000000000 ?啟用2G內(nèi)存
#是否在每次更新操作后進(jìn)行日志記錄,如果不開(kāi)啟,可能會(huì)在斷電時(shí)導(dǎo)致一段時(shí)間內(nèi)的數(shù)據(jù)丟失。因?yàn)閞edis本身同步數(shù)據(jù)文件是按上面save條件來(lái)同步的,所以有的數(shù)據(jù)會(huì)在一段時(shí)間內(nèi)只存在于內(nèi)存中。默認(rèn)值為no?
appendonly no?
#更新日志文件名,默認(rèn)值為appendonly.aof?
#appendfilename?
#更新日志條件,共有3個(gè)可選值。no表示等操作系統(tǒng)進(jìn)行數(shù)據(jù)緩存同步到磁盤(pán),always表示每次更新操作后手動(dòng)調(diào)用fsync()將數(shù)據(jù)寫(xiě)到磁盤(pán),everysec表示每秒同步一次(默認(rèn)值)。?
# appendfsync always?
appendfsync everysec?
# appendfsync no ? 推薦
################ VIRTUAL MEMORY ###########?
#是否開(kāi)啟VM功能,默認(rèn)值為no?
vm-enabled no?
# vm-enabled yes?
#虛擬內(nèi)存文件路徑,默認(rèn)值為/tmp/redis.swap,不可多個(gè)Redis實(shí)例共享?
vm-swap-file /tmp/redis.swap?
#將所有大于vm-max-memory的數(shù)據(jù)存入虛擬內(nèi)存,無(wú)論vm-max-memory設(shè)置多小,所有索引數(shù)據(jù)都是內(nèi)存存儲(chǔ)的 (Redis的索引數(shù)據(jù)就是keys),也就是說(shuō),當(dāng)vm-max-memory設(shè)置為0的時(shí)候,其實(shí)是所有value都存在于磁盤(pán)。默認(rèn)值為0。?
vm-max-memory 0?
vm-page-size 32?
vm-pages 134217728?
vm-max-threads 4?
############# ADVANCED CONFIG ###############?
glueoutputbuf yes?
hash-max-zipmap-entries 64?
hash-max-zipmap-value 512?
#是否重置Hash表?
activerehashing yes?
注意:Redis官方文檔對(duì)VM的使用提出了一些建議:?
- 當(dāng)你的key很小而value很大時(shí),使用VM的效果會(huì)比較好.因?yàn)檫@樣節(jié)約的內(nèi)存比較大.?
- 當(dāng)你的key不小時(shí),可以考慮使用一些非常方法將很大的key變成很大的value,比如你可以考慮將key,value組合成一個(gè)新的value.?
- 最好使用linux ext3 等對(duì)稀疏文件支持比較好的文件系統(tǒng)保存你的swap文件.?
- vm-max-threads這個(gè)參數(shù),可以設(shè)置訪(fǎng)問(wèn)swap文件的線(xiàn)程數(shù),設(shè)置最好不要超過(guò)機(jī)器的核數(shù).如果設(shè)置為0,那么所有對(duì)swap文件的操作都是串行的.可能會(huì)造成比較長(zhǎng)時(shí)間的延遲,但是對(duì)數(shù)據(jù)完整性有很好的保證.
?
2. 調(diào)整系統(tǒng)內(nèi)核參數(shù)
如果內(nèi)存情況比較緊張的話(huà),需要設(shè)定內(nèi)核參數(shù):?
echo 1 > /proc/sys/vm/overcommit_memory?
這里說(shuō)一下這個(gè)配置的含義:/proc/sys/vm/overcommit_memory
該文件指定了內(nèi)核針對(duì)內(nèi)存分配的策略,其值可以是0、1、2。
0,表示內(nèi)核將檢查是否有足夠的可用內(nèi)存供應(yīng)用進(jìn)程使用;如果有足夠的可用內(nèi)存,內(nèi)存申請(qǐng)?jiān)试S;否則,內(nèi)存申請(qǐng)失敗,并把錯(cuò)誤返回給應(yīng)用進(jìn)程。
1,表示內(nèi)核允許分配所有的物理內(nèi)存,而不管當(dāng)前的內(nèi)存狀態(tài)如何。
2,表示內(nèi)核允許分配超過(guò)所有物理內(nèi)存和交換空間總和的內(nèi)存
Redis在dump數(shù)據(jù)的時(shí)候,會(huì)fork出一個(gè)子進(jìn)程,理論上child進(jìn)程所占用的內(nèi)存和parent是一樣的,比如parent占用的內(nèi)存為 8G,這個(gè)時(shí)候也要同樣分配8G的內(nèi)存給child, 如果內(nèi)存無(wú)法負(fù)擔(dān),往往會(huì)造成redis服務(wù)器的down機(jī)或者IO負(fù)載過(guò)高,效率下降。所以這里比較優(yōu)化的內(nèi)存分配策略應(yīng)該設(shè)置為 1(表示內(nèi)核允許分配所有的物理內(nèi)存,而不管當(dāng)前的內(nèi)存狀態(tài)如何)
?
4.調(diào)試debug
注意由于redis默認(rèn)是啟用了內(nèi)存優(yōu)化的,所以必須修改編譯選項(xiàng)。不然,在gdb內(nèi)打印變量時(shí)提示"<value optimized out>",這多半是因?yàn)間cc的優(yōu)化導(dǎo)致,我們可以加上-O0選項(xiàng)來(lái)強(qiáng)制禁用gcc的編譯優(yōu)化。
Compiling Redis without optimizations
By default Redis is compiled with the -O2 switch, this means that compiler??????? optimizations are enabled. This makes the Redis executable faster, but at the??????? same time it makes Redis (like any other program) harder to inspect using GDB.
所以要修改Makefile文件,該文件在/src目錄下,修改OPTIMIZATION?=-O2選項(xiàng)即可,修改為O0
OPTIMIZATION?=-O0
?
刪掉原來(lái)的redis重新修改makefile重新make,啟動(dòng)redis
?
具體調(diào)試技巧,查看指針變量
查看redis進(jìn)程
# ps? aux|grep redis
gdb附加到進(jìn)程
# gdb -p? 進(jìn)程id
(gdb)r???? 重新開(kāi)始不然不會(huì)從main函數(shù)開(kāi)始
(gdb)break main????????????????? 設(shè)置斷點(diǎn)
(gdb)list????????????????? 查看代碼
(gdb)p? 變量名?????? 查看變量?jī)?nèi)容,使用p查看變量,這個(gè)時(shí)候已經(jīng)可以查看
?
redis調(diào)試技巧
redis會(huì)在ae.c的aeMain這個(gè)函數(shù)處循環(huán)處理事件:
// 事件處理器的主循環(huán)
void aeMain(aeEventLoop *eventLoop) {eventLoop->stop = 0;while (!eventLoop->stop) {// 如果有需要在事件處理前執(zhí)行的函數(shù),那么運(yùn)行它if (eventLoop->beforesleep != NULL)eventLoop->beforesleep(eventLoop);// 開(kāi)始處理事件aeProcessEvents(eventLoop, AE_ALL_EVENTS);}
}
#?/usr/redis-2.6.14/src/redis-cli
redis> set foo bar
OK
redis> get foo"bar"
aeMain函數(shù)會(huì)截獲來(lái)自redis-cli的請(qǐng)求,也只有aeMain函數(shù)處理好該請(qǐng)求,redis-cli才會(huì)返回OK,不然就會(huì)一直等待
?
5.基準(zhǔn)測(cè)試第一先用啟動(dòng)命令啟動(dòng)redis
然后在任意目錄使用命令:
# redis-benchmark-h localhost -p 6379 -c 100 -n 100000
模擬100個(gè)并發(fā)連接,100000個(gè)請(qǐng)求,檢測(cè)host為localhost 端口為6379的redis服務(wù)器性能
原文地址:http://blog.csdn.net/unix21/article/details/9526295
6.訪(fǎng)問(wèn)限制
對(duì)redis做端口訪(fǎng)問(wèn)限制
-A INPUT -s 111.111.1.1 -p tcp --dport 6379 -j ACCEPT
-A OUTPUT -d 111.111.1.1 -p tcp --sport 6379 -j ACCEPT
------------------------------------------------------------------------
更多參考
配置參考:CentOS下Redis 2.2.14安裝配置詳解
安裝參考:Redis (一) 安裝
調(diào)試參考:http://redis.io/topics/debugging?利用gdb調(diào)試redis-server
benchmark參數(shù): Redis安裝部署
另外需要在PHP中使用redis需要安裝PHP擴(kuò)展可以參考:
Redis以及Redis的php擴(kuò)展安裝無(wú)錯(cuò)版
phpredis使用方法
redis常用命令參考
總結(jié)
以上是生活随笔為你收集整理的Redis安装与源码调试的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 使用valgrind分析C程序调用线路图
- 下一篇: 计算机科学精彩帖子收集