Documentation
¶
Overview ¶
Package affinity 按会话标识在候选渠道之间做确定性分配,让同一段会话的连续 请求落到同一个上游账号上,从而使上游的提示缓存有机会命中。
这里只做排序,不做选择:粘住的那条排在最前,其余候选按固定顺序跟在后面, 调用方的失败降级照旧生效。
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Chain ¶
Chain 把条目序列折成一条累积哈希链。
链的第 i 项是「前 i + 1 个条目」的指纹。因此同一段会话在连续几轮里的链互为 前缀:上一轮的整条链就是这一轮链的前一段。靠这个关系,查「上一轮走了哪个渠道」 不需要知道上一轮有几个条目,只要从末尾往回查第一个命中的下标。
不用「整段内容算一个哈希」,是因为那样只能回答「这一轮是不是上一轮」,回答不了 「这一轮的开头哪一段是上一轮」。工具调用在一轮里能占六七条,去掉尾部固定条数 这种办法算不准。
func Order ¶
Order 返回 identities 的下标顺序,粘性最强的一条排在最前。
用 rendezvous 哈希(最高随机权重),不用取模。区别在候选集合变化时:取模会让 几乎所有键重新分配,rendezvous 只移动原本落在增删项上的那一部分。渠道上下线 时按取模会让全部会话的缓存集体失效,按 rendezvous 只影响其中一个渠道的份额。
Types ¶
type Table ¶
type Table struct {
// contains filtered or unexported fields
}
Table 记住「请求前缀的指纹 → 渠道」的对应关系,供没有会话标识的客户端兜底。
键是内容指纹而不是会话名,因此两段内容完全相同的前缀会共用一条记忆。这不是 缺陷:内容相同就意味着上游那份缓存真的可以共享。
淘汰按插入顺序,不按最近使用。这里需要的是「上限之内保留各段会话最近若干轮的 指纹」,而活跃会话每一轮都写一条新记忆,上一轮那条只有一轮的岁数,挤不掉。 做成最近最少使用要额外维护一个堆,收益不足以抵消复杂度。
Table 可以并发使用。limit 不大于零时整个记忆关闭,Recall 一律不命中。