redis 常用api的理解和使用

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/m0_37719047/article/details/102519588

预备

redis全局命令

查看所有的键: keys *
键总数:dbsize
检查键是否存在:exists key
删除键:del key
键过期:expire key second,其中ttl 命令会返回键的剩余时间
键的数据结构类型:type key

数据结构和内部编码

type命令实际返回的是当前键的数据结构类型,他们分别是string,hash,list,set,zset但是这只是redis对外的数据结构.
实际上每种数据结构都有着自己的底层内部编码实现,而且是多种实现,这样redis会在合适的场景下选择合适的内部编码.

redis这样的实现有两种好处,

  • 第一:可以改进内部编码,而对外的数据结构和命令没有影响,这样一旦开发出更加优秀的内部编码,无需改动外部数据结构和命令
  • 多种内部编码实现可以在不同场景下发挥各自的优势

单线程架构

redis使用了单线程架构和I/O多路复用模型来实现高性能的内存数据库服务
redis客户端和服务端的调用会经历如下三个阶段:发送命令,执行命令,返回命令在这里插入图片描述因为redis是单线程来处理命令的,所以一条命令从客户端到达服务端不会立即被执行,所有命令都会进入到一个队列中,然后逐个被执行,所以客户端命令执行的顺序是不确定的,但是可以确定不会有两条命令同时被执行

为什么单线程访问还能够这么快:

  • 纯内存访问
  • 非阻塞IO
  • 单线程避免了线程切换和竞态产生的开销
    单线程机制会带来很多的好处,但是对于每个命令的执行时间是有要求的,如果某个命令的执行时间过长,会造成其他命令的阻塞,所有redis是面向快速执行的场景设计的数据库

字符串

字符串类型是redis最基础的数据结构,首先键都是字符串类型的,而且其他几种数据结构都是在字符串类型的基础上构建的,所以字符串类型能够为其他四种数据结构的学习奠定基础,字符串类型的值可以是字符串,数字甚至是二进制文件,但是值最大不能超过512兆

常用命令

  • 设置值:
    set key value [ex|px] [nx|xx]
    ex 为键设置秒级过期时间
    px 为键设置毫秒级过期时间
    nx 键必须不存在才能够设置成功,用于添加
    xx 键必须存在,才能够设置成功,用于更新
    setnx用于实现分布式锁:多个客户端同时执行setnx只有一个能够实现成功
  • 获取值:
    get key
  • 批量设置值
    mset key value [key value … ]
  • 批量获取值
    mget key [key …]
    如果有些键不存在,那么他的值为空,结果是按照传入键的顺序返回
    批量操作可以有效的提高开发效率,加入没有mget这样的命令,要执行n次get需要消耗大量的网络和硬件开销
    学会使用批量操作,有助于提高业务执行效率,但是注意的是每次的批量操作所发送的命令数量是是有节制的,如果数量过多会造成redis阻塞或者网络阻塞
  • 计数
    incr(自增),decr(自减),incrby(自增指定数字),decrby(自减指定数字) incrfloat(自增浮点数)

内部编码

字符串类型的内部编码有三种,

  • int:8字节的长整形
  • embstr 小于等于39字节的字符串
  • raw 大于39字节的字符串

典型使用场景

缓存功能

使用redis作为缓存层,mysql作为存储层,绝大部分请求的数据都从redis数据都从redis中获取,由于redis具有支撑高并发的特性,所以缓存通常能够起到加速读写和降低后端压力的作用

在这里插入图片描述在这里插入图片描述

计数

许多应用都会使用redis作为计数的基础工具,他可以实现快速计数,查询缓存的功能,同时可以异步的落到其他数据源

在这里插入图片描述

共享session

一个分布式web服务器将用户的sesision信息保存在各自的服务器中,这样会造成一个问题,处于负载均衡的考虑,分布式服务器会将用户的访问均衡到不同的服务器上,用户刷新一次会发现需要重新登录,为了解决这个问题,可以使用redis将用户的session进行集中管理,只要保证redis是高可用和可拓展的,每次用户更新或者查询登录信息都直接从redis中集中获取
在这里插入图片描述

哈希

在redis中,哈希类型是指键值本身又是一个键值对结构,

哈希类型中的映射关系叫做field-value,注意这里的value是指field对应的值,不是键对应的值

命令

设置值:hset key field value
获取值:hget key field
删除field:hdel key field [field …]
计算field个数:hlen key
批量设置或获取field-value:
hmget key field [field …]
hmset key field value [field value …]
判断field是否存在:hexists key field
获取所有的field:hkeys key
获取所有的value:hvals key

内部编码

ziplist 压缩列表:当哈希类型元素个数小于配置并且所有值都小于配置时,redis会使用ziplist作为哈希的内部实现
hashtable 哈希表:当无法满足ziplist时,redis会使用hashtable作为哈希的内部实现

列表

列表是用来存储多个有序的字符串,列表中的每个字符串称为元素,一个列表可以存储2^32-1个元素,可以对列表两端插入和弹出,还可以获取指定范围的元素列表,获取制定索引下标的元素,列表是一种比较灵活的数据结构,他可以充当队列和栈的角色
在这里插入图片描述列表类型有两个特点

  • 列表中的元素是有序的
  • 列表中的元素是可以重复的

命令

在这里插入图片描述从右侧插入元素
rpush key value [value …]
从左侧插入元素
lpush key value [value …]
向某个元素前或者后插入元素
linsert key before|after pivot value

获取指定范围内元素列表
lrange key start end
获取列表指定索引下标的元素
lindex key index
获取列表的长度
llen key

从列表左侧弹出元素
lpop key
从列表右侧弹出元素
rpop key
删除置顶元素
lrem命令会从列表中找到等于valuede元素进行删除,根据count的不同分为三种情况
count>0 从左到右,删除最多count个元素
count<0 从右到左,删除最多count绝对值多个元素
count=0 删除所有
按照索引范围修剪列表
ltrim key start end
修改指定索引下标的元素
lset key index newValue
阻塞式弹出
blpop key [key …] timeout
brpop key [key …] timeout

内部编码

当列表中的元素个数小于配置个数或者列表中的每个元素的值都小于配置时的大小时,redis会使用ziplist来作为列表的内部实现以减少内存的使用
当列表的类型无法满足ziplist条件时,redis会使用linkedlist来作为列表的内部实现

使用场景

消息队列

redis的lpush+brpop命令组合即可实现阻塞队列,多个消费者客户端会使用brpop命令阻塞式的抢列表尾部的元素,多个客户端保证了消费的负载均衡和高可用

集合

集合是用来保存多个的字符串元素,但是和列表类型不同的是,集合中的元素不能够有重复的元素,并且集合中的元素是无序的,不能通过索引下标获取元素,一个集合最多可以容纳是2^32-1个元素,redis除了支持集合内的增删查改,还能够支持多个集合取交集,并集差集,合理的使用集合类型,能够在实际开发中解决很多的问题

命令

添加元素:
sadd key element [element …]
删除元素
srem key element [element …]
计算元素个数
scard key
判断元素是否在集合中
sismember key element
随机从集合中返回指定个数元素
srandommember key count
从集合中随机弹出元素
spop key
获取所有的元素
smember key
smember 和lrange,hgetall都是比较重的命令,如果元素过多会存在阻塞redis的可能性,这个时候可以使用sscan来完成
求多个几个的交集
sinter key [key …]
求多个集合的并集
suinon key [key …]
求多个集合的差集
sdiff key [key …]
将交并差集的结果保存
sinterstore destination key [key …]
sunionstore destination key [key …]
sdiffstore destination key [key …]

内部编码

intset(整数集合):当集合中的元素都是整数并且元素的个数小于默认的配置个数,会使用intset来作为几个的内部实现
hashtable:当intset无法满足使用条件时,会使用hashtable作为内部实现

有序集合

有序集合保证了集合不能有重复成员的特性,但是与之不同的是有序集合的元素可以排序,但是他和列表使用索引作为下标排序不同的是,他给每一个元素设置一个分数作为排序的依据,

在这里插入图片描述有序集合中的元素不能够重复,但是score可以重复,就和一个

命令

添加成员
zadd key score member [score member …]
zadd 命令有如下两点需要注意
zadd 命令添加了nx xx ch incr四个选项
nx member必须不存在才可以设置成功,用于添加
xx member必须存在,才可以设置成功,用于更新
ch 返回此次操作后,有序集合和分数发生变化的个数
incr 对score做增加,相当于zincrby
有序集合相比集合增加了排序的功能,但是也付出了代价,有序集合zadd的时间复杂度为logN
计算成员的个数
zcard key
计算某个成员的分数
zscore key member
计算成员的排名
zrank key member
zrevrank key member
zrank 是从分数从低到高返回排名,zrevrank反之
删除成员
zrem key member [member …]
增加成员的分数
zincrby key increment member
返回制定排名范围的成员
zrange key start end
zrevrange key start end
返回指定分数范围的成员
zrangebyscore key min max
zrevrangescore key max min
交集运算
zinterstore destination numberkey key [key…]
并集运算
zunionstore destination numberkey key [key…]

内部编码

有序集合类型的内部编码有两种:
ziplist:当有序集合的元素的个数小于默认的配置个数和每个元素的大小小于默认大小时,会使用ziplist
在不能使用ziplist的情况下使用skiplist

键管理

键重命名:
rename key newKey
如果在rename之前,键java已经存在,那么他的值也将要被覆盖,
为了防止强行被rename.redis提供了renamenx命令,只有再newkey不存在的情况下才能够备覆盖
随机返回一个键
randomkey
键过期
expire key seconds
expire key timestamp
presist命令可以把键的过期时间清楚
对于字符串类型的键,执行set命令会去掉过期时间,这个问题很容易在开发的过程中被忽略

迁移键功能,有时候我们想把数据从一个redis迁移到另外一个redis.redis发展历程中提供了move,dump+restore,migrate三种迁移键的方法

一般建议不要在生产环境下使用keys命令,如果redis包含了大量的键,执行keys命令会造成redis阻塞
渐进式遍历:scan能够有效的解决keys命令存在的问题,和keys命令执行时会遍历所有的键不同,scan采用渐进式遍历的方式解决keys命令带来的阻塞问题,每次执行scan命令的时间复杂度是O(1),但是要真正的实现keys的功能,需要执行多次scan,

redis存储键值对实际采用的是hashtable的数据结构,其简化模型是:
那么每次执行scan,可以想象成只扫描一个字典中的一部分键,直到将字典中的所有键遍历完毕
渐进式遍历可以有效的解决keys可能产生的阻塞问题,但是scan并非完美无瑕,如果在scan过程中有键的变化,那么遍历效果可能会出现新增加的键没有找到,遍历出现了重复的键等情况

数据库管理

切换数据库:
select dbindex
与关系型数据库使用字符来区分不同的数据库名不同,redis只是用数字作为多个数据库的实现,但是不推荐多数据库配置
flushdb 命令会清除当前数据库,flushall会清除所有的数据库

猜你喜欢

转载自blog.csdn.net/m0_37719047/article/details/102519588