Redis需特别注意的场景
来源:互联网 发布:win8.1 mac地址修改器 编辑:程序博客网 时间:2024/05/17 00:52
Redis需特别注意的场景
1、 时间复杂度大O(Big ONotation)
当问题的规模,不断变化,执行时间也会不断变化。这就是时间复杂度大O的概念。对于Redis来说,时间复杂度可以用来描述在某个场景的数据规模下,一个命令会有多快。
Redis文档会告诉我们每一个命令的时间复杂度,它也会告诉我们影响命令性能的关键因素。
我们这里举几个例子:
O(1) 可以表示使用时间最短的。例如,sismember,Redis还有好多命令也都是O(1).
O(log(N)) 使用时间仅次于O(1)。例如,zadd。
O(N)属于线性的,在关系型数据库中,查找没有索引的列,就是O(N)的操作。Redis中的ltrim也是O(N)的操作。不过,这个N不是列表的个数,而是要删除的元素个数。
O(log(N)+M) 比线性使用时间还长。例如,zremrangebyscore,删除有序集合中排序在某个区间段上的数据。N是集合的元素个数,M是要删除的元素个数。
O(N+M*log(M)),是Redis中时间复杂度最高的。例如,sort
2、 伪多键查询(PseudoMulti Key Queries)
有一个很常见的情况,你要通过多个key,查询同一个value。比如,你既想通过email 查询用户数据,也想通过id查询用户数据。一个非常可怕的解决办法,就是再复杂一份value,类似下面的。
set users:test@sina.com '{"id": 123, "name":"test", "email": "test@sina.com", ...}'set users:123 '{"id": 123, "name":"test", "email": "test@sina.com", ...}'
一个比较好的解决办法,应该使用Redis的hash。
set users:123 '{"id": 123, "name":"test", "email": "test@sina.com", ...}'hset users:id:email test@sina.com 123如果想通过id找到用户,可以直接使用命令:
get users:123
如果想通过email找到用户,需要执行两个命令:
hget users:id:email test@sina.comget users:#{上面命令的返回值}3、 管道(Pipeline)
Redis还支持管道。通常情况下,客户端每个请求命令发出后,会阻塞,等待redis服务处理,Redis处理完后请求命令后会将结构通过响应报文返回给client。利用管道模式,我们可以从客户端发出多条命令,不需要等待单条命令的返回,Redis服务端会将多条命令的处理结果打包一起返回给客户端。这减少网络开销,性能得到显著提升。 利用Pipeline打包命令发送,Redis必须在处理完所有命令前线缓存起所有命令的处理结果。打包的命令越多,缓存消耗内存也越多。所以并不是打包的命令越多越好。具体多少合适需要根据情况测试。下面是Jedis客户端利用Pipeline的一段代码。
public void usePipeline(int count){ Jedisjr = null; try{ jr= new Jedis("10.10.232.123", 6379); Pipelinepl = jr.pipelined(); for(inti =0; i<count; i++){ pl.incr("key"); } pl.sync(); }catch (Exception e) { e.printStackTrace(); }finally{ if(jr!=null){ jr.disconnect(); }}4、 事务(Transactions)
Redis的每个命令都是原子的,包括那些需要多步操作的命令(incr,getset,setnx)。
Redis提供了事务机制,可以把多个命令作为一个原子性操作组执行。步骤很简单,先执行multi命令,跟着执行你的命令,最后可以执行exec命令提交所有操作,也可以执行discard命令放弃所有操作。先看看Redis对于事务的都有哪些要素:
(1)、全部命令会被顺序执行。
(2)、全部命令执行不会被打断。
(3)、全部命令或者全部执行,或者一个都不执行。
(4)、如果一个命令出现了异常,其他命令也不会回滚。
multiincr aincr bexec最后,Redis可以允许在一个key或多个keys上使用watch命令,可以根据这些key值是否有变化,来有条件的执行事务。这个非常有用,当你在一个事务里想获取一个key的值,并且操作这个key。如果像下面这样:
redis.multi()current = redis.get('count')redis.set('count’, current + 1)redis.exec()这样是行不通的,因为get操作,需要在exec执行后,才会提交。这时,我们使用watch命令,就可以解决这个问题:
redis.watch('count')current = redis.get('count')redis.multi()redis.set('count', current + 1)redis.exec()如果有其他客户端修改了“count”的值,那么这个事务就会执行失败。
5、 Keys命令
Keys通过模式匹配,可以找到所有的keys。这个命令看起来很万能,但是绝不建议在生产环境使用。因为这个命令会扫描所有的key。
比如你要创建一个主机bug跟踪系统,会不会这样设计系统?
Keys: bug:account_id:bug_idValues:异常信息字符串那么你要查询一个主机的所有bug,你可能会习惯的执行: keys bug:123:* 命令。
但是这样,会很慢。使用hash 会是一个不错的替代方案。
hset bug:1233 1 ‘{“id”:1,”account”:123,”excepiton”:….}’想得到某一个主机的所有bug。我们可以使用 hkeys bugs:1233.
- Redis需特别注意的场景
- C++特别注意的特性
- java特别注意的点
- 特别注意
- 特别注意
- 特别注意
- 特别注意
- redis---应用的场景
- redis---应用的场景
- redis应用的场景
- Redis的使用场景
- Redis的应用场景
- redis的应用场景
- redis的使用场景
- redis的应用场景
- Redis的应用场景
- redis的应用场景
- redis的使用场景
- 面试题29
- Xcode中常用英文
- Android学习笔记四大组件之Service
- SAP 笔记
- bios里IDE改AHCI-win7启用ahci蓝屏解决办法
- Redis需特别注意的场景
- 学会这9招,你也能成为演讲高手
- Android中github上的开源工程
- Http接口获取数据
- LeetCode 345: Reverse Vowels of a String
- Android基础知识之JVM && Dalvik && ART
- html滚动字幕代码(咋个办呢 zgbn )
- 微电影大赛二等奖
- 图片 + 时间节点 合成 视频。