基础组件
前面几部分讲的 pingora-core、pingora-proxy、pingora-cache 底下,垫着一组各自只有几百到几千行的 crate。它们不依赖 pingora-core,可以单独拿来用;有的被框架处处用到(pingora-timeout、pingora-http),有的框架里一处都没用(TinyUFO、pingora-memory-cache)。pingora-pool 和 pingora-runtime 也属于这一类,已经在连接池和运行时讲过;pingora-error 在错误、重试与故障转移。
- TinyUFO 与内存缓存:TinyUFO 是 small、main 两条无锁 FIFO 加一个 Count-Min 草图,草图顶替了 S3-FIFO 的幽灵队列,只存键的哈希;实测 Zipf 访问下比 LRU 高 1.9 到 14.1 个百分点,一百万容量的空缓存就占 71 MB;
RTCache合并同键查询,但写者被取消后锁永远留下;pingora-lru是缓存淘汰用的分片近似 LRU。 - 超时:
pingora_timeout::timeout挂起时才登记定时器,定时器按 10 ms 归入每线程一棵BTreeMap,一个时钟线程触发;实测登记加取消比 tokio 快 1.9 倍、8 线程时快 8 倍,代价是到期晚 0 到 20 多毫秒;15 分钟以上的超时 0.9.0 起改回 tokio。 - 请求头与错误:
RequestHeader/ResponseHeader在HeaderMap旁边存一张CaseMap,两张表按位置配对写出;0.8.0 的DerefMut能绕开它,删头 panic、加头被悄悄丢掉,0.9.0 删掉了它;pingora-header-serde用 zstd 压缩缓存里的响应头,字典只对同类的头有用。
flowchart TB core["pingora-core"] --> tmo["pingora-timeout"] core --> http["pingora-http"] cache["pingora-cache"] --> lru["pingora-lru"] cache --> serde["pingora-header-serde"] cache --> tmo serde --> http mem["pingora-memory-cache"] --> ufo["TinyUFO"] mem --> tmo
图里只画了本部分几个 crate 之间、以及它们和框架之间的依赖;pingora-memory-cache 那一支没有任何框架 crate 依赖,要用就自己加进 Cargo.toml。
💬 关联讨论
发起讨论加载中...