Redis概述
Redis是一个开源的key-value存储系统。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set --有序集合)和hash(哈希类型)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,Redis支持各种不同方式的排序。与memcached一样,为了保证效率,数据都是缓存在内存中。区别的是Redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件。并且在此基础上实现了master-slave(主从)同步。
Redis特征
•数据间没有必然的关联关系•内部采用单线程机制进行工作•高性能•多数据类型支持•持久化支持。可以进行数据灾难恢复
Redis 的应用
•为热点数据加速查询(主要场景),如热点商品、热点新闻、热点资讯、推广类等高访问量信息等•任务队列,如秒杀、抢购、购票排队等•即时信息查询,如各位排行榜、各类网站访问统计、公交到站信息、在线人数信息(聊天室、网站)、设备信号等•时效性信息控制,如验证码控制、投票控制等•分布式数据共享,如分布式集群架构中的 session 分离•消息队列•分布式锁
Redis的基本操作
信息添加
•功能: 设置key, value数据,如果key重复,则将覆盖原始数据
命令:
set key value
复制
示例:
set name zhangsan
复制
信息获取
•根据key查询对应的value,如果不存在,则返回空(nil)
命令:
get key
复制
示例:
get name
复制
redis 数据存储格式
•redis 自身是一个 Map,其中所有的数据都是采用 key : value
的形式存储•数据类型指的是存储的数据的类型,也就是 value 部分的类型,key 部分永远都是字符串
key 的设置约定
key命名惯例
表名:主键名:主键值:字段名
复制
例子:
order:id:29437595:name
equip:id:390472345:type
复制
Redis 数据类型
Redis 数据类型 | 与之相似的Java类型 |
string | String |
hash | HashMap |
list | LinkedList |
set | HashSet |
sorted_set | TreeSet |
string 类型
•存储的数据:单个数据,最简单的数据存储类型,也是最常用的数据存储类型•存储数据的格式:一个存储空间保存一个数据•存储内容:通常使用字符串,如果字符串以整数的形式展示,可以作为数字操作使用
string 类型数据的基本操作
添加/修改数据
set key value
复制
获取数据
get key
复制
删除数据
del key
复制
添加/修改多个数据
mset key1 value1 key2 value2 …
复制
获取多个数据
mget key1 key2 …
复制
获取数据字符个数(字符串长度)
strlen key
复制
追加信息到原始信息后部(如果原始信息存在就追加,否则新建)
append key value
复制
string 类型数据的扩展操作
设置数值数据增加指定范围的值
# 执行原子加1操作
incr key
# 执行原子增加一个整数
incrby key increment
# 执行原子增加一个浮点数
incrbyfloat key increment
复制
设置数值数据减少指定范围的值
# 整数原子减1
decr key
# 原子减指定的整数
decrby key increment
复制
string 作为数值操作
•string在redis内部存储默认就是一个字符串,当遇到增减类操作incr,decr时会转成数值型进行计算。•redis所有的操作都是原子性的,采用单线程处理所有业务,命令是一个一个执行的,因此无需考虑并发带来的数据影响。•注意:按数值进行操作的数据,如果原始数据不能转成数值,或超越了redis 数值上限范围,将报错。9223372036854775807(java中long型数据最大值,Long.MAX_VALUE)
PS:
•redis还可用于控制数据库表主键id,为数据库表主键提供生成策略,保障数据库表的主键唯一性,此方案适用于所有数据库,且支持数据库集群
设置数据具有指定的生命周期
# 设置key-value并设置过期时间(单位:秒)
setex key seconds value
# PSETEX和SETEX一样,唯一的区别是到期时间以毫秒为单位,而不是秒。
psetex key milliseconds value
复制
string 类型数据操作的注意事项
•数据操作不成功的反馈与数据正常操作之间的差异
•运行结果是否成功
•(integer) 0 → false 失败•(integer) 1 → true 成功
•运行结果值
•(integer) 3 → 3 3个•(integer) 1 → 1 1个
•数据未获取到
(nil)等同于null
hash 类型
•适用于存储需求:对一系列存储的数据进行编组,方便管理,典型应用存储对象信息•hash 类型存储结构:一个存储空间保存多个键值对数据•hash类型:底层使用哈希表结构实现数据存储
hash存储结构优化
•如果field数量较少,存储结构优化为类数组结构•如果field数量较多,存储结构使用HashMap结构
hash 类型数据的基本操作
添加/修改数据
# 设置hash里面一个字段的值
hset key field value
复制
获取数据
# 返回 key 指定的哈希集中该字段所关联的值
hget key field
# 从hash中读取全部的域和值
hgetall key
复制
删除数据
# 从 key 指定的哈希集中移除指定的域。在哈希集中不存在的域将被忽略。如果 key 指定的哈希集不存在,它将被认为是一个空的哈希集,该命令将返回0
hdel key field [field ...]
复制
添加/修改多个数据
# 设置 key 指定的哈希集中指定字段的值。
hmset key field1 value1 field2 value2 …
复制
获取多个数据
# 返回 key 指定的哈希集中指定字段的值。对于哈希集中不存在的每个字段,返回 nil 值。
hmget key field1 field2 …
复制
获取哈希表中字段的数量
# 返回 key 指定的哈希集包含的字段的数量。当 key 指定的哈希集不存在时返回 0
hlen key
复制
获取哈希表中是否存在指定的字段
•1 hash里面包含该field。•0 hash里面不包含该field或者key不存在。
# 返回hash里面field是否存在
hexists key field
复制
hash 类型数据扩展操作
获取哈希表中所有的字段名或字段值
# 返回 key 指定的哈希集中所有字段的名字。
hkeys key
# 返回 key 指定的哈希集中所有字段的值。
hvals key
复制
设置指定字段的数值数据增加指定范围的值
# 增加 key 指定的哈希集中指定字段的数值,如果字段不存在,则字段的值在该操作执行前被设置为 0,HINCRBY 支持的值的范围限定在 64位 有符号整数
hincrby key field increment
# 将hash中指定域的值增加给定的浮点数,如果field不存在,则在执行该操作前设置为0.如果出现下列情况之一,则返回错误:
# 1. field的值包含的类型错误(不是字符串)。
# 2. 当前field或者increment不能解析为一个float类型。
hincrbyfloat key field increment
复制
设置指定字段的值(如果有才进行操作)
# 只在 key 指定的哈希集中不存在指定的字段时,设置字段的值。如果 key 指定的哈希集不存在,会创建一个新的哈希集并与 key 关联。如果字段已存在,该操作无效果。
hsetnx key field value
复制
获取hash指定field的value的字符串长度
# 返回hash指定field的value的字符串长度,如果hash或者field不存在,返回0.
hstrlen key field
复制
hash 类型数据操作的注意事项
•ash类型下的value只能存储字符串,不允许存储其他数据类型,不存在嵌套现象。如果数据未获取到,对应的值为(nil)•每个 hash 可以存储 232 - 1 个键值对•hash类型十分贴近对象的数据存储形式,并且可以灵活添加删除对象属性。但hash设计初衷不是为了存储大量对象而设计的,切记不可滥用,更不可以将hash作为对象列表使用•hgetall 操作可以获取全部属性,如果内部field过多,遍历整体数据效率就很会低,有可能成为数据访问瓶颈•如果hash中字段有50个,而只需要其中一部分,尽量不要使用hgetall 来获取,只拿去需要的数据
list 类型
•适用于存储需求:存储多个数据,并对数据进入存储空间的顺序进行区分•list 类型存储结构:一个存储空间保存多个数据,且通过数据可以体现进入顺序•list 类型:保存多个数据,底层使用双向链表存储结构实现
list 类型数据基本操作
添加/修改数据
# 从队列的左边入队一个或多个元素,如果 key 对应的值不是一个 list 的话,那么会返回一个错误,其返回值为在 push 操作后的 list 长度。
lpush key value1 [value2] ……
# 从队列的右边入队一个元素
rpush key value1 [value2] ……
复制
获取数据
# 返回存储在 key 的列表里指定范围内的元素。start 和 end 偏移量都是基于0的下标,即list的第一个元素下标是0(list的表头),第二个元素下标是1,以此类推。偏移量也可以是负数,表示偏移量是从list尾部开始计数。例如, -1 表示列表的最后一个元素,-2 是倒数第二个,以此类推。
lrange key start stop
# 返回列表里的元素的索引 index 存储在 key 里面,当 index 超过范围的时候返回 nil。当 key 位置的值不是一个列表的时候,会返回一个error。
lindex key index
# 返回存储在 key 里的list的长度。如果 key 不存在,那么就被看作是空list,并且返回长度为 0。当存储在 key 里的值不是一个list的话,会返回error。
llen key
复制
获取并移除数据
# 移除并且返回 key 对应的 list 的第一个元素。
lpop key
# 移除并返回存于 key 的 list 的最后一个元素。
rpop key
复制
list 类型数据扩展操作
规定时间内获取并移除数据
# 它是命令 LPOP 的阻塞版本,这是因为当给定列表内没有任何元素可供弹出的时候, 连接将被 BLPOP 命令阻塞。当给定多个 key 参数时,按参数 key 的先后顺序依次检查各个列表,弹出第一个非空列表的头元素。
blpop key1 [key...] timeout
# 它是 RPOP 的阻塞版本,因为这个命令会在给定list无法弹出任何元素的时候阻塞连接。该命令会按照给出的 key 顺序查看 list,并在找到的第一个非空 list 的尾部弹出一个元素。
brpop key1 [key...] timeout
# BRPOPLPUSH 是 RPOPLPUSH 的阻塞版本。当 source 包含元素的时候,这个命令表现得跟 RPOPLPUSH 一模一样。当 source 是空的时候,Redis将会阻塞这个连接,直到另一个客户端 push 元素进入或者达到 timeout 时限。timeout 为 0 能用于无限期阻塞客户端。
brpoplpush source destination timeout
复制
移除指定数据
# 从存于 key 的列表里移除前 count 次出现的值为 value 的元素。这个 count 参数通过下面几种方式影响这个操作:
# count > 0: 从头往尾移除值为 value 的元素。
# count < 0: 从尾往头移除值为 value 的元素。
# count = 0: 移除所有值为 value 的元素。
lrem key count value
复制
list 类型数据操作注意事项
•list中保存的数据都是string类型的,数据总容量是有限的,最多232 - 1 个元素 (4294967295)。•list具有索引的概念,但是操作数据时通常以队列的形式进行入队出队操作,或以栈的形式进行入栈出栈操作•获取全部数据操作结束索引设置为-1•ist可以对数据进行分页操作,通常第一页的信息来自于list,第2页及更多的信息通过数据库的形式加载
set 类型
•适用于存储需求:存储大量的数据,在查询方面提供更高的效率•set 类型存储结构:能够保存大量的数据,高效的内部存储机制,便于查询•set 类型:与hash存储结构完全相同,仅存储键,不存储值(nil),并且值是不允许重复的
set 类型数据的基本操作
添加数据
# 添加一个或多个指定的member元素到集合的 key中,如果已经在集合key中存在则忽略,如果key 的类型不是集合则返回错误.其返回值为新成功添加到集合里元素的数量
sadd key member [member ...]
复制
获取全部数据
# 返回key集合所有的元素.
smembers key
复制
删除数据
# 在key集合中移除指定的元素. 如果指定的元素不是key集合中的元素则忽略 如果key集合不存在则被视为一个空的集合,该命令返回0.如果key的类型不是一个集合,则返回错误.
srem key member [member ...]
复制
获取集合数据总量
# 返回集合的基数(元素的数量),如果key不存在,则返回 0.
scard key
复制
判断集合中是否包含指定数据.
# 返回成员 member 是否是存储的集合 key的成员.如果member元素是集合key的成员,则返回1,如果member元素不是key的成员,或者集合key不存在,则返回0
sismember key member
复制
set类型数据的扩展操作
随机获取集合中指定数量的数据
# 如果仅提供key参数,那么随机返回key集合中的一个元素.Redis 2.6开始,可以接受 count 参数,
# 如果count是整数且小于元素的个数,返回含有 count 个不同的元素的数组,
# 如果count是个整数且大于集合中元素的个数时,仅返回整个集合的所有元素,
# 当count是负数,则会返回一个包含count的绝对值的个数元素的数组,
# 如果count的绝对值大于元素的个数,则返回的结果集里会出现一个元素出现多次的情况.
srandmember key [count]
复制
随机获取集合中的某个数据并将该数据移出集合
# 从存储在key的集合中移除并返回一个或多个随机元素。返回被删除的元素,或者当key不存在时返回nil。
spop key [count]
复制
求两个集合的交、并、差集
# 返回指定所有的集合的成员的交集.
sinter key1 [key...]
# 返回给定的多个集合的并集中的所有成员.
sunion key1 [key...]
# 返回一个集合与给定集合的差集的元素.
sdiff key1 [key...]
复制
求两个集合的交、并、差集并存储到指定集合中
# 交集,这个命令与SINTER命令类似, 但是它并不是直接返回结果集,而是将结果保存在 destination集合中.如果destination 集合存在, 则会被重写.其返回值为结果集中成员的个数.
sinterstore destination key1 [key2]
# 并集
sunionstore destination key1 [key2]
# 差集
sdiffstore destination key1 [key2]
复制
将指定数据从原始集合中移动到目标集合中
smove source destination member
复制
set 类型数据操作的注意事项
•set 类型不允许数据重复,如果添加的数据在 set 中已经存在,将只保留一份•set 虽然与hash的存储结构相同,但是无法启用hash中存储值的空间
sorted_set 类型
•适用于存储需求:数据排序有利于数据的有效展示,需要提供一种可以根据自身特征进行排序的方式•sorted_set存储结构:新的存储模型,可以保存可排序的数据•sorted_set类型:在set的存储结构基础上添加可排序字段
sorted_set 类型数据的基本操作
添加数据
# 将所有指定成员添加到键为key有序集合(sorted set)里面。添加时可以指定多个分数/成员(score/member)对。如果指定添加的成员已经是有序集合里面的成员,则会更新改成员的分数(scrore)并更新到正确的排序位置。
#如果key不存在,将会创建一个新的有序集合(sorted set)并将分数/成员(score/member)对添加到有序集合,就像原来存在一个空的有序集合一样。如果key存在,但是类型不是有序集合,将会返回一个错误应答。
# 分数值是一个双精度的浮点型数字字符串。+inf和-inf都是有效值。
zadd key [nx|xx] [ch] [incr] score member [score member ...]
复制
PS:
ZADD 参数(options) (>= Redis 3.0.2)
ZADD 命令在key
后面分数/成员(score/member)对前面支持一些参数,他们是:
•XX: 仅仅更新存在的成员,不添加新成员。•NX: 不更新存在的成员。只添加新成员。•CH: 修改返回值为发生变化的成员总数,原始是返回新添加成员的总数 (CH 是 changed 的意思)。更改的元素是新添加的成员,已经存在的成员更新分数。所以在命令中指定的成员有相同的分数将不被计算在内。注:在通常情况下,ZADD
返回值只计算新添加成员的数量。•INCR: 当ZADD
指定这个选项时,成员的操作就等同ZINCRBY[1]命令,对成员的分数进行递增操作。
获取全部数据
# 返回存储在有序集合key中的指定范围的元素。返回的元素可以认为是按得分从最低到最高排列。如果得分相同,将按字典排序。
zrange key start stop [WITHSCORES]
# 返回有序集key中,指定区间内的成员。其中成员的位置按score值递减(从大到小)来排列。具有相同score值的成员按字典序的反序排列。
zrevrange key start stop [WITHSCORES]
复制
删除数据
# 删除数据,当key存在,但是其不是有序集合类型,就返回一个错误。
zrem key member [member ...]
复制
按条件获取数据
# 返回key的有序集合中的分数在min和max之间的所有元素(包括分数等于max或者min的元素)。元素被认为是从低分到高分排序的。
zrangebyscore key min max [WITHSCORES] [LIMIT]
# 返回有序集合中指定分数区间内的成员,分数由高到低排序。
zrevrangebyscore key max min [WITHSCORES]
复制
PS:
•min与max用于限定搜索查询的条件•start与stop用于限定查询范围,作用于索引,表示开始和结束索引•offset与count用于限定查询范围,作用于查询结果,表示开始位置和数据总量
获取集合数据总量
# 返回key的有序集元素个数。
zcard key
# 返回指定分数范围的元素个数。
zcount key min max
复制
集合交、并操作
# 计算给定的numkeys个有序集合的交集,并且把结果放到destination中。在给定要计算的key和其它参数之前,必须先给定key个数(numberkeys)。如果destination存在,就把它覆盖。
zinterstore destination numkeys key [key ...] [weights weight] [sum|min|max]
# 计算给定的numkeys个有序集合的并集,并且把结果放到destination中。在给定要计算的key和其它参数之前,必须先给定key个数(numberkeys)。默认情况下,结果集中某个成员的score值是所有给定集下该成员score值之和。如果destination存在,就把它覆盖。
zunionstore destination numkeys key [key ...] [weights weight] [sum|min|max]
复制
sorted_set 类型数据的扩展操作
获取数据对应的索引(排名)
# 返回有序集key中成员member的排名。其中有序集成员按score值递增(从小到大)顺序排列。排名以0为底,也就是说,score值最小的成员排名为0。
zrank key member
# 返回有序集key中成员member的排名,其中有序集成员按score值从大到小排列。排名以0为底,也就是说,score值最大的成员排名为0。
zrevrank key member
复制
score值获取与修改
# 返回有序集key中,成员member的score值。如果member元素不是有序集key的成员,或key不存在,返回nil。
zscore key member
# 为有序集key的成员member的score值加上增量increment。如果key中不存在member,就在key中添加一个member,score是increment。如果key不存在,就创建一个只含有指定member成员的有序集合。当key不是有序集类型时,返回一个错误。
zincrby key increment member
复制
sorted_set 类型数据操作的注意事项
•score保存的数据存储空间是64位,如果是整数范围是-9007199254740992~9007199254740992•score保存的数据也可以是一个双精度的double值,基于双精度浮点数的特征,可能会丢失精度,使用时候要慎重•orted_set 底层存储还是基于set结构的,因此数据不能重复,如果重复添加相同的数据,score值将被反复覆盖,保留最后一次修改的结果
Redis 通用指令
key通用指令
key 特征
key是一个字符串,通过key获取redis中保存的数据
key 基本操作
删除指定key
# 删除指定的一批keys,如果删除中的某些key不存在,则直接忽略。其返回值为被删除的keys的数量
del key [key ...]
复制
获取key是否存在
exists key [key ...]
复制
获取key的类型
# 返回key所存储的value的数据结构类型,它可以返回string, list, set, zset 和 hash等不同的类型。如果key不存在时返回none。
type key
复制
key 扩展操作(时效性控制)
# 设置key的过期时间,超过时间后,将会自动删除该key。
expire key seconds
# 这个命令和EXPIRE命令的作用类似,但是它以毫秒为单位设置 key 的生存时间,而不像EXPIRE命令那样,以秒为单位。
pexpire key milliseconds
# EXPIREAT 的作用和 EXPIRE类似,都用于为 key 设置生存时间。不同在于 EXPIREAT 命令接受的时间参数是 UNIX 时间戳 Unix timestamp 。
expireat key timestamp
# PEXPIREAT 这个命令和EXPIREAT命令类似,但它以毫秒为单位设置 key 的过期 unix 时间戳,而不是像EXPIREAT那样,以秒为单位。
pexpireat key milliseconds-timestamp
复制
获取key的有效时间
# 返回key剩余的过期时间。如果key不存在或者已过期,返回 -2,如果key存在并且没有设置过期时间(永久有效),返回 -1 。
ttl key
# 这个命令类似于TTL命令,但它以毫秒为单位返回 key 的剩余生存时间,而不是像TTL命令那样,以秒为单位。如果key不存在返回-2,如果key存在且无过期时间返回-1
pttl key
复制
切换key从时效性转换为永久性
# 移除给定key的生存时间,当生存时间移除成功时,返回 1 .如果 key 不存在或 key 没有设置生存时间,返回 0 .
persist key
复制
查询key
# 查找所有符合给定模式pattern(正则表达式)的 key 。
keys pattern
复制
查询模式规则
•*
匹配任意数量的任意符号•?
配合一个任意符号•[]
匹配一个指定符号
示例:
命令 | 作用 |
keys * | 查询所有 |
keys it* | 查询所有以it开头 |
keys *heima | 查询所有以heima结尾 |
keys ??heima | 查询所有前面两个字符任意,后面以heima结尾 |
keys user:? | 查询所有以user:开头,最后一个字符任意 |
keys u[st]er:1 | 查询所有以u开头,以er:1结尾,中间包含一个字母,s或t |
为key改名
# 将key重命名为newkey,如果key与newkey相同,将返回一个错误。如果newkey已经存在,则值将被覆盖。
rename key newkey
# 当且仅当 newkey 不存在时,将 key 改名为 newkey 。当 key 不存在时,返回一个错误。
renamenx key newkey
复制
对所有key排序
# 返回或存储key的list、 set 或sorted set 中的元素。默认是按照数值类型排序的,并且按照两个元素的双精度浮点数类型值进行比较。
# 具体命令请参考 http://redis.cn/commands/sort.html
sort key [by pattern] [limit offset count] [get pattern] [asc|desc] [alpha] destination
复制
数据库通用操作
key 的重复问题
•key是由程序员定义的•redis在使用过程中,伴随着操作数据量的增加,会出现大量的数据以及对应的key•数据不区分种类、类别混杂在一起,极易出现重复或冲突
解决方案
•redis为每个服务提供有16个数据库,编号从0到15•每个数据库之间的数据相互独立
db 基本操作
切换数据库
# 选择一个数据库,下标值从0开始,一个新连接默认连接的数据库是DB0。
select index
复制
关闭连接
quit
复制
测试连接
# 测试一个连接是否还是可用的,或者用来测试一个连接的延时。
ping
复制
返回消息
# 返回消息
echo message
复制
数据移动
# 将当前数据库的 key 移动到给定的数据库 db 当中。如果当前数据库(源数据库)和给定数据库(目标数据库)有相同名字的给定 key ,或者 key 不存在于当前数据库,那么 MOVE 没有任何效果。
move key db
复制
查询数据库中key数量
# 返回当前数据里面keys的数量。
dbsize
复制
删除当前数据库中所有数据
# 删除当前数据库里面的所有数据。
flushdb
复制
删除所有数据库中全部数据
# 删除所有数据库里面的所有数据
flushall
复制
References
[1]
ZINCRBY: http://redis.cn/commands/zincrby.html