Redis中7种集合类型应用场景&redis经常使用命令

Redis经常使用数据类型

Redis最为经常使用的数据类型主要有如下五种:redis

  • String
  • Hash
  • List
  • Set
  • Sorted set

在具体描述这几种数据类型以前,咱们先经过一张图了解下Redis内部内存管理中是如何描述这些不一样数据类型的:数据库

首先Redis内部使用一个redisObject对象来表示全部的key和value,redisObject最主要的信息如上图所示:type表明一个value对象具体是何种数据类型,encoding是不一样数据类型在redis内部的存储方式,好比:type=string表明value存储的是一个普通字符串,那么对应的encoding能够是raw或者是int,若是是int则表明实际redis内部是按数值型类存储和表示这个字符串的,固然前提是这个字符串自己能够用数值表示,好比:"123" "456"这样的字符串。api

这里须要特殊说明一下vm字段,只有打开了Redis的虚拟内存功能,此字段才会真正的分配内存,该功能默认是关闭状态的,该功能会在后面具体描述。经过上图咱们能够发现Redis使用redisObject来表示全部的key/value数据是比较浪费内存的,固然这些内存管理成本的付出主要也是为了给Redis不一样数据类型提供一个统一的管理接口,实际做者也提供了多种方法帮助咱们尽可能节省内存使用,咱们随后会具体讨论。数组

Strings

Strings 数据结构是简单的key-value类型,value其实不只是String,也能够是数字。使用Strings类型,你能够彻底实现目前 Memcached 的功能,而且效率更高。还能够享受Redis的定时持久化,操做日志及 Replication等功能。除了提供与 Memcached 同样的get、set、incr、decr 等操做外,Redis还提供了下面一些操做:服务器

获取字符串长度
往字符串append内容
设置和获取字符串的某一段内容
设置及获取字符串的某一位(bit)
批量设置一系列字符串的内容数据结构

 

经常使用命令:并发

set,get,decr,incr,mget 等app

应用场景:dom

String是最经常使用的一种数据类型,普通的key/value存储均可以归为此类,这里就不所作解释了。异步

实现方式:

String在redis内部存储默认就是一个字符串,被redisObject所引用,当遇到incr,decr等操做时会转成数值型进行计算,此时redisObject的encoding字段为int。

Hashs

在Memcached中,咱们常常将一些结构化的信息打包成hashmap,在客户端序列化后存储为一个字符串的值,好比用户的昵称、年龄、性别、积分等,这时候在须要修改其中某一项时,一般须要将全部值取出反序列化后,修改某一项的值,再序列化存储回去。这样不只增大了开销,也不适用于一些可能并发操做的场合(好比两个并发的操做都须要修改积分)。而Redis的Hash结构可使你像在数据库中Update一个属性同样只修改某一项属性值。

经常使用命令:

hget,hset,hgetall 等。

应用场景:

咱们简单举个实例来描述下Hash的应用场景,好比咱们要存储一个用户信息对象数据,包含如下信息:

用户ID为查找的key,存储的value用户对象包含姓名,年龄,生日等信息,若是用普通的key/value结构来存储,主要有如下2种存储方式:

第一种方式将用户ID做为查找key,把其余信息封装成一个对象以序列化的方式存储,这种方式的缺点是,增长了序列化/反序列化的开销,而且在须要修改其中一项信息时,须要把整个对象取回,而且修改操做须要对并发进行保护,引入CAS等复杂问题。

第二种方法是这个用户信息对象有多少成员就存成多少个key-value对儿,用用户ID+对应属性的名称做为惟一标识来取得对应属性的值,虽然省去了序列化开销和并发问题,可是用户ID为重复存储,若是存在大量这样的数据,内存浪费仍是很是可观的。

那么Redis提供的Hash很好的解决了这个问题,Redis的Hash实际是内部存储的Value为一个HashMap,并提供了直接存取这个Map成员的接口,以下图:

也就是说,Key仍然是用户ID, value是一个Map,这个Map的key是成员的属性名,value是属性值,这样对数据的修改和存取均可以直接经过其内部Map的Key(Redis里称内部Map的key为field), 也就是经过 key(用户ID) + field(属性标签) 就能够操做对应属性数据了,既不须要重复存储数据,也不会带来序列化和并发修改控制的问题。很好的解决了问题。

这里同时须要注意,Redis提供了接口(hgetall)能够直接取到所有的属性数据,可是若是内部Map的成员不少,那么涉及到遍历整个内部Map的操做,因为Redis单线程模型的缘故,这个遍历操做可能会比较耗时,而另其它客户端的请求彻底不响应,这点须要格外注意。

实现方式:

上面已经说到Redis Hash对应Value内部实际就是一个HashMap,实际这里会有2种不一样实现,这个Hash的成员比较少时Redis为了节省内存会采用相似一维数组的方式来紧凑存储,而不会采用真正的HashMap结构,对应的value redisObject的encoding为zipmap,当成员数量增大时会自动转成真正的HashMap,此时encoding为ht。

Lists
Lists 就是链表,相信略有数据结构知识的人都应该能理解其结构。使用Lists结构,咱们能够轻松地实现最新消息排行等功能。Lists的另外一个应用就是消息队列,能够利用Lists的PUSH操做,将任务存在Lists中,而后工做线程再用POP操做将任务取出进行执行。Redis还提供了操做Lists中某一段的api,你能够直接查询,删除Lists中某一段的元素。

经常使用命令:

lpush,rpush,lpop,rpop,lrange等。

应用场景:

Redis list的应用场景很是多,也是Redis最重要的数据结构之一,好比twitter的关注列表,粉丝列表等均可以用Redis的list结构来实现,比较好理解,这里再也不重复。

实现方式:

Redis list的实现为一个双向链表,便可以支持反向查找和遍历,更方便操做,不过带来了部分额外的内存开销,Redis内部的不少实现,包括发送缓冲队列等也都是用的这个数据结构。

Sets
Sets 就是一个集合,集合的概念就是一堆不重复值的组合。利用Redis提供的Sets数据结构,能够存储一些集合性的数据,好比在微博应用中,能够将一个用户全部的关注人存在一个集合中,将其全部粉丝存在一个集合。Redis还为集合提供了求交集、并集、差集等操做,能够很是方便的实现如共同关注、共同喜爱、二度好友等功能,对上面的全部集合操做,你还可使用不一样的命令选择将结果返回给客户端仍是存集到一个新的集合中。

经常使用命令:

sadd,spop,smembers,sunion 等。

应用场景:

Redis set对外提供的功能与list相似是一个列表的功能,特殊之处在于set是能够自动排重的,当你须要存储一个列表数据,又不但愿出现重复数据时,set是一个很好的选择,而且set提供了判断某个成员是否在一个set集合内的重要接口,这个也是list所不能提供的。

实现方式:

set 的内部实现是一个 value永远为null的HashMap,实际就是经过计算hash的方式来快速排重的,这也是set能提供判断一个成员是否在集合内的缘由。

 

Sorted Sets
和Sets相比,Sorted Sets增长了一个权重参数score,使得集合中的元素可以按score进行有序排列,好比一个存储全班同窗成绩的Sorted Sets,其集合value能够是同窗的学号,而score就能够是其考试得分,这样在数据插入集合的时候,就已经进行了自然的排序。另外还能够用Sorted Sets来作带权重的队列,好比普通消息的score为1,重要消息的score为2,而后工做线程能够选择按score的倒序来获取工做任务。让重要的任务优先执行。

经常使用命令:

zadd,zrange,zrem,zcard等

使用场景:

Redis sorted set的使用场景与set相似,区别是set不是自动有序的,而sorted set能够经过用户额外提供一个优先级(score)的参数来为成员排序,而且是插入有序的,即自动排序。当你须要一个有序的而且不重复的集合列表,那么能够选择sorted set数据结构,好比twitter 的public timeline能够以发表时间做为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会发现并拒绝执行。

链接操做相关的命令

quit:关闭链接(connection)
auth:简单密码认证

持久化

save:将数据同步保存到磁盘
bgsave:将数据异步保存到磁盘
lastsave:返回上次成功将数据保存到磁盘的Unix时戳
shundown:将数据同步保存到磁盘,而后关闭服务

远程服务控制

info:提供服务器的信息和统计
monitor:实时转储收到的请求
slaveof:改变复制策略设置
config:在运行时配置Redis服务器

对value操做的命令

exists(key):确认一个key是否存在
del(key):删除一个key
type(key):返回值的类型
keys(pattern):返回知足给定pattern的全部key
randomkey:随机返回key空间的一个
keyrename(oldname, newname):重命名key
dbsize:返回当前数据库中key的数目
expire:设定一个key的活动时间(s)
ttl:得到一个key的活动时间
select(index):按索引查询
move(key, dbindex):移动当前数据库中的key到dbindex数据库
flushdb:删除当前选择数据库中的全部key
flushall:删除全部数据库中的全部key

对String操做的命令

set(key, value):给数据库中名称为key的string赋予值value
get(key):返回数据库中名称为key的string的value
getset(key, value):给名称为key的string赋予上一次的value
mget(key1, key2,…, key N):返回库中多个string的value
setnx(key, value):添加string,名称为key,值为value
setex(key, time, value):向库中添加string,设定过时时间time
mset(key N, value N):批量设置多个string的值
msetnx(key N, value N):若是全部名称为key i的string都不存在
incr(key):名称为key的string增1操做
incrby(key, integer):名称为key的string增长integer
decr(key):名称为key的string减1操做
decrby(key, integer):名称为key的string减小integer
append(key, value):名称为key的string的值附加value
substr(key, start, end):返回名称为key的string的value的子串

对List操做的命令

rpush(key, value):在名称为key的list尾添加一个值为value的元素
lpush(key, value):在名称为key的list头添加一个值为value的 元素
llen(key):返回名称为key的list的长度
lrange(key, start, end):返回名称为key的list中start至end之间的元素
ltrim(key, start, end):截取名称为key的list
lindex(key, index):返回名称为key的list中index位置的元素
lset(key, index, value):给名称为key的list中index位置的元素赋值
lrem(key, count, value):删除count个key的list中值为value的元素
lpop(key):返回并删除名称为key的list中的首元素
rpop(key):返回并删除名称为key的list中的尾元素
blpop(key1, key2,… key N, timeout):lpop命令的block版本。
brpop(key1, key2,… key N, timeout):rpop的block版本。
rpoplpush(srckey, dstkey):返回并删除名称为srckey的list的尾元素,并将该元素添加到名称为dstkey的list的头部

对Set操做的命令

sadd(key, member):向名称为key的set中添加元素member
srem(key, member) :删除名称为key的set中的元素member
spop(key) :随机返回并删除名称为key的set中一个元素
smove(srckey, dstkey, member) :移到集合元素
scard(key) :返回名称为key的set的基数
sismember(key, member) :member是不是名称为key的set的元素
sinter(key1, key2,…key N) :求交集
sinterstore(dstkey, (keys)) :求交集并将交集保存到dstkey的集合
sunion(key1, (keys)) :求并集
sunionstore(dstkey, (keys)) :求并集并将并集保存到dstkey的集合
sdiff(key1, (keys)) :求差集
sdiffstore(dstkey, (keys)) :求差集并将差集保存到dstkey的集合
smembers(key) :返回名称为key的set的全部元素
srandmember(key) :随机返回名称为key的set的一个元素

对Hash操做的命令

hset(key, field, value):向名称为key的hash中添加元素fieldhget(key, field):返回名称为key的hash中field对应的valuehmget(key, (fields)):返回名称为key的hash中field i对应的valuehmset(key, (fields)):向名称为key的hash中添加元素field hincrby(key, field, integer):将名称为key的hash中field的value增长integerhexists(key, field):名称为key的hash中是否存在键为field的域hdel(key, field):删除名称为key的hash中键为field的域hlen(key):返回名称为key的hash中元素个数hkeys(key):返回名称为key的hash中全部键hvals(key):返回名称为key的hash中全部键对应的valuehgetall(key):返回名称为key的hash中全部的键(field)及其对应的value

相关文章
相关标签/搜索