3.5. redis¶
3.5.1. refer¶
http://doc.redisfans.com/ http://www.redis.net.cn/tutorial/3501.html http://www.cnblogs.com/liuconglin/p/5847568.html 这是一篇讲各种数据类型的应用场景的文章,可做参考:http://blog.csdn.net/gaogaoshan/article/details/41039581/ redislive 是一款redis使用状态的软件 具体可参考:http://blog.csdn.net/hz_blog/article/details/41822825 这篇文章讲了此工具如何安装 具体不做说明 地址:http://www.cnblogs.com/hepingqingfeng/p/6107809.html
3.5.2. install&research¶
3.5.2.1. 安装¶
$ tar xzf redis-3.2.6.tar.gz
$ cd redis-3.2.6
$ make
$ src/redis-server 运行redis服务
$ src/redis-cli
redis> set foo bar
OK
redis> get foo
“bar”
3.5.2.2. 配置¶
redis配置
vi redis.conf bind 10.0.0.23 daemonize yes logfile "/var/pbx/tmp/Logs/redis/redis_6379.log" dbfilename dump_6379.rdb //生产环境 rename-command FLUSHALL "" rename-command FLUSHDB "" rename-command KEYS "" rename-command CONFIG "" maxmemory 2gb //占用的最大内存 <span style='color:green;font-weight:bold;'><一般推荐Redis设置内存为最大物理内存的四分之三,设置最大内存后一般需设置过期策略></span> appendonly yes appendfilename "appendonly_6379.aof" requirepass "prettydogKnockTheDoor" //需要密码才能访问 将redis加入到系统自启动的脚本中 Redis使用超过设置的最大值 打开debug模式下的页面,提示错误:OOM command not allowed when used memory > ‘maxmemory’. 设置了maxmemory的选项,redis内存使用达到上限。可以通过设置LRU算法来删除部分key,释放空间。默认是按照过期时间的,如果set时候没有加上过期时间就会导致数据写满maxmemory。 如果不设置maxmemory或者设置为0,64位系统不限制内存,32位系统最多使用3GB内存。 LRU是Least Recently Used 近期最少使用算法。 volatile-lru -> 根据LRU算法生成的过期时间来删除。 allkeys-lru -> 根据LRU算法删除任何key。 volatile-random -> 根据过期设置来随机删除key。 allkeys->random -> 无差别随机删。 volatile-ttl -> 根据最近过期时间来删除(辅以TTL) noeviction -> 谁也不删,直接在写操作时返回错误。
注解
详细配置可参考文章:这篇文章主要讲的是配置的含义和优化 <http://www.tuicool.com/articles/MvMBf2>
iptable配置
考虑到安全,不允许外网用户访问redis 10.0.0.0/24 表示C类地址 24掩码前面的0 iptables -A INPUT ! -s 10.0.0.0/24 -p tcp --dport 6379 -j DROP //拒绝所有非本网段的机器访问redis iptables -A INPUT ! -s 10.0.0.0/24 -p udp --dport 6379 -j DROP 保存iptables规则下次启动时自动启动规则 iptables-save > /etc/iptables.up.rules //保存规则 vi /etc/network/interfaces pre-up iptables-restore < /etc/iptables.up.rules //恢复规则 iptables -F 重启网络 /etc/init.d/networking restart iptables -L -v 重启机器 iptables -L -v 可以看到刚刚配置的规则都在
3.5.2.3. 测试¶
redis数据类型测试
设置值,获取值 * set foo "bar" * get foo * expire foo 120 * ttl foo 查询过期时间 返回-2值不存在 -1 值永不过期 自增变量 set connections 10 incr connections del connections list 队列 rpush friends "alice" 添加到队尾 rpush friends "bob" lpush friends "sam" 添加到队首 lrange friends 0 -1 获取全部队列 lrange friends 0 1 获取0-1 llen friends 队列长度 lpop friends 弹出首个对象 rpop friends 弹出队尾对象 set 与list相似,但没有顺序且对象只能出现一次 sadd superpowers "flight" 添加值 sadd superpowers "x-ray vision" sadd superpowers "reflexes" srem superpowers "reflexes" 删除值 sismember superpowers "reflexes" 判断是否存在0不存在1存在 smembers superpowers sadd birdpowers "flight" sadd birdpowers "pecking" sunion superpowers birdpowers 合并set sorted set 可排序set zadd hackers 1940 "alan key" zadd hackers 1980 "Grace hopper" zadd hackers 1945 "richard stallman" zadd hackers 1944 "macker" zrange hackers 0 -1 hashes hset user:1000 name "john smith" hset user:1000 email "john.smith@example.com" hset user:1000 password "s3cret" hgetall user:1000 HMSET user:1001 name "Mary Jones" password "hidden" email "mjones@example.com" SET user:1000 visits 10 HINCRBY user:1000 visits 1 加1 hdel user:1000 visits 删除值
注解
测试参考文档 <http://www.cnblogs.com/silent2012/p/4514901.html>
安全测试
只有使用密码才能访问
root@1604developer:/var# telnet 10.0.0.23 6379 Trying 10.0.0.23... telnet: Unable to connect to remote host: Connection refused root@1604developer:/var# telnet 10.0.0.23 6379 Trying 10.0.0.23... Connected to 10.0.0.23. Escape character is '^]'. auth prettydogKnockTheDoor +OK keys * *0
指定ip才能访问
iptables -L -v --line-num 配置iptables只允许10.0.0.1-32的ip地址访问redis iptables -A INPUT ! -s 10.0.0.0/27 -p tcp --dport 6379 -j DROP iptables -A INPUT ! -s 10.0.0.0/27 -p udp --dport 6379 -j DROP 在本机访问 root@ubuntu1204base:/home/cxl/redis/redis-3.2.6# telnet 10.0.0.23 6379 Trying 10.0.0.23... Connected to 10.0.0.23. Escape character is '^]'. auth prettydogKnockTheDoor +OK keys * *0 在10.0.0.237机器访问 root@php1 16:51:00:~# telnet 10.0.0.23 6379 Trying 10.0.0.23... 如果策略修改为 iptables -A INPUT ! -s 10.0.0.0/27 -p tcp --dport 6379 -j REJECT iptables -A INPUT ! -s 10.0.0.0/27 -p udp --dport 6379 -j REJECT 再次在10.0.0.237机器访问 root@php1 16:53:23:~# telnet 10.0.0.23 6379 Trying 10.0.0.23... telnet: Unable to connect to remote host: Connection refused
数据恢复测试
kill redis 进程
root@ubuntu1204base:/home/cxl/redis/redis-3.2.6# src/redis-cli -h 10.0.0.23 10.0.0.23:6379> auth prettydogKnockTheDoor OK 10.0.0.23:6379> set "first Key" "first Value" OK 10.0.0.23:6379> get "first Key" "first Value" 10.0.0.23:6379> quit root@ubuntu1204base:/home/cxl/redis/redis-3.2.6# ps -aux |grep redis Warning: bad ps syntax, perhaps a bogus '-'? See http://procps.sf.net/faq.html root 4418 0.1 0.3 36124 1564 ? Ssl 17:54 0:00 src/redis-server 10.0.0.23:6379 root 4497 0.0 0.1 9380 936 pts/2 S+ 17:57 0:00 grep --color=auto redis root@ubuntu1204base:/home/cxl/redis/redis-3.2.6# kill 4418 root@ubuntu1204base:/home/cxl/redis/redis-3.2.6# src/redis-server redis.conf root@ubuntu1204base:/home/cxl/redis/redis-3.2.6# src/redis-cli -h 10.0.0.23 10.0.0.23:6379> auth prettydogKnockTheDoor OK 10.0.0.23:6379> get "first Key" "first Value" 10.0.0.23:6379> quit
重启redis进程,查看redis数据
root@ubuntu1204base:/home/cxl/redis/redis-3.2.6# reboot root@ubuntu1204base:/home/cxl/redis/redis-3.2.6# src/redis-server redis.conf root@ubuntu1204base:/home/cxl/redis/redis-3.2.6# src/redis-cli -h 10.0.0.23 10.0.0.23:6379> auth prettydogKnockTheDoor OK 10.0.0.23:6379> get "first Key" "first Value" 10.0.0.23:6379>
性能测试
内存占用测试
vi redis.conf maxmemory 1m //为了测试方便设置为1mb vi addKey.sh # !/usr/bin/bash echo "AUTH prettydogKnockTheDoor" sleep 1 outstr="" value10="1" j=700 while [ $j -gt 690 ] do for i in {100..199} do outstr="${outstr}set key$j-$i ${value10}\r\n" done printf "$outstr" outstr="" j=`expr $j - 1` done 这个脚本往redis服务器加入1000个key,其中Key值10个字节,value值一个字节 10.0.0.23:6379> flushall //清空redis 10.0.0.23:6379> info # Memory used_memory:821552 used_memory_human:803.70K 看出来,redis初始状态就占用803.70k,所以设置1m最大内存,实际可用应该是200k左右 运行脚本插入1000个键值 >方式1 ./addkey.sh | nc 10.0.0.23 6379 >方式2 ./addkey.sh | ../redis-3.2.6/src/redis-cli -h 10.0.0.23 -a prettydogKnockTheDoor --pipe All data transferred. Waiting for the last reply... Last reply received from server. errors: 0, replies: 100001 10.0.0.23:6379> info # Memory used_memory:871184 used_memory_human:850.77K 占用内存47k,所以11字节的key+value大概占用47字节的内存空间 修改一下脚本加入4000key -OOM command not allowed when used memory > 'maxmemory'. 10.0.0.23:6379> dbsize (integer) 3109 只加入了3109键值 used_memory:980120 used_memory_human:957.15K大并发测试
50个客户端发送100000请求每个请求3个字节,看起来redis很给力 root@ubuntu1204base:/home/cxl/redis/redis-3.2.6# src/redis-benchmark -h 10.0.0.23 -q (<span style='color:red;font-weight:bold'>本机测试</span>) PING_INLINE: 75131.48 requests per second PING_BULK: 74074.07 requests per second SET: 76277.65 requests per second GET: 74349.44 requests per second INCR: 75815.01 requests per second LPUSH: 74074.07 requests per second RPUSH: 73421.44 requests per second LPOP: 74794.31 requests per second RPOP: 74571.22 requests per second SADD: 74906.37 requests per second SPOP: 74794.31 requests per second LPUSH (needed to benchmark LRANGE): 73367.57 requests per second LRANGE_100 (first 100 elements): 72621.64 requests per second LRANGE_300 (first 300 elements): 74515.65 requests per second LRANGE_500 (first 450 elements): 74019.25 requests per second LRANGE_600 (first 600 elements): 76277.65 requests per second MSET (10 keys): 73746.31 requests per second <span style='color:red;font-weight:bold'>内网跨服务器测试</span> PING_INLINE: 13596.19 requests per second PING_BULK: 13696.75 requests per second SET: 13676.15 requests per second GET: 13738.15 requests per second INCR: 13738.15 requests per second LPUSH: 13664.94 requests per second RPUSH: 13585.11 requests per second LPOP: 13730.61 requests per second RPOP: 13719.30 requests per second SADD: 13702.38 requests per second SPOP: 13691.13 requests per second LPUSH (needed to benchmark LRANGE): 13655.61 requests per second LRANGE_100 (first 100 elements): 13650.01 requests per second LRANGE_300 (first 300 elements): 13648.15 requests per second LRANGE_500 (first 450 elements): 13550.14 requests per second LRANGE_600 (first 600 elements): 13674.28 requests per second MSET (10 keys): 13220.52 requests per second
注解
结论:本机访问是内网跨服务器访问各类请求每秒执行数量五倍多
监控性能
>>top监控 root@ubuntu1204base:/home/cxl/redis/redis-3.2.6# top -b -p 16417 -n 2|egrep "16417|PID"|tail -2 PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 16417 root 20 0 42268 8980 1240 S 0.0 1.8 0:02.70 redis-server >>redis-cli info监控 root@ubuntu1204base:/home/cxl/redis/redis-3.2.6# src/redis-cli -h 10.0.0.23 -a prettydogKnockTheDoor info|grep used_memory used_memory:7470144 used_memory_human:7.12M used_memory_rss:9023488 used_memory_rss_human:8.61M used_memory_peak:7470144 used_memory_peak_human:7.12M used_memory_lua:37888 used_memory_lua_human:37.00K
3.5.2.4. 代码示例¶
predis
好处是不需要安装php扩展,直接require就行了 git clone git://github.com/nrk/predis.git wget https://github.com/nrk/predis/archive/v1.1.1.tar.gz 拷贝到Thinkphp vendor目录下 示例代码 <pre> require_once VENDOR_PATH."predis/autoload.php"; try { $redis = new Predis\Client("redis://127.0.0.1:6379/"); $redis->set('library', 'predis1'); $retval = $redis->get('library1'); var_export($retval); } catch (Exception $e) { var_dump($e->getMessage()); } </pre> predis函数集:http://www.open-open.com/lib/view/open1355830836135.html
3.5.3. usage¶
key
1、help set SET key value [EX seconds] [PX milliseconds] [NX|XX] summary: Set the string value of a key since: 1.0.0 group: string set test 10 set test 10 EX 60 60秒过期
- list
- 查询list
- lrange queues:importQueue 0 -1
- 从队列头pop元素,在队列里删除该元素
- lpop queues:importQueue
- 清空队列
- ltrim queues:importQueue 1 0
- set
zset(sorted set)操作相关
1. 查询 zrange queues:importQueue:reserved 0 -1 2. 删除所有元素 zrem queues:importQueue:reserved 0 -1
hash
1. 查看hash中的值和value hgetall job_result 1) "importQueue_p0yzx4AQEcVefgUnvZ9nLLiUprwP6ff5" 2) "{\"job_status\":1}" 2. 删除值 hDel job_result importQueue_p0yzx4AQEcVefgUnvZ9nLLiUprwP6ff5 (integer) 1