redis 数据类型详解 以及 redis适用场景场合( 三 )


List
常用命令:lpush,rpush,lpop,rpop,lrange等 。 应用场景:Redis list的应用场景非常多 , 也是Redis最重要的数据结构之一 , 比如twitter的关注列表 , 粉丝列表等都可以用Redis的list结构来实现 。 Lists 就是链表 , 相信略有数据结构知识的人都应该能理解其结构 。 使用Lists结构 , 我们可以轻松地实现最新消息排行等功能 。 Lists的另一个应用就是消息队列 , 可以利用Lists的PUSH操作 , 将任务存在Lists中 , 然后工作线程再用POP操作将任务取出进行执行 。 Redis还提供了操作Lists中某一段的api , 你可以直接查询 , 删除Lists中某一段的元素 。 实现方式:Redis list的实现为一个双向链表 , 即可以支持反向查找和遍历 , 更方便操作 , 不过带来了部分额外的内存开销 , Redis内部的很多实现 , 包括发送缓冲队列等也都是用的这个数据结构 。
Set
常用命令:sadd,spop,smembers,sunion 等 。 应用场景:Redis set对外提供的功能与list类似是一个列表的功能 , 特殊之处在于set是可以自动排重的 , 当你需要存储一个列表数据 , 又不希望出现重复数据时 , set是一个很好的选择 , 并且set提供了判断某个成员是否在一个set集合内的重要接口 , 这个也是list所不能提供的 。 Sets 集合的概念就是一堆不重复值的组合 。 利用Redis提供的Sets数据结构 , 可以存储一些集合性的数据 , 比如在微博应用中 , 可以将一个用户所有的关注人存在一个集合中 , 将其所有粉丝存在一个集合 。 Redis还为集合提供了求交集、并集、差集等操作 , 可以非常方便的实现如共同关注、共同喜好、二度好友等功能 , 对上面的所有集合操作 , 你还可以使用不同的命令选择将结果返回给客户端还是存集到一个新的集合中 。 实现方式:set 的内部实现是一个 value永远为null的HashMap , 实际就是通过计算hash的方式来快速排重的 , 这也是set能提供判断一个成员是否在集合内的原因 。
Sorted Set
常用命令:zadd,zrange,zrem,zcard等使用场景:Redis sorted set的使用场景与set类似 , 区别是set不是自动有序的 , 而sorted set可以通过用户额外提供一个优先级(score)的参数来为成员排序 , 并且是插入有序的 , 即自动排序 。 当你需要一个有序的并且不重复的集合列表 , 那么可以选择sorted set数据结构 , 比如twitter 的public timeline可以以发表时间作为score来存储 , 这样获取时就是自动按时间排好序的 。 另外还可以用Sorted Sets来做带权重的队列 , 比如普通消息的score为1 , 重要消息的score为2 , 然后工作线程可以选择按score的倒序来获取工作任务 。 让重要的任务优先执行 。 实现方式:Redis sorted set的内部使用HashMap和跳跃表(SkipList)来保证数据的存储和有序 , HashMap里放的是成员到score的映射 , 而跳跃表里存放的是所有的成员 , 排序依据是HashMap里存的score,使用跳跃表的结构可以获得比较高的查找效率 , 并且在实现上比较简单 。
Pub/Sub
Pub/Sub 从字面上理解就是发布(Publish)与订阅(Subscribe) , 在Redis中 , 你可以设定对某一个key值进行消息发布及消息订阅 , 当一个key值上进行了消息发布后 , 所有订阅它的客户端都会收到相应的消息 。 这一功能最明显的用法就是用作实时消息系统 , 比如普通的即时聊天 , 群聊等功能 。
Transactions
谁说NoSQL都不支持事务 , 虽然Redis的Transactions提供的并不是严格的ACID的事务(比如一串用EXEC提交执行的命令 , 在执行中服务器宕机 , 那么会有一部分命令执行了 , 剩下的没执行) , 但是这个Transactions还是提供了基本的命令打包执行的功能(在服务器不出问题的情况下 , 可以保证一连串的命令是顺序在一起执行的 , 中间有会有其它客户端命令插进来执行) 。 Redis还提供了一个Watch功能 , 你可以对一个key进行Watch , 然后再执行Transactions , 在这过程中 , 如果这个Watched的值进行了修改 , 那么这个Transactions会发现并拒绝执行 。