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

journal:kill -9 之后哪些写入还在

实测 kill -9 之后哪些写入还在:w:1 下每次丢 192~420 条已确认的写入,j:true 零丢失但吞吐降到约 1/35;journalCommitInterval 越大丢得越多(中位数 96、198、306 条);没有 checkpoint 时恢复靠 journal 重放;末尾补一次 j:true 能把之前的写入一起落盘。

MongoDB journal kill -9 写关注 持久性 WiredTiger 真实验证 动画演示
爬虫工程 2026-10-12

HTTP/2 多路复用:抓取并发的实际收益

用本机 nginx(HTTP/2)和 curl_cffi 把 HTTP/1.1 与 HTTP/2 的并发对齐后比较:50 个并发请求 HTTP/1.1 用 50 条连接 121 ms,HTTP/2 用 1 条连接 111 ms;无延迟的 600 个请求 131 ms 对 94 ms;服务器流上限为 10 时客户端自动开 5 条连接;一条连接上快请求不再排在慢请求后面。

爬虫 HTTP/2 多路复用 curl_cffi nginx ALPN 并发 真实验证 动画演示
爬虫工程 2026-10-12

DNS 解析:缓存、阻塞线程与每次请求多花多少时间

用包装过的 getaddrinfo 统计爬虫库的 DNS 行为:requests 每建一条新连接解析一次(20 次 requests.get 解析 20 次,Session 复用只解析 1 次);aiohttp 默认缓存 10 秒,关掉后同样 20 次;并发解析被默认线程池的 14 个线程卡住(100 个主机名 1625 ms,换 100 线程 232 ms);localhost 比 127.0.0.1 每次多约 0.21 ms。

爬虫 DNS getaddrinfo requests aiohttp 线程池 localhost Python 真实验证 动画演示
MongoDB 2026-10-12

WiredTiger 缓存:cacheSizeGB 压低时 eviction 怎么表现

实测把 WiredTiger 缓存压到最小的 256 MB:装入两倍于缓存的数据时缓存占用不超过上限;工作集大于缓存时每次读平均要读入 0.62 个页;8 线程写入压力下脏数据封顶在缓存的 10%,应用线程被迫淘汰的耗时从 2 ms 增到 514 ms,吞吐只低约 7%;serverStatus 里直接给出淘汰阈值。

MongoDB WiredTiger 缓存 eviction cacheSizeGB 真实验证 动画演示
爬虫工程 2026-10-12

TLS 会话复用:握手耗时占一次请求的多少

在本机 TLS 服务器上量握手:EC 证书的完整握手占一次 HTTPS 请求约 73%,会话复用后 TLS 握手 0.628 ms 降到 0.528 ms;RSA-4096 证书则从 3.993 ms 降到 0.525 ms;连接被不干净地关掉(没有 close_notify)后读到 EOF,会话不可复用;requests 和 aiohttp 不复用,curl_cffi 的 Session 复用 19/20。

爬虫 TLS 会话复用 握手 session ticket curl_cffi requests Python 真实验证 动画演示
MongoDB 2026-10-12

capped 集合:写满后覆盖的顺序和限制

实测 capped 集合:max 限制文档数、size 限制字节数,写满后最老的先被覆盖,自然顺序即插入顺序;9.0.2 上删除单个文档和把文档改大都能成功(与旧说法不同);tailable 游标实时收到新文档;convertToCapped 与 collMod 可以在线转换和改大小。

MongoDB capped集合 固定大小 tailable convertToCapped 真实验证 动画演示
爬虫工程 2026-10-12

连接异常:RemoteDisconnected、ConnectionReset 分别由什么触发

用纯套接字服务器制造十几种连接异常,看 requests 抛什么:FIN 关闭是 RemoteDisconnected、RST 是 ConnectionResetError、没人监听是 ConnectionRefusedError,全部包成 ConnectionError;响应体阶段的断开是 ChunkedEncodingError,不是 ConnectionError;只发半截响应头就关闭时 requests 不报错,返回 200、空头、空体。

爬虫 requests 异常 ConnectionError RemoteDisconnected ConnectionResetError ChunkedEncodingError SSLError Python 真实验证 动画演示
MongoDB 2026-10-12

TTL 索引:过期文档什么时候才真正被删

实测 TTL 索引的过期时机:5 秒过期的文档要等到每 60 秒运行一次的 TTL 线程(实测 59.0 s 和 119.2 s)才被删;只有 BSON 日期(或日期数组)会过期;expireAfterSeconds 为 0 配合未来时间可让每个文档自己定过期时刻;collMod 在线改过期时间;20 万个过期文档一轮删完。

MongoDB TTL索引 过期 ttlMonitorSleepSecs collMod 真实验证 动画演示
爬虫工程 2026-10-12

请求头顺序与大小写:requests、curl、浏览器实际发出什么

用套接字服务器抓 9 个客户端的原始请求头:requests 5 个、Node fetch 7 个且全小写、真实 Chrome 154 发 14 个;头名顺序有 8 种彼此不同;requests 里想去掉 User-Agent 会被 urllib3 补回 python-urllib3/2.7.0,想改默认头的顺序也改不了。

爬虫 请求头 Header 头顺序 大小写 requests curl Chrome Python 真实验证 动画演示
MongoDB 2026-10-12

时序集合:bucket 文档长什么样

实测 9.0.2 的时序集合:底层 system.buckets 不能再直接访问,用 rawData 读到 3 个传感器各 400 个测量只占 3 个 bucket;bucket 文档按列存放、带 min/max/count;每个 bucket 最多 1000 个测量;合成数据占盘只有普通集合的 2%;默认索引与 update/delete 的限制。

MongoDB 时序集合 time-series bucket rawData 真实验证 动画演示
爬虫工程 2026-10-12

编码识别:Content-Type、meta、chardet 谁说了算,乱码从哪来

实测爬虫里乱码的来源:text/* 没写 charset 时 requests 默认 ISO-8859-1(r.apparent_encoding 其实能猜对 utf-8);requests 不看 meta,lxml 不看响应头;页面声明 gb2312 但含“镕”时 Python 解码替换、lxml 截断;UTF-8 BOM 变成 r.text 开头的 \ufeff;charset_normalizer 36 个组合里有 3 个解错文字。

爬虫 编码 charset requests apparent_encoding GBK 乱码 lxml Python 真实验证 动画演示
MongoDB 2026-10-12

视图:视图就是存下来的 pipeline

实测 MongoDB 视图:只是 system.views 里存下来的一条 pipeline,每次查询重新执行,底层数据一改视图立刻变化;视图没有自己的索引,过滤条件能前移到 $group 之前时走底层索引(150 个文档),在聚合结果上则全表扫描(3000 个);视图只读、深度上限 20、底层集合删除后查询为空、collMod 可以改 pipeline。

MongoDB 视图 view pipeline 索引 explain 真实验证 动画演示
京ICP备2026067502号-1京公网安备11010502063487号