Redis的数据结构指的是键值对中的值。
1.全局命令
key * 查看所有的键,遍历所有的键,O(n),键很多的情况下,线上环境禁止使用。
dbsize 键总数,直接读取Redis内键总数变量,O(1)。
exists key 检查键是否存在,1-存在 0-不存在。
del [key...] 通用的删除命令不区分数据类型,成功-返回删除键的个数,0-删除的键不存在。
expire key seconds 设置键的过期时间,ttl 返回剩余过期时间,>=0 剩余过期时间,-1没设置过期时间,-2键不存在
type key 键的数据结构类型,none不存在。
object encoding 内部编码
2.单线程架构
单线程架构+I/O多路复用模型来实现高性能的内存数据服务
客户端的调用需要经过发送命令、执行命令和返回结果。执行命令的时候,将客户端发送的命令放入到一个队列当中,然后逐个的被执行,命令的执行顺序无法保证但是确定不会有两个命令会被同时执行。
3.单线程架构为什么这么快
a.纯内存的访问,Redis将所有的数据都放在内存中。
b.非阻塞I/O,redis使用epoll作为I/O多路复用技术的实现,在加上Redis自身的事件处理模型将链接、读写和关闭都转换为事件驱动,减少网络I/O的时间。
c.单线程避免了线程切换和竞态产生的消耗,简化数据结构和算法的实现。
如果单个命令执行时间过长会阻塞其他命令。
一、字符串
键都是字符串类型,字符串类型可以是简单的字符串,复杂的JSON XML、数字(整数 浮点数)、二进制(图片 音频 视频),值最大不能超过512MB。
1.命令
set key value [ex seconds] [px milliseconds] [nx|xx]
get key
mset key value [key value]
mget key [key ...] 一次的网络时间+n次的命令执行时间
incr key 键不存在时按照值为0自增,返回结果为1。decr incrby decrby incrbyfloat
strlen key
getset key value
setrange key offeset value
getrange key start end
2.内部编码
int 8 byte的长整型
embstr 小于等于39个Byte的字符串
raw 大于39个Byte的字符串
3.典型的使用场景
缓存功能:键名,"业务名:对象名:id:[属性]",减小键的长度
计数:视频播放计数
分布式下的共享session:将用户的session进行集中管理
限速:限制用户每分钟获取验证码的频率
二、哈希
是指键值本身又是一个键值对结构,映射关系field-value,这里的value是指field对应的值,不是键对应的值。
1.命令
set key field value
hsetnx 作用的域是field而不是key
hget key field
hdel key field [field...]
hlen key 计算field的个数
hmest key field value [field value ....]
hmget key field [field ..]
hexists key field 判断field是否存在
hkeys key 应该叫hfields,返回的是所有的field
hvals key 返回所有的value
hgetall key 获取所有的field-value,在使用的时候如果存在哈希元素的个数比较多,会存在阻塞Redis的可能,可以使用hscan,会渐进式的遍历哈希类型
hincrby key field
hincrbyfloat key field
hstrlen key field 计算value字符串的长度
2.内部编码
ziplist:当哈希类型元素个数小于hash-max-ziplist-entries(默认512) && 所有值都小于hash-max-ziplist-value(默认64字节),会使用ziplist作为哈希的内部实现,使用更加紧凑的结构实现多个元素的连续存储,更加的节省内存。
hashtable:读写时间复杂度是O(1)。
3.使用场景
缓存用户的信息
也可以使用 原生的字符串类型,序列化字符串类型。
三、列表
最多可以存储2的32次幂 - 1个元素,可以对两端进行push和pop,列表中的元素都是有序的可以获取指定范围的元素列表,获取指定索引下标的元素,列表中的元素可以重复。
1.命令
添加:rpush lpush linsert
查:lrange lindex llen
删除:lpop rpop lrem ltrim
修改:lset
阻塞操作:blpop brpop
2.内部编码
ziplist:当列表元素个数小于hash-max-ziplist-entries(默认512) && 列表中每个元素的值都小于hash-max-ziplist-value(默认64字节)
linkedlist:
在3.2的版本中提供了quickLsit内部编码,是一个以zipList为节点的linkedlist
3.使用场景
消息队列:lpush+brpop组合实现阻塞队列
文章列表:将文章的内容存储到hash中,列表中添加文章,分页获取文章列表。但是每次分页获取文章的个数较多的时候,需要多次执行hgetall,可以考虑使用Pipeline批量操作获取,或者将文章的数据序列化为字符串类型在使用mget批量获取。做分页查询的时候在列表的两端性能较好,获取中间范围的元素性能会变差,此时可以考虑做二级拆分,或者使用quickList。
四、集合
保存多个的字符串元素,不允许有重复的元素,集合中的元素是无序的,不能通过索引下标获取元素,一个集合中最多存储2的32次幂-1个元素
1,命令
sadd key element
srem key elemen
scard key 计算元素的个数
sismember key element 判断元素是否在集合中
srandmember key [count] 返回指定个数元素,不删除
spop key 从集合中随机弹出元素,并删除元素
smembers key 获取所有元素,返回结果是无序的,元素过多时不建议使用,sscan来代替
sinter key [key ..] 多个集合的交集
sunion key [key ...] 并集
sdiff key [key ...] 差集
保存结果集
sinterstore destination key [key ...]
sunionstore destination key [key ...]
sdiffstore destination key [key ...]
2.内部编码
intset 整数集合:元素是整数 && 元素个数小于set-max-intset-entries 配置(默认512)
hashtable
3.使用场景
标签
生成随机数,比如抽奖
社交需求
五、有序集合
集合不能有重复的元素,集合中的元素可以排序,给每个元素设置一个分数,作为排序的依据,分数可以重复。
1.命令
zadd key score member [ ...] O(logn)
zcard key 计算成员个数
zscore key member 计算某个成员的分数
zrank key member 从低到高
zrevrank
zrem key member [member ..]
zincrby key increment member
zrange key start end [withscore] zrevrange
2.内部编码
ziplist:128 && 64
跳表
3.使用场景
排行榜系统
添加用户赞数