string
- 常用命令
set key value | 设置 key-value 类型的值 |
setnx key value | 如果存在key不会设置成功 |
get key | 根据 key 获得对应的 value |
set key value ex 10 | 设置数据10s后过期 |
strlen key | 查看字符串长度 |
append key value | 会在name后面拼接 |
mset key1 value1 key2 value2 | 设置多个key value |
mget key1 key2 | 获取多个值 |
incr key | 值加一 |
decr key | 值减一 |
incrby key 10 | 获取累加后的value |
decrby key 10 | 获取累减后的值 |
getrange key 0 -1 | 截取 |
setrange key 1 value | 用abc替换值下标从1开始的3个值 |
- 使用场景
字符串类型的使用场景:信息缓存、计数器、分布式锁等等。
- 实战场景:记录每一个用户的访问次数,或者记录每一个商品的浏览次数
常用键名: userid:pageview 或者 pageview:userid,如果一个用户的id为123,那对应的redis key就为pageview:123,value就为用户的访问次数,增加次数可以使用命令:incr。
使用理由:每一个用户访问次数或者商品浏览次数的修改是很频繁的,如果使用mysql这种文件系统频繁修改会造成mysql压力,效率也低。而使用redis的好处有二:使用内存,很快;单线程,所以无竞争,数据不会被改乱。
- 实战场景:缓存频繁读取,但是不常修改的信息,如用户信息,视频信息
业务逻辑上:先从redis读取,有值就从redis读取,没有则从mysql读取,并写一份到redis中作为缓存,注意要设置过期时间。
键值设计上:直接将用户一条mysql记录做序列化(通常序列化为json)作为值,userInfo:userid 作为key,键名如:userInfo:123,value存储对应用户信息的json串。如 key为:“user:id :name:1”, value为"{“name”:“leijia”,“age”:18}"。
- 实战场景:限定某个ip特定时间内的访问次数
用key记录IP,value记录访问次数,同时key的过期时间设置为60秒,如果key过期了则重新设置,否则进行判断,当一分钟内访问超过100次,则禁止访问。
- 实战场景:分布式session
我们知道session是以文件的形式保存在服务器中的;如果你的应用做了负载均衡,将网站的项目放在多个服务器上,当用户在服务器A上进行登陆,session文件会写在A服务器;当用户跳转页面时,请求被分配到B服务器上的时候,就找不到这个session文件,用户就要重新登陆。
如果想要多个服务器共享一个session,可以将session存放在redis中,redis可以独立于所有负载均衡服务器,也可以放在其中一台负载均衡服务器上;但是所有应用所在的服务器连接的都是同一个redis服务器。
hash
- 常用命令
hmset key key1 value1 | 设置多个key-value |
hmget key key1 key2 | 查询多个值 |
hgetall key | 打印所有key-value |
hlen key | 查看user里面包含多少属性 |
hkey key | 打印user里面所有key |
hvals key | 打印user里面所有value |
hincrby user age 3 | 打印(integer) 21 |
hincrbyfloat user age 2.2 | 打印"23.2" |
hexists user age | 查看属性是否存在 1存在 0返回 |
hdel user name | 删除属性 |
- 使用场景
系统中对象数据的存储
- 实战场景:购物车
以购物车为例子,用户id设置为key,那么购物车里所有的商品就是用户key对应的值了,每个商品有id和购买数量,对应hash的结构就是商品id为field,商品数量为value
当对象的某个属性需要频繁修改时,不适合用string+json,因为它不够灵活,每次修改都需要重新将整个对象序列化并赋值;如果使用hash类型,则可以针对某个属性单独修改,没有序列化,也不需要修改整个对象。比如,商品的价格、销量、关注数、评价数等可能经常发生变化的属性,就适合存储在hash类型里。
list
- 常用命令
lpush list1 a b c d e | 从左边开始放入元素 |
lrange list1 0 -1 | 查看列表中的所有元素 |
rpush list2 a b c d e | 从右边开始放入元素 |
del list1 | 删除 |
- 使用场景
定时排行榜
- 实战场景:定时排行榜
list类型的lrange命令可以分页查看队列中的数据。可将每隔一段时间计算一次的排行榜存储在list类型中,如QQ音乐内地排行榜,每周计算一次存储再list类型中,访问接口时通过page和size分页转化成lrange命令获取排行榜数据。
并不是所有的排行榜都能用list类型实现,只有定时计算的排行榜才适合使用list类型存储,与定时计算的排行榜相对应的是实时计算的排行榜,list类型不能支持实时计算的排行榜,下面介绍有序集合sorted set的应用场景时会详细介绍实时计算的排行榜的实现。
set
- 常用命令
sadd set value1 value2 | 添加元素,不重复 |
smembers set | 查看 set 中所有的元素 |
scard set | 查看 set 的长度 |
sismember set a | 检查某个元素是否存在set 中,只能接收单个元素 |
srem set a | 删除元素 |
spop set 2 | 取出两个元素 |
smove set1 set2 a | 把a从set1移动到set2中 |
sdiff set1 set2 | 区差集 |
sinter set1 set2 | 取交集 |
sunion set1 | 取并集 |
- 使用场景
需要存放的数据不能重复以及需要获取多个数据源交集和并集等场景
- 实战场景:收藏夹
例如QQ音乐中如果你喜欢一首歌,点个『喜欢』就会将歌曲放到个人收藏夹中,每一个用户做一个收藏的集合,每个收藏的集合存放用户收藏过的歌曲id。
key为用户id,value为歌曲id的集合。
zset
- 常用命令
zadd zset 10 a 20 b 30 c 40 d 50 e | 添加多个元素 |
zrange zset 0 -1 | 获取所有元素 |
zadd zset 25 bc 35 cd | 查看元素 a、b、bc、c、cd、d、e |
zrank zset c | 获取元素c在zset中的下标 |
zscore zset c | 获取元素c所占分数 |
zcard | 查看zset中元素数量 |
zcount zset 20 40 | 获取分数在20到40之间的元素包含边界 不包含边界:(20 (40 大于20 小于40 |
zrangebyscore zset 20 40 | 获取分数在20到40之间的元素包含边界 |
zrangebyscore zset 20 40 limit 1 10 | 从下标1开始后10项 |
zrem zset a b | 删除 |
- 使用场景
需要对数据根据某个权重进行排序的场景。比如在直播系统中,实时排行信息包含直播间在线用户列表,各种礼物排行榜,弹幕消息(可以理解为按消息维度的消息排行榜)等信息。
- 实战场景:实时排行榜
QQ音乐中有多种实时榜单,比如飙升榜、热歌榜、新歌榜,可以用redis key存储榜单类型,score为点击量,value为歌曲id,用户每点击一首歌曲会更新redis数据,sorted set会依据score即点击量将歌曲id排序。