Redis6 ACL权限控制实战:从误删事故到精细化权限管理
1. 从一次线上误删事故说起为什么Redis6的ACL值得单独拿出来讲几年前我还在负责一个中小型电商系统的缓存层维护当时整个团队对Redis的使用方式非常“粗放”——所有服务共用同一个默认用户密码就是配置文件里那一行requirepass谁拿到密码谁就是超级管理员能执行任何命令。某天凌晨一个刚入职的同事在排查一个数据不一致问题时本来只想清理某个业务前缀下的几个key结果手一抖敲成了FLUSHALL整个实例的缓存瞬间被清空。虽然缓存可以重建但那一刻数据库被打穿接口响应时间从几十毫秒飙到几秒订单服务直接告警。事后复盘大家最痛的点不是“人犯错”而是Redis根本没有给我们任何细粒度的权限约束手段——那个同事的账号理论上就不该拥有FLUSHALL这种危险命令的执行权限。这件事之后我一直在关注Redis在权限管理上的演进。在Redis6之前官方的安全手段基本只有两样requirepass设置一个全局密码以及通过rename-command把危险命令改名或禁用。前者是“一把钥匙开所有门”后者则是“把门焊死”运维起来极其别扭——你没法针对不同业务分配不同权限也没法在不重启的情况下动态调整。Redis6引入的ACLAccess Control List访问控制列表彻底改变了这个局面它把“用户”这个概念真正带进了Redis让每个连接可以绑定到不同的用户每个用户拥有独立的密码、独立的命令权限、独立的key访问范围。这篇文章我想聊的就是Redis6 ACL这套安全策略到底怎么用、背后的设计逻辑是什么、实际落地时有哪些坑。它适合已经在用Redis、并且开始关心“谁能操作什么”的运维和开发同学也适合那些还在用单密码裸奔、想升级权限体系但不知道从哪下手的朋友。我会从整体设计思路讲到具体命令再到生产环境的实操配置和排查技巧尽量把每个“为什么这么设计”讲透让你看完能直接在自己的环境里落地一套可用的权限方案。2. ACL整体设计与核心概念拆解2.1 为什么是“用户规则”而不是继续加密码要理解ACL的设计先得理解Redis之前的权限模型有多单薄。在Redis6之前一个实例只有一个密码所有客户端连上来都是同一个身份权限完全一致。这种模型在单团队、单业务的小规模场景下勉强够用但一旦实例被多个业务线共享问题就来了A业务只需要读写自己的缓存key却因为共用密码而拥有了删除任意key、甚至执行CONFIG SET改配置的能力。这本质上是一个权限过度授予的问题。Redis6的ACL选择用“用户user”作为权限的载体而不是继续在密码上做文章原因很直接密码只能回答“你能不能进来”回答不了“你进来之后能干什么”。用户这个概念天然可以承载多维度的权限描述——密码、命令白名单/黑名单、key模式、频道模式。这样一来权限的最小粒度就从“整个实例”细化到了“某个用户能碰哪些key、能跑哪些命令”。我在实际项目里最直观的感受是以前给一个新业务开缓存权限只能新建实例或者共用密码现在直接ACL SETUSER建一个用户把它的key前缀和命令范围卡死几分钟就能搞定而且互不干扰。2.2 ACL的四个核心维度ACL对用户的权限描述可以拆成四个维度理解了这四个维度后面所有命令都是它们的组合。第一个维度是认证方式也就是这个用户怎么证明自己是自己。可以是明文密码password也可以是密码的SHA256哈希#hash还可以配置多个密码。第二个维度是命令权限控制这个用户能执行哪些命令可以精确到子命令比如只允许GET不允许SET或者只允许CLIENT LIST不允许CLIENT KILL。第三个维度是key权限通过模式匹配限定用户能访问哪些key比如只允许操作order:*开头的key。第四个维度是频道权限针对发布订阅场景限定用户能订阅或发布哪些频道。这四个维度组合起来就形成了一个用户的完整权限画像。我习惯把它类比成公司门禁系统认证方式是门禁卡命令权限是你能进哪些楼层key权限是你能开哪些房间的门频道权限是你能收听哪些广播。这个类比虽然不严谨但能帮新手快速建立直觉。2.3 默认用户与ACL的兼容性设计Redis6在引入ACL的同时必须保证对老版本的兼容否则升级会变成灾难。它的做法是保留一个名为default的默认用户所有没有显式认证的客户端都自动以default用户身份运行。在默认配置下default用户拥有所有命令、所有key、所有频道的权限并且不需要密码——这跟Redis5的行为完全一致。也就是说你升级到Redis6之后如果什么都不配置业务代码一行不用改照常运行。这个兼容性设计非常关键它意味着ACL的落地可以是渐进的你可以先让default用户继续裸奔同时新建几个受限用户给新业务用等验证稳定后再逐步收紧default的权限最后把它彻底禁用。我在迁移一个老系统时就是这么干的前后花了两周时间业务方完全无感知。这里要提醒一句default用户虽然方便但生产环境最终一定要处理它——要么给它设一个强密码要么直接ACL SETUSER default off禁用它否则ACL形同虚设。3. ACL核心命令与实操要点详解3.1 用户管理命令从创建到删除的完整链路ACL的用户管理命令以ACL为前缀最常用的是ACL SETUSER它既能创建用户也能修改用户。这个命令的语法是ACL SETUSER username [规则...]规则可以一次给多个也可以分多次追加。我个人的习惯是创建用户时一次性把规则写全这样配置意图清晰也方便后续用ACL LIST导出备份。创建用户的基本流程是这样的先ACL SETUSER app_order on OrderPass123 ~order:* read write -dangerous这条命令做了几件事——开启用户、设置密码、限定只能访问order:开头的key、允许读写类命令、禁止危险命令。然后可以用ACL WHOAMI确认当前连接的身份用ACL LIST查看所有用户的完整规则用ACL GETUSER app_order查看单个用户的详情。删除用户用ACL DELUSER username注意default用户不能被删除只能被禁用。这里有个细节值得展开ACL SETUSER的规则是增量叠加的不是覆盖。也就是说如果你先执行了ACL SETUSER app_order read再执行ACL SETUSER app_order write最终这个用户同时拥有读写权限。如果你想重置某个用户的规则得先用ACL SETUSER app_order reset清空再重新配置。我踩过一次坑以为再次SETUSER会覆盖旧规则结果旧权限一直残留排查了半天才发现是增量叠加的机制。3.2 命令权限的精细控制从命令类别到子命令命令权限是ACL里最灵活也最容易配错的部分。Redis把命令分成了若干类别用符号引用比如read、write、admin、dangerous、fast、slow等。你可以用read允许整个读类别也可以用-dangerous禁止所有危险命令。类别的好处是省事坏处是粒度粗——比如write里既有安全的SET也有能清库的FLUSHDB。所以生产环境我一般会采用“类别打底单命令微调”的策略。先用read write给一个基础范围再用-FLUSHALL -FLUSHDB -KEYS -CONFIG把明确的危险命令摘掉。这里要注意命令的大小写不敏感get和GET效果一样但为了可读性建议统一大写。另外子命令的控制用|分隔比如config|get只允许查询配置-config|set禁止修改配置。这个特性在需要给监控系统开只读配置权限时特别有用。还有一个容易被忽略的点命令权限的判定顺序。当用户同时被允许和禁止某个命令时Redis的规则是“后配置的生效”。比如你先all再-GET那GET就是被禁止的反过来先-GET再allGET又会被允许。这个顺序依赖在多人协作维护ACL时很容易出问题我的建议是永远把禁止规则放在允许规则之后并且用ACL GETUSER确认最终生效的权限不要凭记忆。3.3 key权限的模式匹配通配符的边界与陷阱key权限用~符号声明后面跟模式。~order:*表示只能访问order:开头的key~*表示所有key~后面什么都不跟则表示禁止访问任何key。模式匹配用的是glob风格的通配符*匹配任意字符?匹配单个字符[abc]匹配字符集。这套语法跟Redis的KEYS命令一致上手不难但有几个边界要注意。第一模式匹配是针对完整key名的不是前缀匹配。~order:*能匹配order:123但匹配不了myorder:123因为后者不以order:开头。第二多个key权限是“或”的关系~order:* ~user:*表示两类key都能访问。第三key权限对命令的约束是全局的也就是说即使用户有GET命令权限如果目标key不在它的key模式范围内命令依然会被拒绝报错信息是NOPERM。这个报错在实际排查时很有用看到NOPERM基本就能定位到是key权限或命令权限的问题。我在配置key权限时有个经验尽量用业务前缀冒号的模式比如~cache:order:*而不是宽泛的~*order*。后者看起来方便实际上会把user:order_history这种不相关的key也放进来权限边界就模糊了。另外如果业务key的命名本身不规范比如有的用下划线有的用冒号那ACL配置会非常痛苦这时候应该先推动key命名规范再上ACL。3.4 频道权限与发布订阅的权限隔离频道权限用符号声明针对的是发布订阅Pub/Sub场景。news:*表示只能订阅或发布news:开头的频道。这个维度在纯缓存场景下用得少但在用Redis做消息总线的系统里就很重要了。比如一个系统里既有订单消息频道又有用户消息频道你肯定不希望订单服务能往用户频道里发消息。频道权限的配置逻辑和key权限类似也是模式匹配、多个“或”关系。需要注意的是频道权限同时约束PUBLISH和SUBSCRIBE你不能只允许订阅不允许发布或者反过来除非用命令权限单独控制PUBLISH和SUBSCRIBE命令。实际项目里我一般会把频道权限和命令权限配合使用用order:*限定频道范围再用subscribe publish允许这两个命令这样权限边界就很清晰了。4. 生产环境ACL落地的完整实操流程4.1 配置文件持久化让ACL规则不丢用ACL SETUSER在运行时创建的用户默认只存在于内存里重启就没了。这在生产环境是致命的所以必须把ACL规则持久化。Redis提供了两种方式一种是在redis.conf里用user指令声明另一种是用ACL SAVE把当前规则写入ACL文件再在配置里用aclfile指定这个文件。我推荐用aclfile的方式原因是它支持运行时ACL SAVE和ACL LOAD运维起来更灵活。具体做法是在redis.conf里加一行aclfile /etc/redis/users.acl然后执行ACL SAVE当前所有用户规则就会写入这个文件。之后每次修改用户记得再ACL SAVE一次。这里有个坑如果aclfile指定的文件不存在Redis启动会报错所以第一次部署时要先手动创建空文件或者先执行一次ACL SAVE。还有一种情况是配置文件和aclfile同时存在user定义这时候aclfile的优先级更高配置文件里的user会被忽略。这个行为在排查“为什么我改了配置文件没生效”时经常是元凶记住就行。4.2 分阶段迁移从单密码到多用户的平滑过渡直接给一个正在运行的生产实例上ACL风险很高因为一旦配错业务可能瞬间不可用。我的做法是分四个阶段推进。第一阶段保持default用户不变新建受限用户给新业务用老业务继续走default。这个阶段的目标是验证ACL规则本身没问题同时让团队熟悉命令。第二阶段给default用户设置密码但保留全部权限然后逐步把老业务的连接配置改成带密码。第三阶段收紧default用户的权限比如去掉dangerous观察是否有业务报错。第四阶段禁用default用户所有业务都用自己的专属用户。每个阶段之间至少观察一天重点看Redis的慢日志和业务侧的NOPERM报错。我在第二阶段遇到过一个问题某个老服务的连接池配置里密码是写死的改密码后没同步更新导致连接全部失败。所以改default密码前一定要先梳理清楚有哪些客户端在用别漏了。4.3 一个完整的用户配置示例与验证假设我们要给订单服务配一个用户需求是只能访问order:和cart:开头的key允许读写命令禁止所有危险命令密码用强密码。配置命令如下ACL SETUSER app_order on Str0ngPss2024 ~order:* ~cart:* read write -dangerous -FLUSHALL -FLUSHDB -KEYS -CONFIG ACL SAVE配完之后必须验证验证分三步。第一步用ACL GETUSER app_order看规则是否符合预期重点确认keys和commands两栏。第二步用redis-cli --user app_order --pass Str0ngPss2024连上去执行SET order:1 test应该成功执行SET other:1 test应该报NOPERM执行FLUSHALL也应该报NOPERM。第三步用ACL LOG查看被拒绝的命令记录这个命令会列出最近所有权限拒绝事件是排查权限问题的利器。注意ACL LOG默认只保留最近的128条记录高并发场景下可能很快被冲掉排查时要及时查看或者用ACL LOG 数量调整保留条数。5. 常见问题与排查技巧实录5.1 NOPERM报错的定位思路NOPERM是ACL最常见的报错格式一般是NOPERM this user has no permissions to run the xxx command或者NOPERM this user has no permissions to access one of the keys used as arguments。看到这个报错第一步是用ACL WHOAMI确认当前连接用的是哪个用户很多时候问题出在客户端根本没认证成功还在用default或者匿名身份。第二步用ACL GETUSER 用户名看这个用户的命令权限和key权限对照报错里的命令名和key名基本就能定位。我整理了一个排查速查表覆盖了几种典型场景报错信息关键词可能原因排查动作no permissions to run the command命令权限不足检查ACL GETUSER的commands栏确认命令或类别是否被允许no permissions to access one of the keyskey权限不足检查keys栏的模式是否覆盖目标key注意前缀和通配符no permissions to access one of the channels频道权限不足检查channels栏确认发布订阅的频道在范围内WRONGPASS密码错误或用户未开启检查用户是否on密码是否正确注意和#的区别连接直接被拒绝用户被禁用或不存在用ACL LIST确认用户存在且状态为on5.2 密码配置的两种写法与选择ACL支持明文密码和哈希密码两种写法。明文用前缀比如mypassword哈希用#前缀后面跟密码的SHA256值。明文的好处是直观配置时不容易出错坏处是ACL LIST和ACL GETUSER会把密码明文显示出来任何能执行这些命令的人都能看到密码。哈希的好处是即使规则泄露攻击者也无法直接得到明文密码坏处是配置时得先算哈希稍微麻烦一点。我的建议是生产环境用哈希尤其是多人能访问Redis的团队。算哈希可以用echo -n mypassword | sha256sum把结果前面加#填进去。这里有个细节echo -n的-n不能省否则会把换行符也算进哈希导致密码对不上。我见过有人因为这个细节排查了一下午。5.3 ACL规则冲突与优先级问题前面提过命令权限是“后配置生效”但实际场景里还有更复杂的冲突。比如一个用户同时属于read和-GET那GET到底能不能用答案是看配置顺序后配的-GET生效所以GET被禁止。但如果先-GET再readGET又会被read重新允许。这种顺序依赖在规则多的时候非常容易出错。我的应对策略是规则分层先配类别级别的允许read write再配类别级别的禁止-dangerous最后配单命令级别的微调-FLUSHALL config|get。这样从粗到细顺序固定不容易乱。另外每次修改后用ACL GETUSER确认最终结果不要凭记忆推断。如果团队人多建议把ACL规则纳入版本管理每次变更走review避免有人随手改了一条规则把权限放大。5.4 性能影响与监控要点很多人关心ACL会不会拖慢Redis。实测下来ACL的权限检查是在命令执行前做的一次规则匹配开销很小在常规QPS下基本感知不到。但如果一个用户的key权限模式特别多、特别复杂每次命令都要遍历所有模式做匹配理论上会有额外开销。我的经验是单个用户的key模式控制在10个以内超过这个数量就该考虑是不是key命名设计有问题或者该拆实例了。监控方面除了常规的Redis指标建议关注ACL LOG里的拒绝事件数量。如果某个用户的拒绝事件突然飙升要么是业务代码改了命令用法要么是有人在试探权限都值得警惕。可以用ACL LOG 数量配合定时任务把拒绝日志采集出来接入告警系统。另外INFO里的acl相关字段也能反映一些状态虽然信息不多但聊胜于无。6. 我在实际落地中总结的几条经验ACL这套东西刚上手时命令不少但真正用起来核心就是SETUSER、GETUSER、LIST、SAVE、LOG这几个。我最大的体会是ACL的价值不在于技术多复杂而在于它逼着团队去梳理“谁该有什么权限”。以前共用密码时没人说得清某个服务到底需要哪些命令上了ACL之后每个用户的规则就是一份权限文档反而让架构更清晰了。另一个经验是别追求一步到位。我见过有团队想一次性把所有用户配好、把default禁掉结果业务大面积报错回滚都来不及。ACL的迁移一定是渐进的先兼容、再收紧、最后禁用每一步都留观察期。还有ACL SAVE这个动作一定要养成习惯改完就存别等重启时才发现规则丢了。最后分享一个小技巧如果你不确定某个用户该配哪些命令可以先用all让它跑一段时间然后用ACL LOG统计它实际用到的命令再据此收敛权限。这个“先放后收”的思路在权限治理里很实用比拍脑袋配规则靠谱得多。

相关新闻

SPEC CPU2006 安装测试指南:从源码到跑分的完整路径

SPEC CPU2006 安装测试指南:从源码到跑分的完整路径

简介:这份资源是面向CPU性能测试初学者与硬件评测人员的SPEC CPU2006安装测试指南配套项目源码,帮助读者在ARM、x86_64、MIPS等不同平台上完成基准测试工具的部署与验证。压缩包共3个文件,以inscode项目配置、html说明页面和gitignore忽略规则…

2026/10/14 18:25:49 阅读更多 →
用jevos构建自己的评测体系:LLM测试集构建与CI回归测试实战

用jevos构建自己的评测体系:LLM测试集构建与CI回归测试实战

【免费下载链接】jev jevos: an open-source alternative to Jev and Microsoft-Decision-1. Yes/no decisions, choices and scores with probabilities, on your laptops CPU. 项目地址: https://gitcode.com/gh_mirrors/je/jev 点击查看 免费下载 jevos 是一个跑…

2026/10/14 18:25:49 阅读更多 →
做一个常驻菜单栏的小工具,细节比想象中多

做一个常驻菜单栏的小工具,细节比想象中多

做一个常驻菜单栏的小工具,细节比想象中多 一个窗口切换工具,看上去就是把窗口列出来,点一下,再切过去。最近做 TaskView,除了这个基本流程,我花了不少精力处理设置、权限和打包这些事。 做出能展示窗口的…

2026/10/14 18:25:49 阅读更多 →

最新新闻

Python车险理赔车型识别与合规校验:数据工程实践指南

Python车险理赔车型识别与合规校验:数据工程实践指南

1. 项目背景与整体设计思路1.1 车型信息在车险理赔中的关键作用车险理赔看起来是“拍照—定损—打款”的简单流程,但真正做过车险数据的人都知道,车型信息是贯穿整个理赔链路的一个隐形骨架。从承保端的车型定价,到理赔端的配件价格与工时费计…

2026/10/14 19:09:21 阅读更多 →
2026年水质监测无人船推荐:从人工采样到智能巡航的升级之选

2026年水质监测无人船推荐:从人工采样到智能巡航的升级之选

过去很长一段时间,水质监测依赖人工乘船采样。一个断面跑一趟,采样、记录、返航、送检,大半天就没了。遇到恶劣天气,人员安全更是悬在头顶的隐患。2026年,这种局面正在被无人船技术快速改写。今天结合真实落地案例&…

2026/10/14 19:09:21 阅读更多 →
生产计划一定要做这7张表:订单表、排产表、齐套表、产能表、进度表......

生产计划一定要做这7张表:订单表、排产表、齐套表、产能表、进度表......

做生产计划,每天都要跟订单、物料、设备和交期打交道。接到订单后,要安排生产;计划排好了,还得跟着现场变化调整。而“麻烦”往往就出在这些变化上。客户临时加单,供应商晚了两天,设备突然停机,…

2026/10/14 19:09:21 阅读更多 →
向量空间:高等代数分水岭的核心概念与解题指南

向量空间:高等代数分水岭的核心概念与解题指南

1. 为什么向量空间是高等代数的分水岭如果你问一个学过高等代数的人,哪一章开始真正让人感到“抽象”,十有八九会说是向量空间。前面行列式、矩阵还能靠计算硬扛,到了向量空间,突然冒出一堆定义:线性相关、基、维数、子…

2026/10/14 19:09:21 阅读更多 →
ubuntu26.04微信输入法异常

ubuntu26.04微信输入法异常

我在ubuntu26.04系统下使用微信,在输入框中输入文件的时候,输入法的选词条,始终就是无法显示,同时我使用的是双屏幕,微信只在副屏幕上输入文字的时候,能正常显示候选词,主屏幕上不行&#xff0c…

2026/10/14 19:09:21 阅读更多 →
数字孪生解决方案怎么选?企业需求分析、厂商评估与选型指南

数字孪生解决方案怎么选?企业需求分析、厂商评估与选型指南

数字孪生正从概念走向产线。根据Straits Research数据,2025年全球数字孪生市场规模达281亿美元,预计2034年增至5513.9亿美元,复合年增长率39.2%,亚太地区占比36.4%。企业决策者面临的现实问题很具体:预算批了&#xff…

2026/10/14 19:08:21 阅读更多 →

日新闻

AnyPS5通用适配层设计:兼容性与性能的工程取舍

AnyPS5通用适配层设计:兼容性与性能的工程取舍

1. 从"AnyPS5"这个名字说起:它到底想解决什么问题第一次看到"AnyPS5"这个标题,我脑子里冒出来的第一个念头是:这大概率是一个围绕"跨平台运行"或者"通用适配"做文章的项目。名字里的"Any"…

2026/10/14 0:00:41 阅读更多 →
Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

1. 项目概述:Flutter跨平台二手交易应用开发作为一名长期从事移动应用开发的工程师,我最近完成了一个基于Flutter框架的二手物品交易平台项目。这个项目最吸引我的地方在于它完美结合了Flutter的跨平台优势与HarmonyOS的生态特性,实现了"…

2026/10/14 0:00:41 阅读更多 →
DFS算法解决飞机降落调度问题实战

DFS算法解决飞机降落调度问题实战

1. 项目背景与核心思路飞机降落问题是一个经典的调度优化场景,也是算法竞赛和面试中的高频题目。这个题目要求我们合理安排多架飞机的降落顺序和时间,确保所有飞机都能安全着陆而不发生冲突。在实际航空管制中,这类问题直接关系到飞行安全和机…

2026/10/14 0:00:41 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/14 3:30:28 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/14 16:30:29 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/14 3:29:58 阅读更多 →

月新闻

我发现了一个新思路:用 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/13 22:01:27 阅读更多 →
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/13 14:57:39 阅读更多 →
黑夜航拍船只数据集训练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/14 7:53:34 阅读更多 →