↑↑↑ 欢迎 点赞、关注、收藏!!!,10 年 IT 行业老鸟,持续分享更多 IT 干货
目录
如何从 1TB 的搜索日志中找出搜索量最高的 10 个关键词?
如何从 1TB 的搜索日志中找出搜索量最高的 10 个关键词?
海量数据Top K问题解决方案
背景
需求:从 1TB 搜索日志中高效找出搜索量最高的 10 个关键词。
核心挑战:数据量过大,无法直接加载到内存中处理。
核心解决思路
分治 + 堆排序:
-
哈希分片:将数据分散到多个文件,确保相同关键词落入同一分片。
-
分片统计:逐个分片统计词频,生成有序中间文件。
-
全局堆合并:用最大堆提取分片最大值,用最小堆维护全局 Top 10。
详细步骤
1、哈希分片(分治思想)
-
哈希函数选择:使用 MurmurHash 等均匀分布的哈希算法,将关键词映射到固定数量的分片文件(如 1000 个)。
-
分片逻辑:
分片数 = 1000 → 每个分片文件约 1GB(1TB ÷ 1000) 关键词 K → hash(K) % 1000 → 写入对应分片文件
-
优势:保证相同关键词集中在同一分片,减少跨分片计算。
2. 分片统计与中间文件生成
-
逐分片处理:
-
读取单个分片文件,用哈希表统计词频(
HashMap<关键词, 次数>
)。 -
按次数降序排序,保存为中间文件(如
chunk_1.sorted
)。
-
-
输出示例:
chunk_1.sorted: ("keyword1", 10000) ("keyword2", 9800) ...
3. 全局 Top 10 计算
双堆协作:
堆类型 | 作用 | 容量 |
---|---|---|
最大堆 | 提取各分片的当前最大值 | 分片数量 |
最小堆 | 维护全局 Top 10(堆顶为第10大值) | 固定10个 |
循环处理流程:
-
初始化:将每个分片文件的第一个关键词(最大值)加入最大堆。
-
循环提取:
-
从最大堆取出当前全局最大值(关键词 K, 次数 C)。
-
若最小堆未满,直接加入;否则,若 C > 堆顶值则替换。
-
若 C ≤ 堆顶值,且最小堆已满,提前终止(后续值更小)。
-
从 K 所属分片读取下一个关键词,更新最大堆。
-
-
输出结果:最小堆中的关键词即为全局 Top 10。
参考
-
csdn
-
gitee
↑↑↑ 欢迎 点赞、关注、收藏!!!,10 年 IT 行业老鸟,持续分享更多 IT 干货