`
stevencage
  • 浏览: 10419 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

Redis使用小结

 
阅读更多
一、数据类型
String:
redis最基本的类型,二进制安全。
可以包含任何数据:字符串、序列化对象或文件。
最大上限是1G字节。
如果保存的是数值型数据,可以被部分命令按Int处理。

Hash:
存储一个field与value的映射表,即Map结构,field-value对应Map的一个键值对。
相比将对象序列化保存为string类型,把对象保存为hash类型会占用更少内存(省去key值前缀的开销)。当遇到需要修改对象某一项值的时候,采用Hash结构可以只进行一次操作,适应并发操作的场合。
多个string类型的数据可以将命名空间提取为key从而组成一个hash结构的数据,当数据量小时hash采用zipmap存储会节省内存;数据量大时,会节省重复存储前缀造成的内存浪费。


List:
list是一个string类型的双向链表,并且list会记录链表的长度,push命令,pop命令和llen命令的时间复杂度都是O(1)。
list的最大长度是2的32次方-1。
可以通过lpush,lpop,rpush,rpop命令从链表的头或尾添加删除元素,使得list即可用作堆栈也可用作队列。

Set:
set是string类型的无序集合,集合最大可包含32次方-1个元素。
set可以看做是value为空的hash结构,添加删除查找的时间复杂度都是O(1),并且不会出现重复元素。
sismember方法可以很快判断一个元素是否属于这个集合。
set提供集合取并集(sunion)、交集(sinter)、差集(sdiff)的方法。

Sorted Set:
和set类似,sorted set也是string类型元素的集合,不同的是每个元素都会关联一个double类型的score使得sorted set成为一个有序的集合,在sorted set中不可存在重复的value但可存在相同的score。
添加删除单个元素的时间复杂度都是O(LOG(N)),N为集合的基数,在数据插入时就已经进行了天然的排序。
sorted set最经常的使用方式是作为索引来使用,可以将需要排序的字段作为score存储,对象id作为元素存储。

二、高级功能
Pipeline
redis的pipeline(管道)功能在命令行中没有,但redis是支持pipeline的,而且在各个语言版的client中都有相应的实现。
Redis本身是一个cs模式的tcp server, client可以通过一个socket连续发起多个请求命令。 每个请求命令发出后client通常会阻塞并等待redis服务端处理,redis服务端处理完后将结果返回给client。 通过pipeline方式将client端命令一起发出,redis server会处理完多条命令后,将结果一起打包返回client,从而节省大量的网络延迟开销。

Pub/Sub
Pub/Sub 从字面上理解就是发布(Publish)与订阅(Subscribe),在Redis中,你可以设定对某一个key值进行消息发布及消息订阅,当一个key值上进行了消息发布后,所有订阅它的客户端都会收到相应的消息。这一功能最明显的用法就是用作实时消息系统,比如普通的即时聊天,群聊等功能。

Transactions
Redis的Transactions提供的并不是严格的ACID的事务(比如一串用EXEC提交执行的命令,在执行中服务器宕机,那么会有一部分命令执行了,剩下的没执行),但是这个Transactions还是提供了基本的命令打包执行的功能(在服务器不出问题的情况下,可以保证一连串的命令是顺序在一起执行的,中间有会有其它客户端命令插进来执行)。Redis还提供了一个Watch功能,你可以对一个key进行Watch,然后再执行Transactions,在这过程中,如果这个Watched的值进行了修改,那么这个Transactions会发现并拒绝执行。

三、使用技巧
1.对于string和hash结构的数据进行decr/decrBy/incr/incrBy原子操作时,操作结果会直接返回加减后的新值,无需再执行get方法取出验证。
2.如果想在覆盖一条记录之前获取旧值,直接执行getSet方法即可。
3.对于string和hash结构的数据,在执行插入操作时如希望避免覆盖已存在记录,可以使用sexnx/hsetnx方法。
4.在对于hash结构执行ttl或expire命令时,是针对key设置时间而非field,因此在对field进行操作时谨慎使用sexex命令 。
5.对于hash类型的数据,如果需要在一个key中一次插入多条field记录时建议使用hmset批量命令减少链路通信及连接释放的时间,但考虑到网络带宽数据量不宜过大,每次数量不超过100条。
6.在链表两头插入或删除元素是非常高效的操作,因此如果想要从队列头或尾读取多个元素时,可以循环执行pop方法代替lrange方法,尤其当数据量大时pop会明显提高操作的效率。
7.尽量避免使用时间复杂度为O(N)的命令,如keys,mset,hkeys,hmset,如果无法避免应尽量减低N值。
8.Redis集群环境下分布式缓存是根据key做路由,一个key所对应的数据全部存储在一个shard上,因此如果key中包含数据量很大时会造成热点不均问题。
9.sharding环境下不支持mget
10.Redis不支持数据的条件查询,所以当村长基于条件的批量查询和删除场景,在设计时考虑将查询条件对应的结果都放在一个集合数据内部,规避跨key操作尤其杜绝使用Keys abc*等模糊查询命令。






分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics