知其然,知其所以然
MongoDB 2026-10-12

rollback:没复制出去的写入去哪了

实测 rollback:旧 primary 上 w:1 写入的 5 个文档未复制就崩溃,新 primary 选出(10.6 s)后继续写入;旧 primary 重启后 SECONDARY→ROLLBACK→SECONDARY 约 0.5 秒,使用 recoverToStableTimestamp 方式;被回滚的文档保存在 dbpath/rollback/ 的 BSON 文件里,三个节点最终一致。

MongoDB rollback 回滚 副本集 w:1 真实验证 动画演示
MongoDB 2026-10-12

arbiter 与 w:majority 的陷阱

实测 arbiter 与 w:majority 的陷阱:PSA 结构里停掉唯一的 secondary 后 primary 仍是 primary,w:1 与默认写关注(隐式 w:1)成功,w:majority 超时(code 64);majority 读看不到新写入,多数提交点停住且落后越拉越大(5 到 9 秒);恢复后追平;PSS 停一个 secondary 则 w:majority 不受影响。

MongoDB arbiter 仲裁节点 w:majority PSA 副本集 真实验证 动画演示
爬虫工程 2026-10-12

浏览器复用:每次新开与复用上下文的成本

30 次加载同一页面:每页启动新浏览器 46862 ms(452.1 ms/页),复用浏览器新标签页 2289 ms(38.0 ms/页),独立 context 5232 ms(114.1 ms/页),同一个标签页 1305 ms(5.7 ms/页);默认 context 与同一标签页共享 Cookie 和缓存(29/29 带 Cookie、图片只请求 1 次),独立 context 与新浏览器互相隔离;不关标签页 60 次后 69 个进程、7990 MiB。

爬虫 浏览器复用 browser context 标签页 Cookie隔离 内存 CDP Python 真实验证 动画演示
爬虫工程 2026-10-12

页面能观察到哪些自动化信号:navigator.webdriver 等

在本机 headless Chrome 154 里让页面自己的 JavaScript 读自动化相关的值:只开远程调试端口时 navigator.webdriver 是 false,加 --enable-automation 才是 true(同时视口矮 56 像素);User-Agent 里直接写着 HeadlessChrome;JS 与请求头读到的 UA 一致。本文只描述页面能看到什么,不涉及隐藏办法。

爬虫 浏览器自动化 navigator.webdriver HeadlessChrome CDP User-Agent Python 真实验证 动画演示
MongoDB 2026-10-12

hidden 与 delayed 成员

实测 hidden 与 delayed 成员:hidden 成员不出现在 hello.hosts,secondary 读偏好 100 次一次也选不到,但照常复制可直连读;延迟 8 秒的成员 8.1 秒后才有新写入,drop 之后窗口内仍有数据可救回;延迟成员有投票权会让 w:majority 慢约 8 秒。

MongoDB hidden成员 delayed成员 secondaryDelaySecs 副本集 真实验证 动画演示
爬虫工程 2026-10-12

无限滚动:IntersectionObserver 触发的请求

在本机用 IntersectionObserver 做的无限滚动页面上实测:不滚动只有第 1 页(10 条);匀速滚动并用“连续 3 次没增长”判定到底会在第 40 条提前停下;每次滚到底部拿到全部 100 条(10 次请求);3000 px 的高视口下朴素写法卡在 10 条,加载后重新 observe 才能继续。

爬虫 无限滚动 IntersectionObserver CDP 动态加载 headless Chrome Python 真实验证 动画演示
爬虫工程 2026-10-12

WebSocket 数据源:怎么抓取推送的数据

在本机的 WebSocket 服务器上实测:Chrome 的 CDP Network 事件里能看到握手、发出的帧和收到的帧;websocket-client 直接连时握手头和浏览器的差别;服务器断开后不重连、重连不带 since、重连带 since 分别丢多少数据;不发心跳会被服务器关闭;Origin 校验对库和浏览器各是什么结果。

爬虫 WebSocket CDP Network 重连 心跳 Origin websocket-client Python 真实验证 动画演示
爬虫工程 2026-10-12

CDP 网络事件:不用解析页面直接拿响应体

在本机页面上实测 CDP Network 域:事件顺序、getResponseBody 返回的是解压后的文本(图片是 base64)、必须等到 loadingFinished 才能取、页面跳走后取不到、setBlockedURLs 能挡住图片请求、默认缓冲下 150 个 1 MiB 响应事后只取得到 142 个。

爬虫 CDP Network getResponseBody Chrome headless 屏蔽资源 Python 真实验证 动画演示
MongoDB 2026-10-12

stepDown:切主期间读写不可用多久

实测切主期间的不可用时间:replSetStepDown 优雅切主只有约 30 ms,客户端无错误;kill -9 primary 默认约 10.8 秒(electionTimeoutMillis 10 s),调成 4 s 后约 4.2 秒;w:majority 的确认写入一条未丢;切主期间 secondary 读不受影响,primary 读阻塞约 10 秒。

MongoDB stepDown 选举 故障切换 electionTimeoutMillis 副本集 真实验证 动画演示
MongoDB 2026-10-12

oplog 窗口:大小决定了落后多久还能追上

实测 oplog 窗口:getReplicationInfo 的窗口字段;不同写入每条 oplog 的大小(小更新 163 字节、1 KB 插入 1,142 字节、10 KB 插入 10,097 字节);按实测字节估算 128 MB 到 10 GB 的 oplog 在 1,000 次/秒负载下的窗口;size 与压缩后 storageSize;replSetResizeOplog 最小 990 MB;secondary 离线 15 秒后 2.8 秒追平。

MongoDB oplog oplog窗口 replSetResizeOplog secondary 副本集 真实验证 动画演示
MongoDB 2026-10-12

chunk 拆分与迁移:balancer 实际搬了什么

实测分片集群上 chunk 的拆分与迁移:空集合一个 chunk;写入触发分裂,balancer 同时把拆出的 chunk 迁到另一个分片;最终 chunk 个数 1 对 26 但数据量 31.1 MB 对 28.2 MB(按数据量平衡);迁走的数据以孤儿文档形式在源分片留 3600 秒;changelog 记录每次迁移的 6 个步骤;分片键全相同产生 jumbo chunk。

MongoDB 分片 chunk balancer moveChunk jumbo 孤儿文档 真实验证 动画演示
MongoDB 2026-10-12

单调递增的分片键:写入热点实测

实测单调递增分片键的写入热点:关掉 balancer 后 30 秒 287,500 次写入全部打在 sh0(100%),哈希键与手工打散的复合键各占 50%;开 balancer 后旧数据被搬走一部分(119,535 对 167,965),但新写入的 20,000 个更大键仍然全部落在 sh0;范围查询 ranged 只问 1 个分片,hashed 要问全部。

MongoDB 分片键 单调递增 写入热点 hashed balancer 真实验证 动画演示
京ICP备2026067502号-1京公网安备11010502063487号