Redis高频面试题汇总(上)

news2024/11/26 23:38:06

目录

1.什么是Redis?

2.为什么Redis这么快

3.分布式缓存常见的技术选型方案有哪些?

4.你知道 Redis 和 Memcached 的区别吗?

5.Redis使用场景有哪些

6.Redis 常用的数据结构有哪些?

7.Redis 数据类型有哪些底层数据结构?

8.为什么要设计sds?

9.说说zset的底层结构(跳跃表)

10.Redis 一个字符串类型的值能存储最大容量是多少?

11.详细说明Redis 单线程模型

12.为什么要给缓存数据设置过期时间?

13.Redis 是如何判断数据是否过期的呢?

14.说说Redis 内存淘汰机制

15.Redis 的持久化机制是什么?

16.RDB 触发方式? 

17.RDB执行的具体流程

18.AOF是写前日志还是写后日志?

19.如何实现AOF的? 

20.什么是AOF重写?

21.在重写日志整个过程时,主线程有哪些地方会被阻塞?

22.为什么AOF重写不复用原AOF日志?



1.什么是Redis?

Redis是一个开源的内存数据库,它支持持久化存储和多种数据结构,包括字符串、哈希表、列表、集合、有序集合等。Redis被广泛应用于缓存、消息队列、实时统计、排行榜和实时数据分析等场景。

Redis的特点包括:

  1. 高性能:Redis将数据存储在内存中,读写速度非常快。

  2. 多种数据结构:Redis支持多种数据结构,包括字符串、哈希表、列表、集合、有序集合等。

  3. 持久化存储:Redis支持将数据持久化存储到磁盘中,以保证数据不会因为进程终止而丢失。

  4. 分布式支持:Redis支持分布式架构,可以通过多个Redis实例实现数据的分布式存储和负载均衡。

  5. 扩展性好:Redis支持数据的复制和主从同步,可以实现读写分离和高可用性。

总之,Redis是一个功能丰富、性能卓越、易于使用的内存数据库,被广泛应用于各种场景中。

2.为什么Redis这么快

三个原因:

1. Redis 是一种基于 RAM 的数据存储。 RAM 访问至少比随机磁盘访问快 1000 倍。

2. Redis利用IO多路复用和单线程执行循环来提高执行效率。

3. Redis 利用了几个高效的底层数据结构。

3.分布式缓存常见的技术选型方案有哪些?

除了redis。还有Memcached比较常见

Memcached 是一个轻量级的缓存系统,使用简单,性能高,可以处理高并发访问。Memcached 不支持持久化,数据一般在内存中存储,当内存不足时,会根据一致性哈希算法将数据迁移到其他节点上。Memcached 支持多线程,可以同时处理多个请求。

4.你知道 Redis 和 Memcached 的区别吗?

共同点:

  1. 都使用内存作为主要存储介质,可以快速响应读写请求,提高访问速度。
  2. 都支持分布式缓存,可以将数据分散到多个节点中,提高缓存系统的可用性和性能。
  3. 都支持简单的数据结构,如字符串、列表、哈希等,可以满足大部分的缓存需求。

但是,Redis和Memcached也有一些区别:

  1. 数据结构:Redis支持多种数据结构,包括字符串、哈希、列表、集合、有序集合等,每种数据结构都支持不同的操作,可以满足更复杂的缓存需求。而Memcached只支持键值对的存储,操作相对简单。
  2. 持久化:Redis支持数据持久化,可以将数据保存到磁盘上,避免数据丢失。而Memcached不支持持久化,数据一般在内存中存储,当内存不足时,会根据一致性哈希算法将数据迁移到其他节点上。
  3. 性能:Redis的性能相对于Memcached更高,尤其是在高并发、复杂数据结构和数据持久化方面,Redis的表现更优秀。但是,Redis的资源消耗也更高一些。
  4. 分布式锁:Redis支持分布式锁的实现,而Memcached没有原生支持分布式锁的功能,需要通过其他方式实现。

5.Redis使用场景有哪些

列举一些常见的使用场景:

  1. 缓存:Redis最常见的使用场景就是缓存。由于Redis使用内存作为存储介质,因此可以快速响应读写请求,提高访问速度。可以将热点数据缓存到Redis中,避免频繁访问数据库,从而提高应用程序的性能。

  2. 消息队列:Redis的发布订阅机制可以用来构建简单的消息队列系统。可以将消息发布到Redis中的频道,订阅该频道的客户端可以收到该消息,从而实现消息的发布和消费。

  3. 分布式锁:Redis可以用来实现分布式锁。由于Redis支持原子性操作,可以使用Redis实现分布式锁,避免多个进程同时访问共享资源,从而保证系统的数据一致性和安全性。

  4. 计数器:Redis支持原子性操作,可以用来实现计数器。可以将计数器存储在Redis中,多个客户端可以同时对计数器进行操作,从而实现分布式计数器的功能。

  5. 地理位置应用:Redis支持地理位置数据类型,可以用来存储地理位置信息,如经纬度等,从而实现地理位置应用。

  6. 实时排行榜:Redis可以用来存储实时数据,并根据数据进行排序,可以用来实现实时排行榜功能。

  7. 会话管理:Redis可以用来存储会话数据,如用户信息、登录状态等,从而实现会话管理的功能。

6.Redis 常用的数据结构有哪些?

Redis支持多种数据结构,包括以下常用的数据结构:

  1. 字符串(string):字符串是Redis最基本的数据结构之一,可以存储字符串、整数和浮点数等数据类型。

  2. 哈希(hash):哈希是一个键值对的集合,可以存储多个字段和值,类似于一个小型的关系型数据库。

  3. 列表(list):列表是一个有序的字符串集合,可以在列表的两端进行插入和删除操作,支持队列和栈等多种数据结构。

  4. 集合(set):集合是一个无序的字符串集合,可以对集合进行添加、删除、交集、并集等操作,可以用来进行数据去重。

  5. 有序集合(sorted set):有序集合是一个有序的字符串集合,每个元素都有一个分值,可以进行排名、区间查询等操作,常用于实现排行榜和计分系统等功能。

三种特殊的数据类型 分别是 HyperLogLogs(基数统计), Bitmaps (位图) 和 geospatial (地理位置)

7.Redis 数据类型有哪些底层数据结构?

Redis支持以下5种主要数据类型,每种类型在底层都有不同的数据结构实现:

  1. String(字符串):底层采用简单动态字符串(SDS)实现,支持二进制安全操作。

  2. Hash(哈希):底层采用哈希表实现,支持快速的查找、插入和删除操作。

  3. List(列表):底层采用双向链表实现,支持在头部和尾部进行快速的插入和删除操作。

  4. Set(集合):底层采用哈希表或者跳跃表实现,支持高效的集合运算操作,比如并集、交集、差集等。

  5. Sorted Set(有序集合):底层采用跳跃表和哈希表结合实现,同时支持按照分值(score)排序和按照成员(member)排序两种方式进行排序操作。

8.为什么要设计sds?

Redis设计了SDS(Simple Dynamic String)简单动态字符串,主要是为了解决C语言中传统的字符数组(char array)存在的一些问题,如以下几点:

  1. 空间不易动态调整:C语言的字符数组在定义时需要指定其长度,如果长度不够时需要重新定义一个更大的数组,再将原来数组中的数据拷贝到新数组中,这样的操作十分繁琐且容易出错。

  2. 不支持二进制安全:C语言的字符数组中以'\0'作为结束符,因此不支持存储二进制数据或者包含'\0'字符的字符串。

  3. 性能问题:C语言的字符数组在获取其长度时需要遍历整个数组才能计算出长度,效率较低。

SDS通过维护一个buf指针指向动态分配的内存,同时记录字符串的长度信息,可以解决上述问题,其优点如下:

1.动态扩容

SDS 的内部结构是由长度、可用空间和字符数组组成。可用空间指的是字符串数组中未被使用的空间。相比于 C 语言原生字符串类型,SDS 可以进行动态扩容,即在字符串长度超过可用空间时,自动增加可用空间。这种设计使得 SDS 的操作更加高效,避免了多次重新分配内存和复制字符串的开销。

2.减少缓冲区溢出的风险

C 语言原生字符串类型没有对长度进行限制,如果字符串长度超过了字符数组的长度,就会出现缓冲区溢出的问题。SDS 设计了一个 buf 属性,用于存储字符串的实际内容,这个 buf 数组的长度被控制在字符串的实际长度之内,从而避免了缓冲区溢出的风险。

3.兼容 C 语言原生字符串类型

为了兼容 C 语言原生字符串类型,SDS 在内部结构中保留了一个空字符('\0')。这使得 SDS 在与其他 C 语言函数交互时,能够像原生字符串一样正常工作。

4.二进制安全

C 语言原生字符串类型是以空字符('\0')作为字符串的结束标志的,这意味着它只能存储文本数据。SDS 则是二进制安全的,可以存储任何二进制数据。这种设计使得 SDS 在 Redis 中存储键和值时非常有用。

5.优化字符串操作

SDS 内部结构中存储了字符串的长度信息,这使得获取字符串长度的操作 O(1) 时间复杂度。此外,SDS 还提供了一些其他字符串操作函数,如字符串追加、字符串复制等,这些函数都比 C 语言原生的字符串操作函数更加高效。

Redis7.0 的 SDS 的部分源码如下(https://github.com/redis/redis/blob/7.0/src/sds.h):

/* Note: sdshdr5 is never used, we just access the flags byte directly.
 * However is here to document the layout of type 5 SDS strings. */
struct __attribute__ ((__packed__)) sdshdr5 {
    unsigned char flags; /* 3 lsb of type, and 5 msb of string length */
    char buf[];
};
struct __attribute__ ((__packed__)) sdshdr8 {
    uint8_t len; /* used */
    uint8_t alloc; /* excluding the header and null terminator */
    unsigned char flags; /* 3 lsb of type, 5 unused bits */
    char buf[];
};
struct __attribute__ ((__packed__)) sdshdr16 {
    uint16_t len; /* used */
    uint16_t alloc; /* excluding the header and null terminator */
    unsigned char flags; /* 3 lsb of type, 5 unused bits */
    char buf[];
};
struct __attribute__ ((__packed__)) sdshdr32 {
    uint32_t len; /* used */
    uint32_t alloc; /* excluding the header and null terminator */
    unsigned char flags; /* 3 lsb of type, 5 unused bits */
    char buf[];
};
struct __attribute__ ((__packed__)) sdshdr64 {
    uint64_t len; /* used */
    uint64_t alloc; /* excluding the header and null terminator */
    unsigned char flags; /* 3 lsb of type, 5 unused bits */
    char buf[];
};

通过源码可以看出,SDS 共有五种实现方式 SDS_TYPE_5(并未用到)、SDS_TYPE_8、SDS_TYPE_16、SDS_TYPE_32、SDS_TYPE_64,其中只有后四种实际用到。Redis 会根据初始化的长度决定使用哪种类型,从而减少内存的使用。

类型字节
sdshdr5< 1<8
sdshdr818
sdshdr16216
sdshdr32432
sdshdr64864

对于后四种实现都包含了下面这 4 个属性:

  • len :字符串的长度也就是已经使用的字节数
  • alloc:总共可用的字符空间大小,alloc-len 就是 SDS 剩余的空间大小
  • buf[] :实际存储字符串的数组
  • flags :低三位保存类型标志

9.说说zset的底层结构(跳跃表)

跳跃表支持平均O(logN),最坏O(N)复杂度查找 ,zset(有序集合)的底层实现

zset特性:

  • 不重复但有序的字符串元素集合;
  • 每个元素均关联一个double类型的score,Redis 根据score进行从小到大排序;
  • score可以重复,重复的按照插入顺序进行排序;

zskiplistNode 结构体包含了元素值、分值、后退指针和层级指针数组。层级指针数组中的每个元素包含了当前节点在对应层级的下一个节点和当前节点到下一个节点的跨度,用于计算排名和删除节点时的操作。

在 Redis 中,跳跃表中的元素被用于实现有序集合,每个元素都包含了一个值和一个分值,其中分值用于对元素进行排序。因此,zskiplistNode 结构体中的 obj 指针指向了一个 Redis 对象(robj),该对象包含了元素的值,而 score 则表示元素的分值。

除了元素值和分值之外,zskiplistNode 结构体中还包含了一个后退指针,指向当前节点的前一个节点。后退指针的作用是,方便在跳跃表中进行反向遍历。

/* ZSETs use a specialized version of Skiplists */
typedef struct zskiplistNode {
	//数据
    sds ele;
    //节点分值
    double score;
    //节点的后退指针
    struct zskiplistNode *backward;
    struct zskiplistLevel {
        //节点的前进指针
        struct zskiplistNode *forward;
        //跨度
        unsigned long span;
    } level[];
} zskiplistNode;
typedef struct zskiplist {
	//跳跃表的头结点和尾节点
    struct zskiplistNode *header, *tail;
    //跳跃表的长度
    unsigned long length;
    //跳跃表的层数
    int level;
} zskiplist;

最后,跳跃表节点的层级指针数组是跳跃表实现中的核心部分,用于实现快速查找和删除。每个节点的层级数组都包含了若干个指针,指向当前节点在各个层级上的下一个节点。层级指针数组的长度是根据随机算法生成的,每个节点的层级数不同,最大值为 32。层级指针数组中每个元素还包含了一个 span 属性,表示当前节点到下一个节点的跨度,用于计算排名。

10.Redis 一个字符串类型的值能存储最大容量是多少?

Redis字符串类型的值最大可以存储512MB的数据。如果需要存储更大的数据,可以将数据分为多个小于512MB的块,分别存储在多个字符串类型的键中,或者使用Redis的其他数据结构来存储数据。

11.详细说明Redis 单线程模型

Redis是单进程单线程的模型,官方提供的数据是可以达到100000+的QPS(每秒内查询次数)

效率为何高:

1,纯内存操作

2,基于非阻塞的IO多路复用机制

3,避免了多线程的频繁上下文切换

Redis 基于 Reactor 模式开发了自己的网络事件处理器 - 文件事件处理器,而该处理器又是单线程的,所以redis设计为单线程模型。

Reactor模式是一种事件驱动的设计模式,它的核心思想是将事件处理分为两个阶段:事件分发和事件处理。在事件分发阶段,系统会通过一个事件循环(Event Loop)不断地监听事件;在事件处理阶段,当一个事件发生时,系统会将事件交给相应的事件处理器进行处理。这种模式可以减少系统中的线程数量,并且能够提高系统的可伸缩性和性能。

在Redis中,事件循环被称为"main loop",它会监听所有的网络事件和文件事件,并将这些事件加入到一个事件队列中。当事件队列中有事件时,Redis会调用相应的事件处理器进行处理。在处理器的执行过程中,Redis会调用内部的数据结构和算法来高效地处理数据。

此外,Redis还使用了多路复用技术来实现事件监听,即使用一个线程监听多个网络连接,以此来避免线程切换的开销,并提高系统的性能。

12.为什么要给缓存数据设置过期时间?

Redis 给缓存数据设置过期时间的主要作用是为了控制缓存数据的生命周期,

1.确保缓存中的数据不会一直存在,从而保证缓存的有效性和减轻内存压力。

2.业务需求。

具体来说,当 Redis 中的某个键值对设置了过期时间后,在该时间到达之后,Redis 会自动将这个键值对从缓存中删除,这样就可以及时释放缓存空间,避免因缓存过期而导致的内存浪费问题。同时,当客户端请求某个键值对时,如果 Redis 发现该键值对已经过期,它会返回空值或者重新加载最新数据到缓存中。

除此之外,设置过期时间还有助于防止缓存击穿和缓存雪崩等问题的发生。当缓存击穿时,大量请求同时请求一个不存在于缓存中但是在数据库中存在的数据,导致数据库压力过大;而缓存雪崩则是指因为缓存中大量的键值对同时过期而导致数据库压力骤增的情况。设置过期时间可以有效地避免这些问题的发生。

13.Redis 是如何判断数据是否过期的呢?

Redis 通过使用惰性删除和定期删除两种方式来判断数据是否过期。

1.惰性删除

惰性删除是指当 Redis 客户端请求某个键值对时,Redis 在返回数据之前先检查这个键值对是否过期,如果过期则删除并返回空值或者重新加载最新数据到缓存中。这种方式的优点是能够保证数据的实时性,缺点是需要在客户端请求时才能发现过期的数据,可能会导致一些请求响应时间变长。

2.定期删除

定期删除是指 Redis 在后台启动一个定时器,定期检查所有设置了过期时间的键值对,如果发现某个键值对已经过期,则删除该键值对。Redis 通过使用一个叫做「过期字典」的结构来保存所有设置了过期时间的键值对,这个字典中的键是键值对的键,值是键值对的过期时间戳。当定期删除器执行时,Redis 会遍历过期字典,删除所有过期的键值对。

为了平衡惰性删除和定期删除的优缺点,Redis 使用了一种混合策略。当一个键过期时,Redis 会将其添加到一个过期字典中,并使用惰性删除策略来清理过期键。此外,Redis 还会周期性地执行定期删除任务,来清理那些惰性删除未能及时清理的过期键。

为了避免过期键过多堆积在内存中,Redis 在过期键的清理过程中会使用一些技术手段,如:使用分区技术将过期键分散到不同的区域中,限制每个定期删除任务处理的过期键数量等。

14.说说Redis 内存淘汰机制

Redis 实现了多种内存淘汰机制。以下是 Redis 内存淘汰机制的几种常见实现方式:

  1. LRU (Least Recently Used) 最近最少使用算法:Redis 使用 LRU 算法来选择要淘汰的键。LRU 算法会优先淘汰最近最少使用的键,即最近很少或没有被访问过的键。

  2. LFU (Least Frequently Used) 最不经常使用算法:Redis 使用 LFU 算法来选择要淘汰的键。LFU 算法会优先淘汰使用次数最少的键,即最近很少或没有被访问过的键。

  3. Random 随机算法:Redis 也可以使用随机算法来选择要淘汰的键。随机算法会从所有的键中随机选择一个键来淘汰。

  4. TTL (Time To Live) 过期时间算法:Redis 还可以根据键的过期时间来淘汰键。当 Redis 内存不足时,它会优先淘汰已过期的键。

15.Redis 的持久化机制是什么?

Redis 的持久化机制是指将 Redis 的数据持久化到磁盘上,以防止数据丢失。Redis 提供了两种不同的持久化机制:RDB 和 AOF。

1.RDB(Redis DataBase)持久化机制

RDB 是 Redis 默认的持久化机制。RDB 机制会在指定的时间间隔内,对 Redis 数据进行快照(snapshot)并写入磁盘中的 RDB 文件。RDB 文件是一个二进制文件,其中包含了 Redis 在某个时间点上的数据快照。

优点:

  • RDB 文件较小,适用于备份和恢复大量数据。
  • 由于 RDB 文件是二进制的,因此可以更快地加载。
  • 在数据集较大时,RDB 在恢复数据时比 AOF 更快。

缺点:

  • 如果 Redis 发生宕机,最近一次保存的 RDB 文件中的数据将会丢失,可能导致一定程度的数据损失。
  • 由于 RDB 是周期性执行,因此如果 Redis 宕机时,最后一次持久化的数据与宕机前的数据相差较大,可能会导致数据丢失。

2.AOF(Append-Only File)持久化机制

AOF 机制会记录所有写命令,并将这些写命令追加到磁盘中的 AOF 文件中。当 Redis 重启时,可以通过重新执行 AOF 文件中的所有命令,恢复数据。

优点:

  • AOF 文件包含 Redis 服务器执行的所有写操作,因此可以最大程度地减少数据丢失。
  • AOF 文件采用文本格式,易于阅读和调试。
  • AOF 机制支持多种同步方式,包括 no、always 和 everysec 三种方式,可以根据需求选择适合的方式。

缺点:

  • AOF 文件比 RDB 文件大,适合备份和恢复较小量的数据。
  • AOF 机制需要不断地将写命令追加到 AOF 文件中,因此在写入性能方面可能会受到影响。

一般情况下,需要根据实际情况来选择合适的持久化机制。如果数据集较小,可以使用 AOF 机制以最大程度地减少数据丢失;如果数据集较大,可以使用 RDB 机制以较小的成本备份和恢复数据。

同时,也可以将 RDB 和 AOF 机制结合使用,以充分利用它们各自的优势。例如,可以将 AOF 机制设置为 always,并使用 RDB 机制定期进行数据备份。这样既能保证数据不丢失,也能在数据集较大时提高恢复数据的速度。

16.RDB 触发方式? 

手动触发:执行save命令,问题:数据量大会阻塞当前服务器,直到rdb完,生产环境禁用!

解决方案:用bgsave命令(background save),也就是后台备份,主进程会fork一个子进程来完成RDB的过程,完成后自动结束(操作系统的多进程Copy On Write机制,简称COW)。fork的时候也会阻塞子进程,但是时间很短;

自动触发:

1,配置redis.conf,配置触发规则,自动执行:

# 当在规定的时间内,Redis发生了写操作的个数满足条件,会触发发生BGSAVE命令。
# save <seconds> <changes>
# 当用户设置了多个save的选项配置,只要其中任一条满足,Redis都会触发一次BGSAVE操作
save 900 1 
save 300 10 
save 60 10000
# 以上配置的含义:900秒之内至少一次写操作、300秒之内至少发生10次写操作、
# 60秒之内发生至少10000次写操作,只要满足任一条件,均会触发bgsave

2,执行shutdown命令关闭服务器时,如果没有开启AOF持久化功能,那么会自动执行一次bgsave

3,主从同步(slave和master建立同步机制)

从库和主库建立连接后,主库会执行bgsave将当前备份数据传给从库,同时也会缓存备份过程中进来的写操作

17.RDB执行的具体流程

redis主要是用操作系统的多进程cow(copy on write)机制来实RDB快照持久化;

1,执行bgsave时,主线程会先判断是否有子进程在执行rdb/aof持久化任务,如果有直接返回。

2,主进程会fork出一个子进程,fork过程中会对主进程有短暂的阻塞。

3,子进程会根据主进程的内存生成临时的快照文件,持久化完成后会替换掉原来的rdb文件,由于备份的过程中还会不断的有新的写请求进来,这些写操作不会在主进程的主内存中(也就是备份时正在读的内存)。会写到一个临时的内存区域作为副本。

4,子进程完成RDB持久化后会通知主进程,并且会将备份期间写道临时内存的写数据同步到主内存。

18.AOF是写前日志还是写后日志?

AOF是一种写后日志机制,也就是说,当Redis执行写操作时,它首先会将命令追加到内存中的AOF缓冲区中,等待同步到硬盘。只有当命令成功被追加到AOF文件中并同步到硬盘后,Redis才会执行实际的写操作。因此,即使Redis在写操作期间发生崩溃,已经被追加到AOF缓冲区中但尚未同步到硬盘中的命令也不会丢失,可以通过重放AOF文件来恢复数据。

由于写后日志机制不需要立即将每个写操作同步到硬盘中,因此可以大大提高Redis的写入性能。在使用写前日志机制时,每个写操作都必须等待同步到硬盘后才能返回客户端,这会造成较大的延迟,尤其是在写入负载较高的情况下。而采用写后日志机制后,Redis可以将写操作先保存到内存中的缓冲区,然后异步地将缓冲区中的内容写入硬盘,从而大大提高了写入性能。

其次,采用写后日志机制还可以提高Redis的可靠性。由于AOF文件记录了Redis执行的每个写操作,因此即使Redis在运行过程中发生崩溃,也可以通过重放AOF文件来恢复数据。而如果采用写前日志机制,由于每个写操作必须立即同步到硬盘中,一旦发生崩溃就会导致数据的丢失。

19.如何实现AOF的? 

要实现AOF(Append-Only File)机制,需要在Redis配置文件中启用AOF功能,并设置AOF的相关参数。在Redis中,可以通过以下步骤来实现AOF:

  1. 启用AOF功能:在Redis的配置文件redis.conf中,可以通过将appendonly参数设置为yes来启用AOF功能。例如:appendonly yes

  2. 设置AOF文件名和路径:可以通过设置dir和appendfilename参数来指定AOF文件的保存路径和文件名。例如:dir /var/lib/redisappendfilename "appendonly.aof"

  3. 设置AOF的同步策略:可以通过设置appendfsync参数来指定AOF的同步策略,即指定何时将AOF缓冲区中的数据同步到硬盘中的AOF文件中。Redis提供了以下三种同步策略:

  • always:每个写操作都会立即同步到硬盘中的AOF文件中,保证数据完整性,但是性能较低。

  • everysec:每秒钟将AOF缓冲区中的数据同步到硬盘中的AOF文件中,可以在一定程度上提高性能,但是可能会丢失1秒钟的数据。

  • no:将AOF缓冲区中的数据定期刷写到硬盘中的AOF文件中,性能最高,但可能会导致数据的丢失。

例如:appendfsync everysec

        4.重启Redis服务:在修改了Redis配置文件中的AOF相关参数后,需要重启Redis服务才能使配置生效。

20.什么是AOF重写?

aof Rewrite 是压缩aof文件的过程,但不是基于原文件进行压缩,而是类似于RDB快照的方式,基于COPY ON WRITE,遍历内存中的数据,将最终态的数据以命令的形式存储,相当于一条数据可能经过多次操作对应多条命令,但是最终会变成一个命令来表示最终状态就可以了。

和rdb一样,重写也是需要fork子进程,在子进程中完成的,重写过程中,新的操作还是会写入原aof文件,同时这些操作也会被redis收集起来。当重写完成后,这些操作也会被追加到新的aof文件中。

触发机制

手动触发:直接调用bgrewriteaof命令执行一次重写操作

自动触发:根据auto-aof-rewrite-min-size和auto-aof-rewrite-percentage参数确定自动触发时机

auto-aof-rewrite-min-size:表示运行AOF重写时文件最小体积,默认为64MB(我们线上是512MB)。

auto-aof-rewrite-percentage:相对于“上一次”rewrite,本次rewrite触发时aof文件应该增长的百分比。 代表当前AOF文件空间(aof_current_size)和上一次重写后AOF文件空间(aof_base_size)的值

21.在重写日志整个过程时,主线程有哪些地方会被阻塞?

  1. 在 Redis fork 子进程时,需要拷贝父进程的内存映射表,这个操作会阻塞主线程。

  2. 在 Redis 主进程写入 bigkey 数据时,操作系统会为该数据创建一个页面的副本,并拷贝原有的数据,这个操作也会阻塞主线程。

  3. 在 AOF 重写过程中,子进程会独立执行重写操作,但是在子进程执行完毕之后,子进程会发送一个信号给主进程,让主进程将重写缓冲区的内容追加到 AOF 文件中。这个操作可能会阻塞主线程。

22.为什么AOF重写不复用原AOF日志?

  1. 父子进程写同一个文件会产生竞争问题,影响父进程的性能。
  2. 如果AOF重写过程中失败了,相当于污染了原本的AOF文件,无法做恢复数据使用。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

sonarqube指标详解

最近公司引入了sonar&#xff0c;作为代码质量检测工具&#xff0c;以期提高研发同学的代码质量&#xff0c;但是结果出来后&#xff0c;有些同学不清楚相应的指标内容&#xff0c;不知道应该重点关注哪些指标&#xff0c;于是查询了一下相关的资料&#xff0c;加以总结同时也分…

【数据结构】堆排序

堆是一种叫做完全二叉树的数据结构&#xff0c;可以分为大根堆&#xff0c;小根堆&#xff0c;而堆排序就是基于这种结构而产生的一种程序算法。大堆&#xff1a;每个节点的值都大于或者等于他的左右孩子节点的值小堆&#xff1a;每个结点的值都小于或等于其左孩子和右孩子结点…

扬帆优配|业务量大突破,这个行业发展明显向好

近期上市的新股&#xff0c;大都在招股阐明书里公布了本年第一季度成绩预告。 我国快递事务量本年已达200亿件 国家邮政局监测数据显现&#xff0c;到3月8日&#xff0c;本年我国快递事务量已到达200.9亿件&#xff0c;比2019年到达200亿件提前了72天&#xff0c;比2022年提前…

goland开发环境搭建及运行第一个go程序HelloWorld

1、下载和安装golang 点击进入下载页面 下载好安装包&#xff0c;点击安装。 我之前安装过低版本的安装包&#xff0c;所以这里提示要先卸载已经安装过的低版本的。 同意协议&#xff0c;继续安装。 默认安装的文件夹为C盘&#xff0c;建议更改&#xff0c;我这里更改为D盘…

YOLOv5训练大规模的遥感实例分割数据集 iSAID从切图到数据集制作及训练

最近想训练遥感实例分割&#xff0c;纵观博客发现较少相关 iSAID数据集的切分及数据集转换内容&#xff0c;思来想去应该在繁忙之中抽出时间写个详细的教程。 iSAID数据集下载 iSAID数据集链接 下载上述数据集。 百度网盘中的train和val中包含了实例和语义分割标签。 上述…

哪些职业适合创业?学习哪些技能可以自己创业?

创意行业&#xff1a;创意行业包括广告、设计、影视等领域&#xff0c;需要创新思维和创意能力&#xff0c;适合创业。学习创意思维、平面设计、影视制作等技能可以自己创业。 科技行业&#xff1a;科技行业包括互联网、人工智能、物联网等领域&#xff0c;需要技术能力和创新思…

基于JavaEE开发博客系统项目开发与设计(附源码)

文章目录1.项目介绍2.项目模块3.项目效果1.项目介绍 这是一个基于JavaEE开发的一个博客系统。实现了博客的基本功能&#xff0c;前台页面可以进行文章浏览&#xff0c;关键词搜索&#xff0c;登录注册&#xff1b;登陆后支持对文章进行感谢、评论&#xff1b;然后还可以对评论…

[网络工程师]-网络规划与设计-逻辑网络设计(二)

3、广域网技术选择 3.1广域网互连技术 3.1.1 数字数据网络 数字数据网络(Digital Data Network,DDN)是一种利用数字信道提供数据信号传输的数据传输网,是一个半永久性连接电路的公共数字数据传输网络,为用户提供了一个高质量、高带宽的数字传输通道。 利用DDN网络实现局…

【C++】7.string

1.标准库的string类 string是表示字符串的字符串类在使用string类时&#xff0c;必须包含#include头文件以及using namespace std;string类是使用char(即作为它的字符类型&#xff0c;使用它的默认char_traits和分配器类型(关于模板的更多信息&#xff0c;请参阅basic_string)…

智能网联汽车安全芯片介绍(一)

汽车的新四化(电动化、网联化、智能化、共享化)让汽车安全越来越受到重视,比如一个不太容易被破解的汽车遥控钥匙或者非接触开门等,越智能越开始需要安全。而过去的一些安全事件也凸显了安全的必要性。 黑客早已经盯上了汽车。2015年,Charlie Miller 、 Chris Valsek曾通过…

熟悉mmdetection3d数据在模型中的处理流程

目录1、搭建模型2、读取数据3、运行流程3.1 图像特征获取3.2 点云特征获取3.3 head3.4 编码bbox4、可视化5、总结本图文数据集采取KITTI数据集配置文件的介绍可以参考博主上一篇图文本图文旨在利用一条数据&#xff0c;走完整个多模态数据处理分支&#xff0c;获得bbox&#xf…

Linux内核里的传输层数据流

传输层发送数据包socket sendto系统调用应用程序通过socket调用sendto系统调用发送数据包&#xff0c;根据网络层协议调用inet_sendmsg或者inet6_sendmsg()函数&#xff0c;将数据包送入协议栈发送。SYSCALL_DEFINE6(sendto...) - net/socket.csock_sendmsg() - net/socket.cso…

compose系列教程-2. 显示图片

要在Android中使用Compose显示图片&#xff0c;需要使用Image组件。以下是一个简单的例子&#xff0c;它显示了一张图片&#xff1a; Composable fun MyApp() { val image painterResource(id R.drawable.my_image) Image(painter image, contentDescription "…

dynamics 365的增删改查

今天需要完成对dynamics 365的增删改查&#xff0c;网上一直找不到合适的教程&#xff0c;官方文档看不懂&#xff0c;实在没办法了&#xff0c;于是下载了chatgpt,对他进行了提问。 我&#xff1a;怎么用visual studio基于dynamics 365进行增删改查&#xff1f; ChatGPT 中文…

Python笔记 -- 类

文章目录1、引入2、操作属性3、继承4、将实例用作属性5、导入类1、引入 类和实例 使用类可以模拟任何东西&#xff0c;下面是一个小狗的简单类Dog&#xff0c;它表示任意小狗&#xff0c;实例my_dog表示一个具体的小狗方法 类中的函数称为方法&#xff0c;有关函数的一切均适用…

兔c同学的一篇:使用python 的 unittest模块对类和函数进行测试

文章目录1. 测试函数简单的函数测试单元测试和测试用例可通过的测试不可通过的测试测试未通过时怎么办2. 测试类各种断言方法测试一个类测试 AnonymousSurvey方法setUp()导言 在编写函数或类时&#xff0c;还可为其编写测试。通过测试&#xff0c;可以确定代码面对各种输入都能…

面试官必问--谈谈Spring Bean对象的生命周期吧

现在是时候讨论Spring Bean从产生到销毁整个过程的细节了&#xff0c;也就是Spring Bean的生命周期。在这里文哥先温馨提示&#xff1a;Spring Bean的生命周期是面试高频点之一&#xff0c;希望大家好好掌握哦~一. Spring Bean生命周期的概述如果没有Spring的环境&#xff0c;J…

张力控制之开环模式

张力控制的相关知识也可以参看专栏的其它文章,链接如下: 张力闭环控制之传感器篇(精密调节气阀应用)_RXXW_Dor的博客-CSDN博客跳舞轮对应张力调节范围,我们可以通过改变气缸的气压方式间接改变,张力跳舞轮在收放卷闭环控制上的详细应用,可以参看下面的文章链接,这里我…

人工智能实验一:利用遗传算法求解 TSP(旅行商)问题

1.任务描述 本关任务&#xff1a;利用遗传算法求解 TSP 问题。 2.相关知识 为了完成本关任务&#xff0c;你需要掌握&#xff1a;1. 遗传算法&#xff1b;2. TSP问题。 遗传算法 一个后继状态由两个父状态决定&#xff0c;以k个随机产生的状态开始&#xff08;population&…

Kaggle赛题解析:Diffusion Prompt生成

文章目录一、比赛信息二、比赛背景三、比赛任务四、评价指标五、数据描述六、解题思路一、比赛信息 比赛名称&#xff1a;Stable Diffusion - Image to Prompts 推断生成高度详细、清晰的焦点、插图、宏伟、史诗般的 3d 渲染图像的prompt 比赛链接&#xff1a;https://www.k…