1. 首页 > Hadoop教程 > 正文

大数据教程FG085-HBase项目实战案例

本文档风哥主要介绍HBase项目实战案例,包括用户行为分析、订单系统等实际应用场景,风哥教程参考HBase官方文档Architecture、Performance等内容,适合大数据开发运维人员在学习和测试中使用,如果要应用于生产环境则需要自行确认。更多视频教程www.fgedu.net.cn

Part01-基础概念与理论知识

1.1 项目概述

HBase项目实战案例涵盖用户行为分析、订单系统、实时推荐等典型应用场景。学习交流加群风哥微信: itpux-com

HBase典型应用场景:

  • 用户行为分析:存储和分析用户行为数据
  • 订单系统:海量订单数据存储和查询
  • 实时推荐:用户画像和推荐数据
  • 物联网数据:传感器数据存储和分析
# 项目背景

某电商平台需要构建大数据平台,主要需求:
1. 用户行为数据存储和分析
2. 订单数据实时查询
3. 用户画像和推荐
4. 数据量:日增10亿条,总量100TB

# 技术选型

1. 数据存储:HBase 2.5.5
– 海量数据存储
– 实时读写
– 高可用

2. 数据处理:Spark 3.5.0
– 批量处理
– 实时处理
– 机器学习

3. 数据采集:Kafka + Flume
– 实时采集
– 消息队列

4. 数据查询:Phoenix
– SQL查询
– 二级索引

# 系统架构

┌─────────────────────────────────────────────┐
│ 应用层 │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ 行为分析 │ │ 订单查询 │ │ 推荐系统 │ │
│ └────┬────┘ └────┬────┘ └────┬────┘ │
└───────┼────────────┼────────────┼───────────┘
│ │ │
┌───────┼────────────┼────────────┼───────────┐
│ │ 数据处理层 │ │
│ ┌────┴────┐ ┌────┴────┐ ┌────┴────┐ │
│ │ Spark │ │ Spark │ │ Spark │ │
│ │ Streaming│ │ SQL │ │ MLlib │ │
│ └────┬────┘ └────┬────┘ └────┬────┘ │
└───────┼────────────┼────────────┼───────────┘
│ │ │
┌───────┼────────────┼────────────┼───────────┐
│ │ 数据存储层 │ │
│ ┌────┴────────────┴────────────┴────┐ │
│ │ HBase Cluster │ │
│ │ ┌─────────┐ ┌─────────┐ │ │
│ │ │行为表 │ │订单表 │ │ │
│ │ └─────────┘ └─────────┘ │ │
│ └───────────────────────────────────┘ │
└─────────────────────────────────────────────┘

# 数据流

1. 用户行为数据流
用户操作 -> 前端埋点 -> Kafka -> Spark Streaming -> HBase

2. 订单数据流
订单系统 -> Kafka -> Spark -> HBase

3. 推荐数据流
HBase -> Spark MLlib -> 推荐结果 -> HBase

# 项目目标

1. 性能目标
– 写入性能:10万条/秒
– 查询延迟:< 100ms - 系统可用性:99.99% 2. 容量目标 - 数据存储:100TB - 日增量:1TB - 保留周期:1年

1.2 架构设计

架构设计详解:

# HBase集群架构

1. Master节点(2个)
– Active Master
– Standby Master
– 高可用配置

2. RegionServer节点(10个)
– 数据存储
– 读写服务
– 负载均衡

3. ZooKeeper节点(3个)
– 协调服务
– Master选举
– 元数据管理

# 集群配置

节点类型 数量 配置
Master 2 16C/32G/500G SSD
RegionServer 10 32C/128G/10T HDD
ZooKeeper 3 8C/16G/100G SSD

# 网络架构

┌─────────────────────────────────────┐
│ 业务网络 (10.0.0.0/16) │
├─────────────────────────────────────┤
│ 管理网络 (172.16.0.0/24) │
└─────────────────────────────────────┘

# 存储架构

1. HDFS存储
– 副本数:3
– 块大小:128MB
– 存储策略:HOT

2. HBase存储
– MemStore:512MB
– BlockCache:4GB
– Compaction:自动

# 高可用设计

1. Master高可用
– Active/Standby模式
– ZooKeeper选举
– 自动故障转移

2. RegionServer高可用
– 数据多副本
– 自动Region迁移
– WAL日志

3. 数据高可用
– HDFS副本
– WAL日志
– 快照备份

# 容灾设计

1. 同城容灾
– 主备集群
– 异步复制
– RPO: 5分钟

2. 异地容灾
– 异地主备
– 定时同步
– RPO: 1小时

1.3 数据模型设计

数据模型设计详解:

# 用户行为表设计

表名:fgedu_user_behavior

RowKey设计:
格式:用户ID_时间戳_行为类型
示例:user_00000001_1680940800000_view

列族设计:
info:
– user_id: 用户ID
– action: 行为类型(view/click/buy)
– item_id: 商品ID
– action_time: 行为时间
– platform: 平台(app/web)
– device: 设备信息

detail:
– duration: 停留时长
– referer: 来源页面
– extra: 扩展信息

建表语句:
create ‘fgedu_user_behavior’,
{NAME => ‘info’, VERSIONS => 1, COMPRESSION => ‘SNAPPY’, TTL => 31536000},
{NAME => ‘detail’, VERSIONS => 1, COMPRESSION => ‘SNAPPY’, TTL => 31536000},
SPLITS => [’10’, ’20’, ’30’, ’40’, ’50’, ’60’, ’70’, ’80’, ’90’]

# 订单表设计

表名:fgedu_order

RowKey设计:
格式:订单ID
示例:order_20260408000001

列族设计:
info:
– order_id: 订单ID
– user_id: 用户ID
– order_time: 下单时间
– status: 订单状态
– total_amount: 总金额

items:
– item_id: 商品ID
– item_name: 商品名称
– quantity: 数量
– price: 单价

payment:
– pay_method: 支付方式
– pay_time: 支付时间
– pay_status: 支付状态

建表语句:
create ‘fgedu_order’,
{NAME => ‘info’, VERSIONS => 1, COMPRESSION => ‘SNAPPY’},
{NAME => ‘items’, VERSIONS => 3, COMPRESSION => ‘SNAPPY’},
{NAME => ‘payment’, VERSIONS => 1, COMPRESSION => ‘SNAPPY’},
SPLITS => [‘order_202601’, ‘order_202602’, ‘order_202603’, ‘order_202604’]

# 用户画像表设计

表名:fgedu_user_profile

RowKey设计:
格式:用户ID
示例:user_00000001

列族设计:
basic:
– user_id: 用户ID
– name: 姓名
– age: 年龄
– gender: 性别
– city: 城市

preference:
– category: 偏好品类
– brand: 偏好品牌
– price_range: 价格偏好

behavior:
– active_time: 活跃时间
– buy_count: 购买次数
– total_amount: 总消费

建表语句:
create ‘fgedu_user_profile’,
{NAME => ‘basic’, VERSIONS => 1, COMPRESSION => ‘SNAPPY’},
{NAME => ‘preference’, VERSIONS => 1, COMPRESSION => ‘SNAPPY’},
{NAME => ‘behavior’, VERSIONS => 1, COMPRESSION => ‘SNAPPY’},
SPLITS => [‘user_20000000’, ‘user_40000000’, ‘user_60000000’, ‘user_80000000’]

# RowKey设计原则

1. 唯一性:RowKey必须唯一
2. 散列性:避免热点问题
3. 长度:建议10-50字节
4. 有序性:支持范围查询

# 预分区策略

1. 根据数据量预估Region数量
Region数 = 数据量 / Region大小(10GB)

2. 设计RowKey前缀
使用散列前缀避免热点

3. 创建预分区
create ‘table’, ‘cf’, SPLITS => [’10’, ’20’, …]

风哥提示:HBase项目设计需要充分考虑业务需求和数据特点。RowKey设计是关键,需要平衡查询效率和负载均衡。

Part02-生产环境规划与建议

2.1 环境规划建议

环境规划建议:

# 硬件规划

1. Master节点
CPU: 16核
内存: 32GB
磁盘: 500GB SSD
网络: 万兆网卡

数量: 2台
角色: Active/Standby

2. RegionServer节点
CPU: 32核
内存: 128GB
磁盘: 10TB HDD (数据盘)
500GB SSD (系统盘)
网络: 万兆网卡

数量: 10台
角色: 数据存储

3. ZooKeeper节点
CPU: 8核
内存: 16GB
磁盘: 100GB SSD
网络: 万兆网卡

数量: 3台
角色: 协调服务

# 软件规划

组件 版本 用途
Hadoop 3.3.6 HDFS存储
HBase 2.5.5 数据存储
ZooKeeper 3.8.3 协调服务
Spark 3.5.0 数据处理
Kafka 3.6.0 消息队列
Phoenix 5.2.0 SQL查询

# 操作系统规划

系统: Oracle Linux 9.3
内核: 5.15.x
文件系统: XFS

# 网络规划

网络类型 网段 用途
业务网络 10.0.0.0/16 业务访问
管理网络 172.16.0.0/24 管理访问

# 存储规划

存储类型 大小 用途
系统盘 500GB 操作系统
数据盘 10TB HBase数据
日志盘 1TB 日志存储

# JVM规划

组件 堆内存 元空间
Master 4GB 512MB
RegionServer 32GB 1GB
ZooKeeper 2GB 256MB

# 配置参数

hbase-site.xml关键配置: hbase.regionserver.handler.count
200
hbase.hregion.memstore.flush.size
536870912
hfile.block.cache.size
0.4

2.2 容量规划建议

容量规划建议:

# 数据量评估

1. 用户行为数据
日增量: 10亿条
单条大小: 500字节
日增量大小: 500GB
年增量: 180TB

2. 订单数据
日增量: 1000万条
单条大小: 1KB
日增量大小: 10GB
年增量: 3.6TB

3. 用户画像数据
总量: 1亿用户
单条大小: 2KB
总大小: 200GB

# 存储容量计算

1. 原始数据量
用户行为: 180TB/年
订单数据: 3.6TB/年
用户画像: 200GB
总计: 183.8TB

2. HDFS存储(3副本)
183.8TB × 3 = 551.4TB

3. 考虑压缩(SNAPPY压缩比0.3)
551.4TB × 0.3 = 165.4TB

4. 预留空间(30%)
165.4TB / 0.7 = 236.3TB

5. 实际需求
约250TB存储空间

# RegionServer容量

1. 单节点存储
10TB磁盘 × 10节点 = 100TB
考虑副本: 100TB / 3 = 33TB有效存储

2. 需要节点数
250TB / 33TB = 8节点
预留: 10节点

# 内存容量

1. RegionServer内存
MemStore: 32GB × 0.4 = 12.8GB
BlockCache: 32GB × 0.4 = 12.8GB
其他: 6.4GB

2. 总内存需求
10节点 × 32GB = 320GB

# Region数量规划

1. 单Region大小
推荐: 10-20GB

2. Region数量
用户行为: 180TB / 10GB = 18000个Region
订单数据: 3.6TB / 10GB = 360个Region
用户画像: 200GB / 10GB = 20个Region

3. 单节点Region数
18380 / 10 = 1838个Region/节点

# 带宽规划

1. 写入带宽
日增量: 500GB
峰值写入: 500GB / 8小时 = 62.5GB/小时
峰值带宽: 62.5GB × 8 / 3600 = 138MB/s

2. 读取带宽
预估: 写入的2倍
峰值带宽: 276MB/s

3. 网络需求
万兆网卡: 1.25GB/s
满足需求

2.3 性能规划建议

性能规划建议:

# 性能目标

指标 目标值
写入吞吐量 10万条/秒
读取延迟(P99) < 100ms 扫描延迟(1000条) < 500ms 系统可用性 99.99% # 写入性能优化 1. 批量写入 - 使用批量Put - 批量大小: 100-1000条 2. 预分区 - 避免热点 - 均匀分布Region 3. MemStore调优 - 增大MemStore - 调整刷写阈值 4. WAL优化 - 异步WAL - 批量提交 # 读取性能优化 1. BlockCache - 增大BlockCache - 使用LRU策略 2. BloomFilter - 启用行级布隆过滤器 - 减少磁盘IO 3. Scan优化 - 设置缓存大小 - 使用过滤器 - 指定列 4. 并发查询 - 多线程查询 - 异步查询 # 配置优化 # RegionServer配置 hbase.regionserver.handler.count=200 hbase.regionserver.metahandler.count=50 # MemStore配置 hbase.hregion.memstore.flush.size=536870912 hbase.regionserver.global.memstore.size=0.4 hbase.regionserver.global.memstore.size.lower.limit=0.95 # BlockCache配置 hfile.block.cache.size=0.4 hbase.block.cache.size=0.4 # Compaction配置 hbase.hstore.compaction.min=3 hbase.hstore.compaction.max=10 hbase.hstore.compaction.max.size=21474836480 # 性能监控 监控项 告警阈值 RegionServer CPU > 80%
RegionServer 内存 > 85%
请求延迟(P99) > 200ms
请求失败率 > 0.1%

生产环境建议:生产环境需要根据实际业务需求进行容量和性能规划。建议预留30%的资源和性能冗余。学习交流加群风哥QQ113257174

Part03-生产环境项目实施方案

3.1 表设计实战

3.1.1 创建用户行为表

# 1. 设计RowKey
RowKey格式:MD5(用户ID).substring(0,4) + 用户ID + 时间戳 + 行为类型
示例:a1b2_user_00000001_1680940800000_view

# 2. 创建表
$ hbase shell

hbase(main):001:0> create ‘fgedu_user_behavior’,
{NAME => ‘info’, VERSIONS => 1, COMPRESSION => ‘SNAPPY’,
TTL => 31536000, BLOOMFILTER => ‘ROW’},
{NAME => ‘detail’, VERSIONS => 1, COMPRESSION => ‘SNAPPY’,
TTL => 31536000, BLOOMFILTER => ‘ROW’},
SPLITS => [‘1’, ‘2’, ‘3’, ‘4’, ‘5’, ‘6’, ‘7’, ‘8’, ‘9’, ‘a’, ‘b’, ‘c’, ‘d’, ‘e’, ‘f’]

Created table fgedu_user_behavior

# 3. 验证表结构
hbase(main):002:0> describe ‘fgedu_user_behavior’

Table fgedu_user_behavior is ENABLED
fgedu_user_behavior
COLUMN FAMILIES DESCRIPTION
{NAME => ‘detail’, BLOOMFILTER => ‘ROW’, COMPRESSION => ‘SNAPPY’, TTL => ‘31536000’, …}
{NAME => ‘info’, BLOOMFILTER => ‘ROW’, COMPRESSION => ‘SNAPPY’, TTL => ‘31536000’, …}
2 row(s)

# 4. 查看Region分布
hbase(main):003:0> get_splits ‘fgedu_user_behavior’

Total number of splits = 16

# 5. 插入测试数据
hbase(main):004:0> put ‘fgedu_user_behavior’,
‘a1b2_user_00000001_1680940800000_view’,
‘info:user_id’, ‘user_00000001’

Took 0.0123 seconds.

hbase(main):005:0> put ‘fgedu_user_behavior’,
‘a1b2_user_00000001_1680940800000_view’,
‘info:action’, ‘view’

Took 0.0123 seconds.

hbase(main):006:0> put ‘fgedu_user_behavior’,
‘a1b2_user_00000001_1680940800000_view’,
‘info:item_id’, ‘item_000001’

Took 0.0123 seconds.

hbase(main):007:0> put ‘fgedu_user_behavior’,
‘a1b2_user_00000001_1680940800000_view’,
‘info:action_time’, ‘2026-04-08 15:00:00’

Took 0.0123 seconds.

# 6. 查询数据
hbase(main):008:0> get ‘fgedu_user_behavior’,
‘a1b2_user_00000001_1680940800000_view’

COLUMN CELL
info:action timestamp=1680940800001, value=view
info:action_time timestamp=1680940800003, value=2026-04-08 15:00:00
info:item_id timestamp=1680940800002, value=item_000001
info:user_id timestamp=1680940800000, value=user_00000001
1 row(s)

# 7. 扫描数据
hbase(main):009:0> scan ‘fgedu_user_behavior’,
{STARTROW => ‘a1b2_user_00000001’, STOPROW => ‘a1b2_user_00000002’}

ROW COLUMN+CELL
a1b2_user_00000001_16809 column=info:action, timestamp=1680940800001, value=view
40800000_view column=info:action_time, timestamp=1680940800003, value=2026-04-08 15:00:00
column=info:item_id, timestamp=1680940800002, value=item_000001
column=info:user_id, timestamp=1680940800000, value=user_00000001
1 row(s)

3.1.2 创建订单表

# 1. 创建订单表
$ hbase shell

hbase(main):010:0> create ‘fgedu_order’,
{NAME => ‘info’, VERSIONS => 1, COMPRESSION => ‘SNAPPY’, BLOOMFILTER => ‘ROW’},
{NAME => ‘items’, VERSIONS => 3, COMPRESSION => ‘SNAPPY’, BLOOMFILTER => ‘ROW’},
{NAME => ‘payment’, VERSIONS => 1, COMPRESSION => ‘SNAPPY’, BLOOMFILTER => ‘ROW’},
SPLITS => [‘order_202601’, ‘order_202602’, ‘order_202603’, ‘order_202604’,
‘order_202605’, ‘order_202606’, ‘order_202607’, ‘order_202608’,
‘order_202609’, ‘order_202610’, ‘order_202611’, ‘order_202612’]

Created table fgedu_order

# 2. 插入订单数据
hbase(main):011:0> put ‘fgedu_order’, ‘order_20260408000001’, ‘info:order_id’, ‘order_20260408000001’

Took 0.0123 seconds.

hbase(main):012:0> put ‘fgedu_order’, ‘order_20260408000001’, ‘info:user_id’, ‘user_00000001’

Took 0.0123 seconds.

hbase(main):013:0> put ‘fgedu_order’, ‘order_20260408000001’, ‘info:order_time’, ‘2026-04-08 15:00:00’

Took 0.0123 seconds.

hbase(main):014:0> put ‘fgedu_order’, ‘order_20260408000001’, ‘info:status’, ‘paid’

Took 0.0123 seconds.

hbase(main):015:0> put ‘fgedu_order’, ‘order_20260408000001’, ‘info:total_amount’, ‘299.00’

Took 0.0123 seconds.

hbase(main):016:0> put ‘fgedu_order’, ‘order_20260408000001’, ‘items:item_001’, ‘item_000001:1:199.00’

Took 0.0123 seconds.

hbase(main):017:0> put ‘fgedu_order’, ‘order_20260408000001’, ‘items:item_002’, ‘item_000002:1:100.00’

Took 0.0123 seconds.

hbase(main):018:0> put ‘fgedu_order’, ‘order_20260408000001’, ‘payment:pay_method’, ‘alipay’

Took 0.0123 seconds.

hbase(main):019:0> put ‘fgedu_order’, ‘order_20260408000001’, ‘payment:pay_time’, ‘2026-04-08 15:01:00’

Took 0.0123 seconds.

# 3. 查询订单
hbase(main):020:0> get ‘fgedu_order’, ‘order_20260408000001’

COLUMN CELL
info:order_id timestamp=1680940800000, value=order_20260408000001
info:order_time timestamp=1680940800002, value=2026-04-08 15:00:00
info:status timestamp=1680940800003, value=paid
info:total_amount timestamp=1680940800004, value=299.00
info:user_id timestamp=1680940800001, value=user_00000001
items:item_001 timestamp=1680940800005, value=item_000001:1:199.00
items:item_002 timestamp=1680940800006, value=item_000002:1:100.00
payment:pay_method timestamp=1680940800007, value=alipay
payment:pay_time timestamp=1680940800008, value=2026-04-08 15:01:00
1 row(s)

# 4. 查询指定列族
hbase(main):021:0> get ‘fgedu_order’, ‘order_20260408000001’, {COLUMN => ‘info’}

COLUMN CELL
info:order_id timestamp=1680940800000, value=order_20260408000001
info:order_time timestamp=1680940800002, value=2026-04-08 15:00:00
info:status timestamp=1680940800003, value=paid
info:total_amount timestamp=1680940800004, value=299.00
info:user_id timestamp=1680940800001, value=user_00000001
1 row(s)

3.2 数据导入实战

# 1. 批量导入脚本
$ cat > /tmp/import_user_behavior.sh << 'EOF' #!/bin/bash # import_user_behavior.sh # from:www.itpux.com.qq113257174.wx:itpux-com # web: http://www.fgedu.net.cn TABLE="fgedu_user_behavior" DATA_FILE="/data/user_behavior.csv" echo "导入数据到表: $TABLE" echo "数据文件: $DATA_FILE" # 生成HBase Put命令 awk -F',' '{ user_id=$1 action=$2 item_id=$3 action_time=$4 # 生成RowKey md5_hash=substr(md5(user_id), 0, 4) rowkey=md5_hash "_" user_id "_" action_time "_" action print "put '\''" TABLE "'\'' , '\''" rowkey "'\'' , '\''info:user_id'\'', '\''" user_id "'\''" print "put '\''" TABLE "'\'' , '\''" rowkey "'\'' , '\''info:action'\'', '\''" action "'\''" print "put '\''" TABLE "'\'' , '\''" rowkey "'\'' , '\''info:item_id'\'', '\''" item_id "'\''" print "put '\''" TABLE "'\'' , '\''" rowkey "'\'' , '\''info:action_time'\'', '\''" action_time "'\''" }' $DATA_FILE > /tmp/hbase_import.txt

# 执行导入
hbase shell /tmp/hbase_import.txt

echo “导入完成”
EOF

$ chmod +x /tmp/import_user_behavior.sh

# 2. 使用Bulk Load导入
$ cat > /tmp/bulk_import.scala << 'EOF' // bulk_import.scala // from:www.itpux.com.qq113257174.wx:itpux-com // web: http://www.fgedu.net.cn import org.apache.spark.sql.SparkSession import org.apache.hadoop.hbase.HBaseConfiguration import org.apache.hadoop.hbase.client.{Put, ConnectionFactory} import org.apache.hadoop.hbase.TableName import org.apache.hadoop.hbase.util.Bytes import org.apache.hadoop.hbase.io.ImmutableBytesWritable import org.apache.hadoop.hbase.mapreduce.HFileOutputFormat2 val spark = SparkSession.builder().appName("BulkImport").getOrCreate() // 读取CSV数据 val df = spark.read .option("header", "true") .csv("/data/user_behavior.csv") // 转换为HFile格式 val hfileRDD = df.rdd.map { row =>
val userId = row.getAs[String](“user_id”)
val action = row.getAs[String](“action”)
val itemId = row.getAs[String](“item_id”)
val actionTime = row.getAs[String](“action_time”)

// 生成RowKey
val md5Hash = md5(userId).substring(0, 4)
val rowkey = s”${md5Hash}_${userId}_${actionTime}_${action}”

val put = new Put(Bytes.toBytes(rowkey))
put.addColumn(Bytes.toBytes(“info”), Bytes.toBytes(“user_id”), Bytes.toBytes(userId))
put.addColumn(Bytes.toBytes(“info”), Bytes.toBytes(“action”), Bytes.toBytes(action))
put.addColumn(Bytes.toBytes(“info”), Bytes.toBytes(“item_id”), Bytes.toBytes(itemId))
put.addColumn(Bytes.toBytes(“info”), Bytes.toBytes(“action_time”), Bytes.toBytes(actionTime))

(new ImmutableBytesWritable(Bytes.toBytes(rowkey)), put)
}

// 保存HFile
val conf = HBaseConfiguration.create()
val connection = ConnectionFactory.createConnection(conf)
val table = connection.getTable(TableName.valueOf(“fgedu_user_behavior”))
val regionLocator = connection.getRegionLocator(TableName.valueOf(“fgedu_user_behavior”))

hfileRDD.saveAsNewAPIHadoopFile(
“/tmp/hfiles/user_behavior”,
classOf[ImmutableBytesWritable],
classOf[Put],
classOf[HFileOutputFormat2],
conf
)

spark.stop()
EOF

# 3. 执行Bulk Load
$ spark-shell -i /tmp/bulk_import.scala

$ hbase org.apache.hadoop.hbase.mapreduce.LoadIncrementalHFiles \
/tmp/hfiles/user_behavior \
fgedu_user_behavior

# 4. 验证导入数据
$ hbase shell

hbase(main):022:0> count ‘fgedu_user_behavior’

1000000 row(s)

3.3 查询优化实战

# 1. 使用过滤器查询
$ hbase shell

hbase(main):023:0> import org.apache.hadoop.hbase.filter.PrefixFilter

hbase(main):024:0> scan ‘fgedu_user_behavior’,
{FILTER => “PrefixFilter(‘a1b2_user_00000001’)”}

ROW COLUMN+CELL
a1b2_user_00000001_16809 column=info:action, timestamp=1680940800001, value=view
40800000_view …
1 row(s)

# 2. 使用列过滤器
hbase(main):025:0> scan ‘fgedu_user_behavior’,
{COLUMNS => [‘info:user_id’, ‘info:action’], LIMIT => 10}

ROW COLUMN+CELL
a1b2_user_00000001_16809 column=info:action, timestamp=1680940800001, value=view
40800000_view column=info:user_id, timestamp=1680940800000, value=user_00000001
1 row(s)

# 3. 使用时间范围查询
hbase(main):026:0> scan ‘fgedu_user_behavior’,
{TIMERANGE => [1680940800000, 1681027200000], LIMIT => 10}

# 4. 使用PageFilter分页
hbase(main):027:0> import org.apache.hadoop.hbase.filter.PageFilter

hbase(main):028:0> scan ‘fgedu_user_behavior’,
{FILTER => “PageFilter(100)”}

# 5. 使用Phoenix SQL查询
$ phoenix-sqlline.py fgedu-node1:2181:/hbase

0: jdbc:phoenix:fgedu-node1:2181:/hbase> CREATE TABLE IF NOT EXISTS fgedu_user_behavior (
. . . . . . . . . . . . . . . . . . .> rowkey VARCHAR PRIMARY KEY,
. . . . . . . . . . . . . . . . . . .> info.user_id VARCHAR,
. . . . . . . . . . . . . . . . . . .> info.action VARCHAR,
. . . . . . . . . . . . . . . . . . .> info.item_id VARCHAR,
. . . . . . . . . . . . . . . . . . .> info.action_time VARCHAR
. . . . . . . . . . . . . . . . . . .> ) COLUMN_ENCODED_BYTES=0;

No rows affected (1.234 seconds)

0: jdbc:phoenix:fgedu-node1:2181:/hbase> SELECT COUNT(*) FROM fgedu_user_behavior;

+———–+
| COUNT(1) |
+———–+
| 1000000 |
+———–+
1 row selected (0.567 seconds)

0: jdbc:phoenix:fgedu-node1:2181:/hbase> SELECT user_id, action, COUNT(*)
. . . . . . . . . . . . . . . . . . .> FROM fgedu_user_behavior
. . . . . . . . . . . . . . . . . . .> GROUP BY user_id, action
. . . . . . . . . . . . . . . . . . .> LIMIT 10;

+————-+———+———–+
| USER_ID | ACTION | COUNT(1) |
+————-+———+———–+
| user_000001 | view | 156 |
| user_000001 | click | 89 |
| user_000001 | buy | 23 |
+————-+———+———–+
3 rows selected (1.234 seconds)

# 6. 创建二级索引
0: jdbc:phoenix:fgedu-node1:2181:/hbase> CREATE INDEX idx_user_id
. . . . . . . . . . . . . . . . . . .> ON fgedu_user_behavior(info.user_id);

No rows affected (5.678 seconds)

0: jdbc:phoenix:fgedu-node1:2181:/hbase> SELECT * FROM fgedu_user_behavior
. . . . . . . . . . . . . . . . . . .> WHERE info.user_id = ‘user_00000001’;

+——————————————+————-+———+————-+—————-+
| ROWKEY | USER_ID | ACTION | ITEM_ID | ACTION_TIME |
+——————————————+————-+———+————-+—————-+
| a1b2_user_00000001_1680940800000_view | user_00000001| view | item_000001 | 2026-04-08 15:00|
+——————————————+————-+———+————-+—————-+
1 row selected (0.123 seconds)

风哥提示:HBase项目实战需要充分考虑表设计、数据导入和查询优化。使用Phoenix可以简化SQL查询,创建二级索引可以提高查询性能。更多学习教程公众号风哥教程itpux_com

Part04-生产案例与实战讲解

4.1 用户行为分析案例

# 场景:分析用户行为数据

# 1. 统计用户行为类型分布
$ phoenix-sqlline.py fgedu-node1:2181:/hbase

0: jdbc:phoenix:fgedu-node1:2181:/hbase> SELECT info.action, COUNT(*) as cnt
. . . . . . . . . . . . . . . . . . .> FROM fgedu_user_behavior
. . . . . . . . . . . . . . . . . . .> GROUP BY info.action
. . . . . . . . . . . . . . . . . . .> ORDER BY cnt DESC;

+———+———–+
| ACTION | CNT |
+———+———–+
| view | 500000 |
| click | 300000 |
| buy | 100000 |
| cart | 80000 |
| share | 20000 |
+———+———–+
5 rows selected (2.345 seconds)

# 2. 统计用户活跃度
0: jdbc:phoenix:fgedu-node1:2181:/hbase> SELECT info.user_id, COUNT(*) as action_count
. . . . . . . . . . . . . . . . . . .> FROM fgedu_user_behavior
. . . . . . . . . . . . . . . . . . .> GROUP BY info.user_id
. . . . . . . . . . . . . . . . . . .> ORDER BY action_count DESC
. . . . . . . . . . . . . . . . . . .> LIMIT 10;

+————-+—————+
| USER_ID | ACTION_COUNT |
+————-+—————+
| user_000001 | 256 |
| user_000002 | 234 |
| user_000003 | 212 |
| user_000004 | 198 |
| user_000005 | 187 |
+————-+—————+
5 rows selected (3.456 seconds)

# 3. 分析用户行为漏斗
$ cat > /tmp/funnel_analysis.scala << 'EOF' // funnel_analysis.scala // from:www.itpux.com.qq113257174.wx:itpux-com // web: http://www.fgedu.net.cn import org.apache.spark.sql.SparkSession val spark = SparkSession.builder() .appName("FunnelAnalysis") .enableHiveSupport() .getOrCreate() import spark.implicits._ // 读取HBase数据 val behaviorDF = spark.read .format("jdbc") .option("url", "jdbc:phoenix:fgedu-node1:2181:/hbase") .option("dbtable", "FGEDU_USER_BEHAVIOR") .load() // 创建临时视图 behaviorDF.createOrReplaceTempView("user_behavior") // 漏斗分析 val funnelDF = spark.sql(""" SELECT COUNT(DISTINCT CASE WHEN action = 'view' THEN user_id END) as view_users, COUNT(DISTINCT CASE WHEN action = 'click' THEN user_id END) as click_users, COUNT(DISTINCT CASE WHEN action = 'cart' THEN user_id END) as cart_users, COUNT(DISTINCT CASE WHEN action = 'buy' THEN user_id END) as buy_users FROM user_behavior """) funnelDF.show() // 计算转化率 val conversionDF = spark.sql(""" SELECT 'view->click’ as stage,
COUNT(DISTINCT CASE WHEN action = ‘click’ THEN user_id END) * 100.0 /
COUNT(DISTINCT CASE WHEN action = ‘view’ THEN user_id END) as conversion_rate
FROM user_behavior
UNION ALL
SELECT
‘click->cart’ as stage,
COUNT(DISTINCT CASE WHEN action = ‘cart’ THEN user_id END) * 100.0 /
COUNT(DISTINCT CASE WHEN action = ‘click’ THEN user_id END) as conversion_rate
FROM user_behavior
UNION ALL
SELECT
‘cart->buy’ as stage,
COUNT(DISTINCT CASE WHEN action = ‘buy’ THEN user_id END) * 100.0 /
COUNT(DISTINCT CASE WHEN action = ‘cart’ THEN user_id END) as conversion_rate
FROM user_behavior
“””)

conversionDF.show()

spark.stop()
EOF

$ spark-shell -i /tmp/funnel_analysis.scala

+———-+———–+———-+———+
|view_users|click_users|cart_users|buy_users|
+———-+———–+———-+———+
| 100000| 60000| 20000| 10000|
+———-+———–+———-+———+

+————+——————+
| stage| conversion_rate |
+————+——————+
|view->click| 60.0|
| click->cart|33.33333333333333|
| cart->buy| 50.0|
+————+——————+

4.2 订单系统案例

# 场景:订单查询和分析

# 1. 查询用户订单
$ hbase shell

hbase(main):029:0> import org.apache.hadoop.hbase.filter.SingleColumnValueFilter
hbase(main):030:0> import org.apache.hadoop.hbase.filter.CompareFilter

hbase(main):031:0> scan ‘fgedu_order’,
{FILTER => “SingleColumnValueFilter(‘info’, ‘user_id’, =, ‘binary:user_00000001’)”}

# 2. 统计订单状态分布
$ phoenix-sqlline.py fgedu-node1:2181:/hbase

0: jdbc:phoenix:fgedu-node1:2181:/hbase> SELECT info.status, COUNT(*) as cnt
. . . . . . . . . . . . . . . . . . .> FROM fgedu_order
. . . . . . . . . . . . . . . . . . .> GROUP BY info.status
. . . . . . . . . . . . . . . . . . .> ORDER BY cnt DESC;

+———+———–+
| STATUS | CNT |
+———+———–+
| paid | 50000 |
| shipped | 30000 |
| pending | 15000 |
| completed| 4000 |
| cancelled| 1000 |
+———+———–+
5 rows selected (1.234 seconds)

# 3. 订单金额分析
0: jdbc:phoenix:fgedu-node1:2181:/hbase> SELECT
. . . . . . . . . . . . . . . . . . .> CASE
. . . . . . . . . . . . . . . . . . .> WHEN CAST(info.total_amount AS DECIMAL) < 100 THEN '0-100' . . . . . . . . . . . . . . . . . . .> WHEN CAST(info.total_amount AS DECIMAL) < 500 THEN '100-500' . . . . . . . . . . . . . . . . . . .> WHEN CAST(info.total_amount AS DECIMAL) < 1000 THEN '500-1000' . . . . . . . . . . . . . . . . . . .> ELSE ‘1000+’
. . . . . . . . . . . . . . . . . . .> END as amount_range,
. . . . . . . . . . . . . . . . . . .> COUNT(*) as cnt
. . . . . . . . . . . . . . . . . . .> FROM fgedu_order
. . . . . . . . . . . . . . . . . . .> GROUP BY
. . . . . . . . . . . . . . . . . . .> CASE
. . . . . . . . . . . . . . . . . . .> WHEN CAST(info.total_amount AS DECIMAL) < 100 THEN '0-100' . . . . . . . . . . . . . . . . . . .> WHEN CAST(info.total_amount AS DECIMAL) < 500 THEN '100-500' . . . . . . . . . . . . . . . . . . .> WHEN CAST(info.total_amount AS DECIMAL) < 1000 THEN '500-1000' . . . . . . . . . . . . . . . . . . .> ELSE ‘1000+’
. . . . . . . . . . . . . . . . . . .> END;

+————–+———–+
|AMOUNT_RANGE | CNT |
+————–+———–+
| 0-100 | 30000 |
| 100-500 | 40000 |
| 500-1000 | 20000 |
| 1000+ | 10000 |
+————–+———–+
4 rows selected (2.345 seconds)

# 4. 实时订单监控
$ cat > /tmp/order_monitor.sh << 'EOF' #!/bin/bash # order_monitor.sh # from:www.itpux.com.qq113257174.wx:itpux-com # web: http://www.fgedu.net.cn while true; do echo "=== 订单监控 $(date) ===" # 获取今日订单数 TODAY=$(date +%Y%m%d) ORDER_COUNT=$(echo "SELECT COUNT(*) FROM fgedu_order WHERE rowkey LIKE 'order_${TODAY}%'" | phoenix-sqlline.py fgedu-node1:2181:/hbase 2>/dev/null | grep -E “^[0-9]+$”)

echo “今日订单数: $ORDER_COUNT”

# 获取待处理订单数
PENDING_COUNT=$(echo “SELECT COUNT(*) FROM fgedu_order WHERE info.status = ‘pending'” |
phoenix-sqlline.py fgedu-node1:2181:/hbase 2>/dev/null | grep -E “^[0-9]+$”)

echo “待处理订单数: $PENDING_COUNT”

sleep 60
done
EOF

$ chmod +x /tmp/order_monitor.sh
$ /tmp/order_monitor.sh

=== 订单监控 2026年 04月 08日 15:00:00 CST ===
今日订单数: 1234
待处理订单数: 56

4.3 常见问题处理

4.3.1 热点问题

# 问题现象:Region热点

# 排查步骤
# 1. 查看Region分布
$ hbase shell

hbase(main):032:0> describe ‘fgedu_user_behavior’

# 2. 查看RegionServer负载
hbase(main):033:0> status ‘detailed’

# 解决方案
# 1. 优化RowKey设计
– 使用散列前缀
– 避免时间戳开头

# 2. 预分区
hbase(main):034:0> disable ‘fgedu_user_behavior’
hbase(main):035:0> split ‘fgedu_user_behavior’, ‘a1b2_user_50000000’

# 3. Region迁移
hbase(main):036:0> move ‘region_hash’, ‘fgedu-node2’

4.3.2 性能问题

# 问题现象:查询慢

# 排查步骤
# 1. 查看慢查询日志
$ grep “SlowQuery” /bigdata/logs/hbase/hbase.log

# 2. 查看RegionServer状态
$ hbase shell

hbase(main):037:0> status ‘simple’

# 解决方案
# 1. 优化Scan参数
scan ‘table’, {CACHING => 1000, BATCH => 100}

# 2. 使用过滤器
scan ‘table’, {FILTER => “PrefixFilter(‘prefix’)”}

# 3. 创建二级索引
CREATE INDEX idx_column ON table(cf:column)

Part05-风哥经验总结与分享

5.1 项目最佳实践

HBase项目最佳实践建议:

# 项目最佳实践
1. 合理设计RowKey
2. 预分区避免热点
3. 选择合适的压缩算法
4. 配置合理的参数
5. 监控和优化

5.2 优化建议

优化建议:

HBase项目优化建议:

  • RowKey设计要考虑查询模式
  • 使用预分区避免热点
  • 合理配置MemStore和BlockCache
  • 使用Phoenix简化SQL查询

5.3 工具推荐

项目工具:

  • Phoenix:SQL查询
  • Spark:数据处理
  • Kafka:数据采集
  • Grafana:监控可视化
风哥提示:HBase项目实战需要结合业务需求进行合理设计。RowKey设计是关键,需要平衡查询效率和负载均衡。建议使用Phoenix简化SQL查询,创建二级索引提高查询性能。from bigdata视频:www.itpux.com

本文由风哥教程整理发布,仅用于学习测试使用,转载注明出处:http://www.fgedu.net.cn/10327.html

联系我们

在线咨询:点击这里给我发消息

微信号:itpux-com

工作日:9:30-18:30,节假日休息