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.hqwc.cn/news/133172.html

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

相关文章

Webmin远程命令执行漏洞复现报告

漏洞编号 CVE-2019-15107 漏洞描述 Webmin是一个基于Web的系统配置工具&#xff0c;用于类Unix系统。密码重置页面中存在此漏洞&#xff0c;允许未经身份验证的用户通过简单的 POST 请求执行任意命令。 影响版本 Webmin<1.920 漏洞评级 严重 利用方法&#xff08;利…

linux C++ vscode连接mysql

1.linux使用Ubuntu 2.Ubuntu安装vscode 2.1 安装的是snap版本,直接打开命令行执行 sudo snap install --classic code 3.vscode配置C 3.1 直接在扩展中搜索C安装即可 我安装了C, Chinese, code runner, 安装都是同理 4.安装mysql sudo apt update sudo apt install mysql-…

git主干master分支回滚到历史版本(不会有错误的提交记录)

master版本,“合并错了”的回滚步骤: (这样做不会有“合并错了”的提交记录) 注意&#xff1a;操作前先对master拉一个分支出来&#xff0c;做备份&#xff1b; 1. 在gitLab的上一次合并记录&#xff0c;复制commit-id ​ 2. 在本地执行检出master版本&#xff0c;执行 git re…

再谈Java泛型

一.类型参数的约束 我们可以对泛型传进来的参数做一些约束&#xff0c;比如说 用extends表明传进来的参数类型必须是必须是某个类型的子类型或者本身 当然也可以用接口约束&#xff0c;也是用extends表明传进来的参数类型必须实现某个接口。用&连接&#xff0c;注意class…

Avalonia常用小控件Charts

1.项目下载地址&#xff1a;https://gitee.com/confusedkitten/avalonia-demo 2.UI库Semi.Avalonia&#xff0c;项目地址 https://github.com/irihitech/Semi.Avalonia 3.Charts库&#xff0c;LiveChartsCore.SkiaSharpView.Avalonia&#xff0c;Nuget获取只有预览库&#x…

CPU性能分析--火焰图使用

记录工具使用说明&#xff0c;火焰图原理网上分析很多。主要用来分析函数调用栈占用的cpu利用率&#xff0c;分析函数性能。 perf安装&#xff1a; sudo apt-get install linux-tools-common sudo apt-get install linux-tools-"(uname -r)" sudo apt-get install …

【Python爬虫 js渲染思路一】

Python爬虫 破解js渲染思路一 当我们在谈论网页js渲染的时候&#xff0c;我们在谈论什么 js渲染网页&#xff0c;从某种程度来说&#xff0c;是指单纯的http请求&#xff0c;返回的文本数据&#xff0c;与我们在浏览器看到的内容&#xff0c;相距甚远.其可包括为以下几点&…

JavaScript反爬虫技巧详细攻略

在互联网时代&#xff0c;网站采取了各种手段来防止被爬虫抓取数据&#xff0c;其中最常见的就是JavaScript反爬虫技巧。本文将揭示一些常用的JavaScript反爬虫技巧&#xff0c;并提供一些实际操作建议&#xff0c;帮助您保护自己的爬虫免受检测和封禁。 1、为什么网站使用Java…

【NeRF】1、NeRF 是什么

NeRF 最早是在 ECCV2020 中提出的方法&#xff0c;还获得了 ECCV2020 Oral 论文&#xff1a;Representing Scenes as Neural Radiance Fields for View Synthesis代码&#xff1a;https://github.com/bmild/nerf官网&#xff1a;https://www.matthewtancik.com/nerf Neural R…

集成内部高端电源开关LTC3637HMSE、LTC3637MPMSE稳压器,TJA1443AT汽车CAN FD收发器。

一、LTC3637 76V、1A 降压型稳压器 &#xff08;简介&#xff09;LTC3637是一款高效率降压DC/DC稳压器&#xff0c;集成内部高端电源开关&#xff0c;功耗仅12μA DC&#xff0c;空载时可保持稳定的输出电压。LTC3637可提供高达1A的负载电流&#xff0c;并具有可编程峰值电流限…

API攻防-接口安全SOAPOpenAPIRESTful分类特征导入项目联动检测

文章目录 概述什么是接口&#xff1f; 1、API分类特征SOAP - WSDLWeb services 三种基本元素&#xff1a; OpenApi - Swagger UISpringboot Actuator 2、API检测流程Method&#xff1a;请求方法URL&#xff1a;唯一资源定位符Params&#xff1a;请求参数Authorization&#xff…

【算法系列 | 10】深入解析查找算法之—线性查找

序言 心若有阳光&#xff0c;你便会看见这个世界有那么多美好值得期待和向往。 决定开一个算法专栏&#xff0c;希望能帮助大家很好的了解算法。主要深入解析每个算法&#xff0c;从概念到示例。 我们一起努力&#xff0c;成为更好的自己&#xff01; 今天第10讲&#xff0c;讲…