知其然,知其所以然
爬虫工程 2026-10-12

文件描述符上限:并发连接撞到 ulimit -n 时的报错

实测文件描述符上限:软限制压到 100 时 300 个并发连接只有约 94–97 个成功,其余是 OSError errno 24;每条连接约占 1 个描述符;更隐蔽的是保留 requests.get 返回的 Response 对象——97 个就耗尽描述符,而只保留 .content 或用同一个 Session 则全部成功。

爬虫 文件描述符 ulimit Too many open files EMFILE aiohttp requests Python 真实验证 动画演示
MongoDB 2026-10-12

2dsphere 地理索引:$near 怎么查

实测 2dsphere 地理索引:5 万个点每个一个索引条目;$near 按距离排序,与 Python haversine 暴力计算的 272 个结果顺序完全一致;GEO_NEAR_2DSPHERE 逐圈扩展搜索(452 个键);多边形生成 5~20 个索引键;经纬度写反的两种后果。

MongoDB 2dsphere 地理索引 $near $geoNear GeoJSON 真实验证 动画演示
爬虫工程 2026-10-12

robots.txt:规则匹配的优先级与 robotparser 的差异

实测 robots.txt 的解析:Python 3.14.8 标准库 urllib.robotparser 与 protego 0.7.0 在 26 个边界用例中只有 1 个不一致(组名是 UA 名字的子串时是否适用);两者都是最长匹配并支持 * 与 $;Crawl-delay 的小数两者都读不出;robots.txt 本身返回 404/410/429 时全部允许,401/403/500/503 时全部禁止。

爬虫 robots.txt robotparser protego Crawl-delay 礼貌 Python 真实验证 动画演示
MongoDB 2026-10-12

哈希索引:能做等值,不能做范围

实测哈希索引:存值的 64 位哈希,相邻值哈希后差很远;只能做等值,范围查询要扫整个索引(200,000 个键,142 ms 对普通索引的 2 ms),排序也不行;不支持 unique、数组,复合索引最多一个哈希字段;浮点数会截断成整数再哈希;连续整数哈希后均匀分散。

MongoDB 哈希索引 hashed 分片 等值查询 真实验证 动画演示
爬虫工程 2026-10-12

限速:令牌桶与固定间隔的实际请求节奏

用服务器记录的到达时间量爬虫的限速:每个 worker 各自 sleep(0.1) 时 1、5、20 个 worker 分别是 6.4、33.8、143.7 个/秒;全局固定间隔稳定 10.0 个/秒;令牌桶 burst=20 时任意 0.1 秒内最多 21 个;空闲后桶重新装满再次突发;从完成算起的间隔让速率降到 1.7–6.4 个/秒。

爬虫 限速 令牌桶 速率限制 礼貌 asyncio Python 真实验证 动画演示
MongoDB 2026-10-12

通配符索引:什么场景值得用

实测通配符索引:一个 attrs.$** 覆盖 50 个动态键名(300,000 条索引),查询检查 291 个文档而不是全表 100,000 个;两个条件同时出现只能用一个字段;能做同字段的范围加排序和 $exists: true,不能做 $ne;写入慢 1.9 倍;不支持 unique,复合通配符的要求。

MongoDB 通配符索引 wildcard attrs 动态字段 真实验证 动画演示
MongoDB 2026-10-12

建索引期间读写会被阻塞吗

实测建索引期间读写会不会被阻塞:800 万个文档上建索引 7.9 s,并发线程的读写 p99 几乎不变且没有错误;currentOp 显示 scanning collection 与 inserting keys 的进度;期间插入的文档也被建进索引;唯一索引期间并发插入的重复值不会被拒绝,建索引最后以 E11000 失败;drop 会中止构建。

MongoDB 建索引 index build 阻塞 currentOp 真实验证 动画演示
爬虫工程 2026-10-12

按域名分队列:一个慢站点会不会拖住整个爬虫

用三个速度不同的本机站点实测爬虫调度:全局先进先出队列里,慢站点排前面会让快站点晚到 3.1 秒才完成(排后面是 0.1 秒);每个站点独立队列加 3 个 worker 后快站点恒为 0.4 秒,每站点并发峰值 3,但总时间从 4.2 秒变成 10.0 秒。

爬虫 调度 按域名分队列 队头阻塞 并发 礼貌 asyncio Python 真实验证 动画演示
爬虫工程 2026-10-12

抓取顺序:BFS、DFS、优先级队列的覆盖率对比

在一个自己设计的合成站点(6374 页,6000 个商品页)上比较抓取顺序:预算 100 时 BFS 抓到 15 个商品页,DFS 33 个,按 URL 模式排优先级的 93 个;预算接近全站时三者趋同;待抓队列峰值 BFS 270、DFS 72;标签云陷阱让 BFS 和 DFS 各浪费 61 页。

爬虫 抓取顺序 BFS DFS 优先级队列 覆盖率 frontier Python 真实验证 动画演示
MongoDB 2026-10-12

隐藏索引:不删索引也能评估删掉的影响

实测隐藏索引:hideIndex 之后优化器不再考虑它(0.2 ms 变成 28 ms 全表扫描),unhideIndex 立刻恢复;隐藏的索引仍然被维护(隐藏期间写入的数据取消隐藏后立即可查),唯一与 TTL 约束照常工作,hint 视其为不存在,$indexStats 不再计数。

MongoDB 隐藏索引 hideIndex 索引 计划器 真实验证 动画演示
MongoDB 2026-10-12

skip 大偏移的代价与范围分页

实测 skip 大偏移的代价与范围分页:50 万个文档上 skip 400,000 要 74 ms、检查 400,020 个键,范围分页每页恒定 0.2~0.4 ms;SKIP 在 FETCH 之下,只读索引键不读文档;排序键不唯一要带 _id 平局打破;翻页期间有新数据时 skip 重复 10 条而范围分页不重复;count 的两种代价。

MongoDB 分页 skip 范围分页 游标 性能 真实验证 动画演示
MongoDB 2026-10-12

$in 的元素数量对查询的影响

实测 $in 元素数量对查询的影响:S 从 1 到 100,000 耗时 0.2 ms 到 126 ms(每个值约 1.4 μs,检查的键约是返回数的 2 倍);规划耗时在 S=100,000 时达 4.4 ms;结果按索引键顺序返回、重复值去重;无索引时全表扫描 79 到 200 ms;$in 与 $or 接近;150 万个整数的 $in 超出 16 MB 上限。

MongoDB $in 索引 查询 性能 真实验证 动画演示
京ICP备2026067502号-1京公网安备11010502063487号