redis的api使用

Redis Api

Posted by zwtisme on August 21, 2018

介绍redis中数据结构及api的使用。

前言

1.数据结构与内部编码

redis主要包含5种数据结构,每种数据结构的内部编码可能有多个,redis会根据实际使用情况选择合适的编码,来优化内存与性能。

#数据结构
127.0.0.1:6379[1]> type k_string
string

#内部编码
127.0.0.1:6379[1]> OBJECT encoding k_string
"int"

数据结构与内部编码对应关系。

Tips:内部编码的限定条件,可能会根据redis的不同版本有所调整或者增加新的内部编码,这里的版本为3.0.7。redis里中文占3个字节。

数据结构 内部编码 备注 优点 缺点
string int 8个字节的长整型
embstr 小于等于39个字节的字符串
raw 大于39个字节的字符串
hash ziplist
(压缩列表)
元素个数小于hash-max-ziplist-entries配置(默认512个),同时所有值都小于hash-max-ziplist-value配置(默认64字节) 节省内存 读写效率不足
hashtable
(哈希表)
不满足ziplist条件时 读写为o(1)
list ziplist
(压缩列表)
元素个数小于list-max-ziplist-entries配置(默认512个),同时所有值都小于list-max-ziplist-value配置(默认64字节) 节省内存
linkedlist
(链表)
不满足ziplist条件时
set intset
整数集合
元素都是整数且元素个数小于set-maxintset-entries配置(默认512个) 节省内存
hashtable
(哈希表)
不满足intset条件时
zset ziplist 元素个数小于zset-max-ziplist-entries配置(默认128个),同时每个元素的值都小于zset-max-ziplist-value配置(默认64字节) 节省内存
skiplist 不满足ziplist条件时

2.单线程

redis使用的是单线程与I/O多路复用模式,所有到服务器的命令都会进行排队然后逐个执行,所以需要特别注意每个命令的执行时间,因为可能会阻塞其它命令的执行。

redis高性能因素:

  • 纯内存访问,内存响应时间100纳秒左右
  • 非阻塞I/O,使用epoll作为I/O多路复用技术的实现,再加上 redis自身的事件处理模型将epoll中的连接、读写、关闭都转换为事件,不 在网络I/O上浪费过多的时间
  • 避免线程切换与竞态产生的消耗

字符串

字符串是最基础的数据结构,字符串的值可以是字符串(简单的字符串、复杂的字符串(例如JSON、XML))、数字(整数、浮点数),甚至是二进制(图片、音频、视频),但是值最大不能超过512MB

1.常用命令

命令类型 命令格式 备注 复杂度 官方说明
增/改 set key value [EX seconds] [PX milliseconds] [NX|XX] 设置键的值 o(1) link
getset key value 设置键的值,返回原值 o(1) link
mset key value [key value ...] 设置多个键值对 o(n) link
setrange key offset value 替换键的值 o(1)/o(m) link
append key value 追加键的值 o(1) link
del key [key ...] 删除键,阻塞 o(n) link
unlink key [key ...] 删除键,非阻塞 o(n) link
get key 获取键的值 o(1) link
mget key [key ...] 获取多个键的值 o(n) link
其它 incr key 键的值加1 o(1) link
incrby key increment 键的值加给定值,整数 o(1) link
incrbyfloat key increment 键的值加给定值,浮点数 o(1) link
decr key 键的值减1 o(1) link
decrby key 键的值减给定值 o(1) link
strlen key 获取键的值长度 o(1) link

2.使用场景

数据缓存

将redis作为缓存层,mysql作为存储层,可以加速读写,降低数据库的压力。

一般思路,如果缓存有读缓存,缓存没有从库里读取后返回数据,同时将数据放入缓存+过期时间,等待下次的数据访问。

计数

可用于记录商品被查看的次数、视频观看次数等,异步将统计数据同步到存储层。

session共享

目前大多数的web网站都会使用负载均衡来提高网站的可用性与并发量,如果session存储在各自服务器上的话,可能就会导致用户在A服务器存的session,当用户访问到B服务器时找不到session的情况。

可将用户的session信息存储到redis中,在redis是高可用的情况下,无论用户访问的是哪台服务器,都可以获取到session信息。

token共享

对于像微信token这种每天有获取上限的token,需要将token记录到涉及web应用都可以访问到的地方,使用redis记录是一个不错的选择。

限流

为了防止接口被恶意调用,或者对于某些接口在一定时间范围内有调用限制,可使用redis的带过期时间的数值key来处理。

哈希

哈希结构也可以叫做字典、关联数组等,键的值是(field-value)的映射关系。

1.常用命令

命令类型 命令格式 备注 复杂度 官方说明
增/改 hset key field value 设置键的field-value,单个 o(1) link
hmset key field value [field value ...] 设置键的field-value,多个 o(n) link
hsetnx key field value 设置键的field-value,当field不存在时 o(1) link
hdel key field [field ...] 删除键的field o(n) link
hget key field 获取键的field-value,单个field o(1) link
hmget key field [field ...] 获取键的field-value,多个field o(n) link
hgetall key 获取键的field-value,所有field
此命名为重命令,控制获取元素个数
o(n) link
hkeys key 获取键的所有field o(n) link
hvals key 获取键的所有field对应的value o(n) link
其它 hexists key field 判断键是否存在field o(1) link
hincrby key field increment 键的field对应value加给定值,整数 o(1) link
hincrbyfloat key field increment 键的field对应value加给定值,浮点数 o(1) link
hlen key 获取键中field数 o(1) link
hstrlen key field 获取键的field对应value的长度 o(1) link
hscan key cursor [MATCH pattern] [COUNT count] 递归获取键的field-value o(1)/o(n) link

2.使用场景

商品/用户信息

一般商品/用户信息会有多个属性,如果只许调整某些属性值,可以比较方便。

列表

列表用来存储有序的可重复的字符串,根据使用方式可实现栈或队列的功能。

1.常用命令

命令类型 命令格式 备注 复杂度 官方说明
增/改 lpush key value [value ...] 向队列的左边插入元素 o(n) link
lpushx key value 向队列的左边插入元素,当队列不存在 o(1) link
rpush key value [value ...] 向队列的右边插入元素 o(n) link
rpushx key value 向队列的右边插入元素,当队列不存在 o(1) link
lset key index value 设置队列某个位置的元素 o(1)/o(n) link
linsert key BEFORE|AFTER pivot value 在队列某个元素的前面或后面插入元素 o(1)/o(n) link
lpop key 从队列左边弹出一个元素 o(1) link
rpop key 从队列右边弹出一个元素 o(1) link
lrem key count value 从队列的左边或右边删除指定个数的给定元素 o(n) link
ltrim key start stop 按索引范围裁剪队列 o(n) link
lindex key index 获取索引位置的元素 o(n) link
lrange key start stop 获取索引范围的元素
此命名为重命令,控制获取元素个数
o(n) link
其它 llen key 队列中元素的个数 o(1) link

2.使用场景

lpush+lpop,向列表的一端插入数据,再从同样一端获取数据。

队列

lpush+rpop,向列表的一端插入数据,再从另外一端获取数据。

有限集合

lpush+ltrim,向列表的一端插入数据,获取当前列表中的记录数,当记录数超过限定值时,截断列表。

消息队列

lpush+brpop,向列表的一端插入数据,再从另外一端阻塞获取数据。

集合

集合用来存储无序的不可重复的字符串,多个集合可取交集、并 集、差集。

1.常用命令

命令类型 命令格式 备注 复杂度 官方说明
增/改 sadd key member [member ...] 向集合插入元素 o(n) link
srem key member [member ...] 从集合删除元素 o(n) link
spop key [count] 从集合弹出一个元素 o(1) link
smove source destination member 将元素从一个集合转移到另一个集合 o(1) link
srandmember key [count] 从集合中返回随机元素 o(1)/o(n) link
smembers key 从集合中返回所有元素
此命名为重命令,控制获取元素个数
o(n) link
其它 scard key 集合中元素的个数 o(1) link
sismember key member 集合中是否存在某个元素 o(1) link
sscan key cursor [MATCH pattern] [COUNT count] 递归获取集合的元素 o(1)/o(n) link
集合 sinter key [key ...] 获取集合的交集 o(1) link
sinterstore destination key [key ...] 获取集合的交集,并保存 o(n*m) link
sunion key [key ...] 获取集合的并集 o(n) link
sunionstore destination key [key ...] 获取集合的并集,并保存 o(n) link
sdiff key [key ...] 获取集合的差集 o(n) link
sdiffstore destination key [key ...] 获取集合的差集,并保存 o(n) link

2.使用场景

用户标签

sadd,记录用户喜欢的标签,标签被哪些用户喜欢。

抽奖

sadd+spop/srandmember,从所有id中获取随机值。

社交

sadd+sinter,获取不同用户相同的标签。

有序集合

有序集合用来存储有序的不可重复的字符串,使用score来进行排序。

1.常用命令

命令类型 命令格式 备注 复杂度 官方说明
增/改 zadd key [NX|XX] [CH] [INCR] score member [score member ...] 向集合插入元素 o(log(n)) link
zrem key member [member ...] 从集合删除元素 o(m*log(n)) link
zremrangebyrank key start stop 从集合删除指定排序范围的元素 o(m*log(n)) link
zremrangebyscore key min max 从集合删除指定分数范围的元素 o(m*log(n)) link
zremrangebylex key min max 从集合删除指定元素秩范围的元素 o(m*log(n)) link
zrange key start stop [WITHSCORES] 返回指定排序范围的元素(由低到高) o(log(n)+m) link
zrangebyscore key min max [WITHSCORES] [LIMIT offset count] 返回指定分数范围的元素(由低到高) o(log(n)+m) link
zrangebylex key min max [LIMIT offset count] 返回指定元素秩范围的元素个数(由低到高) o(log(n)+m) link
zrevrange key start stop [WITHSCORES] 返回指定排序范围的元素(由高到低) o(log(n)+m) link
zrevrangebyscore key max min [WITHSCORES] [LIMIT offset count] 返回指定分数范围的元素(由高到低) o(log(n)+m) link
zrevrangebylex key max min [LIMIT offset count] 返回指定元素秩范围的元素个数(由高到低) o(log(n)+m) link
其它 zcard key 集合中元素的个数 o(1) link
zcount key min max 返回指定分数范围的元素个数 o(log(n)) link
zincrby key increment member 增加集合中元素的分值 o(log(n)) link
zlexcount key min max 返回分数范围内的元素个数 o(log(n)) link
zrank key member 返回元素的排名(由低到高) o(log(n)) link
zrevrank key member 返回元素的排名(由低到高) o(log(n)) link
zscan key cursor [MATCH pattern] [COUNT count] 递归获取集合中的元素 o(1)/o(n) link
集合 zinterstore destination numkeys key [key ...]
[WEIGHTS weight] [AGGREGATE SUM|MIN|MAX]
获取集合的交集 o(n*k)+o(m*log(n))  link
zunionstore destination numkeys key [key ...]
[WEIGHTS weight] [AGGREGATE SUM|MIN|MAX]
获取集合的并集 o(n*k)+o(m*log(n))  link

2.使用场景

排行榜

如游戏中可以按照各种维度提供排行的功能。

redis中不管值是什么数据结构,它们的键一样都是字符串,对于键的管理也有相关方法。

1.常用命令

命令格式 备注 复杂度 官方说明
del key [key ...] 删除键值对,阻塞 o(n) link
unlink key arg ...options... 删除键值对,非阻塞 o(n) link
exists key [key ...] 键是否存在 on) link
expire key seconds 设置键的过期时间,秒 o(1) link
pexpire key milliseconds 设置键的过期时间,毫秒 o(1) link
expireat key timestamp 设置键在何时过期,秒 o(1) link
pexpireat key milliseconds-timestamp 设置键在何时过期,毫秒 o(1) link
persist key 移除键的过期时间 o(1) link
ttl key 获取键的过期时间,秒 o(1) link
pttl key 获取键的过期时间,毫秒 o(1) link
rename key newkey 重命名键 o(1) link
renamenx key newkey 重命名键,newkey不存在 o(1) link
type key 键的数据结构 o(1) link
object encoding [arguments [arguments ...]] 键的内部编码 o(1) link
keys pattern 模糊匹配键,阻塞 o(n) link
scan cursor [MATCH pattern] [COUNT count] 模糊匹配键,不阻塞,渐进式 o(1)/o(n) link

参考资料

redis command

redis

phpredis

redis开发与运维