Redis命令使用

标签: redisredis命令redis脚本redis使用
885人阅读 评论(1) 收藏 举报
分类:

之前安装好了Redis之后,对于如何使用,还不是特别清楚,因此百度了下,同时结合了下自己常用的命令,做了下整合,

以下是一些相关常用的命令;

 

1  Redis数据类型及应用场景

Redis最为常用的数据类型主要有以下五种:

·        String

·        Hash

·        List

·        Set

·        Sortedset

  • 下图为Redis内部内存管理中是如何描述这些不同数据类型的:

 


  • 首先Redis内部使用一个redisObject对象来表示所有的key和value,redisObject最主要的信息如上图所示:type代表一个value对象具体是何种数据类型,encoding是不同数据类型在redis内部的存储方式,比如:type=string代表value存储的是一个普通字符串,那么对应的encoding可以是raw或者是int,如果是int则代表实际redis内部是按数值型类存储和表示这个字符串的,当然前提是这个字符串本身可以用数值表示,比如:"123" "456"这样的字符串。
  • 这里需要特殊说明一下vm字段,只有打开了Redis的虚拟内存功能,此字段才会真正的分配内存,该功能默认是关闭状态的,该功能会在后面具体描述。通过上图我们可以发现Redis使用redisObject来表示所有的key/value数据是比较浪费内存的,当然这些内存管理成本的付出主要也是为了给Redis不同数据类型提供一个统一的管理接口,实际作者也提供了多种方法帮助我们尽量节省内存使用,我们随后会具体讨论。

 

 

 

1.1String类型

常用命令:

set,get,decr,incr,mget等。

应用场景:

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

实现方式:

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

 

 

 

1.2List类型

常用命令:

lpush,lpop,rpop,lrange等。

应用场景:

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

实现方式:

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

 

 

 

1.3Set类型

常用命令:

sadd,spop,smembers,sunion等。

应用场景:

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

实现方式:

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

 

 

 

1.4Sorted Set类型

常用命令:

zadd,zrange,zrem,zcard

使用场景:

Redissorted set的使用场景与set类似,区别是set不是自动有序的,而sorted set可以通过用户额外提供一个优先级(score)的参数来为成员排序,并且是插入有序的,即自动排序。当你需要一个有序的并且不重复的集合列表,那么可以选择sorted set数据结构,比如twitter 的public timeline可以以发表时间作为score来存储,这样获取时就是自动按时间排好序的。

实现方式:

Redissorted set的内部使用HashMap和跳跃表(SkipList)来保证数据的存储和有序,HashMap里放的是成员到score的映射,而跳跃表里存放的是所有的成员,排序依据是HashMap里存的score,使用跳跃表的结构可以获得比较高的查找效率,并且在实现上比较简单。

 

 

 

1.5Hash类型

常用命令:

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。

 

 

 

2  Redis数据类型相关命令

2.1String命令

字符串数据类型 string

字符串类型是redis基本数据类型,能存储任何形式的字符串,包括二进制数据。

set key value 赋值

get key 取值

incr key 递增数字(所有redis命令都是原子操作)

redis键命名实践 “对象类型:对象id:对象属性”,对于多个单词推荐用.分割。如键user:1:friends表示id为1的用户的好友列表。

incrby key increment 增加指定整数

decrby key decrement 减少指定的整数

incrbyfloat key increment 增加指定浮点数

append key value 向尾部追加值,返回追加后字符串的长度

strlen key 返回键值的长度

mget key [key ...] 获取多个健值

mset key value [key value ...] 设置多个键值

 

位操作

getbit key offset 获得一个字符串指定位置的二进制位的值(0或1)

setbit key offset value 设置字符串类型键指定位置的二进制值,返回该位置的旧值

bitcount key [start] [end] 统计字符串类型中值为1的二进制位个数,可以指定字节的范围

bitop operation destkey key [key...] (and, or, xor, not)

 

 

 

2.2List命令

列表类型可以存储一个有序的字符串列表,常用的操作是向列表两端添加元素或者获得某个列表的某一个片段。

内部使用双向链表实现,获取越接近两端的元素速度就越快,不过索引访问元素比较慢。列表类型能非常快速地完成关系数据库难以应付的场景,如社交网络新鲜事。

lpush key value [value...] 从列表左边增加元素

rpush key value [value...] 从列表右边增加元素

lpop key 从列表左边弹出元素

rpop key 从列表右边弹出元素

llen key 获取列表中元素的个数

lrange key start stop 获取列表片段(包括stop,支持负数表示从最右边开始计数)

lrem key count value 删除前count个值为value的元素(count>0时从左边开始删除,count<0从右边开始删除,count=0删除所有为value的元素)

lindex key index 获取指定索引的元素值

lset key index value 设置指定索引的元素值

ltrim key start end 只保留指定片段

linsert key fefore|after pivot value 首先从左到右查找pivot元素,再根据第二个参赛将value插入该元素前面或后面。

rpoplpush source destination 将一个元素转移到另一个列表 ,原子操作。当source和destination相同时会不断将对尾元素移到队首,实现网站监控系统。

 

 

 

2.3Set命令

集合类型每个元素不同,且无序。

sadd key member [member...] 增加元素,返回成功加入元素的个数

srem key member [member...] 删除元素

smembers key 获得集合中所有元素

sismember key member 判断是否存在集合中

集合间运算

sdiff [destination] key [key ...] 多个集合求差运算a-b,并存储到destination中

sinter [destination] key [key ...] 多个集合执行交运算

sunion [destination] key [key...] 多个集合求并运算

scard key 集合中元素个数

srandmemeber key [count] 随机获得集合中元素(当count>0时随机获取count个不重复元素,count<0时不保证重复)

spop key 从集合中随机弹出一个元素

 

 

 

2.4Sorted Set命令

列表类型通过链表实现,获取靠近两端的数据速度极快,当元素增加后中间元素比较慢,更适合"新鲜事"或“日志”这样很少访问中间元素的应用。

有序集合类型通过散列表和跳跃表实现的,所以即使读取位于中间位置也很快o(nlgn)。

列表中不能简单调整某个元素位置,有序集合可以。有序集合更耗费内存。

zadd key score member [score member...] 加入一个元素和该元素的分数(分数可以是整数或小数,+inf和-inf表示正负无穷)

zscore key member 获得元素的分数

zrange key start stop [withscore] 按照从从小到大的顺序返回start和stop之间所有元素(withscore表示带上分数)复杂度o(logn+m)

zrevrange key start stop [withscore] 从大到小的顺序

zrangebyscore key min max [withscore] [limit offset count] 按照从小到大返回分数在min和max之间的元素

zincrby key increment member 增加某个元素的分数

zcard key 获得集合中元素个数

zcount key min max 获得指定范围内的元素个数

zrem key member [member ...] 删除一个或多个元素

zremrangebyrank key start stop 按照元素分数从小到大的顺序删除指定排名范围内的所有元素,并返回删除元素的个数

zremrangebyscore key min max 删除指定分数范围内的所有元素

zrank key member 获得元素的排名

zrevrank key member

 

 

 

2.5Hash命令

散列类型的键值也是一种字典结构,其存储了字段和字段值的映射,但字段值只能是字符串,不支持其他类型。(集合类型也不支持数据类型嵌套)

hset key field value 赋值(插入时返回1,更新时返回0)

hget key field 取值

hmset key field value [field value ...]

hmget key field [feild...]

hgetall key

hexists key field 判断字段是否存在

hsetnx key field value 当字段不存在时赋值

hincrby key field increment 增加数字

hdel key field [field...] 删除字段

hkeys key 只获取字段名

hvals key 只获取字段值

hlen key 获得字段数量


1
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:450601次
    • 积分:5808
    • 等级:
    • 排名:第4896名
    • 原创:173篇
    • 转载:19篇
    • 译文:0篇
    • 评论:63条
    博客专栏
    最新评论