Redis第一关之常规用法

2024-02-19 22:20
文章标签 redis 用法 常规 第一关

本文主要是介绍Redis第一关之常规用法,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

简介

Redis不用多说,已经火了很多年了,也用了很多年了。现在做一些归纳总结。
这篇文章主要介绍Redis的常规知识及用法,包括数据结构、使用场景、特性、过期机制、持久化机制。

Redis与Mysql

Mysql是一款基于磁盘的关系型SQL数据库。
Redis是一款基于内存的、非关系型、Nosql数据库,

Mysql的基本构成结构是二维表,由行和列组成。
Redis的数据存储形式是Key-Value结构,由键和值组成。

相较于传统的RDBMS数据库,NOSQL数据库更满足Web2.0时代数据爆炸式需求。不需要固定的格式,严格的关系,提供高并发性能等等。单NOSQL并不能完全取代传统数据库,因此,RDBMS+NOSQL是最好的方式。

下面具体来分析Redis的数据结构

Redis数据结构

Redis是Key-Value结构,Key值都是单字符串,Value也是字符串,但却有9种数据类型,分别如下:

  1. String(字符串)
  2. List(链表)
  3. Set(无序集合)
  4. ZSet(有序集合)
  5. Hash(哈希)
  6. Geo 地理位置
  7. Bitmaps 位图
  8. HyperLogLog 基数统计

除了最后三种特殊数据结构外,常用的5种数据结构可以按类型分类。

1. 按单、多个字符串分类:
String为单个字符串结构
List、Set、Zset、Hash为多字符串结构2. 在多字符串结构中,再按有序、无序分类
List、ZSet为有序数据结构,其中List底层为链表结构,以插入顺序排序。ZSet通过分数Score来排序。
Set、Hash为无序数据结构,其中Set为无序唯一性集合,会自动去重。

Hash数据结构是以field-value形式,非常适合存储对象结构。同时支持对对象属性的增删。
在这里插入图片描述

Redis应用场景

Redis作为Web2.0时代受欢迎的产物,其基于内存的高性能、过期机制、特殊的数据结构都分别决定了它的用途广泛。

在这里插入图片描述

缓存应用的三大问题

缓存击穿

概念: 缓存将某个或小面积热Key击穿,
造成原因:误操作、缓存过期
解决办法:暂时设置永不过期、增加热点监控

缓存穿透

概念: 请求穿过了缓存,直达缓存后的数据库层,大并发下容易造成数据库宕机,从而影响全局。
造成原因:大并发请求,缓存层未命中,黑客攻击等
解决办法:增加数据有效性校验,对不存在的数据进行Null值缓存,使用布隆过滤器。

缓存雪崩

概念:大面积缓存的key值在同一时间段都未命中
造成原因:key值过期时间过于集中,或者Redis宕机。
解决办法:分散key值得过期时间,通过随机数加权计算。增加Redis高可用性。 

过期时间

在Redis中,很多场景可以通过过期机制来实现。比如短信验证码、七天免登录等。
但是Redis中允许key不设置过期时间,这会让key值永不过期,占用内存。如果不是特殊设计不建议这样使用。

关于Redis的设计缺陷及补丁措施思考

Redis是一款基于内存的数据库,其目的是为了满足快速处理的高并发特性。
但是内存是有物理局限的,它无法像硬盘一样容量可以扩充到很大,也容易受到断电丢失数据影响。
在这里插入图片描述

因此,Redis作者又做了几个补丁。

补丁一:过期机制

如果Redis没有过期机制?

那么意味着,所有存入到内存的数据都是永不过期的,使用完了就得删除,这像是 C++语言开发,而过期机制相当于Java的内存回收机制,操作起来更柔性。

过期机制的底层原理?

Redis内部采用的是定期删除+惰性删除,两种机制相配合保证了最终一定被删除。

定期删除
设置了定时器,每次会取出一部分过期的key进行删除。

为什么不是轮询全部过期的key值?

因为如果内存较大,过期的key值较多,轮询比较耗时,会消耗大量的CPU在轮询上。

那么,未被取出的过期key值如何删除?

惰性删除
惰性删除,类似于java中的类的懒加载,Spring IOC对象的懒加载。
未被定期删除策略命中的过期key,只有当这个key再次被访问时来判断是否要删除。

因此,定期删除+惰性删除策略,一定会删除所有过期的key,但是有一个时间差问题。

某个key值过期了,它的最快删除时间是定期任务第一次扫描就被取出来并删除。它的最慢删除时间是…很久,这取决于定期删除是怎么取出数据的了。

在这里插入图片描述

虽然这些过期的key最终会被删除,但Redis内存容量总是动态变化的,不断的有增量Key,也有不断的删除Key。

在这里插入图片描述
如果:

增量速度 > 删除速度,删除速度>=0(等于0时所有的key都未过期)

Redis内存就会膨胀,逐渐趋于饱和。这时候,那些未被及时删除的过期Key就亟需被找到并删除掉了,作者怎么做的呢?

内存淘汰策略

当出现上述情况时,作者设计了一种内存淘汰机制,使用者可以不同的策略来清理内存,保证Redis能否正常使用。

1. volatile-lru(least recently used) 从设置了过期时间的数据中(server.db[i].expires) 淘汰最近最少被使用的数据。
2. volatile-random 从设置了过期时间的数据中 随机淘汰数据。
3. volatile-lfu 从设置了过期时间的数据中 淘汰最不频繁被使用的数据。4. allkeys-lru 从所有的数据中(server.db[i].dict) 淘汰最近最少被使用的数据。- 常用
5. allkeys-random 从所有的数据中(server.db[i].dict)随机淘汰数据。
6. allkeys-lfu 从所有的数据中(server.db[i].dict)淘汰最不频繁被使用的数据。7. volatile-ttl 从设置了过期时间的数据中(server.db[i].expires)淘汰将要过期的数据。
8. no-eviction 禁止淘汰数据。

补丁二: 持久化机制

Redis毕竟是基于内存的数据库,如果断电了肯定会导致数据丢失。所以设计持久化机制是必然的。

作者设计了两种持久化机制:AOF、RDB

AOF持久化

AOF是一种以记录实时日志的方式,将Redis的每个操作命令持久化,其优点是实时性比较强,可以每秒钟记录一次,其缺点是产生的日志量较大,重启恢复时的耗时较长。

RDB持久化

RDB是一种全量备份模式,将Redis中的所有数据全部备份下来,可以实现备份和迁移。
其优点是产生的数据量较小,重启时可以快速的恢复,其缺点是实时性较弱,容易产生数据丢失。

RDB持久化时,如果发生在Redis运行中,由于数据是动态变化的,因此常见的备份方式是将Redis其他操作阻塞,直到全量备份完成在放行,另一种方式是Redis作者提供的异步备份。

1. 同步备份 save
2. 异步备份 bgsave

异步备份是bgsave命令,其原理是在主进程中fork一个子进程异步执行,不会阻塞主进程操作。

Redis高可用设计

Redis提供了高可用设计,分别是主从模式、哨兵模式、集群模式。

主从模式
Redis数据库的主从模式和Mysql数据库的主从模式类似,都是以容灾备份为目的设计的,因此当Redis主结点发生故障时,可手动切换为从结点提供服务。
主从模式需要两个Redis结点。

哨兵模式

虽然主从模式可以提供容灾备份的功能,但是当发生故障时,需要手动切换,并不智能。 于是,哨兵模式解决了这个问题。

哨兵模式通过哨兵集群监控所有Redis结点,让主结点发生故障时,自动将主节点踢出,然后重新选择一个从节点作为主节点提供服务,保证了高可用性。
哨兵模式最大的优点是故障自动转移,但至少需要3个Redis结点。

群集模式

群集模式提供了Redis分布式数据存储功能,由于单机内存上限的限制,群集模式解决了这个问题,通过数据分片的形式将Redis数据分散到多个结点,实现容量的横向扩展,每个主结点都需要配置一个从结点作为数据容灾备份,以便故障自动转移。
Redis群集模式一般需要3主3从,共6个Redis结点。

这篇关于Redis第一关之常规用法的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/726146

相关文章

零基础学习Redis(10) -- zset类型命令使用

zset是有序集合,内部除了存储元素外,还会存储一个score,存储在zset中的元素会按照score的大小升序排列,不同元素的score可以重复,score相同的元素会按照元素的字典序排列。 1. zset常用命令 1.1 zadd  zadd key [NX | XX] [GT | LT]   [CH] [INCR] score member [score member ...]

bytes.split的用法和注意事项

当然,我很乐意详细介绍 bytes.Split 的用法和注意事项。这个函数是 Go 标准库中 bytes 包的一个重要组成部分,用于分割字节切片。 基本用法 bytes.Split 的函数签名如下: func Split(s, sep []byte) [][]byte s 是要分割的字节切片sep 是用作分隔符的字节切片返回值是一个二维字节切片,包含分割后的结果 基本使用示例: pa

Redis中使用布隆过滤器解决缓存穿透问题

一、缓存穿透(失效)问题 缓存穿透是指查询一个一定不存在的数据,由于缓存中没有命中,会去数据库中查询,而数据库中也没有该数据,并且每次查询都不会命中缓存,从而每次请求都直接打到了数据库上,这会给数据库带来巨大压力。 二、布隆过滤器原理 布隆过滤器(Bloom Filter)是一种空间效率很高的随机数据结构,它利用多个不同的哈希函数将一个元素映射到一个位数组中的多个位置,并将这些位置的值置

UVM:callback机制的意义和用法

1. 作用         Callback机制在UVM验证平台,最大用处就是为了提高验证平台的可重用性。在不创建复杂的OOP层次结构前提下,针对组件中的某些行为,在其之前后之后,内置一些函数,增加或者修改UVM组件的操作,增加新的功能,从而实现一个环境多个用例。此外还可以通过Callback机制构建异常的测试用例。 2. 使用步骤         (1)在UVM组件中内嵌callback函

Lua 脚本在 Redis 中执行时的原子性以及与redis的事务的区别

在 Redis 中,Lua 脚本具有原子性是因为 Redis 保证在执行脚本时,脚本中的所有操作都会被当作一个不可分割的整体。具体来说,Redis 使用单线程的执行模型来处理命令,因此当 Lua 脚本在 Redis 中执行时,不会有其他命令打断脚本的执行过程。脚本中的所有操作都将连续执行,直到脚本执行完成后,Redis 才会继续处理其他客户端的请求。 Lua 脚本在 Redis 中原子性的原因

这些ES6用法你都会吗?

一 关于取值 取值在程序中非常常见,比如从对象obj中取值 const obj = {a:1b:2c:3d:4} 吐槽: const a = obj.a;const b = obj.b;const c = obj.c;//或者const f = obj.a + obj.b;const g = obj.c + obj.d; 改进:用ES6解构赋值

laravel框架实现redis分布式集群原理

在app/config/database.php中配置如下: 'redis' => array('cluster' => true,'default' => array('host' => '172.21.107.247','port' => 6379,),'redis1' => array('host' => '172.21.107.248','port' => 6379,),) 其中cl

Redis的rehash机制

在Redis中,键值对(Key-Value Pair)存储方式是由字典(Dict)保存的,而字典底层是通过哈希表来实现的。通过哈希表中的节点保存字典中的键值对。我们知道当HashMap中由于Hash冲突(负载因子)超过某个阈值时,出于链表性能的考虑,会进行Resize的操作。Redis也一样。 在redis的具体实现中,使用了一种叫做渐进式哈希(rehashing)的机制来提高字典的缩放效率,避

【吊打面试官系列-Redis面试题】说说 Redis 哈希槽的概念?

大家好,我是锋哥。今天分享关于 【说说 Redis 哈希槽的概念?】面试题,希望对大家有帮助; 说说 Redis 哈希槽的概念? Redis 集群没有使用一致性 hash,而是引入了哈希槽的概念,Redis 集群有 16384 个哈希槽,每个 key 通过 CRC16 校验后对 16384 取模来决定放置哪个槽, 集群的每个节点负责一部分 hash 槽。

2021-8-14 react笔记-2 创建组件 基本用法

1、目录解析 public中的index.html为入口文件 src目录中文件很乱,先整理文件夹。 新建components 放组件 新建assets放资源   ->/images      ->/css 把乱的文件放进去  修改App.js 根组件和index.js入口文件中的引入路径 2、新建组件 在components文件夹中新建[Name].js文件 //组件名首字母大写