Rust in Everything
基于 pingora 0.9.0

基础组件

前面几部分讲的 pingora-core、pingora-proxy、pingora-cache 底下,垫着一组各自只有几百到几千行的 crate。它们不依赖 pingora-core,可以单独拿来用;有的被框架处处用到(pingora-timeout、pingora-http),有的框架里一处都没用(TinyUFO、pingora-memory-cache)。pingora-pool 和 pingora-runtime 也属于这一类,已经在连接池和运行时讲过;pingora-error 在错误、重试与故障转移。

  1. TinyUFO 与内存缓存:TinyUFO 是 small、main 两条无锁 FIFO 加一个 Count-Min 草图,草图顶替了 S3-FIFO 的幽灵队列,只存键的哈希;实测 Zipf 访问下比 LRU 高 1.9 到 14.1 个百分点,一百万容量的空缓存就占 71 MB;RTCache 合并同键查询,但写者被取消后锁永远留下;pingora-lru 是缓存淘汰用的分片近似 LRU。
  2. 超时:pingora_timeout::timeout 挂起时才登记定时器,定时器按 10 ms 归入每线程一棵 BTreeMap,一个时钟线程触发;实测登记加取消比 tokio 快 1.9 倍、8 线程时快 8 倍,代价是到期晚 0 到 20 多毫秒;15 分钟以上的超时 0.9.0 起改回 tokio。
  3. 请求头与错误: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。

💬 关联讨论

发起讨论
加载中...