首页 > 数据库 >Redis篇

Redis篇

时间:2024-07-25 15:51:49浏览次数:10  
标签:AOF Redis redis master key 集群

目录

Redis持久化方式

通常两者结合一起使用

方式一:RDB

RDB全称Redis数据备份文件,也叫作Redis数据快照。简单的说就是把内存中的数据都记录到磁盘

1、实现命令

  • 手动
save	# 由Redis主进程执行,会阻塞所有命令
bgsave	# 开启子进程执行,避免影响主进程
  • 配置文件 redis.conf
save 100 1	# 指100秒内至少有一个key被修改时,则执行RDB备份

2、RDB执行原理

RDB执行时会从主进程fork一个子进程,子进程共享主进程的内存空间,实际上是复制了主进程的页表,因此子进程就可以读取内存中的数据到RDB文件中。

fork采用的是copy-on-write技术:

主进程读时,访问共享空间

主进程写时,复制一份副本,再进行写操作

方式二:AOF

AOF全称追加文件,Redis处理的每一个写命令都会记录在AOF文件中

1、开启AOF模式

默认关闭,开启需在redis.conf文件中进行配置:

appendonly=yes,

appendfilename="aofile.aof"

2、AOF记录的频率(又称刷盘策略

在redis.conf文件中配置:

appendfsync always # 每执行一次写命令,立即写入AOF文件

appendfsync everysec(默认) # 写命令执行完先放入缓冲区,每隔1秒从缓冲区写入AOF文件

appendfsync no # 写命令执行完先放入缓冲区,由操作系统决定何时写入AOF文件

3、命令重写

由于AOF是记录命令,通常空间占用会高的多,可以使用命令重写的策略来缩小文件体积,在redis.conf文件中配置如下:

# AOF文件比上次文件 增长超过多少百分比则触发重写
auto-aof-rewrite-percentage 100
# AOF文件体积最小多大以上才触发重写
auto-aof-rewrite-min-size 64mb 

两种持久化方式对比

image-20240514094158065

Redis数据过期策略

主要有惰性删除定时删除两种,定时删除又分为两种模式:SLOWFAST模式

通常两者结合一起使用

1、惰性删除

当key过期后,不立即删除,而是等到需要使用该key时,再进行检查并删除过期key

优点:对CPU友好

缺点:过期key积累对内存占用不友好

2、定时删除

每隔一段时间,就随机的对一些key进行检查,并删除过期key

SLOW:SLOW模式是定时任务,执行频率默认为10hz,每次不超过25ms,以通过修改配置文件redis.conf 的hz选项来调整这个次数

FAST:FAST模式执行频率不固定,但两次间隔不低于2ms,每次耗时不超过1ms

Redis数据淘汰策略

LRU: 最近最少使用算法。用当前时间减去最后一次访问时间,这个值越大则淘汰优先级越高

LFU: 最少频率使用。会统计每个key的访问频率,值越小淘汰优先级越高

redis提供了8中数据淘汰策略:

  1. noeviction

默认策略,不淘汰任何key,但是内存满时不允许写入新数据,并且会直接报错

  1. allkeys-lru

对全体key,基于LRU算法进行淘汰

  1. volatile-lru

对设置了TTL的key,基于LRU算法进行淘汰

  1. allkeys-lfu

对全体key,基于LFU算法进行淘汰

  1. 对设置了TTL的key,基于LFU算法进行淘汰

分布式锁

使用redisson集成的分布式锁有三大好处:

  1. 提供watchdog监控执行线程,可实现锁自动续期,默认10秒一次
  2. 其他线程想要加锁,会进行一定次数的阻塞循环等待
  3. 底层基于LUA脚本,实现了原子操作
  4. 可重入,在redis中进行存储的时候使用的hash结构,来存储线程信息和重入的次数,多个锁重入需要判断是否是当前线程,主要是根据线程ID进行判断

缺点:

不能实现主从一致性

解决方案:

  1. 红锁,缺点是会导致性能变低
  2. 采用zonkeeper实现的CP思想的分布式锁

image-20240514110209194

代码实现:

// 1.构造redisson实现分布式锁必要的Config
Config config = new Config();
config.useSingleServer().setAddress("redis://127.0.0.1:5379").setPassword("123456").setDatabase(0);
// 2.构造RedissonClient
RedissonClient redissonClient = Redisson.create(config);
// 3.获取锁对象实例(无法保证是按线程的顺序获取到)
RLock rLock = redissonClient.getLock(lockKey);
try {
    /**
     * 4.尝试获取锁
     * waitTimeout 尝试获取锁的最大等待时间,超过这个值,则认为获取锁失败
     * leaseTime   锁的持有时间,超过这个时间锁会自动失效(值应设置为大于业务处理的时间,确保在锁有效期内业务能处理完)
     */
    boolean res = rLock.tryLock((long)waitTimeout, (long)leaseTime, TimeUnit.SECONDS);
    if (res) {
        //成功获得锁,在这里处理业务
    }
} catch (Exception e) {
    throw new RuntimeException("aquire lock fail");
}finally{
    //无论如何, 最后都要解锁
    rLock.unlock();
}

如何保证Redis的高并发高可用

主从模式搭建

一、高并发

要想提高redis的并发能力,就需要搭建主从集群,实现读写分离,节点用于操作,节点用于操作

image-20240514161048497

主从数据同步

从节点第一次与主节点建立连接时使用全量同步

image-20240514161230609

image-20240514161327595

二、高可用

如果只是单纯的主从集群模式,并不能保证Redis的高可用性,因此Redis提供了一种保证高可用的哨兵机制,来实现主从集群的自动故障恢复

哨兵机制的三大特点:

  • 监控:Sentinel会不断检查master和slave是否按预期工作,Sentinel基于心跳机制监测服务状态,每隔1秒向集群的每个实例发送ping命令
  • 自动故障恢复:如果master故障,Sentinel会将一个slave提升为master。当故障实例恢复后也以新的master为主
  • 通知:Sentinel充当Redis客户端的服务发现来源,当集群发生故障转移时,会将最新信息推送给Redis的客户端以连接新的master

哨兵模式结构:

image-20240514163126718

脑裂问题

使用哨兵模式时,当master网络卡顿时,选取了一个从节点作为主节点,但是旧的master在网络恢复后处理了之前的写操作,更新了数据,而新master为了同步从节点的数据,把老master的数据清空了,从而导致数据丢失,这种就叫做脑裂问题

  • 解决方法

只需要在redis配置文件中配置

min-replicas-to-write 1   # 表示最少的salve节点为1个
min-replicas-max-lag 5  # 表示数据复制和同步的延迟不能超过5秒

三、分片集群

前面主从哨兵模式解决了高并发高可用的问题,但是仍有两个问题没有解决

  • 海量数据存储问题

  • 高并发写的问题

使用分片集群可以解决上述问题,分片集群特征

  • 集群中有多个master,每个master保存不同数据

  • 每个master都可以有多个slave节点

  • master之间通过ping监测彼此健康状态

  • 客户端请求可以访问集群任意节点,最终都会被转发到正确节点

PS: Redis 分片集群引入了哈希槽的概念,Redis 集群有 16384 个哈希槽,每个 key通过 CRC16 校验后对 16384 取模来决定放置哪个槽,集群的每个节点负责一部分 hash 槽。

Redis是单线程,为什么还能这么快

原因很简单:

  • Redis是纯内存操作,执行速度非常快,并且基于C语言实现

  • 采用单线程,避免不必要的上下文切换可竞争条件,多线程还要考虑线程安全问题

  • 使用I/O多路复用模型,非阻塞IO

四、Redis网络模型

image-20240514170808332

标签:AOF,Redis,redis,master,key,集群
From: https://www.cnblogs.com/six-years/p/18323357

相关文章

  • redis工具类封装,redis的使用方式新增修改删除等,
    publicclassRedisUtil{@ResourceprivateRedisTemplate<String,Object>redisTemplate;privateHashOperations<String,String,Object>hashOperations;publicRedisUtil(RedisTemplate<String,Object>redisTemplate){......
  • redis哨兵实现
    redis单哨兵模式实现:前提:完成redis主从架构https://www.cnblogs.com/lifeiLinux/p/18317986环境: 服务器:54主53和52从 redis版本:3.2.1354机器操作: 配置哨兵配置文件: install-d/fan/etc/redis/ install-d/fan/{logs,data}/sentinel/ cat>/fan/etc/redis/s......
  • Redisson常用的数据结构及应用场景
    Redisson提供了一系列高级数据结构,这些数据结构封装了Redis的原生数据类型,提供了JavaAPI的便利性和分布式特性。以下是Redisson中一些常用的数据结构,场景还在不断完善中:RBucket:这是一个简单的键值对存储,相当于Redis中的String类型。你可以使用它来存储和检索......
  • 第二部分:关键技术领域的开源数据库实践【开源NoSQL数据库保姆级教程之Redis数据库】
    Redis数据库Redis简介Redis(RemoteDictionaryServer:远程字典服务)是完全开源并免费的,遵守BSD协议,是一个高性能的key-value数据库中Redis与其他key-value缓存产品有以下三个特点Redis支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用。Red......
  • redis的持久化和集群模式
    redis的持久化什么是持久化把内存中的数据存储到磁盘的,同时也可以把磁盘中的数据加载到内存中redis实现持久化的方式erdis实现持久化的方式有两种:RDB、AOF第一种RDB(RedisDataBase快照模式,每隔一段时间对内存数据进行快照存储)触发方式手动触发:使用save或bgsave触发r......
  • java连接redis和基础操作命令
    引入依赖<!--引入java连接redis的驱动--><dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>4.3.1</version></dependency>单机模式连接redismain(){//连接redis的信息默......
  • Springboot整合redis
    引入依赖<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency>修改配置文件//单机模式配置spring.redis.host=172.16.7.21 //ip地址spring.redis.port=6379 //端口号s......
  • alpine 3.18.7 编译安装redis7.2.5
    1.安装对应的包apkaddbuild-basegcclibc-devlinux-headers安装makeapkaddmake2.解压缩redis包,tar-xzvfredis-7.2.5.tar.gz#进入src目录cd/root/redis-7.2.5/src3.进行make编译make 但是还是提示jemalloc/jemalloc.h:Nosuch......
  • 【分布式锁】Redis实现分布式锁
    在分布式系统中,当多个服务实例(或节点)需要访问或修改同一份共享资源时,就需要使用分布式锁来确保数据的一致性和防止并发问题。这种情况下,传统的Java并发控制机制如ReentrantLock或synchronized就无法满足需求,因为它们是JVM级别的锁,只能保证单个JVM实例内部的线程同步,而无法......
  • Prometheus监控Redis
    Redis是一个广泛使用的内存数据库和缓存系统。使用Prometheus监控Redis可以帮助我们实时了解Redis的性能和健康状况。本文将详细介绍如何使用Prometheus来监控Redis。1.RedisExporterRedisExporter是连接Redis和Prometheus的桥梁,它负责从Redis收集指标并以Prometheus可以......