#1243 SQLite 适用一切场景

2026-08-26

在 Dr. Raphael A. Bauer 发表《PostgreSQL for Everything》之后,JoeCode 发表了一篇《SQLite for Everything》调侃式回应(作者强调自己同样喜欢 PostgreSQL,但认为 SQLite 被严重低估)。
参考:PostgreSQL 适用一切场景

作者的核心观点:很多团队为了"看起来像生产系统"而引入的一整排基础设施(搜索、队列、缓存、向量库、图库、微服务……),在大多数项目里其实一个 SQLite 单文件就能顶替。
开发新项目的时候,先判断"它能跑在单机+单文件上吗"——能就先上 SQLite,真撞到写并发或分布式天花板再换重的。大多数业务比开发者以为的更晚才会撞墙,而期间你省掉的是大量运维工作。

SQLite 三大底层优势

  • 坚如磐石:2000 年发布,公有领域(public domain,不是普通开源),MC/DC 100% 分支覆盖、测试代码是库代码的约 500 倍,官方支持承诺到 2050 年;手机/浏览器/汽车/飞机里都在跑,部署量超过其他数据库总和。
  • 零运行成本:没有 daemon、没有端口、没有 Docker。已绑定在 Linux/Python/Go/Rust/.NET/Android/iOS 里;测试用 :memory: 微秒级拉起,和生产同库同二进制。
  • 极大简化 IT 拓扑:它不止是 RDBMS,还能当全文搜索引擎、文档库、队列、时序库、向量索引、缓存、文件格式、图存储——"少装一个服务"就是少一个要监控/升级/背锅的系统。

"SQLite 替代 X" 对照表

原本的组件 SQLite 怎么顶 关键机制
Solr / Elastic 全文搜索 FTS5(BM25、短语、NEAR、高亮),索引与数据同事务,不会"索引是旧的"
MongoDB JSON 文档存 jsonb、生成列、严格表
Kafka / RabbitMQ 任务队列 一张表 + BEGIN IMMEDIATE + UPDATE…RETURNING 抢单条作业,WAL 下读写不互锁
ClickHouse 时序数据 按时间分区单文件,中等体量够用
向量数据库 AI 检索 sqlite-vec 扩展做 embedding 相似度
Redis 非持久/高性能缓存 进程内点查 ~1µs,比 localhost 跑 Redis 的 ~100µs 快约 100 倍
文件系统 存小文件/BLOB 官方基准:<100KB blob 比裸文件系统更快、省空间
图数据库 关系遍历 递归 CTE
微服务 跨函数调用 直接同进程函数调用 + 本地事务
(彩蛋)PlayStation 5 纯玩笑章节

SQLite 的天花板

  • 不支持并发写入:高并发写入(每秒几万条以上)会卡在写锁;多机多写、跨机房分布式写不适合原生 SQLite。
  • 规模边界:超 TB 级数据、百万点/秒时序、需要用户/角色级 ACL 的多租户 SaaS,应换 Postgres/MySQL/ClickHouse 等。
  • 扩展方案:Litestream(WAL 流式备份到 S3)、LiteFS(分布式读)、Turso / Cloudflare D1 / rqlite(托管 SQLite)可缓解部分限制,但不改变单写本质。

#1242 PostgreSQL 适用一切场景

2026-08-26

这篇文章(Dr. Raphael A. Bauer 的《PostgreSQL for Everything》)的核心论点是:PostgreSQL 不是万能答案,但能覆盖你想象中多得多的场景;在中小规模下,先用 PG 统一数据层,遇到真实瓶颈再换专用系统,是更省维护成本、更快交付的架构选择。

PostgreSQL 凭借“老牌稳定 + 现代特性 + 插件生态”,在初创和中型业务里可以一个数据库顶住搜索、文档、队列、时序、向量、缓存、层级数据等多套中间件;它的真正价值不是性能碾压专用库,而是用更低的运维与认知成本,让你把时间花在业务功能上

一、为什么选 PostgreSQL:三个底层优势

  • 成熟且持续进化:1996 年至今,bug 被长期打磨;社区向后兼容地加现代特性(CTE、分区、JSONB、逻辑复制等)。
  • 部署与生态极简:本地 brew/apt/docker、Testcontainers 测生产一致性、云厂商一键托管,维护成本极低。
  • 可扩展性强:原生能力 + 插件(TimescaleDB、pgvector、pgai、LTREE 等)把多种数据模型收进同一个 ACID 库。

二、PG 能“单库替多中间件”的场景清单

作者用自己 CTO 生涯的实战说明,以下场景不必急着引入专用组件

原本的专用系统 PostgreSQL 方案 关键机制
MySQL + Lucene/Solr 原生全文检索 tsvector + GIN 索引(Contentful、Instacart 实践)
MongoDB 文档存储 jsonb + GIN,支持 JSONPath 查询
Kafka / RabbitMQ / SQS 表即队列 FOR UPDATE SKIP LOCKED、递归/游标消费,先 PG 后换 MQ
ClickHouse / InfluxDB 时序数据 TimescaleDB 超表 + 连续聚合
Pinecone / 专用向量库 向量检索 pgvectorpgai 做 embedding 同步与 RAG
Redis 缓存 内存级缓存 UNLOGGED 表 + 触发器模拟 TTL,多数用例够快
文件系统存小二进制 Blob 列 Flatbuffers 序列化入 bytea,缓存策略下比裸文件 IO 更快
树形/层级数据 LTREE 类型 比递归 CTE 更易维护
微服务中间层 直接出 JSON 查询里拼 JSON 返回,省一层应用中间层

作者强调:这些都是“先 PG 起步”的策略,不是否认专用系统——当吞吐/并发/规模真正打满时,再切 Kafka、ClickHouse、Redis 不迟。

三、架构哲学:用“无聊”换速度

  • 少零件 = 少同步 = 少漂移:避免 ES 与 PG 双写、Mongo 与 PG 对账这类管道腐烂。
  • 团队认知负担下降:一套 SQL 技能覆盖关系、文档、搜索、队列、时序、向量。
  • 决策顺序建议:新需求来了先问“PG 能不能做”→ 能做就用 → 压测出真实瓶颈再引入新技术,而不是反过来为“技术新鲜感”买单。

这篇文章带来很好的启发:PostgreSQL拥有多模型存储能力,原生支持文档(jsonb)、轻量缓存、全文检索、向量检索、队列表等场景。在不少业务场景下,可以优先基于PG实现相关能力,避免盲目引入新的中间件,降低系统复杂度。

但我不认同将其作为一套可直接落地的生产级通用方案,存在明显边界约束(架构收敛不能牺牲稳定性):

  1. 把缓存、海量文档等旁路能力并入同一套业务主库,存在严重稳定性风险。
    业务主库承载核心交易、用户等核心数据,属于不可丢失的Source of Truth。缓存、高频半结构化读写具备流量大、允许降级、可丢失的特征,二者共用数据库会造成资源互相抢占、故障域合并;缓存流量抖动、jsonb频繁更新引发的膨胀与IO压力,会直接拖慢核心业务SQL,极端场景导致全站故障。
  2. 如果为了替代Redis、MongoDB等而新部署一套PostgreSQL,无法降低架构成本,反而是牺牲性能、增加运维负担。
    新增独立PG集群会带来额外的机器、运维、监控、高可用成本,相比直接引入轻量专用组件,总体成本更高,违背“简化架构”初衷。

适用场景:

  1. 新项目、初创项目、MVP阶段:快速迭代优先,减少中间件维护成本,等业务出现真实瓶颈后再拆分专用组件;
  2. 内部系统、后台管理平台、低频运营系统:无C端高并发压力,可用性要求适中;
  3. 边缘业务、工具类、小型独立服务:规模有限,无需搭建复杂中间件体系。

#1241 同样吃苦,山河四省省吃俭用、云贵川渝活在当下,为何苦难传承出的生活态度截然不同?

2026-08-25

知乎上看到这个问题,还让我一征,好像是这么回事,浏览了网友的回复更让我觉得有点道理:两种观念差异,根源在于两地先民承受的苦难模式截然不同,因此造就两种生存哲学。

山河四省地处平原,土地广阔却人多地少,常年要应对旱涝灾害,苦难细碎、漫长、持续不断,如同钝刀割肉。日子尚可维持,但未来充满不确定性,今年丰收不代表来年风调雨顺。长久以来,人们依靠积攒粮食与钱财抵御长期风险,省吃俭用不是吝啬,而是对抗持续性困境的生存智慧。这份未雨绸缪的观念代代相传,叠加当地激烈的教育、就业竞争,让储备资源、为长远谋划成为普遍选择。

云贵川渝多山地,耕地零散,地震、山洪、泥石流等灾害突如其来,属于毁灭性的突发大难。这类天灾难以依靠平日省吃俭用积攒的物资规避,人们渐渐意识到,很多无常无法提前防范。既然无法预判明天,便不愿亏待眼前,有条件就好好享受生活,把开销优先投入当下的饮食与欢愉。

需要厘清的是,这种区分并非绝对标签。山河四省遇上喜事也愿意大方消费;云贵川渝民众同样懂得精打细算,只是消费重心偏向当下生活。

两种生活态度,都是祖辈在苦难之中摸索出的生存选择。一方依靠积蓄抵御绵长困境,一方选择拥抱当下对抗命运无常,没有高下之分,都是普通人应对生活磨难沉淀下来的生活哲学。

#1239 实现 SSH 安全防护的方案

2026-08-23

Why I close SSH port 22 entirely (and what I use instead)》作者主张:

  1. 彻底关闭公网 SSH 22 端口,而非仅靠密钥登录或 fail2ban。
    传统端口敲门(port knocking)用明文序列开端口,易被抓包重放。
  2. 改用 fwknop 单包授权(SPA):客户端发一个 加密+HMAC-SHA512 签名的 UDP 包,内含时间戳与一次性计数器。
    1. SPA 包加密防窃听、签名防伪造、时间戳/计数器防重放
    2. 加密密钥与 HMAC 密钥分离,一个负责"别让人偷看",一个负责"别让人造假"
  3. 服务端 fwknopd 校验通过后,临时(如 120 秒)向 iptables 插入仅放行客户端 IP 的 22 端口规则,超时自动回收。
  4. 配合 ~/.ssh/config 的 ProxyCommand 可让 ssh server1 透明敲门。
  5. Tailscale 加密隧道作兜底,确保万一 SPA 机制失效还能成功登录机器。

这个方案不是“换端口藏起来”,而是默认全拒+密码学鉴权,把攻击面缩到仅收 SPA 的 UDP 口,好处就是对扫描器而言 22 端口始终 filtered,无 banner、无 RST,OpenSSH 零日无法被触及。

#1238 Golang 新提案,拟在标准库新增 crypto/passkey​ 包

2026-08-22

关于Passkey 的介绍参见 《Passkey 无密码登录》。

前 Go 密码学负责人 Filippo Valsorda 提交 golang/go#80663 提案,拟在标准库新增 crypto/passkey 包,用“无状态、无回调、无接口”的极简服务端 API,把中小型网站接入 Passkey(WebAuthn 可发现凭据)的门槛降到最低。

核心设计有三块。一是 passkey-record 规范:把认证器数据、transports 等编码成类似 PHC 密码哈希的单行不透明字符串(如 $webauthn$v=1$...),存库时当黑盒文本即可,支持跨语言、跨库迁移。 二是 存储模型简化:数据库只需 user_id + record 两列、按 user_id 建索引,不对 credential_id 建唯一索引——凭据永远先按用户查再逐条比对,从根上规避跨账号主键碰撞攻击。 三是 流式无状态工作流RelyingParty 是纯配置对象,注册走 NewRegistration→前端 navigator.credentials.createRegister 存串;登录走 NewLoginParseResponseUnauthenticatedUserID(验签前不可信,仅用于查记录)→Login

关键安全取舍:弃用回调(吸取 GO-2024-3321 教训,避免未验数据流入应用判断)、强制单 Origin 配置(多源需建多个 RP 实例,防跨站断言重放)、User ID 用 crypto/rand.Text() 生成随机不透明串、不校验 attestation 与签名计数器,专为消费级 95% 场景减负。

提案仍处评审期,未进正式版本,但信号明确:Passkey 接入正从“懂协议”降级为“按 user_id 存一个字符串”。

#1237 三元节:上元、中元、下元分别是哪一天?

2026-08-21

中国传统节日中,有一组以农历月份命名的“三元节”,分别是上元节、中元节和下元节。

上元节为农历正月十五,也就是今天所说的元宵节,是一年中的第一个月圆之夜。道教认为这一天是天官赐福之日,因此有张灯结彩、赏灯、祈福等习俗。

中元节为农历七月十五,又称“七月半”。在道教体系中,这一天是地官赦罪之日;民间则逐渐形成祭祖、超度亡灵、普渡孤魂等习俗,因此俗称“鬼节”。佛教则有“盂兰盆节”或“盂兰盆会”,源于《盂兰盆经》中目犍连救母的故事。需要注意的是,中元节与盂兰盆节日期相同、习俗相互融合,但两者的宗教来源并不相同

下元节为农历十月十五,道教称这一天为水官解厄之日,民间传统影响相对较小。

我第一次知道这个说法还是来自《西游记》观灯金平府这一集,唐僧师徒来到天竺国东界金平府,正值上元佳节(就是元宵节,我老家叫“月半”),当地举行盛大的元宵灯会。三名犀牛精——辟寒大王、辟暑大王、辟尘大王——趁灯会之夜化作佛像,借灯油显灵,将唐僧摄走。后来孙悟空请来二十八宿中的四木星官,最终降服三妖。

#1236 Cursor重新设计Git:S3 WAL成为唯一数据源

2026-08-20

2026年8月18日,Cursor发布技术博客《Git at any scale》,详细介绍其为代码托管服务 Origin 开发的新型Git存储系统 Continuity。此前一天,Cursor已开始向付费用户推出 Origin 早期Beta。

与 GitHub 等传统代码托管架构不同,Cursor没有把服务器本地Git仓库视为最终数据,而是采用了一种更接近数据库的设计:将S3上的Write-Ahead Log(WAL)作为仓库唯一权威数据源。

传统Git托管需要维护大量状态,包括仓库与服务器的映射、Primary节点、Replica副本以及故障转移等。Continuity则把这些状态尽可能“缓存化”。用户执行 git push 后,数据首先写入S3 WAL,确认持久化后才返回成功;服务器本地的Git仓库则只是高速缓存,即使服务器磁盘损坏,也可以依据WAL重新构建。

在一致性方面,Continuity利用S3提供的原子CAS机制处理并发写入,并通过Rendezvous Hashing选择合适节点。同一个仓库通常由固定节点处理,以降低冲突,但Primary并不是系统正确性的必要条件。新增服务器时,也无需复杂的数据迁移,只需从S3 WAL恢复对应仓库即可。

这种架构特别适合AI Agent时代。未来大量Agent可能同时执行Clone、Commit、Push、创建PR和CI任务,Git平台需要承受远高于传统开发模式的并发访问。Cursor希望通过“S3负责事实、本地Git负责性能”的方式,让代码托管基础设施更容易水平扩展。

因此,Continuity真正值得关注的并非简单地“用S3存Git”,而是将权威状态与计算节点彻底解耦:服务器可以故障、迁移甚至直接删除,而数据仍然可以从WAL重建。这可能成为AI Agent驱动的新一代代码托管平台值得借鉴的架构方向。

#1235 Cloudflare 开始向 AI 爬虫收费,免费内容换流量的时代正在结束

2026-08-19

过去三十年,互联网形成了一套默认规则:网站免费提供内容,搜索引擎免费抓取,再通过搜索流量让网站获得广告收益。但生成式 AI 正在打破这套平衡。

Cloudflare计划于 2026年9月15日 调整默认爬虫规则,将爬虫分为 Search、Agent 和 Training 三类。新接入及免费客户的网站默认允许搜索爬虫访问,同时阻止 AI 代理和训练爬虫。更复杂的是 Googlebot、Bingbot 等混合爬虫既负责搜索索引,又可能服务于 AI 摘要,因此可能受到更严格策略影响。

Cloudflare还推出 Pay Per Crawl(按次付费爬取),要求 AI 公司为内容访问表达明确的支付意图。

这背后的核心矛盾是:传统搜索是“抓取内容→带来流量”,而 AI 搜索则可能“抓取内容→直接生成答案”,用户甚至无需点击原网站。内容生产者因此承担创作成本,却未必获得相应流量回报。

Cloudflare此举,本质上是在重新定义互联网内容的计价方式:从“免费抓取换流量”,转向“访问内容就要付费”。AI可以快速总结知识,但前提是有人持续生产知识。免费白嫖内容的时代,正在结束。