Redis分布式集群入门:核心数据结构、持久化与高可用基础
1. 从单机缓存到分布式集群Redis到底解决了什么问题很多人第一次接触Redis是因为项目里某个接口慢得让人抓狂——数据库查询要几百毫秒并发一上来直接打满连接池。这时候老同事通常会甩过来一句加个Redis缓存吧然后你就开始了一边查文档一边往代码里塞set和get的日子。但真正要把Redis用好尤其是当数据量从几万涨到几千万、并发从几十涨到几万的时候单机Redis很快就会碰到天花板内存不够、QPS上不去、宕机后数据全丢。这时候就不得不面对分布式集群这个话题。Redis本质上是一个基于内存的键值存储系统但它和简单的HashMap有本质区别。它支持持久化意味着重启后数据还在它支持多种数据结构不只是字符串它支持主从复制和集群分片能横向扩展。这些特性叠加起来才让Redis从缓存工具变成了基础设施。我见过不少团队把Redis当纯缓存用结果某天缓存雪崩数据库直接被压垮也见过把Redis当数据库用的结果持久化配置没调好重启后数据丢了一大半。这些坑的根源都是对Redis的基础知识理解不够扎实。这篇文章面向的是准备系统学习Redis分布式集群的开发者不管你是刚接触Redis的新手还是已经用过但没深入理解原理的老手都能从中找到有价值的内容。我会从最基础的核心概念讲起把单机Redis的关键知识点打牢再逐步过渡到分布式场景下会遇到的问题和解决思路。整个系列会分多篇展开这是第一篇重点放在基础知识上——别小看这些基础后面集群搭建、故障排查、性能调优全都建立在这些概念之上。2. Redis的核心数据结构与底层编码机制2.1 五种基础类型的使用场景与选择逻辑Redis最常被提到的就是五种基础数据类型String、List、Hash、Set、ZSet。但很多人只是知道名字并不清楚什么时候该用哪个。我刚开始用的时候把所有东西都塞成String结果一个简单的排行榜功能写了上百行代码后来才发现ZSet几行就能搞定。String是最简单的类型可以存文本、数字、二进制数据。它的典型场景是缓存单个对象、计数器、分布式锁。比如缓存用户信息把整个JSON序列化后存进去读取时反序列化这是最常见的用法。但要注意如果只是更新对象里的某一个字段String类型就得整体读出来、改完再写回去并发场景下容易出问题。List是有序的字符串列表支持从两端插入和弹出。它天然适合做消息队列——生产者LPUSH消费者BRPOP简单可靠。但List有个局限它不支持按索引快速查找中间元素如果你需要频繁随机访问List就不合适了。Hash是键值对集合适合存储对象的多个字段。比如用户信息可以用HSET user:1001 name 张三 age 28更新单个字段时只改那一个不用整体读写。这在并发场景下比String有优势。但Hash的字段不能单独设置过期时间只能对整个key设置。Set是无序不重复集合适合做去重、交集、并集运算。比如统计两个用户的共同关注用SINTER一行搞定。ZSet在Set基础上给每个元素加了一个分数自动按分数排序是做排行榜、延迟队列的利器。选择数据类型的核心逻辑是先看数据之间的关系再看访问模式。如果只是简单的键值映射用String如果是一个对象的多个属性用Hash如果需要去重或集合运算用Set如果需要排序用ZSet如果需要队列语义用List。2.2 底层编码为什么同样的类型有不同的性能表现Redis的每种数据类型在底层都有多种编码方式Redis会根据数据量自动切换。这个机制很多人不知道但它直接影响内存占用和操作性能。以Hash为例当字段数量少且值比较小时Redis用ziplist压缩列表存储这是一块连续内存节省空间但插入删除需要移动数据。当字段数量超过hash-max-ziplist-entries默认128或某个值超过hash-max-ziplist-value默认64字节时会转成hashtable查询和插入都是O(1)但内存占用更高。List也有类似的机制早期版本用ziplist和linkedlist后来引入了quicklist本质是ziplist组成的双向链表兼顾了空间和性能。ZSet在元素少时用ziplist多了之后转成skiplist跳表加hashtable。理解这些编码机制的实际意义在于你可以通过调整配置参数来优化内存或性能。比如你的Hash字段数刚好在130左右每个值都不大那把hash-max-ziplist-entries调到256就能继续用ziplist省下不少内存。但要注意ziplist的插入删除是O(n)的如果写操作非常频繁还是让它转成hashtable更合适。提示可以通过OBJECT ENCODING key命令查看某个key当前的底层编码调试时非常有用。2.3 过期策略与内存淘汰数据不丢和内存不爆的平衡Redis作为缓存通常会给key设置过期时间。但过期了并不代表立刻被删除这里涉及惰性删除和定期删除两种策略。惰性删除是指当客户端访问某个key时Redis才检查它是否过期过期就删除并返回空。这保证了不会返回过期数据但如果某个key一直不被访问它就会一直占着内存。定期删除是Redis每隔一段时间随机抽取一部分设置了过期时间的key检查并删除过期的。注意是随机抽取不是全量扫描这是为了控制CPU消耗。这两种策略结合仍然可能出现大量过期key堆积的情况。这时候就需要内存淘汰策略兜底。Redis提供了8种淘汰策略常用的有noeviction内存满了直接报错不淘汰任何key。这是默认策略适合把Redis当数据库用的场景。allkeys-lru从所有key中淘汰最近最少使用的。这是纯缓存场景最常用的策略。volatile-lru只从设置了过期时间的key中淘汰。allkeys-random随机淘汰适合访问分布均匀的场景。volatile-ttl优先淘汰剩余生存时间短的key。选择哪种策略取决于你的业务能否容忍数据丢失。如果Redis只是缓存丢了可以从数据库重建用allkeys-lru最省心。如果Redis存了一些不能丢的数据那要么用noeviction并做好内存监控要么把重要数据单独处理。我踩过的一个坑是线上Redis用了默认的noeviction某天内存写满后所有写操作全部报错但读操作还正常导致监控没及时发现业务侧写数据全部失败。后来改成allkeys-lru并加了内存告警才解决。所以这个参数一定要根据业务场景显式配置不要用默认值。3. 持久化机制RDB和AOF到底该怎么选3.1 RDB快照定时备份的利与弊RDB是Redis默认的持久化方式它把某一时刻的内存数据生成一个二进制文件保存到磁盘。触发方式有两种手动执行SAVE或BGSAVE命令或者通过配置save规则自动触发比如save 900 1表示900秒内至少有1个key被修改就触发。SAVE命令会阻塞Redis主线程期间所有客户端请求都会被卡住生产环境绝对不要用。BGSAVE会fork一个子进程来执行持久化主进程继续处理请求。但fork本身在数据量大时也会阻塞而且子进程写文件时会占用大量内存和IO资源。RDB的优点是文件紧凑、恢复速度快适合做冷备和灾难恢复。缺点是两次快照之间的数据会丢失。比如你配置了5分钟一次快照那最多可能丢5分钟的数据。对于缓存场景这通常可以接受但对于存储重要数据的场景就不行了。3.2 AOF日志实时性更好但文件更大AOF是把每次写命令追加到日志文件末尾。Redis重启时通过重放AOF文件里的命令来恢复数据。AOF的实时性比RDB好得多默认每秒同步一次appendfsync everysec最多丢1秒数据。如果设置成appendfsync always每条命令都同步基本不丢数据但性能会大幅下降。AOF文件会随着时间越来越大因为很多命令是重复的或者可以合并的。比如对同一个key执行了100次INCRAOF里就有100条记录但其实只需要记录最终值就行。Redis提供了AOF重写机制通过BGREWRITEAOF命令或自动触发生成一个精简后的新AOF文件。AOF的缺点是文件比RDB大恢复速度慢因为要逐条重放命令。而且如果AOF文件损坏恢复时可能失败需要用redis-check-aof工具修复。3.3 混合持久化兼顾速度和安全Redis 4.0之后引入了混合持久化结合了RDB和AOF的优点。开启后AOF重写时会把当前内存数据以RDB格式写入AOF文件开头后续的写命令以AOF格式追加。这样恢复时先加载RDB部分再重放增量命令速度比纯AOF快很多同时数据安全性也比纯RDB好。配置方式是设置aof-use-rdb-preamble yes。这是目前生产环境比较推荐的方案兼顾了恢复速度和数据安全。注意无论用哪种持久化方式都要定期做恢复演练。我见过配置了AOF但从来没验证过恢复的团队真出故障时才发现AOF文件损坏数据全丢。持久化不是配了就完事验证才是关键。4. 主从复制与哨兵高可用的第一道防线4.1 主从复制的完整流程单机Redis最大的问题是单点故障——机器挂了服务就不可用。主从复制通过把数据复制到多个节点来解决这个问题。一个主节点负责写多个从节点负责读主节点挂掉后可以从从节点选一个顶上。主从复制的建立过程分几个阶段。首先从节点连接主节点发送PSYNC命令。如果是第一次连接主节点会执行一次全量复制fork子进程生成RDB文件发送给从节点从节点加载RDB。在全量复制期间主节点会把新的写命令缓存到复制缓冲区等RDB发送完后再把缓冲区的命令发给从节点。全量复制完成后进入增量复制阶段。主节点每执行一个写命令就异步发给从节点。从节点通过REPLCONF ACK定期向主节点汇报自己复制到了哪个偏移量。如果从节点短暂断连后重连主节点可以根据偏移量只发送缺失的部分这就是部分复制。但部分复制不是总能成功。如果断连时间太长主节点的复制缓冲区repl-backlog被写满了就只能再次全量复制。所以repl-backlog-size这个参数要根据写入量和断连容忍时间合理设置。4.2 哨兵机制自动故障转移的实现细节主从复制解决了数据冗余但主节点挂了之后需要人工切换这不够自动化。哨兵Sentinel就是来解决自动故障转移的。哨兵本身是一个独立的进程可以部署多个组成哨兵集群。它做三件事监控、通知、自动故障转移。监控是指哨兵定期向所有Redis节点发送PING如果在down-after-milliseconds内没收到回复就标记为主观下线。但单个哨兵说节点挂了不算数需要多个哨兵都认为它挂了才标记为客观下线。客观下线后哨兵集群会选举一个领导者来执行故障转移。选举用的是Raft算法的变种。领导者从从节点中选一个升级为主节点选择依据是优先级replica-priority最高的、复制偏移量最大的、runid最小的。选完后其他从节点指向新主节点旧主节点恢复后变成从节点。哨兵配置里有个容易忽略的参数是quorum它表示判断客观下线至少需要多少个哨兵同意。通常设置为哨兵总数的一半加一。如果设置得太小容易误判太大又可能迟迟无法触发故障转移。4.3 主从架构的读写分离与一致性权衡主从架构天然支持读写分离写请求走主节点读请求走从节点。这能大幅提升读吞吐量但引入了主从延迟问题。主节点写入后从节点可能还没同步到这时候读从节点会读到旧数据。对于一致性要求高的场景比如刚写入就要立刻读到只能强制读主节点。但这样读写分离的意义就打了折扣。折中方案是对一致性敏感的读走主节点对延迟不敏感的读走从节点。或者用WAIT命令让主节点阻塞直到指定数量的从节点确认复制但这会降低写入性能。我的经验是大部分业务场景其实能容忍毫秒级的主从延迟真正需要强一致的读操作并不多。与其纠结一致性不如先把主从延迟监控做好当延迟超过阈值时自动把读流量切回主节点。5. 集群分片数据量超过单机内存后的必然选择5.1 哈希槽分片的核心原理主从复制解决了高可用但没解决数据量问题——所有数据还是存在一个主节点上。当数据量超过单机内存时就需要分片。Redis Cluster是官方提供的分片方案它把整个数据空间分成16384个哈希槽每个节点负责一部分槽。当客户端要读写一个key时先对key计算CRC16值然后对16384取模得到对应的槽再根据槽找到负责的节点。如果客户端连错了节点节点会返回MOVED重定向告诉客户端正确的节点地址。为什么是16384个槽而不是更多官方给出的解释是节点之间交换槽信息时16384个槽的位图是2KB网络开销小而如果槽太多心跳包会太大。另外Redis Cluster的节点数理论上限是1000个16384个槽足够均匀分配。5.2 集群的搭建与节点通信Redis Cluster至少需要3个主节点才能工作通常推荐3主3从的配置。搭建时用redis-cli --cluster create命令指定所有节点地址和--cluster-replicas 1表示每个主节点配一个从节点。集群节点之间通过Gossip协议通信每个节点定期向其他节点发送PING收到PONG回复。通信端口是服务端口加10000比如服务端口6379集群总线端口就是16379。这个端口如果被防火墙挡住集群就建不起来这是新手最容易踩的坑之一。节点之间交换的信息包括节点ID、IP、端口、负责的槽、最后通信时间等。通过Gossip每个节点最终都能知道整个集群的状态。5.3 集群模式下的限制与应对Redis Cluster不是万能的它有一些限制需要提前知道。首先不支持多key操作除非这些key在同一个槽里。比如MGET多个key如果它们分布在不同的槽就会报错。解决办法是用hash tag把需要一起操作的key用{}括起来比如user:{1001}:name和user:{1001}:age这样它们会落在同一个槽。其次集群模式下数据库只有0号库不支持SELECT切换。还有集群的批量操作性能不如单机因为客户端需要维护槽映射并处理重定向。另外集群的故障转移和哨兵不同。集群没有独立的哨兵进程而是由节点之间互相投票决定。当某个主节点被多数节点标记为下线时它的从节点会发起选举获得多数主节点投票后升级为主节点。6. 从基础到实战几个必须提前想清楚的问题6.1 缓存穿透、击穿、雪崩的本质区别这三个词经常被混着说但它们的成因和应对方式完全不同。缓存穿透是查询一个数据库里也不存在的key缓存和数据库都查不到每次请求都打到数据库。解决办法是缓存空值设置短过期时间或者用布隆过滤器提前拦截。缓存击穿是某个热点key过期瞬间大量请求同时打到数据库。解决办法是热点key不过期或者用互斥锁保证只有一个请求去数据库加载。缓存雪崩是大量key同时过期或者Redis集群整体宕机导致所有请求都打到数据库。解决办法是过期时间加随机值避免同时过期以及做好Redis的高可用。这三个问题的应对策略不同但根源都是缓存失效后的流量冲击。理解它们的区别才能在出问题时快速定位。6.2 分布式锁的正确实现方式用Redis做分布式锁很多人第一反应是SETNX加EXPIRE但这两条命令不是原子的中间如果宕机就会死锁。正确做法是用SET key value NX EX seconds一条命令搞定。但还有问题如果业务执行时间超过了锁的过期时间锁自动释放了其他线程就能拿到锁导致并发问题。解决办法是加一个看门狗机制后台线程定期给锁续期。另外释放锁时要检查value是不是自己设置的避免误删别人的锁。这些逻辑用Lua脚本保证原子性。更成熟的方案是用Redisson这类客户端库它封装了看门狗和可重入锁的逻辑比手写靠谱得多。6.3 性能监控与常见瓶颈定位Redis的性能问题通常出在几个地方大key、热key、慢查询、内存碎片。大key是指单个key的value特别大比如一个List有几百万个元素。操作大key会阻塞Redis因为Redis是单线程的。排查方法是用redis-cli --bigkeys扫描或者用MEMORY USAGE key查看单个key的内存占用。热key是指某个key被极高频率访问导致单个节点压力过大。排查可以用MONITOR命令但生产环境慎用会影响性能或者用redis-cli --hotkeys。慢查询通过SLOWLOG GET查看配置slowlog-log-slower-than设置阈值。内存碎片用INFO memory里的mem_fragmentation_ratio查看大于1.5说明碎片较多可以考虑重启或开启activedefrag。这些监控手段是集群运维的基础后面搭建集群时这些排查工具会频繁用到。7. 一些实际踩坑后的经验总结学Redis基础知识的时候最容易犯的错是只看不练。文档看一遍觉得都懂了真到线上出问题还是懵。我的建议是本地搭一个单机Redis把五种数据类型、持久化、主从复制都手动配一遍用redis-cli敲一遍命令看看INFO输出里各项指标的变化。这种手感是看文档看不来的。还有一个经验是不要过早追求集群。很多项目数据量其实不大单机Redis加主从哨兵完全够用。集群带来的复杂度——槽迁移、多key限制、客户端适配——在数据量没到瓶颈之前收益远小于成本。我见过一个日活几千的项目上来就搭集群结果运维成本翻了几倍性能问题反而更多。最后Redis的参数配置一定要根据业务场景调整不要用默认值。maxmemory、maxmemory-policy、appendfsync、repl-backlog-size这几个参数默认值在大多数生产场景下都不合适。花半小时理解每个参数的含义比出故障后熬夜排查划算得多。下一篇会进入实战环节从零搭建一个三主三从的Redis Cluster把这篇讲到的知识点全部串起来。如果你跟着把基础打牢了后面的集群搭建会顺畅很多。

相关新闻

三阶连续时间Delta-Sigma ADC的Matlab仿真与噪声整形设计

三阶连续时间Delta-Sigma ADC的Matlab仿真与噪声整形设计

简介:这是一份面向模拟集成电路与信号处理学习者的3阶连续时间Delta-Sigma ADC Matlab仿真代码,适合具备一定ADC理论基础、希望深入理解CTSDM架构与性能评估的工程师或研究生。资源包共10个文件,包含3个m脚本、3篇pdf参考论文、1个mdl Simuli…

2026/10/18 3:22:16 阅读更多 →
Java游戏矩形碰撞检测实战:从原理到工业级优化

Java游戏矩形碰撞检测实战:从原理到工业级优化

1. 这不是数学题,是游戏里“撞上就该有反应”的真实逻辑“Java游戏中的矩形碰撞检测”——这八个字背后,藏着无数新手在写第一个贪吃蛇、推箱子或横版跳跃游戏时卡住的三小时。它看起来像小学数学里的“两个长方形有没有重叠”,但实际运行中&…

2026/10/18 3:21:15 阅读更多 →
Ubuntu虚拟机滚轮不流畅?从输入事件链路到imwheel配置的完整调优指南

Ubuntu虚拟机滚轮不流畅?从输入事件链路到imwheel配置的完整调优指南

装好 Ubuntu 虚拟机后,很多人都会遇到一个不大不小、但天天折磨人的问题:鼠标滚轮在虚拟机里总觉得不对劲。轻滚一下,网页能直接滑过好几个版面;在终端或者代码编辑器里,却又像便秘一样半天挪不动。网上搜一圈&#xf…

2026/10/18 3:21:15 阅读更多 →

最新新闻

OpenClaw语音控制实战:多用户语音识别与声纹认证的权限隔离方案

OpenClaw语音控制实战:多用户语音识别与声纹认证的权限隔离方案

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 4:19:29 阅读更多 →
昇腾NPU强化学习迁移指南:从DQN到PPO的避坑与提速实践

昇腾NPU强化学习迁移指南:从DQN到PPO的避坑与提速实践

1月29号晚上那场《昇腾NPU强化学习案例》直播,我全程看完了。作为在GPU上跑了两三年强化学习、最近因为成本和资源原因开始评估昇腾NPU的人,直播里提到的报错、性能瓶颈和迁移细节,几乎把我踩过的坑全过了一遍。这篇不是录播的文字稿&#xf…

2026/10/18 4:19:29 阅读更多 →
ai大模型(一)

ai大模型(一)

0.认识大模型1.大模型计量单位2.大模型分类3.大模型训练环节4.大模型如何落地5.工程化几个模块-如何访问大模型6.提示词工程几个要素

2026/10/18 4:19:29 阅读更多 →
RAG效果差?从分块、检索、重排到Prompt的全链路优化指南

RAG效果差?从分块、检索、重排到Prompt的全链路优化指南

1. 先搞清楚:你的RAG为什么效果差?——全链路优化的起点做RAG(检索增强生成)这个方向的人,多半都经历过这种尴尬:辛辛苦苦把文档灌进知识库,上线一问,答得前言不搭后语,引…

2026/10/18 4:19:29 阅读更多 →
Umi-OCR 免费离线 OCR 工具:3 分钟上手,截图抠文字、扫描件能搜索

Umi-OCR 免费离线 OCR 工具:3 分钟上手,截图抠文字、扫描件能搜索

Umi-OCR 免费离线 OCR 工具:3 分钟上手,截图抠文字、扫描件能搜索 【免费下载链接】Umi-OCR OCR software, free and offline. 开源、免费的离线OCR软件。支持截屏/批量导入图片,PDF文档识别,排除水印/页眉页脚,扫描/生…

2026/10/18 4:19:29 阅读更多 →
用anime.js实现无缝滚动走马灯:原理、踩坑与完整方案

用anime.js实现无缝滚动走马灯:原理、踩坑与完整方案

我在给运营后台做公告滚动条的时候,被“走马灯”这个看似不起眼的小组件卡了整整一个下午。需求列出来其实没几条:公告项一行或两行横向滚动,鼠标悬停时暂停、移开继续,窗口从桌面缩到平板时不能出现空白断层,内容列表…

2026/10/18 4:18:29 阅读更多 →

日新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/18 0:00:55 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/18 0:00:55 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 0:55:02 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/17 17:22:31 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 14:23:36 阅读更多 →