温故而知新,一文锤实Redis知识图谱(6)

在这里插入图片描述

🏆作者简介,普修罗双战士,一直追求不断学习和成长,在技术的道路上持续探索和实践。
🏆多年互联网行业从业经验,历任核心研发工程师,项目技术负责人。
🎉欢迎 👍点赞✍评论⭐收藏

🔎 Redis 领域知识 🔎

链接专栏
Redis 数据库专业知识学习一Redis专栏
Redis 数据库专业知识学习二Redis专栏
Redis 数据库专业知识学习三Redis专栏
Redis 数据库专业知识学习四Redis专栏
Redis 数据库专业知识学习五Redis专栏
Redis 数据库专业知识学习六Redis专栏

文章目录


在这里插入图片描述

🔎一、Redis知识文集学习(6)

🍁01 什么是Redis?

Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库、缓存和消息队列。它支持多种数据结构,如字符串、列表、集合、有序集合和哈希表。Redis 速度非常快,因为它使用了内存作为存储介质。它还支持持久化,可以将数据定期保存到磁盘。
Redis 是用 C 语言编写的,并且可以跨平台运行。它支持 Linux、Windows、Mac OS X 和 Solaris。
Redis 非常适合用作缓存,因为它可以非常快速地检索数据。它还可以用作数据库,因为它支持多种数据结构。Redis 还可以用作消息队列,因为它支持发布/订阅模式。
Redis 是一个非常强大的数据结构存储系统,它可以用于许多不同的应用程序。它是许多大型网站和应用程序的关键组件。
以下是 Redis 的一些特性:

  • 速度非常快,因为它使用了内存作为存储介质。
  • 支持多种数据结构,如字符串、列表、集合、有序集合和哈希表。
  • 支持持久化,可以将数据定期保存到磁盘。
  • 跨平台运行,可以运行在 Linux、Windows、Mac OS X 和 Solaris 上。
  • 用 C 语言编写,可移植性强。

Redis 是一个非常强大的数据结构存储系统,它可以用于许多不同的应用程序。它是许多大型网站和应用程序的关键组件。

🍁02 Redis为啥那么快?

Redis 之所以很快,主要有以下几个原因:

  • Redis 使用了内存作为存储介质。内存的访问速度比磁盘快得多,因此 Redis 可以非常快速地检索数据。
  • Redis 使用了单线程模型。单线程模型可以避免多线程带来的竞争条件和锁竞争,从而提高性能。
  • Redis 使用了 C 语言编写。C 语言是编写高性能程序的理想语言。
  • Redis 使用了许多优化技术,如哈希表压缩、惰性过期删除、LRU 缓存淘汰等。这些技术可以进一步提高 Redis 的性能。

总之,Redis 之所以很快,是因为它使用了内存作为存储介质、使用了单线程模型、使用了 C 语言编写,以及使用了许多优化技术。

🍁03 Redis对象有哪5种类型?

Redis 支持五种数据类型:字符串、列表、集合、有序集合和哈希表。

  • 字符串:字符串是 Redis 中最简单的数据类型,它可以存储任何类型的数据,包括字符串、数字、二进制数据等。
  • 列表:列表是一个有序的集合,可以存储多个字符串。列表可以使用 LPUSH 和 RPUSH 命令添加元素,使用 LPOP 和 RPOP 命令删除元素。
  • 集合:集合是一个无序的集合,可以存储多个字符串。集合可以使用 SADD 和 SREM 命令添加和删除元素。
  • 有序集合:有序集合是一个有序的集合,可以存储多个字符串。有序集合可以使用 ZADD 和 ZREM 命令添加和删除元素。有序集合中的元素还可以按照分值进行排序。
  • 哈希表:哈希表是一个键值对的集合,可以存储多个键值对。哈希表可以使用 HSET 和 HGET 命令添加和获取键值对。

以下是 Redis 五种数据类型的使用示例:

* 字符串:
SET key value
GET key

* 列表:
LPUSH key value
RPUSH key value
LPOP key
RPOP key

* 集合:
SADD key value
SREM key value

* 有序集合:
ZADD key score value
ZREM key value

* 哈希表:
HSET key field value
HGET key field

更多关于 Redis 数据类型的使用方法,可以参考 Redis 官方文档:https://redis.io/docs/

🍁04 Reids常用的字符串数据类型和C语言相比较?

Redis 的字符串数据类型和 C 语言的字符串数据类型有以下几个区别:

  • Redis 的字符串是二进制安全的,这意味着可以存储任何类型的数据,包括二进制数据。C 语言的字符串只能存储字符串数据。
  • Redis 的字符串可以动态增长,这意味着可以向字符串中添加数据,而不需要重新分配内存。C 语言的字符串是固定长度的,如果需要添加数据,则需要重新分配内存。
  • Redis 的字符串可以使用 LRU 缓存淘汰算法,这可以防止内存不足。C 语言的字符串没有内存管理功能。

使用表格说明Redis字符串数据类型和C语言字符串数据类型的区别如下:

Redis 字符串数据类型C 语言字符串数据类型区别
二进制安全非二进制安全Redis 的字符串可以存储任何类型的数据,包括二进制数据。C 语言的字符串只能存储字符串数据。
动态增长固定长度Redis 的字符串可以动态增长,这意味着可以向字符串中添加数据,而不需要重新分配内存。C 语言的字符串是固定长度的,如果需要添加数据,则需要重新分配内存。
LRU 缓存淘汰算法Redis 的字符串可以使用 LRU 缓存淘汰算法,这可以防止内存不足。C 语言的字符串没有内存管理功能。

总的来说,Redis 的字符串数据类型比 C 语言的字符串数据类型更灵活和高效。

🍁05 Redis如何做内存优化?

Redis 的内存优化主要包括以下几个方面:

  • 使用内存敏感的数据结构。Redis 支持多种数据结构,其中一些数据结构比其他数据结构更占用内存。例如,哈希表比列表更占用内存。因此,在选择数据结构时,应考虑到内存使用情况。
  • 使用内存压缩。Redis 支持内存压缩,可以减少内存使用量。例如,Redis 可以使用 LZF 压缩算法来压缩字符串。
  • 使用惰性过期删除。Redis 可以使用惰性过期删除,可以减少内存使用量。例如,如果一个键的过期时间为 1 天,但它在 1 天内没有被访问,那么 Redis 不会立即删除这个键。只有当这个键被访问时,Redis 才会删除它。
  • 使用 LRU 缓存淘汰算法。Redis 可以使用 LRU 缓存淘汰算法来淘汰最不常用的键。LRU 缓存淘汰算法可以保证最常用的键不会被淘汰。
  • 使用内存碎片整理。Redis 可以使用内存碎片整理来整理内存碎片。内存碎片整理可以减少内存使用量。

通过以上这些方法,可以有效地优化 Redis 的内存使用。

🍁06 Redis常用管理命令?

Redis 常用的管理命令包括:

  1. PING:检查 Redis 服务器是否运行。
  2. INFO:获取 Redis 服务器的各种信息和统计数据。
  3. CONFIG GET/SET:获取或设置 Redis 服务器的配置参数。
  4. DBSIZE:获取当前数据库中的键的数量。
  5. KEYS:列出符合指定模式的键。
  6. FLUSHDB:清空当前数据库中的所有键。
  7. FLUSHALL:清空所有数据库中的所有键。
  8. SAVE:将数据同步保存到磁盘。
  9. BGSAVE:在后台异步保存数据到磁盘。
  10. BGREWRITEAOF:在后台异步重写 AOF 文件。
  11. CLIENT LIST:列出连接到服务器的客户端信息。
  12. MONITOR:实时监视服务器接收到的命令。
  13. SLOWLOG GET:获取慢查询日志。
  14. CONFIG REWRITE:重写配置文件。
  15. SHUTDOWN:关闭 Redis 服务器。

这些是 Redis 常用的管理命令,可以用于监控、配置和维护 Redis 服务器。

🍁07 Redis持久化数据和缓存怎么做扩容?

Redis 的持久化数据可以通过以下方式进行扩容:

  • 增加 Redis 节点:可以增加 Redis 节点,以增加 Redis 的存储容量。
  • 使用 Redis Cluster:可以使用 Redis Cluster,以实现 Redis 集群的扩容。
  • 使用 Redis Sentinel:可以使用 Redis Sentinel,以实现 Redis 集群的高可用性。

Redis 的缓存可以通过以下方式进行扩容:

  • 增加 Redis 节点:可以增加 Redis 节点,以增加 Redis 的缓存容量。
  • 使用 Redis Cluster:可以使用 Redis Cluster,以实现 Redis 集群的扩容。
  • 使用 Redis Sentinel:可以使用 Redis Sentinel,以实现 Redis 集群的高可用性。

Redis 的持久化数据和缓存都可以通过增加 Redis 节点、使用 Redis Cluster 和使用 Redis Sentinel 来进行扩容。

🍁08 Redis为啥没有直接使用C字符串?

Redis 没有直接使用 C 字符串,主要有以下几个原因:

  • C 字符串是静态分配的,而 Redis 的字符串是动态分配的。这意味着 C 字符串的大小是固定的,而 Redis 的字符串可以根据需要增长。
  • C 字符串是不可变的,而 Redis 的字符串是可变的。这意味着 C 字符串不能被修改,而 Redis 的字符串可以被修改。
  • C 字符串不支持内存压缩,而 Redis 的字符串支持内存压缩。这意味着 Redis 的字符串可以节省内存。

总的来说,Redis 没有直接使用 C 字符串,是因为 C 字符串不满足 Redis 的需求。

🍁09 Redis 过期键的删除策略?

Redis 有两种过期键的删除策略:

  • 惰性删除:当一个键的过期时间到期后,Redis 不会立即删除该键,而是等到该键被访问时才删除。
  • 定期删除:Redis 可以定期扫描所有键,并删除过期键。

默认情况下,Redis 使用惰性删除策略。如果需要定期删除过期键,可以使用 CONFIG SET 命令设置 maxmemory-policy 选项为 allkeys-lru

🍁10 Pipeline 有什么好处,为什么要用pipeline?

Pipeline 可以提高 Redis 的性能,因为它可以减少网络通信次数。当使用 Pipeline 时,客户端可以将多个命令发送到 Redis 服务器,然后 Redis 服务器会在收到所有命令后一次性执行它们。这样可以减少网络通信次数,从而提高 Redis 的性能。

以下是使用 Pipeline 的一些好处:

  • 减少网络通信次数,提高 Redis 的性能。
  • 减少延迟,提高响应速度。
  • 减少 CPU 使用率,提高吞吐量。

总的来说,Pipeline 是一个非常有用的工具,可以提高 Redis 的性能。如果需要提高 Redis 的性能,可以考虑使用 Pipeline。

🍁11 Redis 的内存用完了会发生什么?

Redis 的内存用完了,会发生以下几种情况:

  • Redis 会开始淘汰最不常用的键。
  • Redis 会开始使用 LRU 缓存淘汰算法。
  • Redis 会开始使用内存碎片整理。
  • Redis 会开始使用内存压缩。
  • Redis 会开始使用惰性过期删除。
  • Redis 会开始使用定期删除。

如果 Redis 的内存仍然不够用,那么 Redis 可能会崩溃。

以下是 Redis 的内存用完了会发生的详细说明:

  • Redis 会开始淘汰最不常用的键。

当 Redis 的内存用完了,它会开始淘汰最不常用的键。最不常用的键是指那些很久没有被访问的键。Redis 会根据键的访问时间来判断键的使用频率。如果一个键很久没有被访问,那么它很可能是一个不常用的键。Redis 会淘汰这些不常用的键,以腾出内存。

  • Redis 会开始使用 LRU 缓存淘汰算法。

LRU 缓存淘汰算法是一种基于时间的缓存淘汰算法。它会根据键的访问时间来判断键的使用频率。如果一个键很久没有被访问,那么它很可能是一个不常用的键。LRU 缓存淘汰算法会淘汰这些不常用的键,以腾出内存。

  • Redis 会开始使用内存碎片整理。

内存碎片是指内存中存在大量的未使用空间。当 Redis 的内存用完了,它会开始使用内存碎片整理。内存碎片整理会将内存中未使用的空间重新整理成连续的空间。这样可以提高内存的使用效率。

  • Redis 会开始使用内存压缩。

内存压缩是指将内存中的数据压缩成更小的空间。当 Redis 的内存用完了,它会开始使用内存压缩。内存压缩可以减少内存的使用量。

  • Redis 会开始使用惰性过期删除。

惰性过期删除是指当一个键的过期时间到期后,Redis 不会立即删除该键。Redis 会等到该键被访问时才删除。惰性过期删除可以减少内存的使用量。

  • Redis 会开始使用定期删除。

定期删除是指Redis会定期扫描所有键,并删除过期键。定期删除可以减少内存的使用量。

如果 Redis 的内存仍然不够用,那么 Redis 可能会崩溃。

🍁12 Redis回收进程如何工作的?

Redis 的回收进程主要负责清理过期键和过期数据。当一个键的过期时间到期后,Redis 会将该键标记为过期,并将其添加到回收列表中。当回收进程运行时,它会从回收列表中获取过期键,并将它们从内存中删除。

Redis 的回收进程可以通过以下方式进行配置:

  • maxmemory-policy :设置内存使用策略。
  • maxmemory-samples :设置内存使用样本数。
  • maxmemory-evict-percentage :设置内存使用百分比。

Redis 的回收进程可以通过以下命令进行管理:

  • CONFIG SET maxmemory-policy <policy> :设置内存使用策略。
  • CONFIG SET maxmemory-samples <samples> :设置内存使用样本数。
  • CONFIG SET maxmemory-evict-percentage <percentage> :设置内存使用百分比。
  • CONFIG GET maxmemory-policy :获取内存使用策略。
  • CONFIG GET maxmemory-samples :获取内存使用样本数。
  • CONFIG GET maxmemory-evict-percentage :获取内存使用百分比。

Redis 的回收进程是一个非常重要的进程,它可以帮助我们保持 Redis 内存的清洁。

🍁13 Redis中的管道有什么用?

Redis 中的管道(pipeline)可以提高 Redis 的性能,因为它可以减少网络通信次数。当使用 Pipeline 时,客户端可以将多个命令发送到 Redis 服务器,然后 Redis 服务器会在收到所有命令后一次性执行它们。这样可以减少网络通信次数,从而提高 Redis 的性能。

以下是使用 Pipeline 的一些好处:

  • 减少网络通信次数,提高 Redis 的性能。
  • 减少延迟,提高响应速度。
  • 减少 CPU 使用率,提高吞吐量。

总的来说,Pipeline 是一个非常有用的工具,可以提高 Redis 的性能。如果需要提高 Redis 的性能,可以考虑使用 Pipeline。

🍁14 Redis持久化触发条件?

Redis 的持久化有两种方式:RDB 和 AOF。RDB 是基于快照的持久化方式,AOF 是基于日志的持久化方式。

RDB 的持久化触发条件有以下几种:

  • 手动触发:可以使用 SAVE 命令手动触发 RDB 持久化。
  • 自动触发:当 Redis 内存使用率达到 maxmemory-policy 配置的值时,Redis 会自动触发 RDB 持久化。
  • 定期触发:可以使用 CONFIG SET 命令设置 save 选项,以定期触发 RDB 持久化。

AOF 的持久化触发条件有以下几种:

  • 手动触发:可以使用 BGREWRITEAOF 命令手动触发 AOF 持久化。
  • 自动触发:当 Redis 内存使用率达到 maxmemory-policy 配置的值时,Redis 会自动触发 AOF 持久化。
  • 定期触发:可以使用 CONFIG SET 命令设置 aof-rewrite-incremental 选项,以定期触发 AOF 持久化。

Redis 的持久化可以保证数据在 Redis 服务器崩溃时不会丢失。

🍁15 Memcache与Redis的区别都有哪些?

Memcached 和 Redis 都是内存数据库,但它们在很多方面都有所不同。以下是 Memcached 和 Redis 的主要区别:

  • 数据类型:Memcached 只支持简单的 key-value 数据类型,而 Redis 支持多种数据类型,包括字符串、列表、集合、有序集合和哈希表。
  • 持久化:Memcached 不支持持久化,而 Redis 支持两种持久化方式:RDB 和 AOF。
  • 性能:Memcached 的性能比 Redis 更高,因为 Memcached 使用了更简单的设计。
  • 可用性:Memcached 比 Redis 更容易使用,因为 Memcached 有更多的客户端库。

总的来说,Memcached 是一个简单、高性能的缓存系统,而 Redis 是一个功能更强大、更可靠的缓存系统。

🍁16 Redis的同步机制了解么?

Redis 有两种同步机制:

  • 主从复制:主从复制是 Redis 最常用的同步机制,它可以保证数据在主节点和从节点之间保持一致。
  • 哨兵模式:哨兵模式是 Redis 的高可用性解决方案,它可以保证 Redis 集群在主节点发生故障时仍然可以正常工作。

主从复制和哨兵模式都是非常重要的 Redis 同步机制,它们可以保证 Redis 集群的高可用性和数据一致性。

当涉及到Redis的同步机制时,有两个主要的概念:主从复制和哨兵模式。

  1. 主从复制:
    主从复制是Redis最常用的同步机制之一。它允许将一个Redis节点配置为主节点(master),其他节点配置为从节点(slave)。主节点负责接收写操作和读操作,而从节点会复制主节点的数据。

主从复制的工作流程如下:

  • 从节点通过发送SYNC命令向主节点请求复制数据。
  • 主节点在接收到SYNC命令后,会执行一个全量复制操作,将自己的数据发送给从节点。
  • 一旦全量复制完成,主节点就会将后续的写操作发送给从节点,使得从节点保持与主节点的数据同步。

主从复制的好处包括:

  • 读写分离:从节点可以处理读操作,减轻主节点的负载。
  • 数据冗余:即使主节点发生故障,从节点仍然可以提供服务。
  1. 哨兵模式:
    哨兵模式是Redis的高可用性解决方案之一。它通过监控主节点的状态,自动切换到一个可用的从节点来实现故障转移。

哨兵模式的工作流程如下:

  • 哨兵进程会监控主节点的状态,并与其他哨兵进程进行通信。
  • 如果主节点发生故障,哨兵会选举一个新的主节点。
  • 一旦新的主节点选举完成,哨兵会通知其他节点更新配置,使得它们知道新的主节点是谁。
  • 客户端会重新连接到新的主节点,继续进行操作。

哨兵模式的好处包括:

  • 自动故障转移:当主节点发生故障时,哨兵会自动切换到一个可用的从节点,确保系统的高可用性。
  • 配置更新:哨兵可以自动更新从节点的配置,使得它们知道新的主节点是谁。

综上所述,主从复制和哨兵模式是Redis的两种常见同步机制。它们提供了数据复制和故障转移的功能,以确保Redis系统的可用性和数据一致性。

🍁17 Redis集群会有写操作丢失吗?为什么?

Redis 集群是通过主从复制实现的,主节点的数据会被复制到从节点,这样当主节点发生故障时,从节点可以接替主节点继续提供服务。

在 Redis 集群中,写操作会先写入主节点,然后再复制到从节点。如果主节点在写操作完成之前发生故障,那么写操作可能会丢失。

为了避免写操作丢失,可以使用 Redis 的 AOF 持久化功能。AOF 持久化会将所有写操作记录到磁盘,这样即使主节点发生故障,也可以从 AOF 文件中恢复数据。

总的来说,Redis 集群的写操作可能会丢失,但可以通过使用 AOF 持久化功能来避免。

🍁18 如果有大量的 key 需要设置同一时间过期,一般需要注意什么?

当需要设置大量的 key 同一时间过期时,需要注意以下几点:

  1. 批量操作:为了提高效率,可以使用批量操作命令,如 MSETMSETEX ,一次性设置多个 key 的过期时间。这样可以减少网络通信次数,提高性能。

  2. 分批处理:如果需要设置的 key 数量非常大,可以将它们分成多个批次进行处理,而不是一次性处理所有的 key。这样可以避免一次性处理过多的 key 导致 Redis 阻塞或性能下降。

  3. 合理设置过期时间:根据业务需求,合理设置 key 的过期时间。过期时间过短可能导致频繁的过期操作,增加 Redis 的负载;过期时间过长可能导致过期键积压,占用过多的内存。

  4. 监控过期键:可以使用 Redis 的监控机制,例如通过 EXPIRED 事件通知或 SCAN 命令扫描过期键,及时处理过期键的清理工作,避免过期键堆积导致内存占用过高。

  5. 考虑持久化策略:如果需要保证过期键不会因为 Redis 重启而丢失,可以选择合适的持久化策略,如 AOF 持久化,将过期键的信息记录到磁盘中。

总之,当需要设置大量的 key 同一时间过期时,需要注意批量操作、分批处理、合理设置过期时间、监控过期键和考虑持久化策略等因素,以确保 Redis 的性能和可靠性。

🍁19 使用过 Redis 做异步队列么,你是怎么用的?

以下是我通常使用 Redis 实现异步队列的步骤:

  1. 创建 Redis 连接:首先,我会使用适当的客户端库连接到 Redis 服务器。例如,在 Python 中,我会使用 redis-py 库来连接 Redis。

  2. 将任务添加到队列:我会使用 Redis 的 RPUSH 命令将任务添加到队列中。每个任务都是一个字符串,可以是 JSON 格式或其他适合的格式。

  3. 从队列中获取任务:我使用 BLPOP 命令从队列的左侧获取任务。该命令是一个阻塞操作,如果队列为空,它会一直等待,直到有任务可用。

  4. 处理任务:一旦获取到任务,我会对其进行处理,执行相应的操作。这可以是任何我需要异步执行的任务,例如发送电子邮件、处理数据等。

通过以上步骤,我可以将任务添加到 Redis 队列中,并使用消费者从队列中获取任务并进行处理。这种方式可以实现异步处理,提高系统的响应性能和可伸缩性。

需要注意的是,为了确保任务不会丢失,可以使用 Redis 的持久化功能,如 AOF 持久化或 RDB 持久化,以防止 Redis 服务器重启时数据丢失。

🍁20 使用过Redis分布式锁么,它是怎么回事?

Redis 分布式锁是一种用于在分布式系统中实现互斥访问的机制。它可以确保在多个进程或多台服务器上同时访问共享资源时,只有一个进程或服务器可以获取到锁,从而避免竞争条件和数据不一致的问题。

Redis 分布式锁的实现通常基于 Redis 的原子操作,例如 SETNX(设置值,仅在键不存在时设置)和 EXPIRE(设置键的过期时间)。以下是一种常见的 Redis 分布式锁实现方式:

  1. 获取锁:进程或服务器尝试使用 SETNX 命令在 Redis 中设置一个特定的键作为锁。如果 SETNX 返回成功,表示获取到了锁,并且可以开始执行临界区的代码。同时,需要设置一个适当的过期时间,以防止锁被长时间占用。

  2. 执行临界区代码:获取到锁后,进程或服务器可以执行需要互斥访问的临界区代码,例如访问共享资源、执行关键操作等。

  3. 释放锁:临界区代码执行完毕后,进程或服务器使用 DEL 命令删除锁,释放资源并让其他进程或服务器获取到锁。

需要注意的是,Redis 分布式锁的实现需要考虑一些边界条件和异常情况,例如锁的超时处理、锁的重入性、死锁检测等。

使用 Redis 分布式锁可以确保在分布式环境中的并发访问安全性,避免数据竞争和冲突。它在分布式系统中的应用广泛,例如任务调度、资源管理、分布式事务等场景。

🍁21 Redis 实现分布式锁的方式是什么?

Redis 实现分布式锁的方式有多种,其中最常用的方式是使用 SETNX 命令结合过期时间。

以下是一种常见的 Redis 分布式锁实现方式:

  1. 获取锁:进程或服务器尝试使用 SETNX 命令在 Redis 中设置一个特定的键作为锁。如果 SETNX 返回成功(即键之前不存在),表示获取到了锁,并且可以开始执行临界区的代码。同时,需要设置一个适当的过期时间,以防止锁被长时间占用。
SETNX lock_key 1
EXPIRE lock_key expiration_time
  1. 执行临界区代码:获取到锁后,进程或服务器可以执行需要互斥访问的临界区代码,例如访问共享资源、执行关键操作等。

  2. 释放锁:临界区代码执行完毕后,进程或服务器使用 DEL 命令删除锁,释放资源并让其他进程或服务器获取到锁。

DEL lock_key

需要注意的是,Redis 分布式锁的实现需要考虑一些边界条件和异常情况,例如锁的超时处理、锁的重入性、死锁检测等。

使用 Redis 分布式锁可以确保在分布式环境中的并发访问安全性,避免数据竞争和冲突。它在分布式系统中的应用广泛,例如任务调度、资源管理、分布式事务等场景。

🍁22 Redis 的回收策略(淘汰策略)?

Redis 有几种回收策略(淘汰策略)用于处理内存不足的情况。当 Redis 内存达到最大限制时,会根据配置的回收策略来决定如何淘汰一些键以释放内存。以下是 Redis 的几种回收策略:

  1. noeviction(不淘汰):当内存不足时,Redis 将拒绝写入操作并返回错误。这种策略适用于需要确保数据不被删除的场景。

  2. allkeys-lru(最近最少使用):Redis 会根据键的最近使用时间来淘汰最少使用的键。这是 Redis 默认的回收策略。

  3. volatile-lru(最近最少使用,但仅限于设置了过期时间的键):Redis 只对设置了过期时间的键使用 LRU 策略进行淘汰。

  4. allkeys-random(随机淘汰):Redis 会随机选择一些键进行淘汰。

  5. volatile-random(随机淘汰,但仅限于设置了过期时间的键):Redis 只对设置了过期时间的键进行随机淘汰。

  6. volatile-ttl(根据键的剩余生存时间进行淘汰):Redis 会根据键的剩余生存时间进行淘汰,优先淘汰剩余生存时间较短的键。

可以通过配置文件或在运行时使用 CONFIG SET 命令来设置回收策略。选择适合应用场景的回收策略可以更好地管理内存和保证性能。

🍁23 Jedis 与 Redisson 对比有什么优缺点?

Jedis 和 Redisson 都是用于在 Java 应用程序中与 Redis 进行交互的客户端库,它们在使用方式和功能上有一些区别。

Jedis 的优点:

  • 简单易用:Jedis 是一个轻量级的客户端库,使用简单直观,适合快速集成到项目中。
  • 性能高:Jedis 是直接与 Redis 服务器进行通信,没有额外的网络层,因此在性能方面表现出色。
  • 社区活跃:Jedis 是 Redis 官方推荐的 Java 客户端之一,拥有广泛的用户社区和支持。

Jedis 的缺点:

  • 单线程阻塞:Jedis 在执行命令时是单线程的,每个命令都需要等待响应,可能会导致性能瓶颈。
  • 功能相对较少:相比其他客户端库,Jedis 的功能相对较少,不支持一些高级特性,如分布式锁等。

Redisson 的优点:

  • 多功能支持:Redisson 提供了丰富的功能和特性,如分布式锁、分布式集合、分布式对象等,方便构建复杂的分布式系统。
  • 异步与响应式:Redisson 支持异步和响应式编程模型,可以提高并发性能和响应速度。
  • 分布式部署支持:Redisson 提供了对 Redis 集群和哨兵模式的支持,方便在分布式环境中使用。

Redisson 的缺点:

  • 学习曲线较陡:Redisson 提供了丰富的功能,但也意味着它的使用和配置可能相对复杂,需要一定的学习成本。
  • 额外的依赖:Redisson 需要依赖额外的库,可能会增加项目的依赖复杂性。

选择 Jedis 还是 Redisson 取决于具体的使用场景和需求。如果需要简单、轻量级的 Redis 客户端,可以选择 Jedis。如果需要更多的功能和分布式特性,可以选择 Redisson。

🍁24 你知道有哪些Redis分区实现方案?

有以下几种常见的 Redis 分区实现方案:

  1. 哈希分区(Hash-based Sharding):根据键的哈希值将数据分散到多个 Redis 节点上。不同的键可能会分配到不同的节点上,但在同一个节点上的键可以保证原子性操作。这种方案需要维护一个哈希环来确定键和节点的映射关系。

  2. 范围分区(Range-based Sharding):将数据按照一定的范围划分到不同的节点上。例如,可以按照键的字母顺序或者数值范围将数据分区。这种方案可以保证相关的数据存储在相邻的节点上,方便一些范围查询操作。

  3. 一致性哈希分区(Consistent Hashing):将键和节点通过哈希函数映射到一个固定的环上,每个节点在环上占据一个位置。根据键的哈希值在环上找到对应的位置,然后顺时针寻找下一个节点作为数据的归属节点。这种方案在节点的增减时可以最小程度地迁移数据。

  4. 虚拟分区(Virtual Sharding):将每个物理节点划分为多个虚拟节点,每个虚拟节点负责一部分数据。这种方案可以提高数据的均衡性,减少数据倾斜的情况。

这些分区实现方案可以根据具体的需求和场景来选择和使用。每种方案都有其优势和限制,需要综合考虑数据分布、负载均衡、数据迁移等因素。

🍁25 Redis 持久化方案有哪些?区别是什么?

Redis 提供了两种持久化方案:RDB(Redis Database)和 AOF(Append-Only File)。

  1. RDB(Redis Database)

    • RDB 是 Redis 的默认持久化方式。
    • RDB 基于快照的方式,会定期将内存中的数据以二进制格式保存到磁盘上的 RDB 文件。
    • RDB 文件是一个压缩的二进制文件,可以在需要时进行恢复。
    • RDB 方式适合用于备份和灾难恢复,因为它可以在磁盘上创建一个完整的快照,占用较少的磁盘空间。
    • RDB 方式的缺点是如果 Redis 在发生故障时没有执行最新的 RDB 持久化操作,可能会丢失最后一次快照之后的数据。
  2. AOF(Append-Only File)

    • AOF 将所有的写操作追加到一个日志文件中,记录了 Redis 服务器执行的所有写命令。
    • AOF 文件是一个文本文件,可以通过追加写命令的方式来保证数据的持久化。
    • AOF 方式适合用于数据的持久化和恢复,因为它记录了所有的写操作,可以保证数据的完整性。
    • AOF 方式的缺点是相对于 RDB 来说,AOF 文件会占用更多的磁盘空间,并且恢复数据的速度可能会比 RDB 方式慢一些。

总结来说,RDB 方式适合用于备份和灾难恢复,占用较少的磁盘空间,但可能会丢失最后一次快照之后的数据。AOF 方式适合用于数据的持久化和恢复,保证数据的完整性,但占用更多的磁盘空间。选择哪种持久化方式取决于具体的需求和场景。

🍁26 Redis常见的几种缓存策略有哪些?

Redis常见的几种缓存策略包括:

  1. FIFO(First In, First Out):按照数据进入缓存的顺序进行淘汰,最早进入缓存的数据最先被淘汰。
  2. LRU(Least Recently Used):根据数据的最近访问时间进行淘汰,最近最少被访问的数据最先被淘汰。
  3. LFU(Least Frequently Used):根据数据的访问频率进行淘汰,访问频率最低的数据最先被淘汰。
  4. Random(随机):随机选择数据进行淘汰,没有明确的淘汰策略。
  5. TTL(Time To Live):设置数据的过期时间,到达过期时间后自动被淘汰。
  6. Maxmemory Policy(最大内存策略):根据配置的最大内存限制,当内存超出限制时,根据指定的策略进行淘汰。

这些缓存策略可以根据实际需求进行选择和配置,以提高缓存的效率和命中率。不同的应用场景可能适用不同的缓存策略。

🍁27 Redis 如何做内存优化?

Redis 的内存优化可以通过以下几种方式实现:

  1. 选择合适的数据结构:使用适当的数据结构可以减少内存占用。例如,使用哈希表代替字符串列表可以节省内存。

  2. 压缩字符串:Redis 支持字符串压缩,可以通过配置选项启用压缩算法,如 LZF 或 Snappy。压缩后的字符串可以减少内存占用。

  3. 设置合理的过期时间:合理设置键的过期时间,确保不再需要的数据能够及时释放内存。

  4. 使用适当的内存淘汰策略:根据业务需求选择合适的内存淘汰策略,如 LRU(最近最少使用)或 LFU(最不经常使用)。

  5. 分片和分区:将数据分散到多个 Redis 实例中,可以将数据分散到多个内存中,从而减少单个实例的内存使用。

  6. 使用虚拟内存:Redis 支持将部分数据存储在磁盘上,以减少内存占用。虚拟内存可以将不常访问的数据存储在磁盘上,只在需要时加载到内存中。

  7. 优化配置参数:根据实际需求调整 Redis 的配置参数,如最大内存限制、最大连接数等,以充分利用可用内存资源。

  8. 定期监控和优化:定期监控 Redis 的内存使用情况,进行性能优化和内存回收,确保 Redis 的内存使用保持在合理范围内。

通过以上方法,可以有效地进行 Redis 的内存优化,提高性能并节省内存资源。

🍁28 Redis使用setnx实现分布式锁?

使用Java语言,可以通过Redis的 SETNX 命令来实现分布式锁。下面是一个使用Java Redis客户端实现分布式锁的示例代码:

import redis.clients.jedis.Jedis;

public class DistributedLock {
    private static final String LOCK_KEY = "mylock";
    private static final int LOCK_EXPIRE_TIME = 30000; // 锁的过期时间,单位毫秒

    private Jedis jedis;

    public DistributedLock() {
        // 初始化Redis连接
        jedis = new Jedis("localhost", 6379);
    }

    public boolean acquireLock() {
        // 尝试获取锁
        Long result = jedis.setnx(LOCK_KEY, "locked");
        if (result == 1) {
            // 设置锁的过期时间
            jedis.pexpire(LOCK_KEY, LOCK_EXPIRE_TIME);
            return true;
        }
        return false;
    }

    public void releaseLock() {
        // 释放锁
        jedis.del(LOCK_KEY);
    }
}

在上述示例中, acquireLock 方法尝试获取锁,如果成功获取到锁,则设置锁的过期时间并返回 true 。如果获取锁失败,则返回 falsereleaseLock 方法用于释放锁,即删除对应的键。

需要注意的是,使用 SETNX 命令实现的分布式锁可能存在死锁和竞态条件的问题。为了解决这些问题,可以考虑使用带有超时机制的锁,或者结合其他Redis命令(如 EXISTSGETSET )来实现更复杂的锁机制。

🍁29 MySQL 里有 2000w 数据,Redis 中只存 20w 的数据,如何保证Redis 中的数据都是热点数据?

要保证 Redis 中的数据都是热点数据,可以考虑以下几个方面:

  1. 定期更新数据:通过定期更新 Redis 中的数据,确保存储的数据是最新的热点数据。可以使用定时任务或者在数据更新时触发更新 Redis 的操作。

  2. 使用缓存淘汰策略:选择合适的缓存淘汰策略,确保 Redis 中存储的数据是最常用的热点数据。常用的策略包括 LRU(最近最少使用)、LFU(最不常用)和随机等。

  3. 监控数据访问模式:通过监控数据的访问模式,了解哪些数据是热点数据。可以使用 Redis 的命令如 INFOMONITOR 或者使用 Redis 监控工具来收集访问模式数据,并根据结果进行相应的优化。

  4. 使用数据预热:在 Redis 启动之前,将预先计算好的热点数据加载到 Redis 中。这样可以确保 Redis 中的数据一开始就是热点数据,提高缓存命中率。

  5. 使用合适的数据结构:根据业务需求选择合适的 Redis 数据结构。不同的数据结构适用于不同的场景,选择合适的数据结构可以提高数据访问效率。

综合考虑以上策略,可以有效地保证 Redis 中存储的数据都是热点数据,提高缓存命中率和系统性能。

🍁30 手写一个 LRU 算法?

下面是一个使用 Java 语言手写的简单 LRU (Least Recently Used) 算法的示例:

import java.util.HashMap;
import java.util.Map;

class LRUCache {
    private final int capacity;
    private final Map<Integer, Node> cache;
    private final Node head;
    private final Node tail;

    class Node {
        int key;
        int value;
        Node prev;
        Node next;

        Node(int key, int value) {
            this.key = key;
            this.value = value;
        }
    }

    public LRUCache(int capacity) {
        this.capacity = capacity;
        this.cache = new HashMap<>();
        this.head = new Node(0, 0);
        this.tail = new Node(0, 0);
        head.next = tail;
        tail.prev = head;
    }

    public int get(int key) {
        if (cache.containsKey(key)) {
            Node node = cache.get(key);
            moveToHead(node);
            return node.value;
        }
        return -1;
    }

    public void put(int key, int value) {
        if (cache.containsKey(key)) {
            Node node = cache.get(key);
            node.value = value;
            moveToHead(node);
        } else {
            Node newNode = new Node(key, value);
            cache.put(key, newNode);
            addToHead(newNode);
            if (cache.size() > capacity) {
                Node tailNode = removeTail();
                cache.remove(tailNode.key);
            }
        }
    }

    private void moveToHead(Node node) {
        removeNode(node);
        addToHead(node);
    }

    private void addToHead(Node node) {
        node.next = head.next;
        node.prev = head;
        head.next.prev = node;
        head.next = node;
    }

    private void removeNode(Node node) {
        node.prev.next = node.next;
        node.next.prev = node.prev;
    }

    private Node removeTail() {
        Node tailNode = tail.prev;
        removeNode(tailNode);
        return tailNode;
    }
}

上述示例代码实现了一个简单的 LRU 缓存,使用了双向链表和哈希表的数据结构。LRUCache 类中的 get 和 put 方法实现了缓存的读取和写入操作,保持缓存的容量不超过指定的大小,并按照 LRU 策略进行缓存淘汰。

🍁31 Redis集群方案应该怎么做?都有哪些方案?

Redis 提供了多种集群方案,可以根据实际需求选择适合的方案。以下是几种常见的 Redis 集群方案:

  1. Redis Sentinel:Redis Sentinel 是 Redis 官方提供的高可用性解决方案。它通过监控 Redis 主节点和从节点的状态,并在主节点发生故障时自动进行故障转移,确保集群的可用性。

  2. Redis Cluster:Redis Cluster 是 Redis 官方提供的分布式集群方案。它将数据分片存储在多个节点上,实现数据的分布式存储和高可用性。Redis Cluster 提供了自动的数据分片和故障转移机制。

  3. Twemproxy:Twemproxy(又称为 Nutcracker)是一个代理层,可以将多个 Redis 实例组合成一个逻辑集群。它提供了分片和负载均衡功能,可以将请求均匀地分发到不同的 Redis 实例上。

  4. Redisson:Redisson 是一个基于 Redis 的分布式 Java 对象和服务框架。它提供了分布式集合、分布式锁、分布式队列等功能,可以方便地在 Java 应用中使用 Redis 集群。

  5. 第三方解决方案:除了 Redis 官方提供的方案外,还有一些第三方解决方案,如 Codis、RedisLabs 等,它们提供了更多的功能和扩展性,可以根据具体需求选择适合的方案。

选择适合的 Redis 集群方案需要考虑诸多因素,包括数据一致性、高可用性、性能需求、部署复杂性等。根据具体的业务需求和技术要求,选择合适的方案进行部署和配置。

🍁32 Redis回收使用的是什么算法?

Redis 使用的是 LRU(Least Recently Used,最近最少使用)算法进行回收。LRU 算法基于数据的访问模式,它会优先淘汰最近最少使用的数据,以便腾出更多的内存空间。当 Redis 的内存达到上限时,LRU 算法会从缓存中淘汰最近最少使用的键,以便为新的键腾出空间。这样可以保持缓存中的数据是最有用的数据,提高缓存的效率。

🍁33 Redis的并发竞争问题如何解决?

Redis 的并发竞争问题可以通过以下几种方式来解决:

  1. 使用事务:Redis 支持事务操作,可以通过 MULTI 和 EXEC 命令将多个操作打包成一个原子操作。使用事务可以确保一系列操作的原子性,避免并发竞争问题。

  2. 使用乐观锁:在对数据进行更新操作时,可以使用版本号或时间戳等机制进行乐观锁控制。通过在更新操作前检查版本号或时间戳,可以判断数据是否被其他客户端修改过,从而避免并发竞争问题。

  3. 使用分布式锁:可以使用分布式锁来控制对共享资源的访问。通过在关键代码段前后加锁,可以确保同一时间只有一个客户端能够执行该代码段,避免并发竞争问题。

  4. 使用 Redis 的原子操作:Redis 提供了一些原子操作,如 INCR、HSETNX、SETNX 等。这些原子操作可以在单个命令中完成读取和写入操作,避免了并发竞争问题。

  5. 合理设计数据模型:在设计数据模型时,可以考虑将数据拆分为多个独立的键,减少并发操作同一个键的可能性,从而降低并发竞争问题的发生。

综上所述,通过使用事务、乐观锁、分布式锁、Redis 的原子操作和合理设计数据模型,可以有效地解决 Redis 的并发竞争问题。

🍁34 说说Redis哈希槽的概念?

Redis 哈希槽(Hash Slot)是 Redis 集群中用于分片的概念。在 Redis 集群中,数据被分散存储在多个节点上,每个节点负责管理一部分数据。为了实现数据的均匀分布和高可用性,Redis 将数据划分为固定数量的哈希槽。

Redis 集群默认使用 16384 个哈希槽,每个键通过哈希函数映射到一个具体的哈希槽。每个节点负责管理一部分哈希槽,节点之间通过消息传递来协调数据的迁移和复制。

哈希槽的使用使得 Redis 集群可以方便地进行扩展和水平扩容。当需要增加或减少节点时,Redis 集群会自动进行数据的迁移和重新分配,保证数据的平衡和高可用性。

通过哈希槽的概念,Redis 集群实现了数据的分片和负载均衡,提供了高性能和可扩展性。

🍁35 为什么Redis需要把所有数据放到内存中?

Redis 将所有数据存储在内存中的主要原因是为了提供高性能和低延迟的数据访问。内存的读写速度比磁盘快得多,因此将数据存储在内存中可以实现快速的数据访问和响应。

将数据存储在内存中还可以避免磁盘IO的开销和瓶颈。相比于传统的基于磁盘的数据库系统,Redis 的内存存储方式可以大大提高数据的读写性能,特别适用于对数据响应时间要求较高的应用场景,如缓存、实时计算和高速数据处理等。

尽管 Redis 将数据存储在内存中,但为了保证数据持久性,Redis 提供了持久化机制,可以将数据定期保存到磁盘上,以防止数据丢失。这样既保证了高性能的数据访问,又提供了数据的持久性和可靠性。

总的来说,Redis 将所有数据放到内存中是为了实现高性能、低延迟的数据访问,并通过持久化机制保证数据的持久性。

🍁36 Redis常见性能问题和解决方案?

Redis 常见的性能问题和相应的解决方案如下:

  1. 内存使用过高:当 Redis 的内存使用过高时,可能会导致性能下降或系统崩溃。解决方案包括使用合适的数据结构、压缩数据、设置适当的过期时间、使用分片或集群等来分散数据存储。

  2. 高并发访问:当 Redis 面对高并发访问时,可能会出现性能瓶颈。解决方案包括使用连接池管理连接、增加 Redis 实例的数量、使用 Pipeline 批量操作、使用 Lua 脚本减少网络开销等。

  3. 持久化性能问题:当进行持久化操作(如 RDB 快照或 AOF 日志写入)时,可能会影响 Redis 的性能。解决方案包括调整持久化频率、使用后台持久化、优化磁盘性能等。

  4. 网络延迟:当 Redis 与客户端之间存在网络延迟时,可能会影响请求的响应时间。解决方案包括优化网络配置、使用连接池、在客户端实现请求重试机制等。

  5. 缓存失效问题:当 Redis 用作缓存时,缓存失效可能导致大量请求直接访问后端存储,增加负载和延迟。解决方案包括设置合适的缓存过期时间、使用惰性删除或定期删除策略、使用 LRU 算法等。

  6. 大量 Key 的操作:当需要对大量 Key 进行操作时,如删除、查询等,可能会影响 Redis 的性能。解决方案包括使用批量操作(如 MGET、MSET、DEL)来减少网络开销,或者使用分布式锁来避免并发问题。

以上是一些常见的 Redis 性能问题和相应的解决方案。具体的解决方案应根据实际情况和需求进行选择和调整。

🍁37 Redis集群的主从复制模型是怎样的?

Redis 集群的主从复制模型是一种数据同步机制,用于实现高可用性和数据冗余。在主从复制模型中,一个 Redis 集群由一个主节点和多个从节点组成。

主节点是负责处理写操作的节点,它接收客户端的写请求并将数据更新到自己的数据库中。同时,主节点会将写操作的日志(命令)发送给从节点。

从节点是主节点的复制品,它负责处理读操作和提供冗余备份。从节点通过复制主节点的数据来保持与主节点的数据一致性。从节点会定期从主节点获取数据更新,以确保自己的数据与主节点保持同步。

在主从复制模型中,主节点和从节点之间通过网络进行通信。主节点将写操作的日志以命令的形式发送给从节点,从节点接收并执行这些命令,从而保持自己的数据与主节点一致。

如果主节点发生故障,Redis 集群会自动选举一个从节点作为新的主节点,以继续提供服务。一旦主节点恢复,它将重新成为主节点,并继续处理写操作,而之前的主节点则成为新的从节点。

通过主从复制模型,Redis 集群可以实现数据的高可用性和故障恢复能力。同时,从节点可以提供读操作的负载均衡,提高整体性能。

🍁38 Redis如何做大量数据插入?

Redis 提供了多种方式来进行大量数据插入:

  1. 使用批量命令:Redis 提供了一些批量命令,如 MSETMSETNXLPUSHRPUSH 等,可以一次性插入多个键值对或列表元素。这样可以减少网络通信的开销,提高插入效率。

  2. 使用管道(Pipeline):通过使用管道,可以将多个命令一次性发送到 Redis 服务器,然后一次性获取结果。这样可以减少网络通信的往返时间,提高插入效率。

  3. 使用 Redis Mass Insertion(redis-cli --pipe):Redis 提供了一个专门用于大量数据插入的工具,称为 Redis Mass Insertion。通过使用 redis-cli --pipe 命令,可以将数据以管道方式导入 Redis,以实现高效的大量数据插入。

  4. 使用批量导入工具:如果需要从外部数据源导入大量数据到 Redis,可以使用一些批量导入工具,如 Redis 的官方工具 redis-cliredis-bulkredis-load ,或者第三方工具如 Redis 数据导入工具 redis-py-import 等。

无论选择哪种方式,大量数据插入时应注意以下几点:

  • 合理设置 Redis 的配置参数,如 maxmemorymaxmemory-policy ,以避免内存溢出。
  • 如果数据量过大,可以考虑分批插入,以避免一次性插入过多数据导致性能下降。
  • 针对具体的数据结构选择合适的插入方式,如使用列表的批量插入命令 LPUSHRPUSH ,或者使用哈希表的批量插入命令 HMSET

请根据具体需求选择适合的方式进行大量数据插入。

🍁39 如果有大量的key需要设置同一时间过期,一般需要注意什么?

当需要设置大量的键在同一时间过期时,需要注意以下几点:

  1. 过期时间分布:尽量避免将大量键设置为完全相同的过期时间,以免在同一时间触发大量的键过期导致性能问题。可以考虑使用随机化的方式分散过期时间,或者将过期时间分散在一个较长的时间范围内。

  2. 批量操作:为了提高效率,可以使用批量操作命令(如 MSETMSETEX )来一次性设置多个键的过期时间,而不是逐个设置。

  3. 合理设置过期时间:根据业务需求和数据特点,合理设置过期时间。过长的过期时间可能导致内存占用过高,而过短的过期时间可能导致频繁的键过期操作。

  4. 内存管理:设置大量键的过期时间可能会增加内存压力,要确保 Redis 的内存配置足够支持存储这些键的数据。

  5. 性能评估:在进行大规模键过期设置之前,建议先进行性能评估和测试,确保系统能够处理这样的负载。

通过注意以上事项,可以更好地管理大量键的过期设置,并确保系统的稳定性和性能表现。

🍁40 Redis Module 实现布隆过滤器?

Redis Module 是 Redis 的扩展机制,允许开发者通过编写自定义模块来扩展 Redis 的功能。可以使用 Redis Module 来实现布隆过滤器(Bloom Filter)。

布隆过滤器是一种高效的数据结构,用于判断一个元素是否存在于一个集合中。它通过使用位数组和多个哈希函数来实现。在 Redis 中,可以通过自定义模块来实现布隆过滤器的功能,并将其集成到 Redis 中。

以下是实现布隆过滤器的一般步骤:

  1. 创建 Redis Module:首先,需要创建一个 Redis Module,编写相应的代码来定义布隆过滤器的数据结构和操作方法。

  2. 初始化布隆过滤器:在 Redis Module 中,需要实现初始化布隆过滤器的方法,包括指定位数组的大小和哈希函数的数量。

  3. 添加元素:实现添加元素到布隆过滤器的方法,该方法会根据多个哈希函数的结果将对应的位数组位置置为 1。

  4. 检查元素是否存在:实现检查元素是否存在于布隆过滤器中的方法,该方法会根据多个哈希函数的结果判断对应的位数组位置是否都为 1。

通过 Redis Module 实现布隆过滤器可以将其功能集成到 Redis 中,可以方便地在 Redis 中使用布隆过滤器进行元素判断。具体实现细节可以参考 Redis 官方文档和相关的 Redis Module 开发指南。

在这里插入图片描述

  • 22
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值