#1223 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)可缓解部分限制,但不改变单写本质。

#1222 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. 边缘业务、工具类、小型独立服务:规模有限,无需搭建复杂中间件体系。

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

2026-08-25

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

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

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

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

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

#1219 实现 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 零日无法被触及。

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

2026-08-21

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

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

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

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

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

#1217 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驱动的新一代代码托管平台值得借鉴的架构方向。

#1216 HTML-in-Canvas 与 Canvas UI

2026-08-17

前端圈有一条隐形的墙:DOM 负责结构、文本、无障碍与交互;Canvas / WebGL 负责像素、Shader、粒子与 3D。两边各自很强,却很难融合。

HTML-in-Canvas 是 WICG 正在孵化的提案,试图把这道墙拆掉;
而 Canvas UI 则是基于它(并带降级方案)第一个走红的"GPU 级视觉组件库"。

#1215 浏览器访问本地 HTTPS 网站偶发卡住的排查经验

2026-08-15

我用 Golang 开发了一个本地站点,跑在 Caddy 上(动态注册路径),并使用阿里云 DNS 将域名解析到本地 IP。

今天突然发现网页无法打开,浏览器一直处于 Pending 状态,而 curl 访问正常。关闭网络代理和浏览器插件、清理缓存后问题仍然存在。

怀疑是 DNS 解析的问题,使用 curl -vk --resolve d3v.cn:443:192.168.31.31 https://d3v.cn/markjour/ 访问也正常。

更奇怪的是,发现使用访客模式可以打开。

最后还发现,在关闭一些浏览器 Tab 后,普通模式也恢复正常。暂时推测可能与浏览器 HTTP/2 连接复用有关:

  1. 开机之后我访问相关页面没有成功打开,发现是服务都没有启动,然后启动 Caddy 和后台服务,并动态注册路径。
    可能是这个过程中,有 Tab 没有关闭,一直 Pending。
  2. Caddy 支持 HTTP/2,浏览器会通过 ALPN 协商 HTTP/2;HTTP/2 会在同一个连接上复用多个请求。
    如果底层 HTTP/2 连接本身出现异常,复用该连接的多个请求可能同时表现为 Pending。
    关闭 Tab 后,浏览器可能释放异常连接并重新建立连接,因此问题自动恢复。

以后再次遇到的时候再检查验证。


后续多次遇到这个本地网站访问异常问题,今天抽空继续排查。

发现同一台机器上的 Edge,不同 Profile 对 d3v.cn 的访问结果不同:一个可以正常打开,另一个持续 ERR_TIMED_OUT

进一步查看 Edge 的网络信息发现( / ),异常 Profile 将 d3v.cn 解析为 ::1192.168.31.31,而正常 Profile 解析为 127.0.0.1。随后检查本机 /etc/hosts,发现配置了:

127.0.0.1 localhost
127.0.0.1 eqr.hosts.d3v.cn eqr eqr6
::1       eqr.hosts.d3v.cn

同时公网 DNS 中 eqr.hosts.d3v.cn 也存在地址记录。因此,同一域名实际上同时存在本地 hosts 和公网 DNS 两套解析结果,Edge 不同 Profile 可能缓存或选择了不同地址。

这次基本确认问题核心在域名解析结果不一致,而不是 Caddy、TLS 或 HTTP/2。后续应避免让同一域名同时依赖 hosts 和公网 DNS 提供不同地址,或者至少确保两者解析结果一致。

#1214 Claude 全线产品上线隐形水印

2026-08-11

近日,Anthropic 宣布为旗下 AI 助手 Claude 引入生成内容标记机制。从 8 月 2 日起,Claude 生成的文本将默认携带隐形水印,用户复制、粘贴部分内容后,水印仍可能保留。这意味着,未来一段由 AI 生成的文字,可能具备被检测和追踪来源的能力。