redis能做什么?
缓存
缓存机制几乎在所有的大型网站都有使用, 合理地使用缓存不仅可以加快数据的访问速度, 而且能够有效地降低后端数据源的压力。 Redis提供了键值过期时间设置, 并且也提供了灵活控制最大内存和内存溢出后的淘汰策略。 可以这么说, 一个合理的缓存设计能够为一个网站的稳定保驾护航。排行榜系统
排行榜系统几乎存在于所有的网站, 例如按照热度排名的排榜, 按照发布时间的排行榜, 按照各种复杂维度计算出的排行榜, Redis提供了列表和有序集合数据结构, 合理地使用这些数据结构可以很方便地构建各种排行榜系统。计数器应用
计数器在网站中的作用至关重要, 例如视频网站有播放数、 电商网站有浏览数, 为了保证数据的实时性, 每一次播放和浏览都要做加1的操作, 如果并发量很大对于传统关系型数据的性能是一种挑战。 Redis天然支持计数功能而且计数的性能也非常好, 可以说是计数器系统的重要选择。社交网络
赞/踩、 粉丝、 共同好友/喜好、 推送、 下拉刷新等是社交网站的必备功能, 由于社交网站访问量通常比较大, 而且传统的关系型数据不太适合保存这种类型的数据, Redis提供的数据结构可以相对比较容易地实现这些功能。消息队列系统
消息队列系统可以说是一个大型网站的必备基础组件, 因为其具有业务解耦、 非实时业务削峰等特性。 Redis提供了发布订阅功能和阻塞队列的功能, 虽然和专业的消息队列比还不够足够强大, 但是对于一般的消息队列功能基本可以满足。
redis不能做什么?
站在数据规模的角度分析
数据可以分为大规模数据和小规模数据, 我们知道Redis的数据是存放在内存中的, 虽然现在内存已经足够便宜, 但是如果数据量非常大, 例如每天有几亿的用户行为数据, 使用Redis来存储的话, 基本上是个无底洞, 经济成本相当的高。站在数据冷热的角度分析
数据分为热数据和冷数据, 热数据通常是指需要频繁操作的数据, 反之为冷数据, 例如对于视频网站来说, 视频基本信息基本上在各个业务线都是经常要操作的数据, 而用户的观看记录不一定是经常需要访问的数据, 这里暂且不讨论两者数据规模的差异, 单纯站在数据冷热的角度上看, 视频信息属于热数据, 用户观看记录属于冷数据。 如果将这些冷数据放在Redis中, 基本上是对于内存的一种浪费, 但是对于一些热数据可以放在Redis中加速读写, 也可以减轻后端存储的负载, 可以说是事半功倍。
redis API的理解和使用
- 全局命令
查看所有键 keys *
keys*命令会将所有的键输出键总数 dbsize
dbsize命令会返回当前数据库中键的总数。检查键是否存在 exists key
键存在则返回1, 不存在则返回0删除键 del key [key ...]
del是一个通用命令,无论值是什么数据结构类型,del命令都可以将其删除
返回结果为成功删除键的个数, 假设删除一个不存在的键, 就会返回0,同时del命令可以支持删除多个键键过期 expire key seconds
对键添加过期时间, 当超过过期时间后, 会自动删除键
ttl命令会返回键的剩余过期时间, 它有3种返回值:
大于等于0的整数: 键剩余的过期时间
-1: 键没设置过期时间。
-2: 键不存在键的数据结构类型 type key
键hello是字符串类型, 返回结果为string。 键mylist是列表类型, 返回结果为list,键不存在, 则返回none
-
字符窜
字符串类型是Redis最基础的数据结构。 首先键都是字符串类型, 而且其他几种数据结构都是在字符串类型基础上构建的, 所以字符串类型能为其他四种数据结构的学习奠定基础。 如图2-7所示, 字符串类型的值实际可以是字符串(简单的字符串、 复杂的字符串(例如JSON、 XML) ) 、 数字(整数、 浮点数) , 甚至是二进制(图片、 音频、 视频) , 但是值最大不能超过512MB。
设置值 set key value [ex seconds] [px milliseconds] [nx|xx]
为指定键设置值,返回OK代表设置成功,set命令有几个选项:
· ex seconds: 为键设置秒级过期时间。
· px milliseconds: 为键设置毫秒级过期时间。
· nx: 键必须不存在, 才可以设置成功, 用于添加。
· xx: 与nx相反, 键必须存在, 才可以设置成功, 用于更新。
redis还提供了setex和setnx两个命令:setex key seconds value 和 setnx key value,它们的作用和ex和nx选项是一样的获取值 get key
返回键对应的值,如果要获取的键不存在, 则返回nil(空)批量设置值 mset key value [key value ...]
批量获取值 mget key [key ...]
键不存在, 那么它的值为nil(空) , 结果是按照传入键的顺序返回计数
自增 incr key
自减 decr key
自增指定数字 incrby key increment
自减指定数字 decrby key decrement
自增浮点数 incrbyfloat key increment
incr命令用于对值做自增操作, 返回结果分为三种情况:
· 值不是整数, 返回错误。
· 值是整数, 返回自增后的结果。
· 键不存在, 按照值为0自增, 返回结果为1。-
字符窜命令时间复杂度image.png
-
哈希
在Redis中, 哈希类型是指键值本身又是一个键值对结构, 形如value={{field1, value1}, ...{fieldN, valueN}}
哈希类型中的映射关系叫作field-value, 注意这里的value是指field对应的值, 不是键对应的值
设置值 hset key field value
设置成功会返回1, 反之会返回0获取值 hget key field
键或field不存在, 会返回nil删除field hdel key field [field ...]
hdel会删除一个或多个field, 返回结果为成功删除field的个数计算field个数 hlen key
批量设置或获取field-value
hmget key field [field ...]
hmset key field value [field value ...]
hmset和hmget分别是批量设置和获取field-value, hmset需要的参数是key和多对field-value, hmget需要的参数是key和多个field判断field是否存在 hexists key field
存在返回1, 不存在返回0获取所有field hkeys key
hkeys命令应该叫hfields更为恰当, 它返回指定哈希键所有的field获取所有value hvals key
获取所有的field-value hgetall key
在使用hgetall时, 如果哈希元素个数较多, 会存在阻塞Redis的可能。
如果开发人员只需要获取部分field, 可以使用hmget, 如果一定要获取全部field-value, 可以使用hscan命令, 该命令会渐进式遍历哈希类型计数 hincrby key field & hincrbyfloat key field
hincrby和hincrbyfloat, 就像incrby和incrbyfloat命令一样, 但是它们的作用域是filed。
11.计算value的字符串长度 hstrlen key field
12.哈希类型命令的时间复杂度
-
列表
列表(list) 类型是用来存储多个有序的字符串, 例如 a、b、 c、 d、 e五个元素从左到右组成了一个有序的列表, 列表中的每个字符串称为元素(element) , 一个列表最多可以存储2^32-1个元素。 在Redis中, 可以对列表两端插入(push) 和弹出(pop) , 还可以获取指定范围的元素列表、 获取指定索引下标的元素等 。 列表是一种比较灵活的数据结构, 它可以充当栈和队列的角色, 在实际开发上有很多应用场景。
列表类型有两个特点:
第一, 列表中的元素是有序的, 可以通过索引下标获取某个元素或者某个范围内的元素列表
第二,列表中的元素可以是重复的
添加操作
从右边插入元素 rpush key value [value ...]
从左边插入元素 lpush key value [value ...]
向某个元素前或者后插入元素 linsert key before|after pivot value
linsert命令会从列表中找到等于pivot的元素, 在其前(before) 或者后(after) 插入一个新的元素value。如果命令执行成功,返回插入操作完成之后,列表的长度。 如果没有找到指定元素 ,返回 -1 。如果 key 不存在或为空列表,返回 0 。-
查找
① 获取指定范围内的元素列表 lrange key start end
lrange操作会获取列表指定索引范围所有的元素。 索引下标有两个特点:
第一, 索引下标从左到右分别是0到N-1, 但是从右到左分别是-1到-N。
第二, lrange中的end选项包含了自身, 这个和很多编程语言不包含end不太相同② 获取列表指定索引下标的元素 lindex key index
③ 获取列表长度 llen key
-
删除
① 从列表左侧弹出元素 lpop key
② 从列表右侧弹出元素 rpop key
③ 删除指定元素 lrem key count value
lrem命令会从列表中找到等于value的元素进行删除, 根据count的不同分为三种情况:
· count>0, 从左到右, 删除最多count个元素。
· count<0, 从右到左, 删除最多count绝对值个元素。
· count=0, 删除所有。④ 按照索引范围修剪列表 ltrim key start end
对一个列表进行修剪(trim),就是说,让列表只保留指定区间内的元素,不在指定区间之内的元素都将被删除。 修改
修改指定索引下标的元素 lset key index newValue阻塞操作
blpop key [key ...] timeout
brpop key [key ...] timeout
blpop和brpop是lpop和rpop的阻塞版本, 它们除了弹出方向不同, 使用方法基本相同(执行流程详细分析看113页)-
列表命令时间复杂度图片.png
-
集合
集合(set) 类型也是用来保存多个的字符串元素, 但和列表类型不一样的是,集合中不允许有重复元素, 并且集合中的元素是无序的, 不能通过索引下标获取元素。一个集合最多可以存储2^32-1个元素。 Redis除了支持集合内的增删改查,同时还支持多个集合取交集、 并集、 差集, 合理地使用好集合类型, 能在实际开发中解决很多实际问题。
-
集合内操作
① 添加元素 sadd key element [element ...]
返回结果为添加成功的元素个数② 删除元素 srem key element [element ...]
返回结果为成功删除元素个数③ 计算元素个数 scard key
scard的时间复杂度为O(1) , 它不会遍历集合所有元素, 而是直接用Redis内部的变量④ 判断元素是否在集合中 sismember key element
如果给定元素element在集合内返回1, 反之返回0⑤ 随机从集合返回指定个数元素 srandmember key [count]
[count]是可选参数, 如果不写默认为1⑥ 从集合随机弹出元素 spop key & srandmember key
从3.2版本开始, spop也支持[count]参数。
srandmember和spop都是随机从集合选出元素, 两者不同的是spop命令执行后, 元素会从集合中删除, 而srandmember不会。⑦ 获取所有元素 smembers key
返回结果是无序的。smembers 和 lrange、 hgetall都属于比较重的命令, 如果元素过多存在阻塞Redis的可能性, 这时候可以使用sscan来完成 集合间操作
暂略-
集合常用命令时间复杂度图片.png
-
有序集合
有序集合相对于哈希、 列表、 集合来说会有一点点陌生, 但既然叫有序集合, 那么它和集合必然有着联系, 它保留了集合不能有重复成员的特性,但不同的是, 有序集合中的元素可以排序。 但是它和列表使用索引下标作为排序依据不同的是, 它给每个元素设置一个分数(score) 作为排序的依据。(有序集合中的元素不能重复, 但是score可以重复) 有序集合提供了获取指定分数和元素范围查询、 计算成员排名等功能, 合理的利用有序集合, 能帮助我们在实际开发中解决很多问题。
-
集合内
(1) 添加成员 zadd key score member [score member ...]
返回结果代表成功添加成员的个数
有关zadd命令有两点需要注意:
·Redis3.2为zadd命令添加了nx、 xx、 ch、 incr四个选项:
·nx: member必须不存在, 才可以设置成功, 用于添加。
·xx: member必须存在, 才可以设置成功, 用于更新。
·ch: 返回此次操作后, 有序集合元素和分数发生变化的个数
·incr: 对score做增加, 相当于后面介绍的zincrby。
有序集合相比集合提供了排序字段, 但是也产生了代价, zadd的时间复杂度为O(log(n)) , sadd的时间复杂度为O(1) 。(2) 计算成员个数 zcard key
和集合类型的scard命令一样, zcard的时间复杂度为O(1) 。(3) 计算某个成员的分数 zscore key member
不存在则返回nil(4) 计算成员的排名 zrank key member & zrevrank key member
zrank是从分数从低到高返回排名, zrevrank反之。(5) 删除成员 zrem key member [member ...]
返回结果为成功删除的个数。( 6) 增加成员的分数 zincrby key increment member
( 7) 返回指定排名范围的成员
zrange key start end [withscores]
zrevrange key start end [withscores]
有序集合是按照分值排名的, zrange是从低到高返回, zrevrange反之。加上withscores选项, 同时会返回成员的分数( 8) 返回指定分数范围的成员
zrangebyscore key min max [withscores] [limit offset count]
zrevrangebyscore key max min [withscores] [limit offset count]
其中zrangebyscore按照分数从低到高返回, zrevrangebyscore反之。withscores选项会同时返回每个成员的分数。 [limit offset count]选项可以限制输出的起始位置和个数
同时min和max还支持开区间( 小括号) 和闭区间( 中括号) , -inf和+inf分别代表无限小和无限大( 9) 返回指定分数范围成员个数 zremrangebyrank key start end
( 10) 删除指定排名内的升序元素 zremrangebyrank key start end
( 11) 删除指定分数范围的成员 zremrangebyscore key min max
集合间的操作
暂略-
有序集合命令的时间复杂度图片.png
-
键管理
待续