Redis(基础篇 + 实践篇 )
01 | 基本架构:一个键值数据库包含什么?
Redis 作为一个内存数据存储系统,它的架构设计非常简洁,但功能非常强大。理解其核心架构对高效使用 Redis 至关重要。
-
客户端与服务器架构:
- 客户端通过 TCP 协议连接到 Redis 服务器,Redis 使用客户端与服务器模式来处理请求。所有请求都被发送到一个主 Redis 实例,客户端与 Redis 服务器的交互通过 RESP (Redis Serialization Protocol) 协议进行数据传输。该协议轻量且高效,确保了 Redis 高性能的请求处理。
- 由于 Redis 是单线程的,客户端发送的请求被一次性地处理并返回响应,避免了线程切换的开销。
-
数据存储:
- Redis 将数据存储在内存中,而不是传统的磁盘存储。由于内存读写速度比磁盘快得多,Redis 能够在大规模并发访问的情况下依然保持低延迟和高吞吐量。
- Redis 支持的数据类型不仅仅是字符串,还包括哈希、列表、集合、有序集合等,使得它能够处理复杂的应用场景。
-
持久化机制:
- RDB(Redis 数据库快照):通过定期保存数据库状态来实现持久化。RDB 文件是压缩格式,可以快速加载,但存在数据丢失的风险。
- AOF(Append-Only File):通过将每个写操作追加到日志文件来实现持久化。AOF 能够保证数据的持久化,但相较于 RDB 更占用磁盘空间,且恢复速度较慢。
02 | 数据结构:快速的 Redis 有哪些慢操作?
Redis 提供了非常丰富的数据结构,可以高效地处理不同场景的数据需求。但并不是所有操作都高效,以下是一些常见的慢操作:
-
字符串(String):
- Redis 字符串是基础数据类型,虽然对简单的读写操作非常高效,但当你频繁修改较大的字符串时,操作可能会变得缓慢。特别是当字符串长度超过内存的一定阈值时,Redis 需要进行内存重分配,可能会导致性能瓶颈。
-
哈希(Hash):
- 哈希类型是 Redis 用来存储对象的理想选择,但是执行
HGETALL
等操作时,如果哈希中的字段较多,可能会出现性能下降的情况,因为它需要遍历所有的字段。
- 哈希类型是 Redis 用来存储对象的理想选择,但是执行
-
列表(List):
- 列表数据类型支持高效的两端操作,如
LPUSH
和RPUSH
。但如果使用LRANGE
来查询整个列表,特别是当列表很长时,性能会下降。Redis 内部会遍历列表中的所有元素,导致操作变慢。
- 列表数据类型支持高效的两端操作,如
-
集合(Set):
- 集合支持高效的集合操作,如交集、并集和差集。然而,类似
SINTER
和SUNION
等操作,当集合的元素非常多时,也会引起性能下降。
- 集合支持高效的集合操作,如交集、并集和差集。然而,类似
-
有序集合(Sorted Set):
- 有序集合用于存储带有权重(score)的元素,并能够按权重进行排序。操作如
ZREVRANGE
或ZRANGE
会涉及大量的排序操作,如果集合中有大量的数据,可能会导致性能问题。
- 有序集合用于存储带有权重(score)的元素,并能够按权重进行排序。操作如
优化技巧:
- 避免在集合中存储大量元素,特别是当需要频繁读取或操作所有数据时。
- 对于大数据量的操作,可以考虑通过分片(Sharding)来减少单个 Redis 实例的压力。
03 | 高性能 IO 模型:为什么单线程 Redis 能那么快?
Redis 是单线程的,这意味着它所有的请求都在一个线程中处理。那么,为什么 Redis 仍然能够在高并发场景下表现出色呢?
-
事件驱动架构:
- Redis 使用了 I/O 多路复用(IO Multiplexing)机制,常见的技术有
epoll
或select
。这意味着 Redis 通过一个线程管理多个连接,它可以高效地处理多个客户端的请求。 - 通过非阻塞的方式,Redis 能够在一个线程内快速切换和处理多个请求。每当一个请求完成后,Redis 会立刻响应,处理下一个请求。
- Redis 使用了 I/O 多路复用(IO Multiplexing)机制,常见的技术有
-
内存存储:
- Redis 是基于内存的数据库,数据的访问速度非常快。内存操作的延迟通常在微秒级别,而不像磁盘存储那样需要进行大量的 I/O 操作。
- 由于 Redis 所有的数据都存储在内存中,它避免了磁盘读写的延迟,因此即便是单线程,也能够支持极高的请求吞吐量。
-
轻量级的命令:
- Redis 的命令非常简洁,每个命令的执行时间非常短,不需要复杂的计算过程。Redis 能够快速地解析命令并执行操作,减少了处理请求的时间。
04 | AOF 日志:宕机了,Redis 如何避免数据丢失?
AOF(Append-Only File)是 Redis 的一种持久化机制,它可以保证在 Redis 宕机或重启时,数据不会丢失。AOF 记录每个写操作,将其追加到日志文件中。
-
AOF 的写入策略:
- Redis 提供了三种 AOF 写入策略:
- 每次写操作都同步到磁盘:这确保数据持久化最为可靠,但会对性能产生很大影响。
- 每秒同步一次:每秒钟将写操作同步到磁盘,这是 Redis 默认的策略,平衡了数据可靠性和性能。
- 不进行同步:Redis 将写操作缓存到内存中,稍后批量写入磁盘。此策略的性能最好,但可能会导致数据丢失。
- Redis 提供了三种 AOF 写入策略:
-
AOF 重写机制:
- AOF 文件会随着时间变得越来越大,Redis 提供了 AOF 重写机制,将旧的写操作日志压缩成较小的文件。
- AOF 重写不会阻塞主线程,它在后台进行,避免了对业务的影响。
05 | 内存快照:宕机后,Redis 如何实现快速恢复?
RDB(Redis 数据库快照)是 Redis 提供的另一种持久化机制,它通过定期保存 Redis 内存数据的快照来保证数据的持久性。
-
快照的触发:
- 快照通常根据时间和写操作次数的条件来触发,例如:
save 900 1 # 如果在 900 秒内有 1 次写操作,就保存一次快照 save 300 10 # 如果在 300 秒内有 10 次写操作,就保存一次快照
- 快照通常根据时间和写操作次数的条件来触发,例如:
-
恢复过程:
- 在 Redis 启动时,如果配置了 RDB 持久化机制,Redis 会读取最后的 RDB 快照文件,并将数据恢复到内存中。这是 Redis 恢复速度最快的方式,因为 RDB 文件是压缩的,恢复过程简单高效。
实践篇(28讲)
11 | “万金油”的 String,为什么不好用了?
Redis 的 String 是最基础的数据类型,但它也有一些局限性。在一些复杂场景下,单纯使用字符串存储和操作数据会影响性能和代码的可读性。
-
数据结构的选择:
- 对于需要存储多个字段的数据,使用哈希(Hash)而非字符串会更加高效。哈希类型允许你在一个键下存储多个字段,而不必为每个字段创建一个独立的键。
-
操作效率:
- 复杂的字符串拼接操作会造成 Redis 需要频繁地进行内存重分配。若应用中频繁修改字符串值,建议考虑使用其他数据结构,例如列表或集合,这些数据结构的内存管理机制更加高效。
12 | 有一亿个 keys 要统计,应该用哪种集合?
Redis 提供了多种集合数据结构,包括 Set、Sorted Set 和 HyperLogLog。对于需要统计大量数据的场景,选择合适的数据结构至关重要。
- 使用 Set 进行去重:
- Redis Set 是一个无序的集合,适用于存储唯一元素。Set 的
SADD
和SINTER
等操作非常高效,适合用来存储和操作大量唯一数据
- Redis Set 是一个无序的集合,适用于存储唯一元素。Set 的
。
-
Sorted Set 用于排序统计:
- Redis 的 Sorted Set 结合了集合和有序列表的特点,适用于需要排序统计的场景,如排行榜、时序数据等。每个元素都带有一个分数,支持按分数排序。
-
HyperLogLog 用于大规模计数:
- Redis 的 HyperLogLog 是一种基于概率算法的数据结构,适合用来做基数统计,能够用较少的内存计算出大量数据的基数(例如 URL 的去重)。
好的,接下来继续深入分析 Redis 实践篇 中的每个讲解内容。我们将探讨一些更为复杂的应用场景、性能优化策略、常见问题及解决方案,帮助你掌握 Redis 的高级使用和实际操作。
13 | GEO 是什么?还可以定义新的数据类型吗?
Redis 提供了对地理位置信息的支持,通过 GEO 命令,开发者可以在 Redis 中存储、查询和处理地理位置数据。Geo 数据结构背后实际上是 Redis 的 Sorted Set,它通过经纬度将数据按分数进行排序。
-
Geo 操作命令:
GEOADD
:将地理位置添加到 Redis 数据库中,地理位置信息是以经度、纬度和成员值(如城市名称)为参数存储。GEODIST
:返回两点之间的距离,支持多种单位(如米、千米、英里等)。GEORADIUS
和GEORADIUSBYMEMBER
:根据半径查询附近的地理位置。Redis 使用的是 Geohash 算法,将经纬度转化为一种数字,可以通过排序快速查询。
-
自定义数据类型(Redis Modules):
Redis 允许通过 Redis Module 扩展新的数据类型。通过 Redis 的module
API,开发者可以创建自定义数据类型,并实现对这些数据类型的支持,例如时间序列数据、全文搜索等功能。例如,RedisSearch 模块就实现了对搜索引擎功能的扩展,支持索引文本、查询等操作。
14 | 如何在 Redis 中保存时间序列数据?
时间序列数据的存储通常包括时间戳和数据项,Redis 通过 Sorted Set 来高效地存储时间序列数据,因为它支持按分数(时间戳)排序。
-
使用 Sorted Set 存储时间序列数据:
- 每条时间序列数据的时间戳可以作为分数,数据本身作为成员。通过
ZADD
命令将数据按时间顺序添加到有序集合中。 - 查询时,可以通过
ZRANGEBYSCORE
或ZREVRANGEBYSCORE
命令快速获取某个时间范围内的数据。
- 每条时间序列数据的时间戳可以作为分数,数据本身作为成员。通过
-
使用 RedisTimeSeries:
- RedisTimeSeries 是 Redis 官方提供的模块,专门用于处理时间序列数据。它为时间序列数据提供了专门的命令和优化,支持高效的时间序列写入和查询。
15 | 消息队列的考验:Redis 有哪些解决方案?
Redis 在消息队列方面有多个实现方案,最常见的方式是使用 列表(List)、发布/订阅(Pub/Sub) 和 Stream(流) 数据结构。
-
使用 List 实现简单队列:
- Redis 列表类型本质上是一个双端队列,可以使用
LPUSH
和RPUSH
命令进行生产者写入,LPOP
和RPOP
命令进行消费者读取。这种方式适合简单的消息队列应用。
- Redis 列表类型本质上是一个双端队列,可以使用
-
使用 Pub/Sub 实现发布/订阅模式:
- Redis 支持发布/订阅模式(Pub/Sub),适用于实时消息的广播。客户端通过
PUBLISH
发布消息,订阅者通过SUBSCRIBE
订阅消息。适合用于实时消息通知、推送等场景。
- Redis 支持发布/订阅模式(Pub/Sub),适用于实时消息的广播。客户端通过
-
使用 Stream 处理高吞吐量消息:
- Redis 5.0 引入了 Stream 数据类型,专为高吞吐量的消息队列设计。Stream 支持消息持久化,消费者可以确认消息的处理状态。Stream 还支持消费者组(Consumer Group),允许多个消费者并行处理消息。
-
性能优化:
- 在高并发和高吞吐量的场景下,使用 Stream 比 List 更适合,特别是在需要持久化消息且具有消费者组的情况下。可以根据业务需求选择合适的消息队列模式。
16 | 异步机制:如何避免单线程模型的阻塞?
Redis 使用单线程模型来处理请求,这使得它的性能非常高,但也带来了一些挑战,特别是在面对高延迟的操作时。为了避免阻塞,Redis 采用了多种异步机制来提升性能。
-
非阻塞 I/O 模型:
- Redis 使用 I/O 多路复用(如 epoll、select、poll)来监听多个 I/O 事件,能够在单个线程中异步处理多个客户端的请求,避免了线程间的上下文切换和调度延迟。
-
命令异步执行:
- Redis 的所有命令都是非阻塞的,尤其是在执行某些耗时操作时(如
BGREWRITEAOF
、BGSAVE
等)。这些命令将操作交给后台执行,主线程会继续处理其他请求,直到异步操作完成。
- Redis 的所有命令都是非阻塞的,尤其是在执行某些耗时操作时(如
-
使用 Redis 异步客户端:
- 在客户端,异步 I/O 模式也非常重要。通过 Redis 异步客户端(如 Jedis 的 Async API),可以避免因为网络阻塞而影响系统性能。客户端异步执行命令后,可以继续执行其他任务,直到收到响应。
17 | 为什么 CPU 结构也会影响 Redis 的性能?
Redis 性能受限于 CPU 的架构,特别是多核处理器与单核处理器之间的差异,以及 CPU 缓存和内存的访问模式。
-
单线程 vs 多线程:
- Redis 使用单线程来执行所有命令,它并未充分利用多核 CPU 的优势。虽然 Redis 的单线程模型避免了上下文切换的开销,但在某些多核系统中,CPU 核心之间的资源共享仍会对 Redis 的性能产生影响。
-
CPU 缓存和内存访问:
- Redis 是一个内存数据库,它的数据访问模式对 CPU 缓存有较高的要求。数据的局部性和访问模式直接影响 Redis 的性能。例如,大量的随机内存访问会导致 CPU 缓存失效,进而增加内存访问延迟。
-
优化方式:
- 使用 CPU 亲和性(CPU Affinity) 和 NUMA(Non-Uniform Memory Access) 来优化 Redis 性能。通过设置 Redis 进程绑定到特定的 CPU 核心,减少跨核访问,可以提高性能。
18 | 波动的响应延迟:如何应对变慢的 Redis?(上)
Redis 在高负载下可能会出现响应延迟波动,原因通常与内存碎片、硬件瓶颈和操作系统调度等因素相关。分析和解决这些问题非常重要。
-
内存碎片问题:
- Redis 运行时会分配内存,并且内存的分配方式是动态的,这可能导致内存碎片问题。碎片化会导致内存的利用率降低,并可能造成 Redis 响应时间波动。
- 使用
INFO MEMORY
命令可以查看 Redis 的内存使用情况,判断是否存在碎片问题。
-
垃圾回收和内存管理:
- Redis 内部有 jemalloc(一种内存分配器),它负责内存的动态分配和释放。通过优化内存分配器和配置 Redis 使用的最大内存大小,可以避免内存过度分配,减少垃圾回收的影响。
-
优化 I/O 操作:
- Redis 的性能受限于 I/O 操作,尤其是磁盘 I/O。通过调整
vm.overcommit_memory
配置和优化内存映射的方式,可以提高内存的使用效率,减少 I/O 延迟。
- Redis 的性能受限于 I/O 操作,尤其是磁盘 I/O。通过调整
19 | 波动的响应延迟:如何应对变慢的 Redis?(下)
继续分析如何处理 Redis 在高负载下的响应波动问题。
-
CPU 性能瓶颈:
- 如果 Redis 运行在 CPU 密集型的负载下(如大量的计算、排序操作),可以通过 Redis 的多实例部署 来分担压力,或者考虑将 Redis 配置为多个 CPU 核心并行执行任务。
-
网络延迟问题:
- 网络延迟是影响 Redis 响应时间的另一个重要因素。通过优化客户端与 Redis 之间的网络连接、减少 TCP 连接的数目、增加 Redis 实例的带宽等手段,可以有效减少延迟。
-
Redis 内存优化:
- 增加物理内存,或者合理配置 Redis 的最大内存使用上限,可以帮助 Redis 在处理大量数据时保持更好的性能。
继续深入探讨 Redis 在实际应用中的复杂场景和高级技术。接下来,我们将继续展开 实践篇 和 未来篇 的内容,探索一些高级功能、优化技巧、故障处理和扩展方案等。
20 | 删除数据后,为什么内存占用率还是很高?
Redis 在执行删除操作后,内存占用率可能不会立即下降,这通常与 Redis 内部的内存管理机制和数据删除的实际过程有关。
-
删除操作与内存释放:
- 当执行删除操作(如
DEL
命令)时,Redis 会将数据标记为“已删除”,但并不会立即释放对应的内存。内存的释放通常在 Redis 的空闲周期中或通过 内存回收机制(如 垃圾回收)来进行。这是由于 Redis 通过 jemalloc 进行内存分配,该分配器会延迟释放内存以减少频繁的内存操作。
- 当执行删除操作(如
-
内存碎片:
- 如果 Redis 的内存碎片较严重,那么即使删除了数据,内存的占用率也可能维持较高。可以通过命令
INFO MEMORY
来查看内存碎片的情况,了解是否有内存释放不完全的问题。 - 解决方案:定期执行
MEMORY PURGE
来清理无用的内存,或者设置合理的内存回收策略。
- 如果 Redis 的内存碎片较严重,那么即使删除了数据,内存的占用率也可能维持较高。可以通过命令
-
RDB 和 AOF 文件的影响:
- 在执行 RDB 或 AOF 持久化操作时,内存中的数据会被写入磁盘。如果存在大量删除操作,Redis 可能会出现磁盘与内存数据不一致的情况,导致删除的数据仍然在磁盘文件中。
- 解决方案:可以考虑手动触发 AOF 文件重写(
BGREWRITEAOF
)或 RDB 快照操作,来确保持久化文件与内存一致。
21 | 缓冲区:一个可能引发“惨案”的地方
Redis 使用缓冲区来处理客户端的请求,这意味着当请求量较大时,缓冲区的管理和处理变得尤为重要。如果缓冲区管理不当,可能会导致内存消耗急剧增加或请求延迟显著上升。
-
缓冲区的工作原理:
- Redis 会为每个客户端维护一个缓冲区,用来存储客户端请求的数据。每当客户端发起请求时,数据会先写入缓冲区,等待 Redis 处理完当前请求后再返回结果给客户端。
- 如果客户端连接过多或者单个请求的负载过大,可能会导致缓冲区积压,造成 Redis 的响应延迟和内存占用增加。
-
缓冲区溢出:
- 在某些极端负载下,缓冲区可能会溢出,导致 Redis 的性能下降,甚至可能导致系统崩溃。特别是在 Redis 与客户端的网络连接中断时,缓冲区中的数据无法及时发送给客户端。
-
解决方案:
- 客户端流量控制:确保客户端在发送请求时不会超出 Redis 的承载能力,使用批量操作和管道技术来减少请求次数。
- 使用 Redis 的
CLIENT PAUSE
命令:可以在特定情况下暂停客户端的请求,避免由于突发流量导致的缓冲区积压。 - 设置最大客户端连接数:通过配置
maxclients
限制连接数,防止 Redis 被过多的客户端请求淹没。
22 | 第 11~21 讲课后思考题答案及常见问题答疑
这些讲解中提到的许多问题和技术细节,可能在实际应用中会遇到各种问题。常见问题的答案包括:
- 如何避免 Redis 单线程的瓶颈?
通过合理的 Redis 分片(Sharding)方案,利用多个 Redis 实例来分摊请求负载,或者在极端情况下使用 Redis Cluster 来实现多节点并行处理。 - Redis 中的数据丢失问题如何处理?
如果使用 AOF 和 RDB 持久化机制配置得当,可以最大程度避免数据丢失。通过配置合理的同步策略和定期重写 AOF 文件来减少丢失风险。 - Redis 是否支持 ACID 事务?
Redis 本身不支持严格的 ACID 事务,但它支持通过 MULTI、EXEC 和 WATCH 命令模拟事务,确保多个操作的原子性。
23 | 旁路缓存:Redis 是如何工作的?
旁路缓存是一种常见的缓存优化方案,主要用于当缓存层和数据库层的访问逻辑发生变化时,可以使得 Redis 成为数据库查询的 “旁路”,即首先查询 Redis 缓存,如果缓存没有命中再查询数据库。
-
旁路缓存的工作原理:
- 客户端查询时,首先访问 Redis 缓存,如果 Redis 中有数据则直接返回。
- 如果 Redis 中没有数据(即缓存未命中),则从数据库中查询数据,查询到后将结果存入 Redis 中,并返回给客户端。
-
缓存穿透、击穿和雪崩问题:
- 缓存穿透:查询的对象在缓存和数据库中都不存在,导致每次请求都需要查询数据库。解决方案可以是设置布隆过滤器来快速判断数据是否存在。
- 缓存击穿:热点数据在缓存中失效,导致大量请求同时查询数据库。解决方案可以是使用互斥锁(Mutex)机制,保证同一时间只有一个请求访问数据库。
- 缓存雪崩:大量缓存同时失效,导致短时间内大量请求访问数据库。解决方案是使用合理的缓存过期时间,并通过 缓存预热 减少突然失效的概率。
24 | 替换策略:缓存满了怎么办?
当 Redis 缓存满时,如何选择合适的替换策略是缓存系统的核心问题。Redis 提供了多种缓存替换策略来应对这种情况。
-
LRU(Least Recently Used):
- LRU 策略会淘汰最久未使用的数据。当缓存达到最大容量时,Redis 会选择最久未被访问的键值对进行删除。
- Redis 内部实现了一个 2^10 的 LRU 算法 来高效实现 LRU 策略。
-
LFU(Least Frequently Used):
- LFU 策略会淘汰访问频率最少的数据。Redis 在 4.0 版本后增加了 LFU 策略,可以通过
maxmemory-policy
配置选择使用 LFU 策略。
- LFU 策略会淘汰访问频率最少的数据。Redis 在 4.0 版本后增加了 LFU 策略,可以通过
-
TTL(Time To Live)策略:
- 设置键值对的过期时间,超过时间限制后自动删除。可以用于一些短期有效的数据缓存。
-
配置优化:
- 可以通过配置
maxmemory
和maxmemory-policy
来设置 Redis 的最大内存限制和替换策略,从而避免缓存满时导致系统崩溃。
- 可以通过配置
25 | 缓存异常(上):如何解决缓存和数据库的数据不一致问题?
缓存和数据库的数据不一致问题是缓存系统常见的挑战。尤其在高并发的情况下,缓存和数据库的更新需要保证一致性。
-
缓存更新策略:
- Write-Through:每次更新缓存时,都会同步更新数据库。这种策略保证了数据的一致性,但会影响性能,因为每次写入都会触发数据库操作。
- Write-Behind:更新缓存时先更新缓存,然后异步地更新数据库。该策略提高了性能,但会导致数据在一段时间内处于不一致状态。
-
缓存失效策略:
- 当缓存的数据失效或过期时,可能会出现数据不一致的情况。常见的解决办法包括:在更新缓存时提前将缓存标记为失效,或通过 双写机制,即同时写入数据库和缓存,避免数据不一致。
26 | 缓存异常(下):如何解决缓存雪崩、击穿、穿透难题?
在高并发场景下,缓存可能会遇到雪崩、击穿、穿透等问题,这些问题会极大地影响系统的性能和可靠性。
-
缓存穿透:
- 布隆过滤器:布隆过滤器是一种高效的概率性数据结构,可以用来过滤不存在的数据请求,避免直接访问数据库。
-
缓存击穿:
- 互斥锁:在缓存失效时,使用互斥锁来保证同一时间只有一个请求可以查询数据库,避免多个请求同时查询数据库。
-
缓存雪崩:
- 合理的过期时间设计:避免大量缓存同时失效,可以设置不同的过期时间,或者采用 随机过期时间 来避免缓存雪崩。
27 | 缓存被污染了,该怎么办?
缓存污染指的是缓存中存储了不正确或不一致的数据,这种情况会导致应用程序读取到错误的数据,从而影响业务的正确性。
-
缓存污染的常见原因:
- 数据不一致:由于数据在缓存和数据库之间同步延迟,可能会出现缓存数据过期或者被错误地更新的情况。
- 缓存击穿或雪崩:大量缓存失效,导致请求直接击中数据库。如果数据库中有不正确或过期的数据,这可能被写入缓存,从而导致缓存污染。
-
解决方案:
- 缓存更新策略:使用双写策略(在更新数据库的同时,更新缓存)来保证数据的一致性。采用 异步刷新 来避免缓存污染的影响。
- 过期策略:合理设置缓存的过期时间,避免缓存中的数据长时间不更新,减少缓存污染的可能性。
- 数据校验:定期对缓存数据进行有效性校验。如果缓存中存在不合规的数据,可以重新从数据库中加载最新数据。
-
使用缓存清理机制:
- 定期清理过期缓存:可以通过设置缓存的过期时间
EXPIRE
来确保缓存数据不会长时间过期。或者使用 LRU(最少使用)策略淘汰无效数据。 - 主动清理:使用
DEL
或FLUSHDB
命令主动清理已知污染的数据,确保系统稳定。
- 定期清理过期缓存:可以通过设置缓存的过期时间
28 | Pika:如何基于SSD实现大容量Redis?
Pika 是一个兼容 Redis 协议的高性能 NoSQL 数据库,它在 Redis 基础上做了扩展,尤其在大规模数据存储和持久化方面做了优化,特别适用于 SSD(固态硬盘)存储环境。
-
Pika 与 Redis 的异同:
- Pika 使用 SSD 存储作为持久化方案,而 Redis 更依赖内存作为主要存储介质。Pika 将数据持久化到 SSD,使得它能够处理比 Redis 更大的数据集,同时保持高性能。
- Pika 的优势:使用 SSD 存储减少了内存瓶颈,适用于大数据量场景,比如实时日志存储、时序数据存储等。
-
Pika 的数据结构:
- 与 Redis 类似,Pika 支持常见的 Redis 数据结构(如字符串、哈希、列表、集合、排序集合等),并扩展了对磁盘存储的支持。这使得它在对大规模数据存储时能够提供比传统 Redis 更高的效率。
-
如何使用 Pika:
- 在使用 Pika 时,数据会被持久化到 SSD 存储,降低了内存消耗并扩展了 Redis 的数据存储能力。可以使用 RDB 持久化 和 AOF 日志 来确保数据的持久性。
- 适合对磁盘 I/O 能力有要求的场景,比如高并发、大数据量的应用系统。
29 | 无锁的原子操作:Redis 如何应对并发访问?
Redis 虽然是单线程处理请求,但它通过无锁的原子操作来确保并发请求之间的数据一致性。这是 Redis 高性能的关键之一。
-
Redis 的单线程模型:
- Redis 采用单线程模型,即一个 Redis 实例只有一个主线程来处理所有的客户端请求。所有的命令都按照请求的顺序依次处理,不会发生线程切换带来的上下文切换开销。
- 单线程模型使得 Redis 避免了并发环境下的 锁竞争,大大简化了设计和实现。
-
原子性操作:
- Redis 的命令在执行时都是 原子操作,即每个命令执行时要么完全成功,要么完全失败,不会出现部分成功、部分失败的情况。
- 例如,
INCR
、DECR
等操作是原子性的,不会受到其他操作干扰。即使多个客户端同时访问相同的键值,Redis 也能够保证最终一致性。
-
乐观锁与事务:
- Redis 还通过 乐观锁 来处理一些并发场景。使用
WATCH
命令可以监听某个或多个键的变化,只有在这些键未被其他客户端修改的情况下,事务才会成功执行。 - MULTI/EXEC 机制允许一组命令作为一个事务执行,从而确保命令的原子性。
- Redis 还通过 乐观锁 来处理一些并发场景。使用
-
无锁并发设计:
- Redis 使用无锁并发技术,通过 哈希表 等高效的数据结构,确保即使在单线程模式下,依然能够处理高并发请求。比如,Redis 的 链表 和 跳表 数据结构非常适合并发场景。
30 | 如何使用 Redis 实现分布式锁?
Redis 分布式锁是实现分布式系统中共享资源互斥访问的一种重要方式。通过 Redis 来实现分布式锁,可以确保在分布式系统中多个客户端对共享资源进行互斥访问。
-
分布式锁的工作原理:
- 基于 Redis 的分布式锁通常利用 Redis 的 SETNX(SET if Not eXists)命令来实现。该命令只能在键不存在时设置值,从而实现锁的获取。
- 锁的实现流程如下:
- 客户端尝试设置一个键值对,表示获取锁。
SET key lock_value NX EX 30
,这意味着如果键不存在,则设置值并设置过期时间为 30 秒,防止死锁。 - 客户端通过检查是否成功设置键来判断是否成功获得锁。
- 如果操作成功,则执行临界区操作,执行完毕后,删除锁。
- 如果操作失败,则进行重试。
- 客户端尝试设置一个键值对,表示获取锁。
-
防止死锁:
- 为了防止死锁,分布式锁通常会设置过期时间。锁持有者在过期时间内未释放锁时,其他客户端可以重新获得锁。
- 过期时间需要根据业务逻辑设置合理的值。锁持有者完成任务后应及时释放锁,避免其他客户端无法获取锁。
-
解决锁失效问题:
- 在一些极端情况下,Redis 锁可能会因为网络故障或 Redis 崩溃导致锁失效。为了避免这种情况,可以使用 RedLock 算法(由 Redis 作者提出),该算法通过多个 Redis 实例来确保锁的可靠性和高可用性。
-
最佳实践:
- 使用
SETNX
+EXPIRE
配合 Redis 的WATCH
命令 来确保锁的安全性和防止死锁。 - 注意在进行锁操作时,考虑网络延迟和 Redis 响应时间,避免由于锁超时导致的竞争条件。
- 使用
31 | 事务机制:Redis 能实现 ACID 属性吗?
Redis 是一个高性能的 NoSQL 数据库,它并没有严格的实现 ACID 属性,但提供了一些机制来保证部分事务的一致性。
-
Redis 的事务模型:
- Redis 的事务是通过
MULTI
、EXEC
和WATCH
实现的。使用MULTI
开启事务,后续的命令将会被放入队列,直到使用EXEC
提交事务。事务执行时,Redis 会确保队列中的命令按顺序依次执行。 WATCH
命令可以在事务执行前对某个键进行监视。如果在事务提交之前键被修改,事务会被 中止,确保数据的一致性。
- Redis 的事务是通过
-
事务的原子性:
- Redis 事务中的命令会按照原子性执行。要么事务中的所有命令执行成功,要么没有命令被执行。这种原子性保证了事务的一致性,但并不能像传统关系型数据库那样提供完全的 隔离性 和 持久性。
-
Redis 事务与 ACID:
-
一致性:Redis 保证事务中的所有命令按顺序执行,事务开始前和提交后,数据处于一致的状态。
-
隔离性:Redis 的事务没有严格的隔离级别,多个客户端可能会并发执行事务中的命令,但 Redis 会保证事务中命令的顺序执行。
-
持久性:Redis 事务并不保证持久性,事务执行后的数据不会自动写入磁盘,需要依赖 Redis 的持久化机制(RDB 或 AOF)来保证数据不会丢失。
-
原子性:Redis 事务是原子的,要么完全成功,要么完全失败。
-
继续深入探讨 Redis 的高阶特性、性能调优以及高级应用。以下内容将着重于 Redis 的数据分布、性能优化策略以及在特定场景下的应用,进一步提升你对 Redis 的理解。
32 | Redis 主从同步与故障切换,有哪些坑?
在 Redis 集群中,主从同步和故障切换是确保高可用性的关键机制。但实际运维中,有一些坑需要特别注意。
-
主从同步原理:
- 主节点(Master) 接收写请求并将数据同步到其从节点(Slave)。
- 从节点 定期向主节点发送同步请求,主节点通过复制协议将数据发送到从节点。
- 在数据同步的过程中,从节点将同步收到的数据保存在内存中,以确保数据的一致性。
-
常见坑:
- 网络延迟与带宽问题:如果主从节点之间的网络带宽较低,或者网络延迟较高,可能导致主从节点的同步过程滞后,从而出现数据不一致的问题。
- 同步延迟:Redis 在进行主从同步时,会产生一定的延迟,尤其是在数据量大的情况下。如果主节点在同步期间遭遇故障,可能导致数据丢失。
- 阻塞操作:在一些高负载的情况下,主节点可能会出现 阻塞(比如执行长时间的写操作),导致主从同步滞后,从而增加故障切换的难度。
-
避免数据丢失:
- 使用 AOF 持久化 和 RDB 快照 配合主从同步,减少数据丢失的概率。AOF 能够记录所有写操作,并在主节点宕机时从从节点中恢复数据。
- 设置合理的
repl-backlog-size
参数,确保主从节点同步过程中,主节点的写入操作不会因同步延迟而丢失。
-
故障切换机制:
- 哨兵模式:使用 Redis Sentinel 来实现主从节点故障切换。当主节点不可用时,Redis Sentinel 会自动选举一个从节点作为新的主节点,从而确保服务的高可用性。
- 手动故障转移:如果 Redis Sentinel 没有自动恢复服务,运维人员也可以手动进行故障转移操作,但这样就无法保证自动化恢复。
33 | 脑裂:一次奇怪的数据丢失
“脑裂”是指 Redis 集群中,多个节点在网络隔离的情况下,认为自己是主节点,从而导致数据的不一致和丢失。
-
脑裂的产生:
- Redis 集群依赖一致性协议来确保数据一致性,但如果网络发生故障,导致集群的部分节点失去联系,可能出现多个节点认为自己是主节点的情况。这样,两个节点同时接收写请求,可能会导致数据的不一致,最终出现数据丢失。
-
如何避免脑裂:
- 集群模式:使用 Redis 集群模式时,集群会自动确保主节点的高可用性。通过数据分片和故障转移机制,减少节点间的网络延迟,确保数据一致性。
- 加大网络隔离阈值:通过配置 Redis 的
cluster-require-full-coverage
参数,控制集群对故障的容忍度。默认情况下,当 Redis 集群的一部分节点无法与其他节点通信时,集群会进行故障切换。 - 使用 Redis Sentinel:如果是单实例 Redis,使用 Redis Sentinel 进行主从同步和故障切换,可以有效减少脑裂问题的发生。
-
故障排查与恢复:
- 当发生脑裂时,首先需要检查 Redis 的
replication
和cluster
配置是否正确。使用INFO replication
和INFO cluster
命令查看节点的同步状态,确认是否有节点异常。 - 可以通过手动调整集群配置,重新启动故障节点来恢复正常状态。需要注意的是,恢复后应立即进行数据一致性检查,以防止数据丢失。
- 当发生脑裂时,首先需要检查 Redis 的
34 | Codis VS Redis Cluster:我该选择哪一个集群方案?
Codis 和 Redis Cluster 都是 Redis 的集群解决方案,但它们在架构、特性和适用场景上有所不同。
-
Codis 架构:
- Codis 是由 猎云网 开源的 Redis 集群方案,基于 Redis 的主从复制模型和代理层架构。它将多个 Redis 实例作为一个整体进行管理,提供了灵活的路由和扩展性。
- Codis 的 Proxy 层 充当客户端和 Redis 实例之间的中间层,处理请求路由、负载均衡等任务。Codis 提供了更灵活的集群扩展方式。
-
Redis Cluster 架构:
- Redis Cluster 是 Redis 官方提供的集群解决方案。与 Codis 不同,Redis Cluster 将数据自动分片,并且每个节点都可以处理客户端请求。集群中没有中间层代理,节点间通过 Gossip 协议 来保持通信。
- Redis Cluster 对集群的管理相对简化,但在节点间同步、容错等方面存在一定的局限性。
-
Codis 与 Redis Cluster 的选择:
- Codis 更适合大规模、跨机房的 Redis 集群,因为其代理层可以更方便地管理节点和数据分片,同时提供了更好的扩展性和灵活性。
- Redis Cluster 更适合需要高可用、高性能、低延迟的场景,并且配置和管理相对简便。如果是较小规模的 Redis 集群,推荐使用 Redis Cluster。
-
性能比较:
- Codis 在性能上略逊于 Redis Cluster,因为它增加了代理层的中间转发,这会带来一定的性能开销。但它在扩展性和灵活性上优于 Redis Cluster,特别是在跨数据中心部署时,Codis 的优势更加明显。
- Redis Cluster 由于没有代理层,性能较高,但它的节点管理、分片以及容错能力不如 Codis 灵活。
35 | Redis 支撑秒杀场景的关键技术和实践
秒杀系统是典型的高并发、高压力场景,Redis 作为高性能缓存系统,通常用于支撑秒杀业务的流量高峰。
-
缓存雪崩与缓存穿透:
- 缓存雪崩:大量缓存同时过期,导致大量请求直接访问数据库,造成数据库压力过大。可以通过设置不同的过期时间,避免缓存同时过期,或使用 加锁机制 来避免并发请求直接击中数据库。
- 缓存穿透:请求的数据在缓存和数据库中都不存在,导致大量请求直接穿透缓存查询数据库。可以通过 布隆过滤器 来解决缓存穿透问题,提前过滤掉不存在的数据。
-
限流与排队机制:
- 在秒杀场景中,通常需要限流来防止瞬间请求过载 Redis。常见的限流策略包括 漏桶算法、令牌桶算法 等。
- Redis 可以作为 队列系统,将请求按顺序存储并逐一处理,避免瞬时请求过多,减缓服务器压力。
-
Redis 的事务支持:
- 秒杀场景中,通常需要确保对库存的操作具有原子性。Redis 提供了 事务 和 乐观锁 等机制,可以确保多个用户并发下的库存修改操作不发生冲突。
- 使用 Redis 的
WATCH
命令 和MULTI/EXEC
事务,可以确保库存的修改是原子性的,避免超卖现象。
-
分布式锁:
- 在秒杀系统中,分布式锁通常用于保证同一时间只有一个请求能够修改库存。通过 Redis 实现分布式锁,能够避免多台服务器同时更新库存,确保数据一致性。
- 使用
SETNX
+EXPIRE
实现 Redis 分布式锁,确保锁的过期时间不会被忽视,避免死锁。
36 | 数据分布优化:如何应对数据倾斜?
数据倾斜是指 Redis 集群中某些节点的数据量过多,导致该节点成为性能瓶颈,而其他节点空闲,无法充分利用集群资源。
- 数据倾斜的原因:
- 不均匀的分片:数据分片策略不合理,可能导致某些键的访问频率过高,从而导致该节点的负载过大。
- 热点数据问题:某些键值(如最常访问的商品)可能会被频繁访问,从而成为热点数据,导致特定节点的负载
压力过大。
- 解决数据倾斜的方法:
- 重新分片:通过调整 Redis 集群的分片策略,避免某个节点的负载过高。可以使用 一致性哈希 算法来优化数据的分布,确保各个节点的负载均衡。
- 分布式负载均衡:通过调整数据访问逻辑,将热点数据分散到多个节点,避免单个节点负载过高。
- 热点数据隔离:将热点数据单独分片,使用 独立缓存 或 异步处理 来减轻主 Redis 节点的压力。
37 | 通信开销:限制 Redis Cluster 规模的关键因素
随着 Redis 集群规模的扩展,通信开销会逐渐增加,进而影响系统的响应时间和吞吐量。
-
集群规模与性能:
- Redis 集群通过节点间的 Gossip 协议 和 复制协议 来进行通信。随着节点数量的增加,网络延迟和数据同步的开销也会增加。
- 跨节点请求:在 Redis Cluster 中,当客户端请求的数据不存在于本地节点时,需要通过 MOVED 重定向到正确的节点。这会增加额外的网络请求,导致响应时间变慢。
-
优化通信开销:
- 合理设置集群节点数:Redis 官方建议,集群的节点数最好保持在 16~64 之间,超过这个范围可能导致网络延迟和数据同步压力增加。
- 数据分片优化:通过合理的分片和 数据热点优化,减少跨节点请求的频率,从而减轻网络开销。
继续深入探讨 Redis 的高级特性、性能调优以及更广泛的应用场景。这一部分将重点关注如何在大规模系统中应用 Redis,解决实际业务中的问题,以及 Redis 在不同技术栈中的集成和高级应用。
38 | 通信开销:限制 Redis Cluster 规模的关键因素
在 Redis 集群的实际应用中,随着集群规模的不断扩大,通信开销成为影响集群性能的关键因素之一。集群中各个节点之间的通信需要消耗一定的网络带宽和时间,而随着节点数的增加,跨节点的通信请求数量也会增加,进而影响整体性能。
-
Redis 集群通信模型:
- Redis 集群使用 Gossip 协议 来实现节点之间的状态同步,每个节点都会定期与其他节点交换信息。这种方式可以减少全局广播和集中式查询,使得每个节点的状态更新和故障检测更加高效。
- 节点之间通过 P2P(点对点) 连接进行信息交换,不同于传统的客户端-服务器通信。虽然这种模型提高了集群的容错性,但也增加了节点之间的通信成本,尤其是在节点数目较多的情况下。
-
通信开销的影响因素:
- 数据迁移:Redis 集群会在集群扩容时进行数据迁移,即通过重新分片将数据从一个节点迁移到另一个节点。这一过程会产生大量的网络流量,尤其是对于大数据量的场景,会增加网络负载。
- 请求重定向:当客户端请求的数据不在本地节点时,Redis 会通过 MOVED 响应将请求重定向到正确的节点。这虽然是 Redis 集群的正常操作,但也增加了额外的请求和响应时间,尤其是在客户端请求频繁时。
- 复制同步:主从节点之间的同步会消耗带宽,尤其是在主节点的数据量较大时,从节点需要不断接收更新。
-
优化通信开销的策略:
- 合理的分片和扩容策略:通过合理分片,减少跨节点的数据请求。例如,尽量避免大量请求都指向同一个 Redis 分片,保持各节点间的负载均衡。
- 数据分区和热点数据隔离:通过热点数据的隔离与负载均衡,减少由于热点数据集中访问所带来的跨节点通信压力。
- 加速数据迁移:在 Redis 集群扩容或缩容时,可以采用 在线扩容 的方式,使数据迁移过程更加平滑,避免集群发生过载。
39 | Redis的下一步:基于NVM内存的实践
随着硬件技术的进步,特别是 非易失性内存(NVM) 的出现,Redis 的存储和性能能力面临着新的机遇与挑战。NVM(如 Intel Optane)提供了较传统内存更高的持久性,并且在访问速度上接近内存,因此 Redis 可以利用这种技术来改善存储和持久化性能。
-
NVM 的优势:
- 高效的数据持久化:Redis 在传统内存上使用 RDB 快照和 AOF 日志来持久化数据,但这些操作的性能往往受到磁盘 I/O 的限制。而使用 NVM,Redis 可以将数据持久化到非易失性存储上,同时具备更低的延迟和更高的吞吐量。
- 数据恢复速度:由于 NVM 的读写速度较传统磁盘存储更快,因此 Redis 使用 NVM 可以显著提高故障恢复的速度,特别是在大规模数据恢复的场景中。
-
Redis 在 NVM 上的挑战:
- 写放大问题:虽然 NVM 的性能优于传统的磁盘存储,但在处理大量写操作时,NVM 也可能面临 写放大(Write Amplification)的问题。Redis 需要采取特殊的机制,避免频繁的写操作对 NVM 存储的性能产生负面影响。
- 内存和持久化的管理:NVM 可以同时作为内存和磁盘的角色,因此 Redis 需要灵活管理 NVM 存储与传统内存之间的区别,避免资源的浪费。
-
Redis 和 NVM 的结合:
- Redis 可以结合 Intel Optane 等 NVM 存储,将数据存储在类似内存的设备上,同时保证数据的持久性。这将使得 Redis 在处理大规模数据时,不再受到传统磁盘的瓶颈,提升整体性能。
- Redis 通过优化数据持久化过程,使得 NVM 的特点能够充分发挥,提高 Redis 的响应速度和存储效率。具体实践中,Redis 将结合 内存数据库 和 持久化存储,为企业级应用提供高性能、高可靠的数据存储解决方案。
相关文章:
Redis(基础篇 + 实践篇 )
01 | 基本架构:一个键值数据库包含什么? Redis 作为一个内存数据存储系统,它的架构设计非常简洁,但功能非常强大。理解其核心架构对高效使用 Redis 至关重要。 客户端与服务器架构: 客户端通过 TCP 协议连接到 Redis …...
单片机-独立按键矩阵按键实验
1、按键介绍 按键管脚两端距离长的表示默认是导通状态,距离短的默认是断开状态, 如果按键按下,初始导通状态变为断开,初始断开状态变为导通 我们开发板是采用软件消抖,一般来说一个简单的按键消抖就是先读取按键的状…...
我用AI学Android Jetpack Compose之入门篇(1)
这篇我们先来跑通第一个Android Jetpack Compose工程,现在新版本的Android Studio,新建工程选择Empty Activity默认就会开启Jetpack Compose的支持,再次声明,答案来自 通义千问Ai 文章目录 1.用Android Jetpack Compose需要安装什…...
简单的生产数据库重连策略优化
简单的druid生产数据库重连策略优化 1. 需求 我们生产环境有一次在大量请求拥堵后,好多数据库操作都超时了,在此之后数据库的连接池不能正常的获取数据库连接了,我们确认了数据库服务是没有问题的,那么就是连接池的配置有问题&a…...
STM32-笔记37-吸烟室管控系统项目
一、项目需求 1. 使用 mq-2 获取环境烟雾值,并显示在 LCD1602 上; 2. 按键修改阈值,并显示在 LCD1602 上; 3. 烟雾值超过阈值时,蜂鸣器长响,风扇打开;烟雾值小于阈值时,蜂鸣器不响…...
2025-01-04 Unity插件 YodaSheet1 —— 插件介绍
文章目录 1 介绍2 工作原理2.1 ScriptableObject -> YadeSheetData2.2 YadeDatabase 存储多个 YadeSheetData 3 用途4 缺点5 推荐 1 介绍 Yade 提供类似于 Excel 或者 Google Sheets 的表格编辑器,可以轻松地在 Unity 编辑器中 编辑,搜索…...
电子电气架构 --- 安全相关内容汇总
我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 所谓鸡汤,要么蛊惑你认命,要么怂恿你拼命,但都是回避问题的根源,以现象替代逻辑,以情绪代替思考,把消极接受现实的懦弱,伪装成乐观面对不幸的…...
科研绘图系列:R语言单细胞数据常见的可视化图形
禁止商业或二改转载,仅供自学使用,侵权必究,如需截取部分内容请后台联系作者! 文章目录 介绍加载R包数据下载导入数据数据预处理图1图2图3图4图5图6系统信息参考介绍 单细胞数据常见的可视化图形 因为本教程是单细胞数据,因此运行本画图脚本需要电脑的内存最少32Gb 加载…...
【顶刊TPAMI 2025】多头编码(MHE)之极限分类 Part 2:基础知识
目录 1 预热1.1 记号1.2 分类器计算过载问题 2 多头编码(MHE)2.1 标签分解2.2 多头组合(Multi-Head Combination) 论文:Multi-Head Encoding for Extreme Label Classification 作者:Daojun Liang, Haixia …...
Flink使用
Window下启动支持 下载或复制老版本的放在bin目录下即可; flink.bat echo off setlocalSET bin%~dp0 SET FLINK_HOME%bin%.. SET FLINK_LIB_DIR%FLINK_HOME%\lib SET FLINK_PLUGINS_DIR%FLINK_HOME%\pluginsSET JVM_ARGS-Xmx512mSET FLINK_JM_CLASSPATH%FLINK_LI…...
一种可复用的AI提效方案:AI点灯
在当今飞速发展的时代,AI技术正不断渗透到我们生活的各个层面,深刻改变着传统的工作方式和生活模式。面对这一重大变革,我们不能被动观望或抗拒,而应积极拥抱AI,将其作为成长的助力。只有与AI协同发展,才能…...
Django 模型
Django 模型 Django 模型是 Django 框架的核心组件之一,它用于定义应用程序的数据结构。在 Django 中,模型是 Python 类,通常继承自 django.db.models.Model。每个模型类代表数据库中的一个表,模型类的属性对应表中的字段。 1. 创建模型 创建 Django 模型非常简单。首先…...
【MySQL 探索者日志 】第二弹 —— 数据库基础
MySQL系列学习笔记: MySQL探索者日志__Zwy的博客-CSDN博客 各位于晏,亦菲们,请点赞关注! 我的个人主页: _Zwy-CSDN博客 目录 1、MySQL服务器,数据库,表关系 2、MySQL登录连接服务器 3、MyS…...
【51单片机-零基础chapter1】
安装软件(配套的有,不多赘述) 1.管理员身份运行keil和破解软件kegen 将CID代码复制粘贴到 一定要管理员方式,不然会error 插入板子 我的电脑,管理 1.如果是拯救者,查看端口,如果没有则显示隐藏 2.苹果不知道,好像不可以 3.其他电脑在"其他设备找" (注:本人在校已…...
stm32的掉电检测机制——PVD
有时在一些应用中,我们需要检测系统是否掉电了,或者要在掉电的瞬间需要做一些处理。 STM32内部自带PVD功能,用于对MCU供电电压VDD进行监控。 STM32就有这样的掉电检测机制——PVD(Programmable Voltage Detecter),即可编程电压检…...
电脑steam api dll缺失了怎么办?
电脑故障解析与自救指南:Steam API DLL缺失问题的全面解析 在软件开发与电脑维护的广阔天地里,我们时常会遇到各种各样的系统报错与文件问题,其中“Steam API DLL缺失”便是让不少游戏爱好者和游戏开发者头疼的难题之一。作为一名深耕软件开…...
Kotlin 协程基础知识总结七 —— Flow 与 Jetpack Paging3
专题分为五大块: Paging3 的结构组成Flow 与 Paging3下拉刷新上拉刷新离奇 Bug上游数据缓存 Demo 会还原开发迭代的过程,不会直接一步到位。 1、Paging3 加载数据流程 (P105)Paging3 的简介详情可参考官方文档 Paging 库概览&…...
使用JMeter玩转tidb压测
作者: du拉松 原文来源: https://tidb.net/blog/3f1ada39 一、前言 tidb是mysql协议的,所以在使用过程中使用tidb的相关工具连接即可。因为jmeter是java开发的相关工具,直接使用mysql的jdbc驱动包即可。 二、linux下安装jmet…...
音视频入门基础:MPEG2-PS专题(3)——MPEG2-PS格式简介
一、引言 本文对MPEG2-PS格式进行简介。 进行简介之前,请各位先下载MPEG2-PS的官方文档。ITU-T和ISO/IEC都分别提供MPEG2-PS的官方文档。但是ITU提供的文档是免费的,ISO/IEC是付费的,所以我们主要阅读ITU提供的官方文档,比如较新…...
ETCD渗透利用指南
目录 未指定使用put操作报错 未指定操作版本使用get报错 首先etcd分为两个版本v2和v3,不同的API结果无论是访问URL还是使用etcdctl进行通信,都会导致问题,例如使用etcdctl和v3进行通信,如果没有实名ETCDCTL_API3指定API版本会直接…...
Python安装(新手详细版)
前言 第一次接触Python,可能是爬虫或者是信息AI开发的小朋友,都说Python 语言简单,那么多学一些总是有好处的,下面从一个完全不懂的Python 的小白来安装Python 等一系列工作的记录,并且遇到的问题也会写出,…...
SQL 中复杂 CASE WHEN 嵌套逻辑优化
目标:优化复杂的 CASE WHEN 逻辑,提升 SQL 语句的可读性与执行效率,减少多层嵌套带来的复杂性。 1. CASE WHEN 的常见问题 嵌套过深:多个条件判断嵌套,难以阅读和维护。重复逻辑:相似逻辑在多个分支中重复…...
【专题】2024年出口跨境电商促销趋势白皮书报告汇总PDF洞察(附原数据表)
原文链接:https://tecdat.cn/?p38722 在当今全球化加速演进、数字经济蓬勃发展的大背景下,跨境电商行业正以前所未有的态势重塑国际贸易格局,成为各方瞩目的焦点领域。 根据亚马逊发布的《2024年出口跨境电商促销趋势白皮书》,…...
C# 设计模式(结构型模式):代理模式
C# 设计模式(结构型模式):代理模式 在软件开发中,有时我们需要通过某种方式间接地访问一个对象,这时就可以使用代理模式(Proxy Pattern)。代理模式通过引入一个代理对象来控制对目标对象的访问…...
单片机复位电路基本理解教程文章·含上拉电阻理解电容开路理解!!!
目录 常见复位电路种类 复位电路电阻上拉理解 电容储能断路理解 编写不易,仅供学习,请勿搬运,感谢理解 常见元器件驱动电路文章专栏连接 LM7805系列降压芯片驱动电路降压芯片驱动电路详解-…...
深入浅出:事件监听中的适配器模式
1. 为什么需要适配器模式? 在Java的事件监听器设计中,许多接口有多个抽象方法。例如,MouseListener 接口有 5 个方法,KeyListener 接口有 3 个方法。如果我们只关心其中的一个方法(例如,鼠标点击事件&…...
常用LabVIEW算法及应用
在LabVIEW项目中,算法的应用是提高系统性能、实现特定功能、完成复杂任务的核心。LabVIEW作为一种图形化编程语言,允许用户通过直观的图形编程来实现各种复杂的算法。这些算法广泛应用于控制系统、数据采集、信号处理、图像处理、机器学习等领域。了解常…...
VTK知识学习(28)-区域提取
1、感兴趣区域(Volume ofInterest,VOI) 它是图像内部的一块子区域。在VTK中,vtkExtractVOI 类可根据用户指定的区域范围提取子图像。该Filter 的输入和输出都是一个vtkImageData,因此其结果可以直接作为图像保存。 代码: private void Test…...
基于Spring Boot + Vue3实现的在线汽车保养维修预约管理系统源码+文档
前言 基于Spring Boot Vue3实现的在线汽车保养维修预约管理系统是一种前后端分离架构的应用,它结合了Java后端开发框架Spring Boot和现代JavaScript前端框架Vue.js 3.0的优势。这样的系统可以为汽车服务站提供一个高效的平台来管理客户的预约请求 技术选型 系统…...
CAN201 Introduction to Networking(计算机网络)Pt.4 链路层
文章目录 5. Link Layer(链路层)5.1 Services of link layer(链路层的服务)5.2 Error detection and correction(错误检测和纠正)5.2.1 Partity Checks(奇偶检验)5.2.2 Checksum&…...
Python视频处理:噪声矩阵与并行计算的完美融合
噪声级别对视频质量有显著的影响,主要体现在以下几个方面: 1. 视觉质量 低噪声级别:当噪声级别较低时,视频的视觉质量较好。噪声对图像细节的干扰较小,画面看起来较为清晰和自然。观众可以更容易地识别图像中的细节和…...
wordpress开发之实现使用第三方库qrcode-generator生成二维码并上传和展示
文章目录 一、需求二、技术实现 - 利用qrcode-generator库三、代码实现 一、需求 客户的需求是能将特定的url生成二维码,以便将二维码分享或贴到合同纸上给他的客户扫描查看信息。 这个url包含的内容类似于如下格式: https://www.example.com/contrac…...
计算机网络——物理层
一、通信基础 1.相关术语: • 数据(data)——运送消息的实体。 • 信号(signal)——数据的电气的或电磁的表现。 • “模拟的”(analogous)——代表消息的参数的取值是连续的。 • “数字的”(digital)——代表消息的参数的取值是离散的。 • 码元(code)——在…...
网络IP协议
IP(Internet Protocol,网际协议)是TCP/IP协议族中重要的协议,主要负责将数据包发送给目标主机。IP相当于OSI(图1)的第三层网络层。网络层的主要作用是失陷终端节点之间的通信。这种终端节点之间的通信也叫点…...
Unity UGUI使用技巧与经验总结(不定期更新)
Text自动缩放参考连接: Unity -UGUI中Text文本框的自动调整,字体大小的自适应调节_unity添加的字体大小锁定-CSDN博客 Toggle按钮选择时,显示对应的UI界面: 为Toggle组件的On Value Change事件添加对需要显示的对象的SetActive…...
Tailwind CSS 使用简介
参考网站安装 - Tailwind CSS 中文网 号称是开始使用 Tailwind CSS 通过 npm 安装 tailwindcss,并创建你的 tailwind.config.js 文件。 npm install -D tailwindcss npx tailwindcss init 在 tailwind.config.js 文件中添加所有模板文件的路径。 /** type {im…...
嵌入式linux中socket控制与实现
一、概述 1、首先网络,一看到这个词,我们就会想到IP地址和端口号,那IP地址和端口各有什么作用呢? (1)IP地址如身份证一样,是标识的电脑的,一台电脑只有一个IP地址。 (2)端口提供了一种访问通道,服务器一般都是通过知名端口号来识别某个服务。例如,对于每个TCP/IP实…...
Go语言的 的数据封装(Data Encapsulation)核心知识
Go语言的数据封装(Data Encapsulation)核心知识 引言 在现代编程语言中,数据封装是一个重要的编程概念。它不仅帮助开发者管理复杂性,还提高了代码的可维护性和安全性。Go语言(Golang)作为一种注重简洁性…...
25/1/5 算法笔记<强化学习> MPC,交叉熵法,PETS算法
MPC 一个棋手下棋,会根据当前的局势来推演落子几步可能发生的局势,然后选择局势最好的一种情况来决定当前落子位置。 模型预测控制方法MPC,就是这样一种迭代的、基于模型的控制方法。值得注意的是MPC中不存在一个显示的策略。具体而言就是MPC在每次采取…...
最新版Chrome浏览器加载ActiveX控件之CFCA安全输入控件
背景 CFCA安全输入控件用于保证用户在浏览器、桌面客户端、移动客户端中输入信息的安全性,防止运行在用户系统上的病毒、木马等恶意程序入侵窃取用户输入的敏感信息。确保用户输入、本地缓存、网络传输整个流程中,输入的敏感信息不被窃取。广泛应用于银行…...
vue 项目集成 electron 和 electron 打包及环境配置
vue electron 开发桌面端应用 安装 electron npm i electron -D记得加上-D,electron 需添加到devDependencies,如果添加到dependencies后面运行可能会报错 根目录创建electron文件夹,在electron文件夹创建main.js(或者backgrou…...
计算机网络--UDP和TCP课后习题
【5-05】 试举例说明有些应用程序愿意采用不可靠的UDP, 而不愿意采用可靠的TCP。 解答: 这可能有以下几种情况。 首先,在互联网上传输实时数据的分组时,有可能会出现差错甚至丢失。如果利用 TCP 协议对这些出错或丢失的分组进行重传&…...
【算法不挂科】算法期末考试题库(带解析)【选择题53道&填空题36道&算法填空题7道&问答题33道】
前言 大家好吖,欢迎来到 YY 滴算法不挂科系列 ,热烈欢迎! 本章主要内容面向接触过C的老铁 下面是相关传送门 【算法不挂科】算法期末考试题库1(带解析)【选择题53道&填空题36道&算法填空题7道&a…...
Java+maven+selenium3+testng 自动化测试环境IDEA
软件测试资料领取:[内部资源] 想拿年薪40W的软件测试人员,这份资料必须领取~ 软件测试面试刷题工具领取:软件测试面试刷题【800道面试题答案免费刷】 idea 、java环境变量jdk maven安装及环境变量配置这里就不多说了,网上有很多…...
【踩坑指南2.0 2025最新】Scala中如何在命令行传入参数以运行主函数
这个地方基本没有任何文档记录,在学习的过程中屡屡碰壁,因此记录一下这部分的内容,懒得看可以直接跳到总结看结论。 踩坑步骤 首先来看看书上让我们怎么写: //main.scala object Start {def main(args:Array[String]) {try {v…...
vue3-watchEffect异步依赖收集
当 b 更新时 a 并不会更新,因为watchEffect的依赖收集在该案例中停止于await asyncFn(),也就是只会收集同步代码的依赖,await 之后的异步代码的依赖并不会收集到 <template> <div>a: {{ a }} <br>b: {{ b }} <br>&l…...
【Go研究】Go语言脚本化的可行性——yaegi项目体验
0x01 背景——云计算中脚本化困境 作为云基础设施管理中,大量需要跟文件系统、容器等相关的操作,这些操作实现通常用脚本来实现。 现在探讨下,这些脚本为什么一定要用脚本语言来实现,以及目前实现中的常见的问题。 常见的两个场…...
Genome Research | 俄亥俄州立于忠堂组-结合深度学习与蛋白质数据库系统探究反刍动物真核微生物...
结合深度学习与蛋白质数据库系统探究反刍动物真核微生物 Probing the eukaryotic microbes of ruminants with a deep-learning classifier and comprehensive protein databases 期刊:Genome Research DOI:https://doi.org/10.1101/gr.279825.124 第一作…...
centos7yum安装mysql5.7
1、安装mysql5.7 (1) 正常安装 [rootBrianZhu /]# wget -i -c http://dev.mysql.com/get/mysql57-community-release-el7-10.noarch.rpm [rootBrianZhu /]# yum -y install mysql57-community-release-el7-10.noarch.rpm [rootBrianZhu /]# yum -y install mysql-community-se…...
JavaScript系列(8)-- Array高级操作
JavaScript Array高级操作 📚 在前七篇文章中,我们探讨了JavaScript的语言特性、ECMAScript标准、引擎工作原理、数值类型、字符串处理、Symbol类型和Object高级特性。今天,让我们深入了解JavaScript中的Array高级操作。数组是最常用的数据结…...