文章目录

  • 题目
    • 场景描述
    • 要求
    • 问题
    • 考察点
  • 解答
    • 思考
    • 一、核心解决方案(基础版,单节点32GB内存、10台节点)
      • 1. 整体架构选型
      • 2. 关键步骤详解
        • (1)数据分片:解决“数据量大,单节点处理不了”的问题
        • (2)本地计算:单节点内完成计数与初步筛选
        • (3)全局汇总:合并各节点结果
        • (4)容错机制
    • 二、内存优化(单节点仅8GB时)
    • 三、提速方法(缩短计算时间)
    • 四、实时统计(每5分钟更新一次)
  • 总结

题目

场景描述

某电商平台的服务器每天会产生约10亿条访问日志,每条日志包含用户ID、访问URL、访问时间等信息(每条日志约100字节)。现在需要设计一个系统,解决两个核心问题:

  1. 找出当天所有仅出现过一次的URL(即独立访问的URL)。
  2. 统计每个URL的访问次数,并按访问量从高到低排序,输出Top 100的URL。

要求

  • 系统需处理每日新增的10亿条日志,原始日志存储在分布式文件系统(如HDFS)中。
  • 服务器集群资源有限:单节点内存最多32GB,可使用的节点数量不超过10台。
  • 需考虑处理效率(尽量缩短计算时间)和容错性(如节点故障时如何处理)。

问题

  1. 请设计一个解决方案,阐述核心思路和关键步骤。
  2. 如果内存有限(如单节点仅8GB),如何优化方案避免OOM?
  3. 如何提高系统的处理速度?可以从算法、数据结构、分布式策略等角度分析。
  4. 若需实时统计(如每5分钟更新一次Top 100 URL),方案需要做哪些调整?

考察点

  • 大数据处理思维(分治、哈希分片)
  • 内存优化能力(数据压缩、磁盘缓存)
  • 分布式系统设计(任务拆分、容错机制)
  • 算法与数据结构选型(哈希表、堆、布隆过滤器等)
  • 实时与离线处理的差异理解

这道题结合了实际业务中的日志处理场景,既考察基础算法能力,也关注工程落地时的资源限制与性能优化,能有效区分候选人的综合技术水平。

解答

思考

  1. 10亿条日志,平均每条100字节,也就是总共100GB数据。如果只存URL统计值,放10台机器应该内存勉强够,这里用hash分片的方式,即URL哈稀按10取模,分到10台机器上统计,完后假设够就能直接统计全量URL出现次数,然后再用小根堆,求出Top 100个url。统计时间复杂度是O(n),小根堆排序时间复杂度是O(nlog100)。
  2. 假设不够,也算回答下面32G改为8G的情况,可以hash分片分为100份,放入100个小文件中,然后再分别基于这100个小文件,计算只出现一次的URL和TOP100,因为是hash分片的,同一个url不可能出现在两台机器上,所以最后汇总100个分片的数据即可。
  3. 假如离线统计变成了实时统计,一天100G,平均5分钟是350M,如果不考虑绝对精确,那么离线数据统计TOP 1000,然后加上5分钟新数据的URL的统计,合并取出TOP100。如果要精确计算,那么有可能TOP 1001的那个URL加上5分钟内的新数据,刚好达到top100,那么就漏统计了。但单纯目前的10台机器很难做到精确统计,可以引入Redis的Zset维护所有url的统计值,通过zrange统计top100.
    针对日志去重与统计系统的设计问题,解决方案需结合分治思想、分布式处理、内存优化三大核心思路,同时兼顾效率与容错性。以下是具体方案拆解:

一、核心解决方案(基础版,单节点32GB内存、10台节点)

1. 整体架构选型

采用**“分布式离线计算框架”(如MapReduce/Spark)作为核心引擎,依托分布式文件系统(HDFS)存储原始日志,利用框架的并行计算能力和容错机制处理10亿条日志。
核心逻辑分为
“分片预处理→本地计算→全局汇总”**三阶段。

2. 关键步骤详解

(1)数据分片:解决“数据量大,单节点处理不了”的问题
  • 分片依据:按URL的哈希值分片(如hash(URL) % 10,10为节点数),确保相同URL被分配到同一节点。
    原理:相同URL的哈希值相同,会被路由到同一个节点,避免“跨节点统计同一URL”导致的计数错误。
  • 分片效果:10亿条日志平均分配到10台节点,每节点处理约1亿条(约10GB原始数据),单节点32GB内存可承载。
(2)本地计算:单节点内完成计数与初步筛选

每台节点对分配到的分片数据执行以下操作:

  • 步骤1:URL去重与计数
    哈希表(如Java的HashMap<String, Integer>)存储“URL→访问次数”映射:

  • 遍历分片内的每条日志,提取URL,在哈希表中累加计数(若不存在则初始化为1,存在则+1)。

  • 优化:用“URL的哈希值”代替原始URL作为key(如将URL通过MD5压缩为16字节哈希值),减少内存占用(原始URL可能很长,哈希值固定长度更省空间)。

  • 步骤2:筛选“仅出现一次的URL”
    遍历本地哈希表,筛选出value=1的URL,暂存为“本地独立URL列表”。

  • 步骤3:计算“本地Top 100 URL”
    对本地哈希表的(URL, 次数)按次数降序排序,取前100条作为“本地Top 100”(用堆排序效率更高:维护一个大小为100的小顶堆,遍历计数时动态更新,时间复杂度O(n log 100))。

(3)全局汇总:合并各节点结果
  • 汇总“独立URL”:收集所有节点的“本地独立URL列表”,合并后即为全局“仅出现一次的URL”(因相同URL已被分片到同一节点,无需去重)。
  • 汇总“全局Top 100”
    收集所有节点的“本地Top 100”(共10×100=1000条),用一个大小为100的小顶堆对这1000条数据重新排序,最终得到全局Top 100 URL。
(4)容错机制
  • 依赖分布式框架的原生容错:若某节点故障,框架会自动将其任务分配给其他节点重新处理(需确保原始日志在HDFS中有多副本,避免数据丢失)。
  • 中间结果持久化:将本地哈希表、本地Top 100等中间结果写入磁盘(如HDFS临时目录),避免节点重启后重复计算。

二、内存优化(单节点仅8GB时)

当单节点内存降至8GB,1亿条日志的哈希表可能超出内存(假设每条URL+计数占32字节,1亿条需3.2GB,但哈希表负载因子会导致实际占用更高,可能达6-8GB),需进一步优化:

  1. 二次分片(分片内再拆分)
    对单节点的1亿条日志再次按hash(URL) % 10拆分(即总分片数10×10=100),每批处理1000万条(约1GB),处理完一批后释放内存,再处理下一批。

  2. 使用磁盘辅助存储
    嵌入式KV数据库(如LevelDB/RocksDB)替代内存哈希表:

  • 遍历日志时,将URL的计数实时写入磁盘数据库(key=URL哈希值,value=次数),利用数据库的磁盘+内存混合存储特性避免OOM。
  • 优势:LevelDB支持按key排序,后续筛选独立URL和Top 100时可按序遍历,效率高于随机读写。
  1. 数据压缩
  • 对URL进行字典编码:将重复出现的URL映射为整数ID(如“www.xxx.com”→1,“www.yyy.com”→2),用ID代替URL存储,减少key的长度。

三、提速方法(缩短计算时间)

  1. 算法与数据结构优化
  • 计数阶段:用数组+哈希函数代替哈希表(若URL哈希值可映射到整数范围),减少哈希冲突带来的开销。
  • Top 100计算:用小顶堆(而非全量排序),将局部排序时间从O(n log n)降至O(n log k)(k=100)。
  1. 分布式并行优化
  • 增加分片数:将10亿条日志拆分为更多分片(如100片),让10台节点并行处理10片/节点,提高CPU利用率(避免单节点处理1亿条时CPU空闲)。
  • 减少数据传输:仅传输“本地结果”(独立URL列表、本地Top 100),而非原始日志(原始10GB/节点,结果可能仅10MB/节点)。
  1. 硬件与框架调优
  • 用Spark替代MapReduce:Spark基于内存计算,中间结果保存在内存(非磁盘),迭代计算速度快3-5倍。
  • 启用数据预读取:利用HDFS的“预取机制”,在处理当前分片时提前加载下一分片数据到内存缓存。

四、实时统计(每5分钟更新一次)

离线方案适合T+1处理,实时统计需切换为流处理架构(如Flink/Kafka Streams),核心调整如下:

  1. 数据接入
    日志通过Kafka实时流入系统(Kafka作为消息队列,缓冲峰值流量),每5分钟划一个“滚动窗口”。

  2. 实时计数

  • Flink的KeyedStream按URL分组,在窗口内累加计数(底层用状态后端存储计数,支持 RocksDB 持久化避免状态丢失)。
  • 窗口结束后,触发“本地Top 100”计算,结果写入全局状态(如Redis)。
  1. 全局Top 100更新
  • 维护一个全局Redis有序集合(ZSet),存储所有URL的累计次数,每5分钟从各窗口结果中合并更新ZSet,再用ZREVRANGE取前100。
  • 优化:用“滑动窗口”代替滚动窗口(如统计最近5分钟,每1分钟更新一次),减少结果抖动。
  1. 处理乱序数据
    日志可能因网络延迟乱序到达,需设置水印(Watermark):允许数据迟到30秒,超过后不再计入当前窗口,平衡实时性与准确性。

总结

该方案通过“分治+分布式”解决大数据量问题,通过“磁盘辅助+二次分片”优化内存,通过“流处理框架”支持实时统计,兼顾了效率、容错性和资源限制,符合实际生产场景的工程落地需求。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/diannao/94447.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/94447.shtml
英文地址,请注明出处:http://en.pswp.cn/diannao/94447.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Day 16】Linux-性能查看

目录 一、Stress系统压力测试工具 二、性能查看 &#xff08;一&#xff09;查看CPU # nproc # lscpu # top # uptime # mpstat 数字1 数字2 &#xff08;二&#xff09;查看内存 # dmidecode -t memory | less # free -h # …

【ICCV2017】Deformable Convolutional Networks

一、摘要尽管卷积神经网络&#xff08;CNN&#xff09;在视觉识别任务上取得巨大成功&#xff0c;但其固有的固定几何结构&#xff08;固定卷积采样网格、固定池化窗口、固定 RoI 划分&#xff09;严重限制了对未知几何变换&#xff08;尺度、姿态、形变、视角变化&#xff09;…

echarts在前后端分离项目中的实践与应用

目录 一、ECharts简介 二、后端数据接口设计 三、数据结构设计 1. 柱状图数据结构 2. 饼图数据结构 四、后端实现要点 五、前端ECharts配置解析 1. 柱状图配置 2. 饼图配置 六、最佳实践建议 七、总结 一、ECharts简介 ECharts是百度开源的一个基于JavaScript的可视…

SQL 四大语言分类详解:DDL、DML、DCL、DQL

SQL&#xff08;结构化查询语言&#xff09;通常被分为四种主要类型&#xff0c;每种类型负责不同的数据库操作。下面我将详细介绍这四类SQL语言的语法和用途。一、DDL (Data Definition Language) 数据定义语言功能&#xff1a;定义和管理数据库对象结构&#xff08;表、视图、…

ESP-idf框架下的HTTP服务器\HTML 485温湿度采集并长传

项目描述:本项目采用485采集温湿度以及电压电流等,485模块分别为下图,串口转485模块采用自动收发模块,ESP32工作在AP热点模式,通过手机连接esp32的热点来和esp进行数据通讯,使用esp32作为HTTP服务器缺陷:项目的最终HTML页面代码可发给AI让其写注释#include "freertos/Free…

雅江工程解锁墨脱秘境:基础条件全展示(区位、地震、景点、天气)

目录 前言 一、区位信息 1、空间位置 2、区位介绍 二、地震信息 1、历史地震信息 2、5.0级以上大地震 三、景点信息 1、景点列表分布 2、4A级以上景点 四、天气信息 1、天气实况 2、天气应对挑战 五、总结 前言 相信最近大家对雅江电站的超级大工程项目应该有所耳…

​​机器学习贝叶斯算法

​​一、引言​​在当今机器学习领域&#xff0c;贝叶斯算法犹如一颗璀璨的明星。你是否想过&#xff0c;垃圾邮件过滤系统是如何准确判断一封邮件是否为垃圾邮件的呢&#xff1f;这背后可能就有贝叶斯算法的功劳。今天&#xff0c;我们就一同走进贝叶斯算法的世界&#xff0c;…

Chisel芯片开发入门系列 -- 18. CPU芯片开发和解释8(流水线架构的代码级理解)

以【5 Stage pipeline CPU】搜索图片&#xff0c;选取5幅有代表性的图列举如下&#xff0c;并结合Chisel代码进行理解和点评。 图1&#xff1a;原文链接如下 https://acsweb.ucsd.edu/~dol031/posts/update/2023/04/10/5stage-cpu-pipeline.html 点评&#xff1a;黑色的部分…

Docker容器中文PDF生成解决方案

在Docker容器中生成包含中文内容的PDF文件时&#xff0c;经常遇到中文字符显示为方块或乱码的问题。本文将详细介绍如何在Docker环境中配置中文字体支持&#xff0c;实现完美的中文PDF生成。 问题现象 当使用wkhtmltopdf、Puppeteer或其他PDF生成工具时&#xff1a; 中文字符…

2.java集合,线程面试题(已实践,目前已找到工作)

1线程的创建方式 继承Thread类实现Runnable接口实现Callable接口 2.这三种方式在项目中的使用有哪些&#xff0c;一般都是怎么用的 继承thread类实现线程的方式通过实现run方法来实现线程&#xff0c;通过run进行线程的启用实现runnable方法实现run方法&#xff0c;然后通过thr…

站在前端的角度,看鸿蒙页面布局

从Web前端转向鸿蒙&#xff08;HarmonyOS&#xff09;开发时&#xff0c;理解其页面布局的相似与差异是快速上手的核心。鸿蒙的ArkUI框架在布局理念上与Web前端有诸多相通之处&#xff0c;但也存在关键区别。以下从五个维度系统分析&#xff1a; &#x1f4e6; 一、盒子模型&a…

JavaWeb遗传算法、TSP、模拟退火、ACO算法等实战应用

Java Web中实现遗传算法的应用 以下是关于Java Web中实现遗传算法的应用场景和实例的整理,涵盖不同领域的解决方案和实现方法: 遗传算法基础结构 在Java Web中实现遗传算法通常需要以下核心组件: 种群初始化:随机生成初始解集。 适应度函数:评估个体优劣。 选择操作:轮…

【图像算法 - 09】基于深度学习的烟雾检测:从算法原理到工程实现,完整实战指南

一、项目背景与需求 视频介绍 【图像算法 - 09】基于深度学习的烟雾检测&#xff1a;从算法原理到工程实现&#xff0c;完整实战指南今天我们使用深度学习来训练一个烟雾明火检测系统。这次我们使用了大概一万五千张图片的数据集训练了这次的基于深度学习的烟雾明火检测模型&a…

间接制冷技术概念及特征

1、基本概念 (1)间接制冷技术即二次制冷技术。常规做法:二次冷却液储液罐增加放置于制冷系统管路,促使冷量再快捷的传递给载冷剂,继而载冷剂冷量促使冷库达到制冷效果。间接制冷技术:通过常压的二次冷却介质进行大循环传送冷量,在直接制冷剂不易应用的位置或者不可运用直…

Antlr学习笔记 01、maven配置Antlr4插件案例Demo

文章目录前言源码插件描述pom引入插件案例&#xff1a;实现hello 标识符 案例1、引入Antlr4的pom运行依赖2、定义语义语法&#xff0c;配置.g4文件实现java代码3、编写完之后&#xff0c;执行命令实现编译4、编写单测测试使用参考文章资料获取前言 博主介绍&#xff1a;✌目前…

PostGIS面试题及详细答案120道之 (101-110 )

《前后端面试题》专栏集合了前后端各个知识模块的面试题&#xff0c;包括html&#xff0c;javascript&#xff0c;css&#xff0c;vue&#xff0c;react&#xff0c;java&#xff0c;Openlayers&#xff0c;leaflet&#xff0c;cesium&#xff0c;mapboxGL&#xff0c;threejs&…

第十七天:原码、反码、补码与位运算

原码、反码、补码与位运算 一、原码、反码、补码 1、原码 定义&#xff1a;原码是一种简单的机器数表示法。对于一个有符号整数&#xff0c;最高位为符号位&#xff0c; 0 表示正数&#xff0c; 1 表示负数&#xff0c;其余位表示数值的绝对值。示例&#xff1a;以 8 位二进制…

一次完整的 Docker 启动失败排错之旅:从 `start-limit` 到 `network not found

一次完整的 Docker 启动失败排错之旅&#xff1a;从 start-limit 到 network not found 你是否也曾自信地敲下 sudo systemctl start docker&#xff0c;却只得到一个冰冷的 failed&#xff1f;这是一个开发者和运维工程师都可能遇到的场景。本文将通过一个真实的排错案例&…

Tdengine 时序库年月日小时分组汇总问题

年月分组select to_char(collection_time ,"yyyy-mm") AS date, cast(SUM(a.stage_value)as DOUBLE) as stage_value from TABLE GROUP BY date年月日分组select to_char(collection_time ,"yyyy-mm-dd") AS date, SUM(a.stage_value)as DOUBLE) as stage_…

数据结构(01)—— 数据结构的基本概念

408前置学习C语言基础也可以看如下专栏&#xff1a;打怪升级之路——C语言之路_ankleless的博客-CSDN博客 目录 1. 基本概念 1.1 数据 1.2 数据元素 1.3 数据项 1.4 组合项 1.5 数据对象 1.6 数据类型 2. 数据结构 2.1 逻辑结构 2.2 存储结构 2.3 数据的运算 在学…