Redis 学习笔记

文章目录

  • 一、基础命令
    • 1.1 通用命令
    • 1.2 String
    • 1.3 Hash
    • 1.4 List
    • 1.5 Set
    • 1.6 SortedSet
  • 二、Redis 和数据库的数据一致性
  • 三、缓存穿透
  • 四、缓存雪崩
  • 五、缓存击穿


一、基础命令

1.1 通用命令

  • KEYS pattern 查找所有符合给定模式 pattern 的 key,其中 * 匹配零个或多个字符,? 匹配一个字符。
  • DEL key [key ...] 删除给定的一个或多个 key。
  • EXISTS key 检查给定 key 是否存在。
  • EXPIRE key seconds 为给定 key 设置生存时间,生存时间为 0 时该 key 过期,它会被自动删除。
  • TTL key 以秒为单位,返回给定 key 的剩余生存时间。

1.2 String

  • SET key value [EX seconds] [PX milliseconds] [NX|XX] 将字符串值 value 关联到 key。如果 key 已经持有其他值,SET 就覆写旧值,无视类型。对于某个原本带有生存时间(TTL)的键来说, 当 SET 命令成功在这个键上执行时, 这个键原有的 TTL 将被清除。
  • GET key 返回 key 所关联的字符串值。如果 key 不存在那么返回特殊值 nil。如果 key 储存的值不是字符串类型,返回一个错误,因为 GET 只能用于处理字符串值。
  • MSET key value [key value ...] 同时设置一个或多个 key-value 对。MSET 是一个原子性(atomic)操作,所有给定 key 都会在同一时间内被设置。
  • MGET key [key ...] 返回一个或多个给定 key 的值,如果给定的 key 里面有某个 key 不存在,那么这个 key 返回 nil
  • INCR key 将 key 中储存的字符串解释为十进制 64 位有符号整数并加一。如果 key 不存在,那么 key 的值会先被初始化为 0,然后再执行 INCR 操作。如果值包含错误的类型,或字符串类型的值不能解释为数字,那么返回一个错误。
  • INCRBY key increment 将 key 所储存的值加上增量 increment,具体实现与 INCR 类似。
  • HINCRBYFLOAT key field increment 将 key 所储存的值加上浮点数增量 increment,INCRBYFLOAT 的计算结果最多只能表示小数点的后十七位。
  • SETNX key value 即 set if not exists,当且仅当 key 不存在时将 key 的值设为 value,若给定的 key 已经存在,则 SETNX 不做任何动作。
  • SETEX key seconds value 即 set with expire,将值 value 关联到 key,并将 key 的生存时间设为 seconds。如果 key 已经存在, SETEX 命令将覆写旧值。

1.3 Hash

  • HSET key field value 将哈希表 key 中的域 field 的值设为 value。如果 key 不存在,一个新的哈希表被创建并进行 HSET 操作。如果域 field 已经存在于哈希表中,旧值将被覆盖。
  • HGET key field 返回哈希表 key 中给定域 field 的值。
  • HMSET key field value [field value ...] 同时将多个 field-value 对设置到哈希表 key 中。
  • HMGET key field [field ...] 返回哈希表 key 中,一个或多个给定域的值。如果给定的域不存在于哈希表,那么返回一个 nil 值。
  • HGETALL key 返回哈希表 key 中所有的域和值。
  • HKEYS key 返回哈希表 key 中的所有域。
  • HVALS key 返回哈希表 key 中所有域的值。
  • HINCRBY key field increment 为哈希表 key 中的域 field 的值加上增量 increment。增量也可以为负数,相当于对给定域进行减法操作。
  • HSETNX key field value 将哈希表 key 中的域 field 的值设置为 value,当且仅当域 field 不存在。

1.4 List

  • LPUSH key value [value ...] 将一个或多个值 value 依次插入到列表 key 的表头(左侧)。
  • LPOP key 移除并返回列表 key 的头元素。
  • RPUSH key value [value ...] 将一个或多个值 value 依次插入到列表 key 的表尾(右侧)。
  • RPOP key 移除并返回列表 key 的尾元素。
  • LRANGE key start stop 返回列表 key 中指定区间内的元素,区间以偏移量 start 和 stop 指定。
  • BLPOP key [key ...] timeoutLPOP 命令的阻塞版本,当给定列表内没有任何元素可供弹出的时候,连接将被 BLPOP 命令阻塞,直到等待超时或发现可弹出元素为止。
  • BRPOP key [key ...] timeoutRPOP 命令的阻塞版本,当给定列表内没有任何元素可供弹出的时候,连接将被 BRPOP 命令阻塞,直到等待超时或发现可弹出元素为止。

1.5 Set

  • SADD key member [member ...] 将一个或多个 member 元素加入到集合 key 当中,已经存在于集合的 member 元素将被忽略。
  • SREM key member [member ...] 移除集合 key 中的一个或多个 member 元素,不存在的 member 元素会被忽略。
  • SCARD key 返回集合 key 中元素的数量。
  • SISMEMBER key member 判断 member 元素是否集合 key 的成员。
  • SMEMBERS key 返回集合 key 中的所有成员,不存在的 key 被视为空集合。
  • SINTER key [key ...] 返回一个集合的全部成员,该集合是所有给定集合的交集。
  • SDIFF key [key ...] 返回一个集合的全部成员,该集合是所有给定集合之间的差集。
  • SUNION key [key ...] 返回一个集合的全部成员,该集合是所有给定集合的并集。

1.6 SortedSet

  • ZADD key score member [[score member] [score member] ...] 将一个或多个 member 元素及其 score 值加入到有序集 key 当中。score 值可以是整数值或双精度浮点数。
  • ZREM key member [member ...] 移除有序集 key 中的一个或多个成员,不存在的成员将被忽略。
  • ZSCORE key member 返回有序集 key 中,成员 member 的 score 值。如果 member 元素不是有序集 key 的成员或 key 不存在,返回 nil
  • ZRANK key member 返回有序集 key 中成员 member 的排名。其中有序集成员按 score 值递增(从小到大)顺序排列。
  • ZCARD key 返回有序集 key 的基数。
  • ZCOUNT key min max 返回有序集 key 中,score 值在 min 和 max 之间(默认包括 score 值等于 min 或 max)的成员的数量。
  • ZINCRBY key increment member 为有序集 key 的成员 member 的 score 值加上增量 increment,increment 可以为负。
  • ZRANGE key start stop [WITHSCORES] 返回有序集 key 中,指定区间内的成员。其中成员的位置按 score 值递增来排序。
  • ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count] 返回有序集 key 中,所有 score 值介于 min 和 max 之间的成员。

二、Redis 和数据库的数据一致性

在并发场景下,如果只有读操作并不会发生数据不一致,但如果存在写操作,不管是先更新数据库还是先更新缓存,只要两次更新操作中夹杂了其他线程的完整更新操作都会导致最终的数据不一致。举两个例子来说就是 线程 A 更新缓存 -> 线程 B 更新缓存 -> 线程 B 更新数据库 -> 线程 A 更新数据库线程 A 更新数据库 -> 线程 B 更新数据库 -> 线程 B 更新缓存 -> 线程 A 更新缓存,以上两种情况下,线程 B 的完整更新均使得线程 A 的更新成为了部分更新,因此发生了最终的数据不一致。

旁路缓存策略(Cache Aside)能在一定程度上解决数据不一致的问题,该策略主要分为读策略和写策略两个部分:

  • 写策略:先更新数据库中的数据,再删除缓存中的数据。
  • 读策略:如果读取的数据命中了缓存,则直接返回数据。如果读取的数据没有命中缓存,则从数据库中读取数据,然后将数据写入到缓存,并且返回给用户。

对于写策略,主要有两个注意事项:

  • 首先是删除缓存还是更新缓存。如果采用更新缓存,那么每次更新数据库都要对应更新缓存,但这些数据并不一定会被查询,此时会导致大量的无效写操作。而删除缓存只需要让缓存失效,开销更小,同时还能在一定程度上避免 线程 A 更新数据库 -> 线程 B 更新数据库 -> 线程 B 更新缓存(删除) -> 线程 A 更新缓存(删除) 的数据不一致问题。
  • 其次是先操作数据库还是先操作缓存。其实,不管是先操作谁都有可能发生数据不一致(见下图),不过由于缓存的写入通常要远远快于数据库的写入,因此先操作数据库发生数据不一致的可能性非常小。

在这里插入图片描述

基于旁路缓存策略,可以通过加锁将更新数据库和删除缓存整合为一个原子操作从而保证强一致性,但很明显这会影响性能。同时,也可以在写入缓存时指定 TTL,这样哪怕发生数据不一致也能在缓存失效后得到解决。

此外,如果采用先删除缓存再更新数据库,通过延迟双删(在更新数据库后延迟一定时间再删除一次缓存)也可以在一定程度上解决数据不一致的问题。因此,任何一种缓存更新方案都不能说是绝对的最优解,具体用哪种方案就要看对性能和一致性的取舍了。


三、缓存穿透

缓存穿透是指客户端请求的数据在缓存和数据库中都不存在,这样缓存永远不会生效,所有的请求都会访问数据库。

常见的解决方案有三种:

  • 限制非法请求:可以在 API 入口处对请求进行判断,如果判断出是恶意请求就直接返回错误,避免进一步访问缓存和数据库。
  • 缓存空对象:缓存空值或者默认值,这样后续请求就可以从缓存中读取到空值或者默认值,返回给应用,而不会继续查询数据库。优点是实现简单、维护方便,缺点是会产生额外的内存消耗已以及短期的数据不一致。
  • 布隆过滤器:布隆过滤器通过对数据取模在位图数组中相应位置进行标记,访问数据前只需要判断对应位置是否被标记即可。因此布隆过滤器能够快速判断数据是否存在,从而过滤请求。优点是内存占用少,不过实现复杂而且存在误判的可能。

四、缓存雪崩

缓存雪崩是指在同一时段大量的缓存数据同时失效或者 Redis 故障宕机,导致大量请求到达数据库,为数据库带来巨大压力。

解决大量的缓存数据同时失效:

  • 均匀设置过期时间:在对缓存数据设置过期时间时,给过期时间加上一个随机数,尽量避免数据在同一时间过期。
  • 对缓存构建加锁:业务线程如果发现访问的数据不在 Redis 里,就加个互斥锁,保证同一时间内只有一个请求来构建缓存(从数据库读取数据并更新到 Redis 里),当缓存构建完成后,再释放锁。未能获取互斥锁的请求,要么等待锁释放后重新读取缓存,要么就返回空值或者默认值。
  • 后台缓存更新:缓存设置为永久有效,业务线程也不再负责更新缓存,将更新缓存的工作交由后台线程定时执行。在业务刚上线的时候,我们可以提前把数据缓起来,而不是等待用户访问才来触发缓存构建,这就是所谓的缓存预热,后台更新缓存的机制很适合完成这个工作。

解决 Redis 故障宕机:

  • 服务熔断、降级或请求限流机制:因为 Redis 故障宕机而导致缓存雪崩问题时,我们可以启用服务熔断,暂停业务应用对缓存服务的访问,直接返回错误,或者启用服务降级,只提供默认值或简化的服务而不是完全失败,从而降低对数据库的访问压力,等到 Redis 恢复正常后,再允许业务应用访问缓存服务。服务熔断机制保护了数据库,但是暂停了业务访问,为了减少对业务的影响,我们可以启用请求限流机制,只将少部分请求发送到数据库进行处理,其余请求就在入口直接被拒绝,等到 Redis 恢复并把缓存预热完后,再解除请求限流。
  • 构建 Redis 缓存高可靠集群:可以搭建 Redis 集群,如果 Redis 缓存的主节点故障宕机,从节点可以切换成为主节点,继续提供缓存服务,避免了由于 Redis 故障宕机而导致的缓存雪崩问题。

五、缓存击穿

缓存击穿也叫热点 key 问题,是指一个被高并发访问并且缓存重建业务较为复杂的 key 突然失效了,无数的请求同时访问数据库并重建缓存。

常见的解决方案有三种:

  • 互斥锁:保证同一时间只有一个业务线程更新缓存,未能获取互斥锁的请求,要么等待锁释放后重新读取缓存,要么就返回空值或者默认值。这种方法可以保证数据一致性但是互斥锁会影响性能。
  • 逻辑过期:不显式地为热点 key 指定 TTL,而是由专门地异步线程在热点 key 逻辑过期前进行缓存更新。这种方法性能较好但是不能保证数据地强一致性。

参考:

http://doc.redisfans.com/index.html
https://www.xiaolincoding.com/redis

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/154231.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Golang】gin框架入门

文章目录 gin框架入门认识gingo流行的web框架gin介绍快速入门 路由RESTful API规范请求方法URI处理函数分组路由 请求参数GET请求参数POST请求参数路径参数文件参数 响应字符串方式JSON方式XML方式文件格式设置HTTP响应头重定向YAML方式 模板渲染基本使用多个模板渲染自定义模板…

Qt中QTimer定时器的用法

Qt中提供了两种定时器的方式一种是使用Qt中的事件处理函数,另一种就是Qt中的定时器类QTimer。 使用QTimer类,需要创建一个QTimer类对象,然后调用其start()方法开启定时器,此后QTimer对象就会周期性的发出timeout()信号。 1.QTimer…

VMware centos7虚拟机修改静态IP

一、修改网络适配器 1、打开 2、使用管理员权限修改 3、按照图中步骤修改为 4、设置网关为10.0.0.2后保存即可 二、修改配置文件 1、输入下面代码进入修改(网卡这里网卡名字为ens33,可使用ifcfig或ip a查看) vi /etc/sysconfig/netwo…

使用vlc获取海康威视视频流

1.下载相关软件 1.1海康威视官网-服务支持-工具软件-设备网络搜索 下载地址: https://www.hikvision.com/cn/support/tools/hitools/注意:必须跟摄像头在同一个局域网下才可以使用设备网络搜索工具,才能使用vlc获取到视频流。 1.2下载VLC …

Hadoop----Azkaban的使用与一些报错问题的解决

1.因为官方只放出源码,并没有放出其tar包,所以需要我们自己编译,通过查阅资料我们可以使用gradlew对其进行编译,还是比较简单,然后将里面需要用到的服务文件夹进行拷贝,完善其文件夹结构,通常会…

leetcode 每日一题复盘(10.9~10.15)

leetcode 101 对称二叉树 这道题一开始想是用层序遍历,看每一层是否都对称,遇到一个问题就是空指针(子树为空)无法记录下来,同时会导致操作空指针的问题,因此需要修改入队条件,并用一个标志去表示空指针 vector<int>numv;for(int i0;i<size;i){TreeNode*frontque.fro…

SpringCloudGateway网关整合swagger3+Knife4j3,basePath丢失请求404问题

很多人都是照着别人的文章粘代码&#xff0c;我也是粘的&#xff0c;但是这样粘也会有问题&#xff0c;我搞这个Knife4j3的时候遇到两个问题&#xff0c;这里记录一下&#xff1a; 第一个是basePath丢失&#xff0c;第二个解决basePath丢失完又引发了会引起application/json数据…

React +ts + babel+webpack

babel babel/preset-typescript 专门处理ts "babel/cli": "^7.17.6", "babel/core": "^7.17.8", "babel/preset-env": "^7.16.11", "babel/preset-react": "^7.16.7", "babel/preset…

第4章 决策树

文章目录 4.1 基本流程4.2 划分选择4.2.1 信息增益4.2.2 增益率4.2.3 基尼指数 4.3 剪枝处理4.3.1 预剪枝4.3.2 后剪枝 4.4 连续与缺失值4.4.1 连续值处理4.4.2 缺失值处理 4.5 多变量决策树4.6 阅读材料 4.1 基本流程 决策树也称判定树&#xff0c;是一类常见的机器学习方法。…

35 WEB漏洞-逻辑越权之找回机制及接口安全

目录 找回重置机制接口调用乱用演示案例绑定手机验证码逻辑-Rep状态值篡改-实例某APP短信轰炸接口乱用-实例接口调用发包 文章分享&#xff1a;https://www.cnblogs.com/zhengna/p/15655691.html 有支付接口、短信发送接口&#xff0c;邮箱的发送接口等等&#xff0c;在接口这…

论文研读|Protecting Intellectual Property of Deep Neural Networks with Watermarking

目录 论文信息文章简介研究动机研究方法水印生成水印嵌入版权验证 实验结果有效性&#xff08;Effectiveness&#xff09;高效性&#xff08;Converge Speed&#xff09;保真度&#xff08;Functionality&#xff09;鲁棒性&#xff08;Robustness&#xff09;Anti-剪枝攻击&am…

镜像仓库harbor安装部署

基础配置 systemctl stop firewalld && systemctl disable firewalld setenforce 0 sed -i s/SELINUXenforcing/SELINUXdisabled/ /etc/selinux/configharbor wget http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo yum install -y docker-ce docke…

Python中套接字实现服务端和客户端3-2

2.3 监听套接字 通过listen()方法监听套接字。该方法的格式如下所示。 socket.listen([backlog]) 其中&#xff0c;参数backlog是一个可选项&#xff0c;表示等待服务器接收连接的客户端的数量。使用listen()方法监听套接字的代码如下所示。 s.listen(1) 当没有客户端连接…

OJ练习第183题——移动机器人

移动机器人 力扣链接&#xff1a;2731. 移动机器人 题目描述 示例 官解思路 当两个机器人相撞时&#xff0c;它们会沿着原本相反的方向移动。由于机器人之间并没有任何区别&#xff0c;相撞可以看做是穿透&#xff0c;原本左边的机器人相撞后交换为右边的机器人&#xff0c…

android Google官网 :支持不同的语言和文化 rtl / ltr : 本地化适配:RTL(right-to-left) 适配

参考 google官网&#xff1a; 支持不同的语言和文化 应用包含可能专门针对特定文化而设计的资源。例如&#xff0c;应用可以包含针对特定文化的字符串&#xff0c;这些字符串将转换为当前语言区域的语言。 将具有文化特异性的资源与应用的其他资源分开是一种很好的做法。And…

HTTPS建立连接的过程

HTTPS 协议是基于 TCP 协议的&#xff0c;因而要先建立 TCP 的连接。在这个例子中&#xff0c;TCP 的连接是在手机上的 App 和负载均衡器 SLB 之间的。 尽管中间要经过很多的路由器和交换机&#xff0c;但是 TCP 的连接是端到端的。TCP 这一层和更上层的 HTTPS 无法看到中间的包…

基于springboot实现家具销售电商平台管理系统项目【项目源码+论文说明】计算机毕业设计

基于springboot实现家具销售电商平台管理系统演示 摘要 社会的发展和科学技术的进步&#xff0c;互联网技术越来越受欢迎。网络计算机的交易方式逐渐受到广大人民群众的喜爱&#xff0c;也逐渐进入了每个用户的使用。互联网具有便利性&#xff0c;速度快&#xff0c;效率高&am…

NLP 项目:维基百科文章爬虫和分类【01】 - 语料库阅读器

自然语言处理是机器学习和人工智能的一个迷人领域。这篇博客文章启动了一个具体的 NLP 项目&#xff0c;涉及使用维基百科文章进行聚类、分类和知识提取。灵感和一般方法源自《Applied Text Analysis with Python》一书。 一、说明 该文是系列文章&#xff0c;揭示如何对爬取文…

SQL多表设计--一对多(外键)

-- 完成部门和员工的-- 选择当前db03 这个数据库use db03;-- 查看当前选中的数据库select database();-- 创建员工表create table tb_emp (id int unsigned primary key auto_increment comment ID,username varchar(20) not null unique comment 用户名,password varchar(32)…

多线程(线程互斥)

抢票代码编写 学习了前面有关线程库的操作后&#xff0c;我们就可以模拟抢票的过程 假设我们创建四个线程&#xff0c;分别代表我们的用户 然后设定总票数为1000张&#xff0c;四个线程分别将进行循环抢票操作&#xff0c;其实就是循环对票数进行打印&#xff0c;并进行对应的…