feat(hadoop): real Hive engine + filterable, detailed analytics with lineage

Deploys Apache Hive 3.1.3 (Derby metastore + external table over the HDFS
historical CSV, MapReduce exec) on the Hadoop master, so the engine comparison
shows a REAL measured Hive latency (~5.2s) next to live Trino (~0.3s); Impala
stays clearly-labelled representative. The API re-measures Hive over SSH on a
30-min TTL (cached + persisted, with a committed seed). Adds filters
(year/region/category/channel), a region×category heatmap, Trino exec stats,
and a "where is this data read from" lineage panel (Trino->S3/Iceberg/Parquet
with snapshot+files, Hive->HDFS/CSV with namenode+files). Mounts host SSH key
read-only into the api container for the live Hive benchmark.
This commit is contained in:
mo
2026-06-26 17:08:57 +00:00
parent 71a64d5a21
commit 96d490807a
7 changed files with 570 additions and 221 deletions
+36
View File
@@ -0,0 +1,36 @@
#!/bin/bash
# Real Hive benchmark on the HDFS historical dataset. Emits one JSON line.
# Retries because Hive's LocalJobRunner can flake on a cold first job.
export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk
export HIVE_HOME=/opt/hive
export HADOOP_HOME=/usr/lib/hadoop
export HADOOP_CONF_DIR=/opt/hive/hadoopconf
export HADOOP_USER_NAME=hdfs
export HADOOP_CLIENT_OPTS="-Xmx3g"
export PATH=$JAVA_HOME/bin:$HIVE_HOME/bin:$PATH
Q="SELECT region, round(sum(amount),2) AS revenue, count(*) AS n FROM lake.historical_sales GROUP BY region ORDER BY revenue DESC"
ISO=$(date -u +%Y-%m-%dT%H:%M:%SZ)
HSIZE=$(hdfs dfs -du -s /data/historical/sales_orders 2>/dev/null | awk '{print $1}'); [ -z "$HSIZE" ] && HSIZE=0
HFILES=$(hdfs dfs -ls -R /data/historical/sales_orders 2>/dev/null | grep -c "part-"); [ -z "$HFILES" ] && HFILES=0
ERR=$(mktemp); OUT=$(mktemp); RC=1; WALL=0; TT=0
for attempt in 1 2 3; do
T0=$(date +%s%3N)
$HIVE_HOME/bin/hive -e "$Q" >"$OUT" 2>"$ERR"
RC=$?
T1=$(date +%s%3N)
WALL=$((T1-T0))
if [ $RC -eq 0 ] && [ -s "$OUT" ]; then
TT=$(grep -oE "Time taken: [0-9.]+ seconds" "$ERR" | grep -oE "[0-9.]+" | sort -nr | head -1)
break
fi
sleep 2
done
[ -z "$TT" ] && TT=0
QMS=$(awk "BEGIN{printf \"%d\", $TT*1000}")
ROWS_JSON=$(awk -F'\t' 'NF>=3{printf "%s{\"region\":\"%s\",\"revenue\":%s,\"n\":%s}", (c++? ",":""), $1,$2,$3}' "$OUT")
cat <<JSON
{"engine":"Hive","ok":$([ $RC -eq 0 ] && echo true || echo false),"attempts":$attempt,"version":"3.1.3","exec":"MapReduce (local)","storage":"HDFS · CSV (TEXTFILE)","table":"lake.historical_sales","hdfs_location":"hdfs://atc-hadoop-m01:8020/data/historical/sales_orders","hdfs_size_bytes":$HSIZE,"hdfs_files":$HFILES,"query":"$Q","query_time_ms":$QMS,"wall_ms":$WALL,"rows":25000,"measured_at":"$ISO","by_region":[${ROWS_JSON}]}
JSON
rm -f "$ERR" "$OUT"
+59
View File
@@ -0,0 +1,59 @@
#!/bin/bash
set -e
export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk
export HIVE_HOME=/opt/hive
# Bigtop hadoop: pick a HADOOP_HOME that contains bin/hadoop
if [ -x /usr/lib/hadoop/bin/hadoop ]; then export HADOOP_HOME=/usr/lib/hadoop; else export HADOOP_HOME=/usr; fi
export HADOOP_CONF_DIR=/etc/hadoop/conf
export PATH=$JAVA_HOME/bin:$HIVE_HOME/bin:$PATH
echo "JAVA_HOME=$JAVA_HOME HADOOP_HOME=$HADOOP_HOME"
echo "=== guava fix ==="
rm -f /opt/hive/lib/guava-19.0.jar
cp -f /usr/lib/hadoop/lib/guava-27.0-jre.jar /opt/hive/lib/ 2>/dev/null || cp -f /usr/lib/hadoop/client/guava-27.0-jre.jar /opt/hive/lib/
ls /opt/hive/lib/guava-*.jar
echo "=== hive-site.xml ==="
cat > /opt/hive/conf/hive-site.xml <<'XML'
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
<property><name>javax.jdo.option.ConnectionURL</name><value>jdbc:derby:;databaseName=/opt/hive/metastore_db;create=true</value></property>
<property><name>javax.jdo.option.ConnectionDriverName</name><value>org.apache.derby.jdbc.EmbeddedDriver</value></property>
<property><name>hive.metastore.warehouse.dir</name><value>/user/hive/warehouse</value></property>
<property><name>hive.execution.engine</name><value>mr</value></property>
<property><name>mapreduce.framework.name</name><value>local</value></property>
<property><name>hive.exec.mode.local.auto</name><value>true</value></property>
<property><name>hive.exec.submitviachild</name><value>false</value></property>
<property><name>hive.metastore.schema.verification</name><value>false</value></property>
<property><name>datanucleus.schema.autoCreateAll</name><value>true</value></property>
<property><name>hive.server2.enable.doAs</name><value>false</value></property>
<property><name>hive.stats.autogather</name><value>false</value></property>
<property><name>hive.metastore.event.db.notification.api.auth</name><value>false</value></property>
</configuration>
XML
cat > /opt/hive/conf/hive-env.sh <<ENV
export JAVA_HOME=$JAVA_HOME
export HADOOP_HOME=$HADOOP_HOME
export HADOOP_CONF_DIR=$HADOOP_CONF_DIR
export HIVE_HOME=$HIVE_HOME
ENV
# reusable wrapper for running hive non-interactively
cat > /opt/hive/runhive.sh <<WRAP
#!/bin/bash
export JAVA_HOME=$JAVA_HOME
export HIVE_HOME=$HIVE_HOME
export HADOOP_HOME=$HADOOP_HOME
export HADOOP_CONF_DIR=$HADOOP_CONF_DIR
export HADOOP_CLIENT_OPTS="-Xmx2g \$HADOOP_CLIENT_OPTS"
export PATH=\$JAVA_HOME/bin:\$HIVE_HOME/bin:\$PATH
exec hive "\$@"
WRAP
chmod +x /opt/hive/runhive.sh
echo "=== init derby metastore schema ==="
rm -rf /opt/hive/metastore_db
cd /opt/hive
$HIVE_HOME/bin/schematool -dbType derby -initSchema >/tmp/schematool.log 2>&1 && echo "schema init OK" || { echo "schema init FAILED"; tail -25 /tmp/schematool.log; exit 1; }