Redis的数据结构和使用场景

Redis(全称:Remote Dictionary Server 远程字典服务)是一个开源的使用ANSIC语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。

redis是一个key-value存储系统。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set --有序集合)和hash(哈希类型)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,redis支持各种不同方式的排序。与memcached一样,为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。

一、为什么要使用redis

因为传统的关系型数据库如Mysql已经不能适用所有的场景了,比如秒杀的库存扣减,APP首页的访问流量高峰等等,都很容易把数据库打崩,所以引入了缓存中间件,目前市面上比较常用的缓存中间件有Redis和Memcached,不过中和考虑了他们的优缺点,最后选择了Redis。

在日常的Java Web开发中,无不都是使用数据库来进行数据的存储,由于一般的系统任务中通常不会存在高并发的情况,所以这样看起来并没有什么问题,可是一旦涉及大数据量的需求,比如一些商品抢购的情景,或者是主页访问量瞬间较大的时候,单一使用数据库来保存数据的系统会因为面向磁盘,磁盘读/写速度比较慢的问题而存在严重的性能弊端,一瞬间成千上万的请求到来,需要系统在极短的时间内完成成千上万次的读/写操作,这个时候往往不是数据库能够承受的,极其容易造成数据库系统瘫痪,最终导致服务宕机的严重生产问题。

为了克服上述的问题,Java Web项目通常会引入NoSQL技术,这是一种基于内存的数据库,并且提供一定的持久化功能。Redis和MongoDB是当前使用最广泛的NoSQL,而就Redis技术而言,它的性能十分优越,可以支持每秒十几万次的读/写操作,其性能远超数据库,并且还支持集群、分布式、主从同步等配置,原则上可以无限扩展,让更多的数据存储在内存中,更让人欣慰的是它还支持一定的事务能力,这保证了高并发的场景下数据的安全和一致性。
 

二、redis的数据结构

Redis是一个高性能的key-value数据库,key是字符串类型的,value支持string(字符串)、list(双向链表)、hash(哈希)、set(集合)、zset(sorted set --有序集合)五种数据结构。

1、string

字符串类型可以是简单的字符串、复杂的字符串(xml、json)、数字(整数、浮点数)、二进制(图片、音频、视频), 但最大不能超过512M。

常用命令:(参考:Redis系列教材 (三)- 常见命令

SET key value 设置key=value

GET key 获得键key对应的值

GETRANGE key start end 得到字符串的子字符串存放在一个键

GETSET key value 设置键的字符串值,并返回旧值

GETBIT key offset 返回存储在键位值的字符串值的偏移

MGET key1 [key2..] 得到所有的给定键的值

SETBIT key offset value 给偏移量offset位置上设置value,value只能取值0和1

SETEX key seconds value 键到期时设置值

SETNX key value 设置键的值,只有当该键不存在

SETRANGE key offset value 覆盖字符串的一部分从指定键的偏移

STRLEN key 得到存储在键的值的长度

MSET key value [key value...] 设置多个键和多个值

MSETNX key value [key value...] 设置多个键多个值,只有在当没有按键的存在时

PSETEX key milliseconds value 设置键的毫秒值和到期时间

INCR key 增加键的整数值一次

INCRBY key increment 由给定的数量递增键的整数值

INCRBYFLOAT key increment 由给定的数量递增键的浮点值

DECR key 递减键一次的整数值

DECRBY key decrement 由给定数目递减键的整数值

APPEND key value 追加值到一个键

DEL key 如果存在删除键

DUMP key 返回存储在指定键的值的序列化版本

EXISTS key 此命令检查该键是否存在

EXPIRE key seconds 指定键的过期时间

EXPIREAT key timestamp 指定的键过期时间。在这里,时间是在Unix时间戳格式

PEXPIRE key milliseconds 设置键以毫秒为单位到期

PEXPIREAT key milliseconds-timestamp 设置键在Unix时间戳指定为毫秒到期

KEYS pattern 查找与指定模式匹配的所有键

MOVE key db 移动键到另一个数据库

PERSIST key 移除过期的键

PTTL key 以毫秒为单位获取剩余时间的到期键。

TTL key 获取键到期的剩余时间。

RANDOMKEY 从Redis返回随机键

RENAME key newkey 更改键的名称

RENAMENX key newkey 重命名键,如果新的键不存在

TYPE key 返回存储在键的数据类型的值。

使用场景:用作计数器(如微博数,关注的其他用户数量,粉丝数等),可以使用bitmap(位图)统计用户某段时间登录次数等。

SETBIT key offset value 给偏移量offset位置上设置value,value只能取值0和1,offset类似于数组下标,取值从0开始,从左到右依次递增。比如setbit key 2 1表示将下标为2的位置设置为1,即0 0 1 0 0 0 0 0。

2、list

redis的list类型其实就是每个元素都是String类型的双向链表。我们可以从链表的头部和尾部添加或者删除元素。这样的List既可以作为栈,也可以作为队列使用。

常用命令:(参考:Redis系列教材 (三)- 常见命令

BLPOP key1 [key2 ] timeout 取出并获取列表中的第一个元素,或阻塞,直到有可用

BRPOP key1 [key2 ] timeout 取出并获取列表中的最后一个元素,或阻塞,直到有可用

BRPOPLPUSH source destination timeout 从列表中弹出一个值,它推到另一个列表并返回它;或阻塞,直到有可用

LINDEX key index 从一个列表其索引获取对应的元素

LINSERT key BEFORE|AFTER pivot value 在列表中的其他元素之后或之前插入一个元素

LLEN key 获取列表的长度

LPOP key 获取并取出列表中的第一个元素

LPUSH key value1 [value2] 在前面加上一个或多个值的列表

LPUSHX key value 在前面加上一个值列表,仅当列表中存在

LRANGE key start stop 从一个列表获取各种元素

LREM key count value 从列表中删除元素

LSET key index value 在列表中的索引设置一个元素的值

LTRIM key start stop 修剪列表到指定的范围内

RPOP key 取出并获取列表中的最后一个元素

RPOPLPUSH source destination 删除最后一个元素的列表,将其附加到另一个列表并返回它

RPUSH key value1 [value2] 添加一个或多个值到列表

RPUSHX key value 添加一个值列表,仅当列表中存在

使用场景:如好友队列、粉丝队列、消息队列、最新消息排行等。另外可以通过lrange命令,就是从某个元素开始读取多少个元素,可以基于list实现分页查询,这是很棒的一个功能,基于redis实现简单的高性能分页,可以做类似微博那种下拉不断分页的东西(一页一页的往下走),性能高。

3、hash

Hash是一个String类型的field和value之间的映射表,即redis的hash数据类型key(hash表名称)对应的value实际的内部存储结构为一个HashMap,因此Hash特别适合存储对象。相当于把一个对象的每个属性存储为String类型,将整个对象存储在hash类型中会占用更少内存。

当前HashMap的实现有两种方式:当HashMap的成员比较少时Redis为了节省内存会采用类似一维数组的方式来紧凑存储,而不会采用真正的HashMap结构,这时对应的value的redisObject的encoding为zipmap,当成员数量增大时会自动转成真正的Hashmap,此时encoding为ht.

常用命令:

HDEL key field[field...] 删除对象的一个或几个属性域,不存在的属性将被忽略

HEXISTS key field 查看对象是否存在该属性域

HGET key field 获取对象中该field属性域的值

HGETALL key 获取对象的所有属性域和值

HINCRBY key field value 将该对象中指定域的值增加给定的value,原子自增操作,只能是integer的属性值可以使用

HINCRBYFLOAT key field increment 将该对象中指定域的值增加给定的浮点数

HKEYS key 获取对象的所有属性字段

HVALS key 获取对象的所有属性值

HLEN key 获取对象的所有属性字段的总数

HMGET key field[field...] 获取对象的一个或多个指定字段的值

HSET key field value 设置对象指定字段的值

HMSET key field value [field value ...] 同时设置对象中一个或多个字段的值

HSETNX key field value 只在对象不存在指定的字段时才设置字段的值

HSTRLEN key field 返回对象指定field的value的字符串长度,如果该对象或者field不存在,返回0.

HSCAN key cursor [MATCH pattern] [COUNT count] 类似SCAN命令

应用场景:用一个对象来存储用户信息,商品信息,订单信息等等。

4、set

Redis集合(Set类型)是一个无序的String类型数据的集合,类似List的一个列表,与List不同的是Set不能有重复的数据。实际上,Set的内部是用HashMap实现的,Set只用了HashMap的key列来存储对象。

常用命令:(参考:Redis系列教材 (三)- 常见命令

SADD key member [member ...] 添加一个或者多个元素到集合(set)里

SCARD key 获取集合里面的元素数量

SDIFF key [key ...] 从一个集合中获取另一个集合中不存在的元素,取差集

SDIFFSTORE destination key [key ...] 获得队列不存在的元素,并存储在一个关键的结果集

SINTER key [key ...] 获得两个集合的交集

SINTERSTORE destination key [key ...] 获得两个集合的交集,并存储在一个集合中

SISMEMBER key member 确定一个给定的值是一个集合的成员

SMEMBERS key 获取集合里面的所有key

SMOVE source destination member 移动集合里面的一个key到另一个集合

SPOP key [count] 获取并删除一个集合里面的元素

SRANDMEMBER key [count] 从集合里面随机获取一个元素

SREM key member [member ...] 从集合里删除一个或多个元素,不存在的元素会被忽略

SUNION key [key ...] 合并多个set元素,取并集

SUNIONSTORE destination key [key ...] 合并多个set元素,并将结果存入新的set里面

SSCAN key cursor [MATCH pattern] [COUNT count] 迭代set里面的元素

使用场景:集合有取交集、并集、差集等操作,因此可以求共同好友、共同兴趣、分类标签等。SRANDMEMBER或SPOP命令可以从集合里随机获取一个元素,因此可以用于抽奖活动。

5、sorted set

有序集合和集合有着必然的联系,他保留了集合不能有重复成员的特性,但不同的是,有序集合中的元素是可以排序的,但是它和列表使用索引下标作为排序依据不同的是,它给每个元素设置一个分数,作为排序的依据。(有序集合中的元素不可以重复,但是score可以重复,就和一个班里的同学学号不能重复,但考试成绩可以相同)。

常用命令:

ZADD key score1 member1 [score2 member2] 添加一个或多个成员到有序集合,或者如果它已经存在更新其分数

ZCARD key 得到的有序集合成员的数量

ZCOUNT key min max 计算一个有序集合成员与给定值范围内的分数

ZINCRBY key increment member 在有序集合增加成员的分数

ZINTERSTORE destination numkeys key [key ...] 多重交叉排序集合,并存储生成一个新的键有序集合。

ZLEXCOUNT key min max 计算一个给定的字典范围之间的有序集合成员的数量

ZRANGE key start stop [WITHSCORES] 由索引返回一个成员范围的有序集合(从低到高)

ZRANGEBYLEX key min max [LIMIT offset count]返回一个成员范围的有序集合(由字典范围)

ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT] 返回有序集key中,所有 score 值介于 min 和 max 之间(包括等于 min 或 max )的成员,有序集成员按 score 值递增(从小到大)次序排列

ZRANK key member 确定成员的索引中有序集合

ZREM key member [member ...] 从有序集合中删除一个或多个成员,不存在的成员将被忽略

ZREMRANGEBYLEX key min max 删除所有成员在给定的字典范围之间的有序集合

ZREMRANGEBYRANK key start stop 在给定的索引之内删除所有成员的有序集合

ZREMRANGEBYSCORE key min max 在给定的分数之内删除所有成员的有序集合

ZREVRANGE key start stop [WITHSCORES] 返回一个成员范围的有序集合,通过索引,以分数排序,从高分到低分

ZREVRANGEBYSCORE key max min [WITHSCORES] 返回一个成员范围的有序集合,以socre排序从高到低

ZREVRANK key member 确定一个有序集合成员的索引,以分数排序,从高分到低分

ZSCORE key member 获取给定成员相关联的分数在一个有序集合

ZUNIONSTORE destination numkeys key [key ...] 添加多个集排序,所得排序集合存储在一个新的键

ZSCAN key cursor [MATCH pattern] [COUNT count] 增量迭代排序元素集和相关的分数

使用场景:排行榜:有序集合经典使用场景。例如视频网站需要对用户上传的视频做排行榜,榜单维护可能是多方面:按照时间、按照播放量、按照获得的赞数等。在直播系统中,实时排行信息包含直播间在线用户列表,各种礼物排行榜,弹幕消息(可以理解为按消息维度的消息排行榜)等信息,适合使用Redis中的Sorted Set结构进行存储。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值