Redis高级特性
Redis高级特性
redis中键的生存时间(expire)
Redis中可以使用expire命令设置一个键的生存时间,到时间后redis会自动删除它。
1. 过期时间可以设置为秒或者毫秒精度。
2. 过期时间分辨率总是 1 毫秒。
3. 过期信息被复制和持久化到磁盘,当 Redis 停止时时间仍然在计算 (也就是说 Redis 保存了过期时间)。
命令
expire 设置生存时间(单位/秒)
expire key seconds(秒)
ttl 查看键的剩余生存时间
ttl key
persist 取消生存时间
persist key
expireat [key] unix时间戳1351858600
EXPIREAT cache 1355292000 # 这个 key 将在 2012.12.12 过期
操作
应用场景
1. 限时的优惠活动信息
2. 网站数据缓存(对于一些需要定时更新的数据,例如:积分排行榜)
3. 手机验证码
4. 限制网站访客访问频率(例如:1分钟最多访问10次)
redis的事务(transaction)
redis中的事务是一组命令的集合。事务同命令一样都是redis的最小执行单元。一组事务中的命令要么都执行,要么都不执行。(例如:转账)
原理:
先将属于一个事务的命令发送给redis进行缓存,最后再让redis依次执行这些命令。
命令:
multi //事务开始
.....
exec //事务结束,开始执行事务中的命令
discard //放弃事务
操作
应用场景:
1. 一组命令必须同时都执行,或者都不执行。
2. 我们想要保证一组命令在执行的过程之中不被其它命令插入。
错误处理
1. 语法错误:致命的错误,事务中的所有命令都不会执行
2. 运行错误:不会影响事务中其他命令的执行
Redis 不支持回滚(roll back)
正因为redis不支持回滚功能,才使得redis在事务上可以保持简洁和快速。
watch命令
作用:监控一个或者多个键,当被监控的键值被修改后阻止之后的一个事务的执行。
但是不能保证其它客户端不修改这一键值,所以我们需要在事务执行失败后重新执行事务中的命令。
注意:执行完事务的exec命令之后,watch就会取消对所有键值的监控
unwatch:取消监控
redis中数据的排序(sort)
sort命令可以对列表类型,集合类型和有序集合类型进行排序。
命令
sort key [desc] [limit offset count]
by 参考键(参考键可以是字符串类型或者是hash类型的某个字段,hash类型的格式为:键名->字段名)
如果参考键中不带*号则不排序
如果某个元素的参考键不存在,则默认参考键的值为0
扩展 get参数
get参数的规则和by参数的规则一样
get # (返回元素本身的值)
扩展 store参数
使用store 参数可以把sort的排序结果保存到指定的列表中
性能优化
1:尽可能减少待排序键中元素的数量
2:使用limit参数只获取需要的数据
3:如果要排序的数据数量很大,尽可能使用store参数将结果缓存。
操作
“发布/订阅”模式
发布:publish
publish channel message
订阅:subscribe
subscribe channel [.....]
取消订阅:unsubscribe
unsubscribe [channel]
按照规则订阅:psubscribe
psubscribe channel ?
按照规则取消订阅:punsubscribe
注意:使用punsubscribe命令只能退订通过psubscribe 订阅的频道。
操作
redis任务队列、栈
任务队列:使用lpush和rpop(brpop)可以实现普通的任务队列
栈:使用rpush和rpop
brpop是列表的阻塞式(blocking)弹出原语。
它是 RPOP命令的阻塞版本,当给定列表内没有任何元素可供弹出的时候,连接将被 BRPOP命令阻塞,直到等待超时或发现可弹出元素为止。
当给定多个 key 参数时,按参数 key 的先后顺序依次检查各个列表,弹出第一个非空列表的尾部元素。
操作
redis管道(pipeline)
redis的pipeline(管道)功能在命令行中没有,但是redis是支持管道的,在Java的客户端(jedis)中是可以使用的。
1:不使用管道方式,插入1000条数据耗时328毫秒
// 测试不使用管道
public static void testInsert() {
long currentTimeMillis = System.currentTimeMillis();
Jedis jedis = new Jedis("192.168.33.130", 6379);
for (int i = 0; i < 1000; i++) {
jedis.set("test" + i, "test" + i);
}
long endTimeMillis = System.currentTimeMillis();
System.out.println(endTimeMillis - currentTimeMillis);
}
2:使用管道方式,插入1000条数据耗时37毫秒
// 测试管道
public static void testPip() {
long currentTimeMillis = System.currentTimeMillis();
Jedis jedis = new Jedis("192.168.33.130", 6379);
Pipeline pipelined = jedis.pipelined();
for (int i = 0; i < 1000; i++) {
pipelined.set("bb" + i, i + "bb");
}
pipelined.sync();
long endTimeMillis = System.currentTimeMillis();
System.out.println(endTimeMillis - currentTimeMillis);
}
在插入更多数据的时候,管道的优势更加明显:测试10万条数据的时候,不使用管道要40秒,实用管道378毫秒。
redis的安全策略
设置数据库密码(配置)
requirepass password
验证密码(命令)
auth password
bind参数(可以让数据库只能在指定IP下访问)
bind 127.0.0.1
修改命令的名称
rename-command flushall cleanall
禁用命令
rename-command flushall ""
redis info命令
以一种易于解释(parse)且易于阅读的格式,返回关于 Redis 服务器的各种信息和统计数值。
通过给定可选的参数 section ,可以让命令只返回某一部分的信息:
http://redisdoc.com/server/info.html
redis内存占用情况
测试情况:
100万个键值对(键是0到999999值是字符串“hello world”)在32位操作系统的笔记本上 用了100MB
使用64位的操作系统的话,相对来说占用的内存会多一点,这是因为64位的系统里指针占用了8个字节,但是64位系统也能支持更大的内存,所以运行大型的redis服务还是建议使用64位服务器
Redis实例最多存keys数
理论上Redis可以处理多达2的32次方的keys,并且在实际中进行了测试,每个实例至少存放了2亿5千万的keys,也可以说Redis的存储极限是系统中的可用内存值。
参考:
http://blog.csdn.net/u011204847/article/details/51302109#