多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

300节点大数据平台验收:TPC-DS、性能压测与量收迁移拆解

300节点大数据平台验收:TPC-DS、性能压测与量收迁移拆解 简介这份2021年XXX大数据平台系统测试报告以PDF形式呈现面向大数据平台建设方、测试工程师、架构师及项目验收人员用于评估平台在性能、可靠性与数据迁移方面的表现并为优化改进提供依据。文件共1个PDF约2.12MB已有414人学习下载。报告目录结构完整依次覆盖性能测试报告、TPC-DS测试报告、量收迁移验证性测试报告及某银行性能测试报告每一模块均从测试目标、测试内容、测试环境、测试过程和结果展开其中迁移部分还细化到串行执行、并行执行、生产表数据规模与测试结果。读者可据此了解大数据平台基准测试的设计思路、负载场景、指标口径与验证流程快速对照自身项目查漏补缺也可作为测试方案编写、验收汇报和平台选型阶段的参考材料对提升系统稳定性与数据安全可靠性具有实际价值。1. 一份300节点的验收报告为什么值得逐页拆日均上网记录近10亿条、每月新增数据近9TB、HDFS已经压了10.5PB还维持3副本——这几个数字摆在一起做数据平台的人都会停一下。这份《2021年XXX大数据平台系统测试报告(完整版).pdf》记录的就是一套运营商手机上网记录查询系统的验收过程300多台服务器、278个DataNode、3台NameNode、7台Zookeeper测试项覆盖性能压测、TPC-DS标准基准、量收系统迁移验证三大块。它适合两类人翻。一类是正准备给自家平台做上线验收需要一份能直接抄的测试项清单和指标口径定义另一类是把 pdf 文档当二手资料用想搞清楚 TPC-DS 到底怎么跑、并发查询这类指标怎么定义才算数。报告是 pdf 格式、目录层级清楚但真正值钱的不是目录是每一节里那些表名、条数、并发数和耗时——这些才是能拿去横向比对的锚点。围绕「这是什么 / 怎么做 / 参数怎么设 / 坑在哪」下面按验收链条一层层拆开。2. 集群配置与三类查询压测性能测试怎么落地运营商上网记录这类业务单表就是几十亿行单日新增日志 21TB 量级传统关系库在这个容量上做全表关联基本没有讨论价值。所以性能测试的第一步不是写 SQL而是先把「存储节点数和存储量」「并发加载效率」「并发查询能力」这三个待验证命题拆成可测量的动作再对应到集群角色上去。2.1 节点角色拆分与硬件基线报告里的部署方式是典型的存算合一 Hadoop 集群角色划分和硬件配置如下表。角色节点数作用NameNode3元数据高可用DataNode278数据存储与本地计算Zookeeper7选主与分布式协调集群监控1指标采集与告警入库服务24数据加载通道Web 查询应用20对外查询入口单机硬件是两路 6 核 E5-2620、64GB ECC DDR3、2 块 600G SAS 做 RAID1 当系统盘、12 块 2TB SATA 7200RPM 不做 RAID 当数据盘、双电口万兆网卡。这套配置放到今天看核心数偏少但它说明了两个关键点数据盘刻意不做 RAID是为了让 HDFS 的三副本机制自己承担可靠性避免 RAID 写惩罚拖慢顺序吞吐把系统盘和数据盘物理分开是为了防止 NameNode 元数据写入和数据块 IO 互相抢盘。注意报告里 HDFS 已有 10.5PB、3 副本、压缩率约 1/3反推实际 HBase 表数据约 3.5PB。做容量规划时必须用「原始数据量 × 副本数 × 压缩率」这条链算而不是只看压缩后的数字。2.2 三类查询场景的口径定义性能测试选了三个由简到繁的场景这个梯度设计本身就是方法论简单点查验证索引和 Region 定位能力单表统计验证聚合扫描能力大表关联验证 Shuffle 与 Join 策略。场景一的短信话单查询目标表CDR_GSM_13有 31.1 亿行。-- 场景一按用户ID点查话单验证 RowKey 定位效率 SELECT * FROM CDR_GSM_13 WHERE USER_ID ?;USER_ID作为过滤条件能否走前缀取决于建表时 RowKey 的设计。如果 RowKey 是USER_ID 时间戳的组合这类查询就是一次连续区间扫描延迟能压到毫秒级如果USER_ID只是普通列就会退化成全表扫。场景二和场景三是统计类查询跨CDR_GSM_1331.1亿行与cdr_gsm_stat4.3亿行两张表关联。-- 场景二/三统计某天某客户的通话次数大表关联聚合 SELECT count(*) FROM CDR_GSM_13 C, cdr_gsm_stat G WHERE C.user_id G.user_id AND G.type 1 AND G.date 20151212 AND G.user_id ?;这段 SQL 有个地方要留神原始报告里场景二和场景三给出的语句几乎一模一样只有场景说明不同。实际落地时场景三的「统计指定用户的上网记录」应该关联的是上网记录表而不是话单表测试前一定要按业务把语句改对否则跑出来的并发和延迟数据没有参考意义。2.3 并发加载与查询压测的执行方式测试结果里最亮眼的两个数是并发加载平均 1500 万条/秒、峰值 5000 万条/秒并发查询支持 10 万 请求/秒点查平均延迟 3msAPI和 12msSQL。这类指标不能只信结论得知道怎么复现。常见做法是用多进程或协程模拟并发固定数据集、固定并发梯度、记录 P95 而不是平均值。import time, threading, statistics from concurrent.futures import ThreadPoolExecutor def query_once(conn, user_id): 单次点查返回耗时(ms) start time.perf_counter() cur conn.cursor() cur.execute(SELECT * FROM CDR_GSM_13 WHERE USER_ID %s, (user_id,)) cur.fetchall() cur.close() return (time.perf_counter() - start) * 1000 def run_concurrency(conn, user_ids, workers): 按指定并发梯度压测输出延迟分位数 latencies [] with ThreadPoolExecutor(max_workersworkers) as pool: futures [pool.submit(query_once, conn, uid) for uid in user_ids] for f in futures: latencies.append(f.result()) latencies.sort() p95 latencies[int(len(latencies) * 0.95)] return statistics.mean(latencies), p95 # 并发梯度从 100 逐级升到 5000观察拐点 for w in (100, 500, 1000, 5000): avg, p95 run_concurrency(conn, sample_user_ids, w) print(fworkers{w} avg{avg:.1f}ms p95{p95:.1f}ms)这段脚本的关键参数有三个。workers是并发梯度逐级升高才能找到吞吐量拐点而不是一上来就飙到 5000。user_ids必须和线上分布一致如果全挑热点用户Region 命中集中延迟会虚低。返回用statistics.mean加 P95 双指标平均值掩盖长尾P95 才能反映真实体感。压测前还要确认客户端本身不是瓶颈3000 并发下压测机的网卡和连接池很容易先崩这时测出来的是客户端上限不是集群上限。3. TPC-DS 99条查询的跑法与结果判定性能测试验证的是「快不快」TPC-DS 验证的是「对不对、稳不稳」。它是事务性能管理委员会发布的数仓评测基准含 7 张事实表、17 张维表平均每张表 18 列覆盖 SQL99 和 SQL2003 的核心语法以及 OLAP 能力共 99 条查询。选它而不是 TPC-H核心原因是它的数据分布带倾斜、查询复杂、几乎每条都有高 IO 和 CPU 需求更贴近真实数仓。3.1 数据生成规模因子决定一切TPC-DS 的数据由官方工具dsdgen生成规模由-SCALE参数控制单位是 GB。# 生成 1000GB1TB规模数据集按并行分片输出 mkdir -p /data/tpcds/1t for i in $(seq 1 32); do dsdgen \ -SCALE 1000 \ -DIR /data/tpcds/1t \ -TERMINATE N \ -PARALLEL 32 \ -CHILD $i \ -FORCE Y done wait # 生成 99 条查询语句指定目标方言 dsqgen \ -DIRECTORY ../query_templates \ -INPUT ../query_templates/templates.lst \ -DIALECT netezza \ -OUTPUT_DIR /data/tpcds/queries \ -SCALE 1000 \ -VERBOSE Y-SCALE是规模因子1000 对应约 1TB 原始数据测试前要和集群容量对齐别把 10TB 规模跑在只有 1TB 空间的集群上。-PARALLEL 32 -CHILD $i是把生成任务拆成 32 个分片并行i从 1 到 32 逐一传给子进程大幅缩短生成时间。-DIALECT决定生成的 SQL 方言不同引擎的语法细节如日期函数、窗口函数写法差异很大选错方言会导致大量语法报错通常先挑一个最接近的方言再人工微调。-TERMINATE N表示每个分片输出不带结束符方便后续合并。3.2 执行与结果判定99 条查询建议按 Power Test单并发顺序跑和 Throughput Test多流并发跑两阶段做。阶段并发观察指标Power Test1单条查询耗时、是否报错Throughput TestN 流总吞吐、流间干扰判定时容易踩三个坑。第一99 条查询里有若干条在单机部署下天然超时做硬件验收时要和基准方约定「剔除哪几条、剔除理由是什么」不能跑挂了就说引擎不行。第二数据倾斜会让个别查询成为长尾比如store_sales表某些维度值极度集中这时要看的是 99 条的完成率和 P95而不是掐头去尾后的平均。第三结果正确性必须校验TPC-DS 自带 99 条查询的答案集用 diff 比对行数和关键聚合值引擎优化器一旦下推错了谓词性能可能反而更好看——那是错得好看。提示跑 TPC-DS 前把数据本地化率和 Shuffle 参数调好默认配置下大数据集的 Shuffle 溢出会非常严重测出来的耗时主要来自磁盘而非计算。4. 量收迁移验证串行并行对比与 Oracle 存储过程改写性能好不好是一回事老系统能不能平滑搬过来是另一回事。量收迁移验证性测试测的就是后者选六个典型场景验证原有量收系统在目标平台上的功能和性能是否等效。这六个方向分别是范围段加载 ETL、收入宽表计算 ETL、量收日统计表查询、Cognos 复杂报表、大表 update/delete 计算、Oracle 存储过程运算。4.1 生产表规模先盘清楚迁移前必须先把源端表规模摸清否则并行度设多少、资源怎么分配全是拍脑袋。报告里部分生产表的记录数如下。表名记录数tb_peo_postcollpric237,097,843tb_peo_postderatepric18,352,483tb_peo_postderate17,841,320tb_prt_custlevel6,267,607tb_fct_sum_det_p_m5,792,946tb_cde_prictyp43tb_cde_custsett6最大的表 2.37 亿行最小的维度表只有 6 行跨度达七个数量级。这种分布决定了 ETL 不能一把梭大表要按分区字段切片并行小维表直接广播。下面这条查询用来盘点规模和空表。-- 盘点表行数识别空表和超大表决定并行切片策略 SELECT table_name, num_rows, ROUND(num_rows / 1000000.0, 2) AS rows_million FROM all_tables WHERE owner PIMS_PDATA ORDER BY num_rows DESC;num_rows来自统计信息如果统计信息过期数值会严重失真。迁移前务必先做一次全库统计信息收集再拿这份清单去定并行度。清单里那些 0 行的表如pro_cgnos_log_r、tb_fct_vip_range_m要么是结果表要么是视图对应的空壳迁移脚本里要单独标注别浪费集群资源去跑。4.2 串行与并行执行的耗时对比同一个批次六个脚本串行跑和并行跑的耗时对比如下。脚本串行耗时(s)并行耗时(s)变化FWDJZETL.SQL39444312.4%SRKBETL.SQL35039011.4%YYKHSJJZETL.SQL657413.8%DWJCX.SQL253228.0%LSRTJBCX.SQL5620.0%ORACLE_STOREPROCEDURE.SQL2350.0%这组数据很有意思并行总耗时并没有因为并发而下降反而每个任务都变慢了。原因不难想——六个任务同时抢占集群的 CPU 和 IO资源争用导致单任务延迟上升总吞吐的收益被抵消。这说明并行度不是越高越好正确做法是按任务资源画像分组把 IO 密集的 ETL 错峰调度CPU 密集的报表查询单独拉一个队列。报告里串行窗口加起来约 14 分钟并行窗口约 15 分钟两者接近恰恰说明当时集群资源对这六个任务来说是够用的并行只是缩短了调度等待没有缩短执行本身。4.3 Oracle 存储过程的兼容性检查最容易出问题的就是存储过程。报告给出了一个明确结论六个案例包括存储过程案例脚本修改量小于 1% 就能在新环境直接运行且结果正确。要把这个结论落到工程上需要一套可重复的检查流程。# 1. 抽取源端存储过程定义 sqlplus -S user/passorcl EOF SET LONG 1000000 PAGESIZE 0 SELECT DBMS_METADATA.GET_DDL(PROCEDURE, object_name, owner) FROM all_procedures WHERE owner PIMS_PDATA AND procedure_name IS NULL; EXIT EOF # 2. 逐个搬迁并跑等价性校验对比新旧系统同一批次的输出 hive -e SELECT COUNT(*), SUM(amount) FROM pims_pdata.tb_sum_dppt new.txt cat oracle_expected.txt diff (awk {print $1} new.txt) (awk {print $1} oracle_expected.txt) echo 行数一致第一步用DBMS_METADATA.GET_DDL批量导出存储过程 DDLSET LONG必须调大否则长的过程定义会被截断。第二步是关键不要只看脚本能不能跑通要拿同一批输入分别在新旧系统跑比对照表行数和关键聚合值。COUNT(*)对行数SUM(amount)对金额两者都对上才叫等价。很多迁移失败案例不是语法不兼容而是循环里的隐式类型转换、日期格式处理在两边语义不同跑得通但数字对不上这种最难查。注意tb_prt_cporgmgtlevvw这类对象是视图而非物理表迁移脚本里要按视图重建直接当表导出会导致依赖失效。5. 从PDF报告里挖指标的验证方法报告给的是结论但结论能不能信、和自家环境差多少得自己算一遍。这里有个实用技巧把 pdf 文档里的表格批量化提出来做成可对比的结构化数据而不是靠肉眼一行行看。import pdfplumber import pandas as pd def extract_tables(pdf_path, pages): 从指定页码范围提取表格并合并 tables [] with pdfplumber.open(pdf_path) as pdf: for p in pages: page pdf.pages[p] for tbl in page.extract_tables(): if tbl and len(tbl) 1: df pd.DataFrame(tbl[1:], columnstbl[0]) tables.append(df) return pd.concat(tables, ignore_indexTrue) # 提取性能测试结果表重点看表名、条数、并发、延迟 df extract_tables(bigdata_test_report.pdf, range(7, 14)) df df.dropna(howall).drop_duplicates() df.to_csv(perf_metrics.csv, indexFalse)pages参数要按报告实际页码给pdf 阅读器里看到的页码常和 pdfplumber 的零基索引差一位先拿一两页试抽确认。extract_tables对规整的网格线表格效果好遇到合并单元格或无线表格会串列这时改用camelot的flavorstream更稳。抽出来之后统一转成 csv就能做交叉验证拿「HDFS 已用 10.5PB × 压缩率 1/3 ÷ 3 副本」反推实际数据量看是否和报告里 HBase 表数据量的说法自洽拿 TPC-DS 的-SCALE反查测试数据总量是否和集群剩余空间匹配。更进一步的用法是横向比对。同一份报告里性能测试的点查延迟是 3msAPI和 12msSQL量收迁移里最小的脚本耗时 2 秒——这两个数量级差了三档说明 API 路径绕过了 SQL 解析和优化器而 ETL 类任务开销主要在调度和 IO。把这个差值记下来就能估算自家平台如果只做点查和如果做批处理分别该按什么量级设 SLA。真正吃透一份 pdf 文档不是把结论抄进 PPT而是把每个数字拆到能复现的粒度再拿自家集群跑一遍对得上号。本文还有配套的精品资源点击获取
返回列表