Redis 是一个高性能的key-value数据库。 redis的出现,很大程度补偿了memcached这类key/value存储的不足,在部 分场合可以对关系数据库起到很好的补充作用。它提供了Python,Ruby,Erlang,PHP客户端,使用很方便。
一.安装tcl
否则在redis make test时出报错
You need tcl 8.5 or newer in order to run the Redis test
make[1]: *** [test] Error 1
wget http://downloads.sourceforge.net/tcl/tcl8.6.0-src.tar.gz
tar zxvf tcl8.6.0-src.tar.gz
cd tcl8.6.0-src
cd unix &&
./configure –prefix=/usr \
–mandir=/usr/share/man \
$([ $(uname -m) = x86_64 ] && echo –enable-64bit)
make &&
sed -e “s@^\(TCL_SRC_DIR=’\).*@\1/usr/include’@” \
-e “/TCL_B/s@=’\(-L\)\?.*unix@=’\1/usr/lib@” \
-i tclConfig.sh
make test
Tests ended at Tue Apr 16 12:02:27 CST 2013
all.tcl: Total 116 Passed 116 Skipped 0 Failed 0
make install &&
make install-private-headers &&
ln -v -sf tclsh8.6 /usr/bin/tclsh &&
chmod -v 755 /usr/lib/libtcl8.6.so
二.redis
1.安装redis
wget http://redis.googlecode.com/files/redis-2.6.12.tar.gz
tar xzf redis-2.6.12.tar.gz
cd redis-2.6.12
make
make test
以下错误可以忽略
https://github.com/antirez/redis/issues/1034
[exception]: Executing test client: assertion:Server started even if RDB was unreadable!.
assertion:Server started even if RDB was unreadable!
while executing
“error “assertion:$msg””
(procedure “fail” line 2)
invoked from within
“fail “Server started even if RDB was unreadable!””
(“uplevel” body line 2)
invoked from within
“uplevel 1 $elsescript”
(procedure “wait_for_condition” line 7)
invoked from within
“wait_for_condition 50 100 {
[string match {*Fatal error loading*} [exec tail -n1 < [dict get $srv stdout]]]
} else {
fail "Server..."
("uplevel" body line 2)
invoked from within
"uplevel 1 $code"
(procedure "start_server_and_kill_it" line 5)
invoked from within
"start_server_and_kill_it [list "dir" $server_path] {
wait_for_condition 50 100 {
[string match {*Fatal error loading*} \
[exec..."
(file "tests/integration/rdb.tcl" line 57)
invoked from within
"source $path"
(procedure "execute_tests" line 4)
invoked from within
"execute_tests $data"
(procedure "test_client_main" line 9)
invoked from within
"test_client_main $::test_server_port "
make[1]: *** [test] Error 1
make命令执行完成后,会在当前目录下生成4个可执行文件,分别是redis-server、redis-cli、redis-benchmark、redis-stat,它们的作用如下:
redis-server:Redis服务器的daemon启动程序
redis-cli:Redis命令行操作工具。当然,你也可以用telnet根据其纯文本协议来操作
redis-benchmark:Redis性能测试工具,测试Redis在你的系统及你的配置下的读写性能
redis-stat:Redis状态检测工具,可以检测Redis当前状态参数及延迟状况
2.建立Redis目录
mkdir -p /opt/redis/bin
mkdir -p /opt/redis/etc
mkdir -p /opt/redis/var
cp redis.conf /opt/redis/etc/
cd src
cp redis-server redis-cli redis-benchmark redis-check-aof redis-check-dump /opt/redis/bin/
useradd redis
chown -R redis.redis /opt/redis
建立Redis目录,只是为了将Redis相关的资源更好的统一管理。你也可以使用
make install
安装在系统默认目录
3.复制启动文件
cp ../utils/redis_init_script /etc/init.d/redis
4.启动redis
cd /opt/redis/bin
./redis-server /opt/redis/etc/redis.conf
_._
_.-“__ ”-._
_.-“ `. `_. ”-._ Redis 2.6.12 (00000000/0) 64 bit
.-“ .-“`. “`\/ _.,_ ”-._
( ‘ , .-` | `, ) Running in stand alone mode
|`-._`-…-` __…-.“-._|’` _.-‘| Port: 6379
| `-._ `._ / _.-‘ | PID: 24454
`-._ `-._ `-./ _.-‘ _.-‘
|`-._`-._ `-.__.-‘ _.-‘_.-‘|
| `-._`-._ _.-‘_.-‘ | http://redis.io
`-._ `-._`-.__.-‘_.-‘ _.-‘
|`-._`-._ `-.__.-‘ _.-‘_.-‘|
| `-._`-._ _.-‘_.-‘ |
`-._ `-._`-.__.-‘_.-‘ _.-‘
`-._ `-.__.-‘ _.-‘
`-._ _.-‘
`-.__.-‘
[24454] 12 Apr 10:34:19.519 # Server started, Redis version 2.6.12
[24454] 12 Apr 10:34:19.519 # 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.
[24454] 12 Apr 10:34:19.519 * The server is now ready to accept connections on port 6379
成功安装Redis后,直接执行redis-server即可运行Redis,此时它是按照默认配置来运行的(默认配置不是后台运行)。如果我们希望Redis按我们的要求运行,则需要修改配置文件,
5.设置itpables,充许192.168.0内网网段访问
iptables -A INPUT -s 192.168.0.0/24 -p tcp -m tcp –dport 6379 -j ACCEPT
/etc/init.d/iptables save
6.配置redis
vi /opt/redis/etc/redis.conf
daemonize yes
#是否作为守护进程运行 默认0
pidfile /var/run/redis.pid
# 指定一个pid,默认为/var/run/redis.pid
port 6379
#Redis默认监听端口
bind 192.168.0.41
#绑定主机IP,默认值为127.0.0.1
timeout 300
#客户端闲置多少秒后,断开连接,默认为300(秒)
tcp-keepalive 0
# tcp保持连接
loglevel notice
#日志记录等级,有4个可选值,debug,verbose(默认值),notice,warning
logfile /opt/redis/var/redis.log
#指定日志输出的文件名,默认值为stdout,也可设为/dev/null屏蔽日志
databases 16
#可用数据库数,默认值为16
save 900 1
#保存数据到disk的策略
#当有一条Keys数据被改变是,900秒刷新到disk一次
save 300 10
#当有10条Keys数据被改变时,300秒刷新到disk一次
save 60 10000
#当有1w条keys数据被改变时,60秒刷新到disk一次
#当dump .rdb数据库的时候是否压缩数据对象
rdbcompression yes
#本地数据库文件名,默认值为dump.rdb
dbfilename dump.rdb
#本地数据库存放路径,默认值为 ./
dir /opt/redis/var/
#内存限制
maxmemory 2G
#刷新策略
maxmemory-policy allkeys-lru
7. 调整系统内核参数
如果内存情况比较紧张的话,需要设定内核参数:
echo 1 > /proc/sys/vm/overcommit_memory
这里说一下这个配置的含义:/proc/sys/vm/overcommit_memory
该文件指定了内核针对内存分配的策略,其值可以是0、1、2。
0,表示内核将检查是否有足够的可用内存供应用进程使用;如果有足够的可用内存,内存申请允许;否则,内存申请失败,并把错误返回给应用进程。
1,表示内核允许分配所有的物理内存,而不管当前的内存状态如何。
2,表示内核允许分配超过所有物理内存和交换空间总和的内存
Redis在dump数据的时候,会fork出一个子进程,理论上child进程所占用的内存和parent是一样的,比如parent占用的内存为8G,这个时候也要同样分配8G的内存给child, 如果内存无法负担,往往会造成redis服务器的down机或者IO负载过高,效率下降。所以这里比较优化的内存分配策略应该设置为 1(表示内核允许分配所有的物理内存,而不管当前的内存状态如何)
vi /etc/sysctl.conf
vm.overcommit_memory = 1
然后应用生效:
sysctl –p
8.修改redis服务脚本
vi /etc/init.d/redis
REDISPORT=6379
EXEC=/opt/redis/bin/redis-server
CLIEXEC=/opt/redis/bin/redis-cli
PIDFILE=/var/run/redis.pid
CONF=”/opt/redis/etc/redis.conf”
如果监听非本机IP地址时还需修改下脚本,不然关不掉
#增加监听地址变量
REDIHOST=192.168.0.41
#增加-h $REDIHOST
echo “Stopping …”
$CLIEXEC -h $REDIHOST -p $REDISPORT shutdown
9.测试
/etc/init.d/redis start
Starting Redis server…
/opt/redis/bin/redis-cli -h 192.168.0.41
redis 127.0.0.1:6379> ping
PONG
redis 127.0.0.1:6379> set mykey c1gstduio
OK
redis 127.0.0.1:6379> get mykey
“c1gstduio”
redis 127.0.0.1:6379> exit
benchmark
/opt/redis/bin/redis-benchmark -h 192.168.0.41
====== PING_INLINE ======
10000 requests completed in 0.17 seconds
50 parallel clients
3 bytes payload
keep alive: 1
99.51% <= 1 milliseconds 100.00% <= 1 milliseconds 60240.96 requests per second ====== PING_BULK ====== 10000 requests completed in 0.17 seconds 50 parallel clients 3 bytes payload keep alive: 1 100.00% <= 0 milliseconds 60240.96 requests per second ====== SET ====== 10000 requests completed in 0.16 seconds 50 parallel clients 3 bytes payload keep alive: 1 100.00% <= 0 milliseconds 61728.39 requests per second ====== GET ====== 10000 requests completed in 0.17 seconds 50 parallel clients 3 bytes payload keep alive: 1 99.49% <= 1 milliseconds 100.00% <= 1 milliseconds 60606.06 requests per second ====== INCR ====== 10000 requests completed in 0.16 seconds 50 parallel clients 3 bytes payload keep alive: 1 96.26% <= 1 milliseconds 100.00% <= 1 milliseconds 64516.13 requests per second ====== LPUSH ====== 10000 requests completed in 0.15 seconds 50 parallel clients 3 bytes payload keep alive: 1 93.60% <= 1 milliseconds 100.00% <= 1 milliseconds 65789.48 requests per second ====== LPOP ====== 10000 requests completed in 0.15 seconds 50 parallel clients 3 bytes payload keep alive: 1 93.50% <= 1 milliseconds 100.00% <= 1 milliseconds 66666.66 requests per second ====== SADD ====== 10000 requests completed in 0.16 seconds 50 parallel clients 3 bytes payload keep alive: 1 96.52% <= 1 milliseconds 100.00% <= 1 milliseconds 61728.39 requests per second ====== SPOP ====== 10000 requests completed in 0.17 seconds 50 parallel clients 3 bytes payload keep alive: 1 100.00% <= 0 milliseconds 57471.27 requests per second ====== LPUSH (needed to benchmark LRANGE) ====== 10000 requests completed in 0.17 seconds 50 parallel clients 3 bytes payload keep alive: 1 100.00% <= 0 milliseconds 58139.53 requests per second ====== LRANGE_100 (first 100 elements) ====== 10000 requests completed in 0.25 seconds 50 parallel clients 3 bytes payload keep alive: 1 99.67% <= 1 milliseconds 100.00% <= 1 milliseconds 40322.58 requests per second ====== LRANGE_300 (first 300 elements) ====== 10000 requests completed in 0.56 seconds 50 parallel clients 3 bytes payload keep alive: 1 0.22% <= 1 milliseconds 98.62% <= 2 milliseconds 99.01% <= 3 milliseconds 99.49% <= 4 milliseconds 100.00% <= 4 milliseconds 17921.15 requests per second ====== LRANGE_500 (first 450 elements) ====== 10000 requests completed in 0.96 seconds 50 parallel clients 3 bytes payload keep alive: 1 0.07% <= 1 milliseconds 40.25% <= 2 milliseconds 73.76% <= 3 milliseconds 99.51% <= 4 milliseconds 100.00% <= 5 milliseconds 10362.69 requests per second ====== LRANGE_600 (first 600 elements) ====== 10000 requests completed in 1.00 seconds 50 parallel clients 3 bytes payload keep alive: 1 0.07% <= 1 milliseconds 0.35% <= 2 milliseconds 98.18% <= 3 milliseconds 99.12% <= 4 milliseconds 99.48% <= 5 milliseconds 99.60% <= 6 milliseconds 99.85% <= 7 milliseconds 100.00% <= 8 milliseconds 10010.01 requests per second ====== MSET (10 keys) ====== 10000 requests completed in 0.26 seconds 50 parallel clients 3 bytes payload keep alive: 1 0.34% <= 1 milliseconds 100.00% <= 2 milliseconds 38167.94 requests per second
10. 关闭服务
/opt/redis/bin/redis-cli shutdown
如果端口变化可以指定端口:
/opt/redis/bin/redis-cli -h 192.168.0.41 -p 6379 shutdown
11. 保存/备份
数据备份可以通过定期备份该文件实现。
因为redis是异步写入磁盘的,如果要让内存中的数据马上写入硬盘可以执行如下命令:
redis-cli save 或者 redis-cli -p 6379 save(指定端口)
注意,以上部署操作需要具备一定的权限,比如复制和设定内核参数等。
执行redis-benchmark命令时也会将内存数据写入硬盘。
/opt/redis/bin/redis-cli save
OK
查看结果
ll -h var/
total 48K
-rw-r–r– 1 root root 40K Apr 12 11:49 dump.rdb
-rw-r–r– 1 root root 5.3K Apr 12 11:49 redis.log
12.开机运行
vi /etc/rc.local
/etc/init.d/redis start
三.php扩展
redis扩展非常多,光php就有好几个,这里选用phpredis,Predis需要PHP >= 5.3
Predis ? ★ Repository JoL1hAHN Mature and supported
phpredis ? ★ Repository yowgi This is a client written in C as a PHP module.
Rediska ? Repository Homepage shumkov
RedisServer Repository OZ Standalone and full-featured class for Redis in PHP
Redisent ? Repository justinpoliey
Credis Repository colinmollenhour Lightweight, standalone, unit-tested fork of Redisent which wraps phpredis for best performance if available.
1.安装php扩展phpredis
wget https://nodeload.github.com/nicolasff/phpredis/zip/master –no-check-certificate
cd phpredis-master
unzip master
cd phpredis-master/
/opt/php/bin/phpize
./configure –with-php-config=/opt/php/bin/php-config
make
make install
接下来在php.ini中添加extension=redis.so
vi /opt/php/etc/php.ini
extension_dir = “/opt/php/lib/php/extensions/no-debug-non-zts-20060613/”
extension=redis.so
vi test.php
phpinfo();
$redis = new Redis();
$redis->connect(“127.0.0.1”,6379);
$redis->set(“test”,”Hello World”);
echo $redis->get(“test”);
?>
redis
Redis Support enabled
Redis Version 2.2.2
四.基于php的web管理工具
phpRedisAdmin
https://github.com/ErikDubbelboer/phpRedisAdmin
演示:http://dubbelboer.com/phpRedisAdmin/?overview
这个用的人很多,但是我装完无法显示
readmin
http://readmin.org/
演示:http://demo.readmin.org/
需要装在根目录
phpredmin
https://github.com/sasanrose/phpredmin#readme
可以显示,有漂良的图表
使用伪rewrite,/index.php/welcome/stats
wget https://nodeload.github.com/sasanrose/phpredmin/zip/master
unzip phpredmin-master.zip
ln -s phpredmin/public predmin
编辑nginx,支持rewrite
nginx.conf
location ~* ^/predmin/index.php/
{
rewrite ^/predmin/index.php/(.*) /predmin/index.php?$1 break;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
include fcgi.conf;
}
crontab -e
* * * * * root cd /var/www/phpredmin/public && php index.php cron/index
配置redis
vi phpreadmin/config
‘redis’ => Array(
‘host’ => ‘192.168.0.30’,
‘port’ => ‘6379’,
‘password’ => Null,
‘database’ => 0
访问admin.xxx.com/predmin/就可以显示界面
五.实际使用感觉
redis装完后做discuzx2.5的cache
带宽消耗惊人,大概是memcached的十倍左右
内存占用也多了四分之一左右
discuz连接redis偶尔会超时和出错
最后还是切回了memcached
参考:
http://redis.io/topics/quickstart
http://hi.baidu.com/mucunzhishu/item/ead872ba3cec36db84dd798c
http://www.linuxfromscratch.org/blfs/view/svn/general/tcl.html
为什么首页可以打开,但是单击info或home或configurations 就会出现 404
路径不对,那可能是nginx或程序里路径没配对.
我在/home/www/predmin 软连接到 /var/phpredmin-master
在ngnix的default 配置中
location ~* ^/predmin/index.php/ {
rewrite ^/predmin/index.php/(.*) /home/www/predmin/index.php/$1 break;
include /etc/nginx/fastcgi_params;
# fastcgi_split_path_info ^(.+\.php)(/.+)$;
# # NOTE: You should have “cgi.fix_pathinfo = 0;” in php.ini
#
# # With php5-cgi alone:
# fastcgi_pass 127.0.0.1:9000;
# # With php5-fpm:
# fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /home/www/predmin$fastcgi_script_name;
# include fastcgi_params;
}
rewrite ^/predmin/index.php/(.*) /home/www/predmin/index.php/$1 break;
改成相对于网站根目录的路径试试
rewrite ^/predmin/index.php/(.*) /predmin/index.php/$1 break;