大数据-36 HBase 增删改查 列族详解 实测

点一下关注吧!!!非常感谢!!持续更新!!!

🚀 AI篇持续更新中!(长期更新)

AI炼丹日志-29 - 字节跳动 DeerFlow 深度研究框斜体样式架 私有部署 测试上手 架构研究,持续打造实用AI工具指南!📐🤖

💻 Java篇正式开启!(300篇)

目前2025年07月10日更新到: Java-68 深入浅出 分布式服务 Netty实现自定义RPC 附详细代码 MyBatis 已完结,Spring 已完结,Nginx已完结,Tomcat已完结,分布式服务正在更新!深入浅出助你打牢基础!

📊 大数据板块已完成多项干货更新(300篇):

包括 Hadoop、Hive、Kafka、Flink、ClickHouse、Elasticsearch 等二十余项核心组件,覆盖离线+实时数仓全栈! 大数据-278 Spark MLib - 基础介绍 机器学习算法 梯度提升树 GBDT案例 详解

章节内容

上一节我们完成了:

  • 集群的分发和配置
  • 集群的启动测试
  • HBaseShell的简单测试

背景介绍

这里是三台公网云服务器,每台 2C4G,搭建一个Hadoop的学习环境,供我学习。

  • 2C4G 编号 h121
  • 2C4G 编号 h122
  • 2C2G 编号 h123

列族

在 HBase 中,列(Column) = 列族名:列限定符。

  • 列族(CF)是物理存储的最小单位;同一列族内的所有数据按行键排序后 顺序写入同一个 HFile block 中,享受相同的压缩、Bloom Filter、TTL 等存储策略。
  • 列限定符(Qualifier)只在逻辑层面区分列,不会触发新的磁盘 seek。

直观地说:列族像「文件夹」,列限定符像「文件」。

列族数量的抉择

越少越好

越少越好 -- 每个列族对应一组 MemStore ➜ flush ➜ HFile;过多列族 = 过多 WAL flush & compaction,I/O 震荡。

典型实践

  • base :核心列(主索引、元数据)
  • detail:低频、大字段(描述、日志)
  • stat :可异步批量写入的派生指标

拆分依据

  • 不同 生命周期/TTL
  • 不同 压缩比/访问模式
  • 是否 需要 BloomFilter / BlockCache

设计示例

shell 复制代码
create 'user_profile',
  {NAME => 'base',   COMPRESSION => 'LZ4',  BLOCKSIZE => '65536', TTL => 31536000},
  {NAME => 'detail', COMPRESSION => 'ZSTD', BLOCKSIZE => '131072', TTL => 7776000, BLOCKCACHE => 'false'},
  {NAME => 'stat',   COMPRESSION => 'LZ4',  BLOOMFILTER => 'ROW',  VERSIONS => 5}
  • 行键:uid#timestamp,使同一用户的新旧记录局部聚簇。
  • base 存 id、注册信息,读写频繁 ➜ LZ4、缓存开启。
  • detail 存大 JSON、头像等低频字段 ➜ 关闭缓存,采用高压缩。
  • stat 存计数器,允许多版本做时间序列分析。

性能与维护要点

  • 避免在列族间跨越事务:HBase 的原子性仅局限于「同一行、同一列族」。
  • 变更列族 = 变更磁盘布局
  • 新列族马上生效,但历史数据仍在旧文件里;
  • 剔除列族需先 disable ➜ drop,并跑 major compaction 回收空间。
  • 每列族数据独立 flush;确保 MemStore 上限×列族数 < 总可用内存。
  • 多 RegionServer 升级:先扩容 Region 数,再逐台迁移 --- 列族多会放大 Region 数;务必监控 storeFileCount 和 compactionQueueSize。
  • HBCK2 检查:列族级别损坏最常见是 HFile 遗失、列族目录权限不一致。定期执行 hdfs fsck & hbck2 report.

启动Shell

上一节已经启动过了,这里为了完整性,也再写一次

shell 复制代码
hbase shell

创建新表

创建新表:表名、字段、字段

shell 复制代码
create 'wzk', 'base_info', 'extra_info'

插入数据

列族 name

  • 写入一条数据到 wzk 表
  • row key 为 rk1
  • base_info添加name列标示符值为 icu

我们执行下面的指令:

shell 复制代码
put 'wzk', 'rk1', 'base_info:name', 'icu'

列族 age

我们在 base_info 列中加入一个字段叫:age

shell 复制代码
put 'wzk', 'rk1', 'base_info:age', 30

多插入几条,这里是三条:

列族 addr

  • 写入一条数据到 wzk 表
  • row key 为 rk1
  • extra_info添加address列标识符值为 Qingdao
shell 复制代码
put 'wzk', 'rk1', 'extra_info:address', 'Qingdao'

也是多插入几条数据,这里也是三条:

查询数据

根据 RowKey

查询的条件:表名、RowKey

shell 复制代码
get 'wzk', 'rk1'

执行后,可以看到我们刚才写入的数据如下:

列族查询

通过 RowKey 查询 base_info 列族的信息:

shell 复制代码
get 'wzk', 'rk1', 'base_info'

查询的结果如下:

列族name和age

通过 RowKey 查询 base_info 列族中的 name 和 age列

shell 复制代码
get 'wzk', 'rk1', 'base_info:name', 'base_info:age'

查询的结果如下:

多个列族

我们可以多加条件来实现多个列族的查询:

shell 复制代码
get 'wzk', 'rk1', 'base_info', 'extra_info'

查询的结果如下:

条件过滤

这里使用的是 ValueFilter 我们使用的条件是 查询 当中有 "icu" 内容数据

shell 复制代码
get 'wzk', 'rk1', {FILTER => "ValueFilter(=, 'binary:icu')"}

查询出来的结果如下图:

更新数据

通过 RowKey 更新数据,更新 base_info 列族中的name为kang

shell 复制代码
put 'wzk', 'rk1', 'base_info:name', 'kang'

更新的结果如下图:

删除数据

shell 复制代码
delete 'wzk', 'rk1', 'base_info:name'

删除列族

shell 复制代码
alter 'wzk', 'delete' => 'base_info'

清空数据

shell 复制代码
truncate 'wzk'

删除表

shell 复制代码
disable 'wzk'
drop 'wzk'
相关推荐
天南星14 分钟前
java-WebSocket在Java生态中的发展历程
java·后端·websocket
朴拙数科28 分钟前
在 macOS 上安装与自定义 Oh My Zsh:让终端美观又高效 [特殊字符]
大数据·elasticsearch·macos
工藤学编程39 分钟前
分库分表之实战-sharding-JDBC绑定表配置实战
数据库·分布式·后端·sql·mysql
fmvrj342021 小时前
云原生:数字化转型的核心引擎
后端
码出极致1 小时前
Redisson分布式缓存与数据一致性保障
后端
用户790349033711 小时前
springboot集成redisson实现redis分布式锁
后端
陈随易1 小时前
程序员的新玩具,MoonBit(月兔)编程语言科普
前端·后端·程序员
码出极致1 小时前
Redisson秒杀系统中的分布式锁应用
后端
xiaok2 小时前
@Param注解的作用
java·后端
Sperains2 小时前
async/await和Synchronous的区别
后端