数十亿消息级搜索引擎索引架构设计与性能调优实战
写这个系列到第20篇今天说一个我在某大型聊天社区项目中啃了很久的硬骨头当消息总量滚到数十亿条以后怎么让用户对着搜索框敲一个关键词就能在几秒内翻出几个月之前某段对话里的内容。这不是单纯把数据库慢查询优化一下就能对付的规模而是需要一套完整的消息索引体系。这篇就把我们踩过的坑、做过的选型、最终落地的方案和调优过程尽量完整地摊开来讲。如果你也在做体量增长很快的社区类应用或者正在为“历史数据没法查”发愁这篇应该能给你省下不少弯路。1. 先算一笔账数十亿条消息到底意味着什么1.1 数据规模的真实面貌很多团队对“数十亿条消息”没有特别具体的概念一说就是“很多很多”。我习惯先把账算明白再决定架构怎么做。假设某聊天社区的日活跃用户是1000万其中一半用户每天会发送消息平均每人20条那一天就是1亿条。这还只是消息表本身的数据。要是日活2000万、人均消息数再高一点一天冲到3到5亿条也很正常。一年下来保守估计就是300亿到500亿条消息正好落在“数十亿”到“数百亿”这个量级。单条聊天消息的payload看起来不大但包含文本内容、发送者ID、所属频道/会话ID、回复引用、提醒列表、附加的富媒体信息时序列化之后通常在200字节到2KB之间。按平均1KB算100亿条消息就是10TB左右的原始数据索引后因为分词、存储开销以及副本数翻倍轻松占用几十TB的空间。这个体量决定了不能再用“一台好机器一个关系型数据库”的思路硬扛。1.2 为什么传统数据库方案最先出局项目早期消息查询就是普通的SQLSELECT * FROM messages WHERE channel_id ? AND content LIKE %关键词% ORDER BY created_at DESC LIMIT 20。这个写法在单表单行几百万的时候没什么问题但数据量到了几亿、几十亿之后就彻底废了。LIKE %关键词%无法走常规的B-Tree索引数据库只能把某个频道或一张大表的所有消息读出来做全表扫描。我见过线上真实情况一次搜索把数据库CPU打到100%一个查询跑几十秒直接把整个实例拖成慢查询重灾区。加再多从库都救不回来因为每次搜索都相当于在IO层做一次全表遍历。而且聊天搜索天然是“按关键词、按频道、按用户、按时间范围”的多维度过滤有一个条件不满足传统索引就失效。所以不用想太多到几十亿条这个量级关系型数据库负责在线事务存储没问题但“历史消息全文搜索”这个功能必须拆出去。1.3 目标量化什么样的索引才算合格到我们动手重构的时候给消息搜索定了几条硬指标这些数字后来一直贴在团队白板上。写入延迟消息发出后到能被搜出来目标在5秒以内线上可接受10秒。聊天搜索不要求毫秒级实时但也不能像离线批处理一样等几个小时。查询性能带时间和频道过滤的搜索P99延迟不超过500毫秒不带过滤的全局搜索P99最差也要在2秒内给出结果。数据完整性不能因为索引系统故障就丢消息即便索引短暂不可用消息数据也要安全存在线上库里。容量扩展分片可线性扩展加节点就加容量不用停服重新灌数据。把目标定清楚后面的架构选型就有的放矢了。2. 索引方案选型与整体架构拆解2.1 为什么选择倒排索引路线要做全文搜索业界成熟方案基本只有一条主线基于Lucene的倒排索引。倒排索引的原理用图书馆类比最容易懂普通存储相当于把书一本本排在书架上找某个词就得一本本翻开去查倒排索引相当于在图书馆门口挂一个“关键词→页码列表”的大目录查“分布式”这个词直接翻目录就知道哪几本书、哪几页出现了这个词。聊天消息的内容检索就是这个道理——用户搜一个词我们只需要在这个目录里查词然后拉出命中的消息ID列表再按时间排序返回。基于Lucene的作品很多我们选了开源的分布式搜索中间件理由很直白它能直接提供分布式分片、副本、故障转移和一套成熟的查询DSL不用自己在Lucene上面造轮子。虽然大厂到最后都会把Lucene用出花来但我们这个规模用成熟中间件完全够用运维生态也省心。2.2 双层写入链路设计索引数据怎么进去是整个系统最容易出事的一环。我们最终定的是“双写加异步消费”的模式画出来大概是这样的链路消息发送API收到消息后先写在线消息存储关系型数据库保证消息不丢同时把一条包含完整消息内容的MQ消息推给索引消费服务。索引服务从MQ批量拉取组装成索引文档批量化写入搜索集群。这样搜索集群挂掉甚至MQ都挂了只要数据库里的消息还在就可以重放MQ或者写个补数脚本把缺的索引补回来。这套链路后来帮了大忙。有次索引集群一个节点磁盘写满消费积压了上千万条业务端消息完全不受影响。我们扩容节点后消费服务自动追平积压整个过程中用户无感知。2.3 分片与路由的基本盘分片是搜索集群里最需要先想清楚的决策我们在这里走过弯路。刚开始图省事按消息ID做哈希路由把所有数据平均打散到固定分片里。结果发现查询很难做用户搜一个频道的历史消息请求要广播到所有分片再聚合频道少时没事到数十亿条级别之后广播查询的CPU开销非常浪费经常一个查询扇出几十个分片P99延迟难看。后来我们改成了更贴合场景的路由策略写入时按频道/会话ID路由同一个频道的消息尽量落在同一组分片上同时按时间维度建滚动索引让索引按天/月隔离。查询时带上频道ID搜索请求就能精准路由到少数几个分片避免全集群广播。时间维度则让历史月份查询可以只扫对应月份的索引不需要带上全部数据玩“大逃杀”。关于分片数量没有绝对真理我们的原则是让单个分片数据量控制在20到50GB左右分片数等于(总数据量预估 / 单分片目标容量)再考虑节点数乘以副本数做冗余。预先留好余量因为后面改分片数要重新索引成本极高。3. 核心细节索引映射与数据模型设计3.1 一个消息文档长什么样索引里的“一条消息”远不只是把消息文本塞进去那么简单。我们最终的消息文档结构大致可以拆成下面几个字段组标识字段messageId、channelId、authorId、replyToId内容字段content全文索引、contentRaw原始文本时间字段createdAt维度字段mentions了谁、attachments附件类型、messageType文本/图片/系统消息拆分的时候要特别小心搜索中间件里的字段类型一旦上线就很难改后面发现类型不对只能重新建索引再灌一遍数据。我们早期把channelId定义成了text类型结果做精确过滤还要额外搞一个keyword副本字段平白多出不少存储和麻烦。3.2 字段设计里的“坑”索引映射看起来简单踩过才知道全是细节。文本字段既需要全文搜索又需要原文展示所以建了双份content用标准分词器做全文索引match查询走它contentRaw用keyword不做分词直接返回给前端显示原文。要是只留一个全文分析字段搜索结果里展示的文本会被分词器处理成小写并去掉标点用户看到的和他发的原话对不上体验很糟。时间字段一定要用date类型并且统一好时区。我们吃过亏写入和查询各用各的默认时区导致用户搜“今天”的消息凌晨的总是匹配不上调了半天才发现是时区偏移。提醒、附件这类维度字段建议全部设计成keyword数组做过滤时才能用精准匹配。keyword字段可以走filter缓存查询性能远高于text字段的全文匹配。3.3 从写入到可见的准实时机制Lucene内在机制决定了数据不是写完立刻就能被搜到这一点很多新手不理解。写入搜索集群的文档会先进内存缓冲区每隔一个刷新间隔才生成一个新的索引段段里的数据才对外可见。默认刷新间隔是1秒意味着写入1秒后就能搜到这个延迟在聊天场景下完全可以接受。但我们没有直接用默认配置。因为刷新间隔和时间点卡得好的话可以显著提升写入吞吐。项目里的做法是把刷新间隔调整为5秒再用批量写入接口一次提交几千条文档而不是一条一条写。刷新间隔变大带来的副作用是故障时最多丢5秒内未持久化的数据。但数据源在数据库里躺着索引只是辅助副本就算真的丢了重放补数也能找回来。这个取舍在吞吐和实时性之间收益非常明显。批量写入的size也有讲究。一次提交的请求体太大容易把搜索节点的内存打爆太小网络往返次数太多吞吐上不去。我们压测下来的经验值是一次批量写入5MB到10MB或者5000到10000条消息具体还看单条大小。提交后观察写入延迟曲线涨得太快就缩小批量躺平不动就继续加大直到找到那个吞吐拐点。4. 搜索查询的工程化实现与性能调优4.1 典型搜索场景如何翻译成查询聊天的搜索场景和网页搜索引擎差别很大。用户很少搜一个词就期望全库盲搜更多是带着上下文过滤搜索。拆下来主要就是这几种“在这个频道里搜XX”channelId过滤 content关键词“搜某个人的历史发言”authorId过滤 关键词可选“翻以前某段时间的聊天记录”channelId 时间范围过滤通常不带关键词“全局搜一个词但只看带附件/我的消息”关键词 类型过滤翻译成查询我们用BoolQuery组合。关键词部分用match查询跑分排序过滤部分全部放到filter上下文中。重点来了filter语境里的条件不参与相关度打分可以被搜索中间件缓存这样同一个频道的不同搜索过滤条件命中的结果集可以直接被复用查询性能提升不是一点半点。每次只翻一页20条的话分页切到很深的页码时传统fromsize的方式会越来越慢因为每次都要拉取前N页全部结果再丢到N页之后。我们后端全部换成了SearchAfter的深分页游标方式滚动加载历史记录时性能稳定不会因为翻到几百页就卡住。顺带一提我们关闭了按相关度打分做默认排序聊天消息场景用户默认按时间倒序看相关度排序只在用户明确选择“最相关”时才启用。4.2 让查询更快的关键配置有一批调整属于“不做不知道做了吓一跳”的类型。第一是filter缓存。给channelId、authorId、messageType这些高频过滤字段打开更积极的缓存实测查询延迟直接下降一半。这里提醒一句字段基数太大的比如messageId就非常不适合做缓存缓存命中率低反而浪费内存。要挑那种枚举值有限、又经常作为查询限定条件的字段来缓存。第二是文档值优化。排序、聚合操作尽量走doc_values而不要开启fielddata。聊天搜索常按时间排序我们把createdAt这类字段的doc_values打开排序时直接从列式存储里读比从倒排表里反查快得多。第三是段合并和存储压缩。Lucene底层数据会不断生成小段段数多了查询就要遍历更多文件。我们设置了一个后台段合并线程池配合磁盘IO水位监控把段数控制在合理范围。另外索引压缩算法选了更高效的压缩方式牺牲一点CPU换存储空间。在几十TB的数据规模下存储每省10%都是实实在在的钱。4.3 调优实录从10秒到100毫秒这里放一组我们真实压测和调优的数据可能比讲理论更有说服力。最开始上线时没有任何优化全频道搜索一个历史关键词P99跑到9到10秒完全不可用。我们一步步做了三轮调整第一轮路由优化。让所有带上channelId的查询都直接路由到对应分片组只扫2个分片而不是全集群50个分片。P99降到2.1秒。第二轮查询结构优化。把时间范围、频道ID、作者过滤全部改为filter上下文关键词只走match。同时打开高频过滤字段的缓存并把默认排序改为时间倒序。P99降到430毫秒。第三轮分片与内存调优。单个分片数据量太大导致查询需要扫描的段太多我们扩容节点并做了数据重分布再把节点堆内存调到32GB同时保证堆外内存足够。最终P99稳定在80到120毫秒之间。这个“10秒到100毫秒”的过程里收益最大的其实是第一轮路由优化这验证了架构层面的决策永远比单个查询调优更值钱。但轮次越往后越接近极限就越要抠细节比如缓存淘汰策略、磁盘IO调度、GC参数每一个都是几个百分点的提升累加起来就是数量级的差距。5. 数十亿规模下的稳定性与成本控制5.1 冷热分离与存储分级数据量到了几十TB以后全放高性能存储是不现实的成本扛不住。我们做了冷热分离。热数据最近30天的消息放在SSD节点这些数据被反复搜索和浏览追求低延迟。 温数据30天到1年迁到普通SATA SSD或大容量HDD的冷节点延迟指标放宽到1到2秒。 冷数据超过1年的压缩归档到对象存储里平时不占在线集群资源真有极个别需求要翻很老的数据走异步任务把对应索引临时加载回来。这个策略帮我们把存储成本压了接近六成同时热数据查询性能不受冷数据拖累。历史搜索和缓存命中是两回事搜索冷数据虽然慢一点但用户能接受业务上完全划得来。冷热切换不是人肉操作是我们写了一个索引生命周期管理任务每天扫索引列表根据索引的覆盖时间范围自动做迁移或归档配置好阈值之后完全自动化。5.2 容量规划与分片生命周期几十亿条消息的索引如果不主动管理生命周期容量会像雪崩一样失控。我们为每个时间滚动的索引预设生命周期“热索引”创建后处于读写状态持续写入新消息这个阶段持续30天。30天后自动切换为只读不允许写入新数据后台把副本数和段结构调优。90天后将副本数从2降到1并迁移到冷节点。1年后对索引做快照推送到对象存储归档然后从在线集群删除。这个生命周期管理带来的好处是在线集群的磁盘占用被控制在一个稳定的水位不会无限增长。哪天磁盘告警了看看是不是某个生命周期任务卡住没执行而不是手忙脚乱地去删索引。容量规划上我们按“日新增消息量 × 保留天数 × 膨胀系数”来提前申请磁盘配额膨胀系数包括副本、分词后的倒排表和doc_values等额外开销通常取2到3倍。别拿原始消息大小直接乘那样规划出来的容量铁定不够。5.3 监控指标与告警设计没有监控的集群就是盲飞。我们上线了这样几个维度的监控和告警写入侧消费积压数、写入吞吐条/秒、批量写失败数查询侧P50/P99延迟、查询QPS、查询拒绝率、缓存命中率集群侧节点磁盘使用率、堆内存使用率、GC耗时与频率、段数量有过一次印象深刻的故障就是靠监控发现的凌晨业务高峰某冷节点磁盘使用率涨到90%触发了段合并风暴大量IO被合并任务占满查询延迟从200毫秒飙到5秒。好在告警及时我们立刻paused段合并任务把查询优先紧服务很快恢复。这类问题如果靠用户反馈才知道后果就是大范围搜索超时口碑和投诉双崩。监控指标不在多贵在能提前暴露问题。磁盘70%就该告警别等到85%——从告警到完成扩容中间操作时间远超你想象。6. 常见问题排查速查表与独门经验6.1 高频问题速查表下面整理的是我们上线至今遇到的高频问题按“问题现象→原因→排查手段→解决动作”四列放成表格方便团队后面翻。问题现象常见原因排查手段解决动作索引消费积压越来越大消费者吞吐不足或批量大小不合理查看消费组积压曲线和写入QPS调大批量大小、增加消费者并发写入时查询延迟飙升段合并拖垮磁盘IO查看段合并线程指标和磁盘IO降低合并线程并发调整IO吞吐阈值节点频繁Full GC堆内存不够或缓存设置过大查看GC日志和堆转储调整堆大小收缩filter缓存分离冷热节点查询只能搜到近几天的消息冷索引被归档或生命周期任务误删检查索引生命周期任务日志从对象存储恢复对应索引快照搜索结果出现相同消息重复数据重复写入或消费重试没做幂等看写入链路消费组的幂等机制在消费端按messageId去重修改了字段类型不生效索引映射创建后不可变查看字段映射元数据新建索引数据重放或reindex深翻页很慢fromsize翻页过深压测深页码查询执行计划改用search_after游标方式6.2 几个常规文档里不写的经验最后分享几个代码和配置之外的经验这些是我觉得比任何参数调优都值钱的东西。第一个经验是索引系统要把“数据可重放”作为底线。消息搜索本质上是聊天业务的一个附属功能聊天数据的第一要务是安全持久化搜索功能可以秒级短暂不可用但消息不能丢。所以任何时刻都不要把搜索集群当成唯一数据源。我们每次改索引结构或升级版本都会提前准备一份数据重放脚本因为跑index变更总会有意外情况能把数据从数据库重新灌回索引心里就有底。第二个经验是新建一个搜索功能前先和产品确认清楚优先级排序规则。聊天搜索的默认排序是时间倒序还是相关度直接影响底层查询的写法。我们早期对着BSR调相关度花了两周最后产品过来说“用户只想看最近的”全部白干。先谈清楚默认行为再动手做调优。第三个经验是保持索引消费链路可观测性。我们给每一条消息从进入MQ到写入搜索集群的全过程加了链路追踪记录在哪个环节耗时多少。没有这套追踪时消费积压了只能靠猜是MQ hang住了还是消费者GC了都要现场抓包。加完之后十分钟就能定位出瓶颈在哪个组件排查效率完全是两个级别。第四个经验也是我认为最重要的一条做索引系统不要试图一开始就设计“完美”。数十亿条数据规模的系统早期一定会推翻早期方案。我们第一次分片策略、第一次字段映射、第一次查询模板全部在后来的真实负载面前做了重构。这不是设计失误是正常演化。重要的是每一版都保留数据重放能力和平滑迁移能力这样即使推倒重来也不会伤筋动骨。这个系列能写到第20篇回头看看我最深的体会是索引的架构和物理存储一样没法一步到位只有持续根据真实数据和流量演进才能持久稳定。如果让我给刚做这类系统的团队一句建议就是先把“写入链路不丢消息可回溯”这件事做对其他性能问题都有资格慢慢调数据安全没有。

相关新闻

Python进阶与并发编程01:报价为什么不能随手改——对象、引用与精确金额

Python进阶与并发编程01:报价为什么不能随手改——对象、引用与精确金额

Python进阶与并发编程01:报价为什么不能随手改——对象、引用与精确金额 你已经会写列表、字典和函数。现在有一个真实后端需求:用户购买 KB-001,系统向几家供应商询价,选出能供货且含运费最便宜的一家。功能第一天似乎只需要 min…

2026/10/16 7:54:14 阅读更多 →
Agent工程化落地的5个关键问题与实战方案

Agent工程化落地的5个关键问题与实战方案

1. 这不是考算法,而是考你能不能把Agent真正跑起来“请手写一个ReAct框架”——这种问题在三年前可能还出现在某些技术面试里,但今天再问,基本等于在面试一个还没摸过生产环境的在校生。我参与过二十多场面向中高级工程师的Agent方向技术面试…

2026/10/17 11:56:15 阅读更多 →
AI日报系统设计:从信源治理到时间戳工程的全链路实践

AI日报系统设计:从信源治理到时间戳工程的全链路实践

1. 项目概述:这不是一份“新闻简报”,而是一套可复用的AI内容日更系统“AI 日报 2026-10-07”这个标题乍看像某平台每日推送的资讯合集,但真正有经验的人一眼就能看出——它背后必然藏着一套稳定、低干预、可持续输出的自动化内容生产流程。…

2026/10/17 10:57:08 阅读更多 →

最新新闻

MoE架构解析:万亿参数模型如何以稀疏激活实现高效计算?

MoE架构解析:万亿参数模型如何以稀疏激活实现高效计算?

1. 核心认知:参数规模和计算量,很多人的第一反应都错了1.1 一个让大模型“变轻”的反直觉设计我最初看到“万亿参数”这个词的时候,跟大部分人一样,第一反应是“这得要多大的算力才能跑起来”。但后来实际接触并拆解了混合专家&am…

2026/10/17 11:55:36 阅读更多 →
AI辅助教材编写:低查重与教学工作流设计实战指南

AI辅助教材编写:低查重与教学工作流设计实战指南

这两年我用AI辅助编写了多本校本教材和课程讲义,最大的体会是:AI写教材真正的“秘密武器”,不是让大模型一口气吐出几十万字,而是把“检索、组织、改写、审校”拆开的一套生产流程。很多人栽跟头,是因为对AI有两层误解…

2026/10/17 11:55:36 阅读更多 →
上海租公寓,这三样我现在一定会现场确认

上海租公寓,这三样我现在一定会现场确认

有一套我当时觉得很合适:月租在预算里,离地铁也近,照片里的客厅很亮。住了两周我才明白,亮是因为下午侧光,早上房间是暗的;晚上临着马路,窗户关上仍有车声。那次之后,看公寓整租我固…

2026/10/17 11:55:36 阅读更多 →
开源Agent网关OpenClaw:架构设计、部署实操与踩坑记录

开源Agent网关OpenClaw:架构设计、部署实操与踩坑记录

做AI Agent也有一段时间了,前后折腾过不少框架和项目,但一直有个问题像鞋里的沙子一样硌脚:AI助手和我的各种终端之间,总是隔着一层说不清的别扭。直到某天我实在忍不住,动手写了个叫OpenClaw的东西——一个开源的AI A…

2026/10/17 11:55:36 阅读更多 →
Hadoop+MapReduce+HBase离线日志分析集群搭建实战

Hadoop+MapReduce+HBase离线日志分析集群搭建实战

最近有个项目要做离线日志分析和实时查询,数据量不大但增长很快,我们最后选择了CentOS 8.1 Hadoop MapReduce HBase这套组合。这套方案最直接的优势在于:Hadoop负责海量文件的分布式存储,MapReduce处理批量计算,HBa…

2026/10/17 11:55:36 阅读更多 →
深入理解 DOM ProcessingInstruction:用法与实战

深入理解 DOM ProcessingInstruction:用法与实战

1. 引言在 DOM(文档对象模型)中,除了常见的元素节点、文本节点和注释节点之外,还存在一类相对冷门但功能明确的节点类型——ProcessingInstruction(处理指令)。它通常出现在 XML 文档中,用于向解…

2026/10/17 11:54:35 阅读更多 →

日新闻

DeepSeek选型与部署:V3/R1、Ollama、API全攻略

DeepSeek选型与部署:V3/R1、Ollama、API全攻略

简介:《DeepSeek使用方法.pdf》是一份面向DeepSeek入门及进阶用户的完整使用指南,重点围绕V3与R1两款模型的能力差异与适用场景展开,帮助读者根据任务类型与成本选择合适的模型。资源共1个PDF文件,压缩包大小约311KB,篇…

2026/10/17 0:00:25 阅读更多 →
200+Deepseek润色指令拆解:从底层原理到场景落地的完整指南

200+Deepseek润色指令拆解:从底层原理到场景落地的完整指南

简介:这是一份聚焦DeepSeek提示词优化的《200Deepseek润色指令》PDF文档,共收录两百余条可直接套用的润色指令,涵盖语法修正、风格统一、逻辑梳理、表达精炼等维度,并针对商务写作、学术论文、广告文案等场景给出差异化建议。文档…

2026/10/17 0:00:25 阅读更多 →
OpenCV轮廓法物体计数系统:轻量、可控、可落地的工业级实现

OpenCV轮廓法物体计数系统:轻量、可控、可落地的工业级实现

简介:本资源是一份基于OpenCV的本科课程设计完整报告,面向计算机视觉初学者、图像处理学习者及高校通信/信息类专业学生,解决物体智能计数与检测结果结构化记录的实际问题。项目覆盖图像预处理、轮廓检测、边界框绘制、轨迹栏交互式参数调节、…

2026/10/17 0:00:25 阅读更多 →

周新闻

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

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

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

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

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

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

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

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

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

2026/10/16 15:04:24 阅读更多 →

月新闻

我发现了一个新思路:用 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/16 21:54:38 阅读更多 →
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/16 3:49:43 阅读更多 →
黑夜航拍船只数据集训练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 阅读更多 →