[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fditewzeoPQSHKxqGY38cVLH4-HR8_mw-QkRntzIaYqE":3},{"item":4,"related":44},{"id":5,"type":6,"title":7,"slug":8,"summary":9,"body":10,"coverUrl":11,"productScreenshots":12,"productLinks":13,"authorName":14,"authorUrl":15,"authorSubject":16,"category":17,"tags":22,"sourceLabel":35,"sourceName":36,"sourceUrl":37,"status":38,"seoTitle":7,"seoDescription":9,"canonicalUrl":35,"isFeatured":39,"sno":40,"sortOrder":41,"publishedAt":42,"updatedAt":43,"createdAt":43},"c1a2b1ed-df5d-4289-9938-8b74d7eae70c","article","HyperLogLog：不保存所有访客 ID，怎样估算独立访客数？","hyperloglog-cardinality-estimation","HyperLogLog 用哈希模式与少量寄存器估算大型集合的不同元素数量，支持合并摘要但不能还原成员名单。本文解释它的空间效率、统计误差与适用场景，并区分估算和精确计数。","网站想统计一个月有多少独立访客，最直接的办法是保存每个访客标识，再去重计数。但数据量可能很大，保存和排序所有 ID 既占空间，也增加处理成本。HyperLogLog 是一种概率型基数估计算法：它不保留每个元素，而是用少量寄存器摘要估算集合里有多少个不同元素。\n\n算法先把每个输入映射为近似均匀的哈希值。哈希值的二进制开头往往会出现一段零；观察这段连续零的长度，偶尔出现很长零串，通常意味着已经看过了相当多样本。HyperLogLog 把哈希空间分成多个桶，每个桶记录自己遇到的最长零串特征，再综合这些统计量估计总基数。\n\n单个桶的估计会有较大波动，多个桶的统计聚合能降低误差。寄存器数量增加时，通常可用更多内存换取更小的相对误差。它的空间使用不会随着访客人数线性增长，因此即便集合达到数亿级，仍可能只需要相对精简的摘要结构。具体误差会受寄存器配置、哈希质量和实现细节影响，不应把估算值当作精确计数。\n\nHyperLogLog 还有一个很实用的性质：相同配置、兼容哈希规则的两个摘要可以合并，得到两个集合并集的估计。这让分布式系统可以先在各机器上统计，再把小型摘要汇总，而无需把全部用户 ID 拉到中心服务器。但摘要只能回答“有多少不同元素”这类问题，不能告诉你访客具体是谁，也不能还原元素名单。\n\n它适合做趋势指标和容量估算，例如统计搜索词种类、独立访问量或去重设备数。若应用要求财务结算、抽奖资格或精准审计，概率误差可能不可接受，仍应采用精确集合或数据库去重。另一个隐私提醒是：摘要不保存原始名单，并不自动等于完整匿名或免除数据治理责任，输入哈希和系统日志仍需按实际风险管理。\n\n可以把它想成不记下每位来客姓名，而是把来客映射到很多小格子，只记录每格里出现过的“罕见程度”，再估算总人数。HyperLogLog 用很小的记忆换取可控的统计误差，特别适合大规模流式去重。看懂这一点，就能分清它与精确位图、布隆过滤器等结构各自回答的是什么问题。\n\n来源：[Flajolet 等：HyperLogLog，2007](https:\u002F\u002Falgo.inria.fr\u002Fflajolet\u002FPublications\u002FFlFuGaMe07.pdf)","\u002Fuploads\u002F2026-10-13\u002F500098d4-e21d-45b6-ab12-8b93fc519fd0.jpg",[],[],"Foundit","https:\u002F\u002Ffoundit.cn","foundit-ai-editorial",{"id":18,"name":19,"slug":20,"description":21},"6179d3b6-dc34-4483-9ded-3cd9f1b37a47","科普","abbreviation","介绍各领域新兴概念",[23,27,31],{"id":24,"name":25,"slug":26},"7c76bfc2-f80f-4ee0-a95d-27bd8708b434","技术","slug",{"id":28,"name":29,"slug":30},"144abe77-0dc6-4f66-a176-20bddb1c0bfa","编程","coding",{"id":32,"name":33,"slug":34},"4c2bbea6-eab7-40a8-8447-1de478ff7749","分析","analyse",null,"INRIA Research Paper","https:\u002F\u002Falgo.inria.fr\u002Fflajolet\u002FPublications\u002FFlFuGaMe07.pdf","published",false,54,0,"2026-10-13T00:00:00.000Z","2026-10-13T02:14:08.058Z",[45,54,62],{"id":46,"type":6,"title":47,"slug":48,"summary":49,"coverUrl":50,"authorName":14,"sno":51,"publishedAt":52,"createdAt":53},"5e0c84da-6011-41e8-b1f7-726c8bf0b30a","RCU：读多写少的系统，为什么敢让读者几乎不加锁？","rcu-read-copy-update-explained","RCU 把共享数据的更新与旧版本回收拆开，让读者以极低成本读取，同时等待所有旧读者离开后再释放内存。本文用导览图解释它的读侧、宽限期与适用边界。","\u002Fuploads\u002F2026-09-26\u002F3398ce37-ca4f-4cc3-84b3-fe931d2f055d.jpg",41,"2026-09-27T00:00:00.000Z","2026-09-26T16:25:40.784Z",{"id":55,"type":6,"title":56,"slug":57,"summary":58,"coverUrl":59,"authorName":14,"sno":60,"publishedAt":42,"createdAt":61},"0bc79f1c-f305-4d64-a9f8-589d1d6da0b3","EEVDF：Linux 如何判断哪个任务“最该先用 CPU”？","eevdf-linux-fair-cpu-scheduling","EEVDF 是 Linux 调度器的一种公平调度思路：先判断任务是否获得了应有份额，再按虚拟截止时间安排运行机会。本文用共享厨房的比喻，解释它如何兼顾长期公平与短期响应，并澄清它并非硬实时保证。","\u002Fuploads\u002F2026-10-13\u002Fdc59d374-8c78-41ba-bdfe-a6f0e62ab246.jpg",43,"2026-10-13T02:13:28.103Z",{"id":63,"type":6,"title":64,"slug":65,"summary":66,"coverUrl":67,"authorName":14,"sno":68,"publishedAt":52,"createdAt":69},"23b5596a-29ab-4ff8-8237-1fd34d8e0bd1","Seqlock：读者不加锁，为什么还能读到一份一致的数据？","seqlock-sequence-counter-explained","Seqlock 让读者先后读取序列号并在变化时重试，以校验快照是否被写者打断，适合读多写少且字段可安全复制的数据。","\u002Fuploads\u002F2026-09-26\u002Fe6a9caee-7551-469f-9b16-d27fcc97f034.jpg",44,"2026-09-26T16:25:51.305Z"]