面向大数据的海量、列式分布式存储系统
为什么需要它?它能解决什么痛点?以及典型的应用场景。
底层是怎么运转的?奇妙的“列式存储”数据模型解析。
不敲代码也能懂!提前解析 HBase 的“工作黑话”与指令逻辑。
在关系型数据库“吃不消”的时代,
HBase 是如何作为超级英雄登场的?
大家在之前学过 MySQL,它像是一个非常严谨的表格管理员。但是当面对真实世界的大数据时,它遇到了麻烦:
如果微信朋友圈要把全国人民(十几亿用户)每天发的状态都存下来,用传统的行列表格(MySQL)能存得下吗?查询快吗?
答案是:极其困难。我们需要一种全新的存储思路!
Hadoop Database的简称
HBase 是一个高可靠性、高性能、面向列、可伸缩的分布式存储系统。
它不擅长做复杂的逻辑运算,但它极其擅长“海量数据的快速存取”。
传统的数据库是“按行”存数据的。而 HBase 是“按列族”存储的。
HBase 运行在 Hadoop 集群之上。
| 特性 | MySQL (关系型) | HBase (NoSQL) |
|---|---|---|
| 数据规模 | 百万级 ~ 千万级 | 十亿级 ~ 百亿级 |
| 数据类型 | 丰富 (int, varchar, date...) | 统一为 Byte 字节数组 (纯粹) |
| 事务支持 | 强 (支持复杂多表事务) | 弱 (仅支持单行事务) |
| 表结构修改 | 困难,牵一发而动全身 | 极其灵活,随时增加列 |
百度的网页库。全网有成百上千亿个网页,每个网页有标题、正文、链接。
HBase 负责将这些海量网页快速存下来,供爬虫和检索调用。
全国的新能源汽车,每隔 5 秒钟就要向云端发送一次定位和电池温度数据。
数据源源不断,HBase 写入速度极快,且支持海量累加。
淘宝、抖音等 APP 会记录你每一个点击、停留时间。你的“标签”会不断增加。
HBase 灵活的“无结构列”,非常适合存储这种经常变化的画像标签。
理解一个技术的缺点,才能说明你真正懂它。遇到以下情况,千万别用 HBase:
在这个部分,我们要拆解 HBase 的“大脑”和“骨架”。
它是怎么把千亿级数据管理的井井有条的?
HBase 不是一个单一的软件,它是一个团队。我们可以把它想象成一个大型的物流仓库。
不直接干活,负责分配任务,监控各个小弟(机器)是否正常工作,管理表结构的修改。
真正干活的人。负责数据的读写、存储,直接和客户(客户端)进行对接。
维持集群稳定。如果某个工人罢工了,它会立刻通知主管。
刚才提到的 HRegionServer (工人) 虽然负责管理数据,但数据最终存放在哪里呢?
🖱️ 刮开查看答案是:Hadoop 的分布式文件系统 (HDFS)。
忘记你在 MySQL 里学到的那些死板的行和列。
欢迎来到 HBase 的立体数据世界!
它是数据行的唯一标识。就像咱们学生的“学号”,或者超市商品的“条形码”。
如果存入学号:202301, 202303, 202302,HBase 底层会自动排成:
(注:这种排序使得相似的数据放在一起,查询非常快。)
HBase 里面,不是所有的列都平铺在一起,而是把意思相近的列,打包放进一个“列族”中。
我们有一张“学生表”:
既然列族是“文件夹”,那么列限定符就是文件夹里面的“具体文件”(也就是我们常说的“列名”)。
在 HBase 中,定位一列必须带上列族的名字。格式为:
列族名 : 列限定符
base_info:name (基础信息里的姓名)score_info:math (成绩里的数学)与 MySQL 最大的不同点在于:
ALTER TABLE 修改全表的结构。score_info 列族里塞个 math,明天可以直接塞个 java,后天塞个 python,极其自由。这就叫“无模式”(Schema-less)的灵活性。
在 HBase 中,当你修改一个数据时,旧数据并不会立刻被覆盖消失!
HBase 会利用时间戳 (Timestamp) 将它们存为不同的“版本”。
在一个具体的单元格 (Cell) 中,数据其实是没有类型的,统统被视为字节数组 (Byte[])。
要精确找到某一个格子里的某个版本的数据,需要一套“四维坐标”:
[ Row Key, Column Family, Column Qualifier, Timestamp ]
(行键,列族,列名,时间戳) -> 唯一确定一个值!
看起来像一个有很多空洞的 Excel 表格。有的学生有 Java 成绩,有的没有,没有的地方看起来是空的 (Null)。
在底层硬盘上,HBase 是一种“稀疏”的存储。没有值的地方,根本就不占用空间!
这就是为什么它存几十亿条数据,哪怕有很多空白列,也不会浪费硬盘的原因。
怎么和 HBase 对话?
本节专注理解指令的逻辑,不涉及真机实操,掌握“沟通语法”即可。
就像在 Windows 里按 cmd 弹出的黑窗口一样,HBase 提供了一个 Shell 工具。
在 MySQL 中,我们会建很多个 Database (数据库) 来区分不同的项目,比如商城数据库、教务数据库。
在 HBase 中,没有 Database 这个词,取而代之的概念叫 Namespace (命名空间)。
hbase (系统表) 和 default (默认空间)。list_namespace
顾名思义,列出当前系统里有多少个“大文件夹”。
create_namespace 'ns1'
创建一个名叫 'ns1' 的新空间。注意要加单引号。
drop_namespace 'ns1'
注意:只有当命名空间里面是空的(没有表)时,才能被删除。
建表是存数据的第一步。
思考:在 HBase 中建表,最关键的要素是什么?
答案:表名 + 列族名
create '表名', '列族1', '列族2'...
案例解释:
假设我们要建一张学生表,包含基础信息和成绩信息两个列族:
create 'student', 'info', 'score'
注意:不需要像 MySQL 那样定义字段类型(int/varchar),只要定好列族即可!
list
这个命令会展示数据库中所有的表名,供你核对。
describe 'student'
或者简写为 desc 'student'
它会列出这个表的列族信息、版本数量限制、压缩方式等底层属性。
为了防止误删核心数据,HBase 规定:删除表之前,必须先让表“下线(停用)”。
(补充:如果想重新启用表,可以使用 enable 'student')
CRUD:Create(增), Read(查), Update(改), Delete(删)
让我们看看 HBase 是如何填装弹药的。
在 HBase 中,增加数据和修改数据使用的是同一个命令:put
逻辑是:如果这个位置没数据,就是新增;如果有数据,就用新的时间戳覆盖它(增加新版本)。
put '表名', 'RowKey', '列族:列名', '具体的值'
实战解释:给学号为 1001 的学生,添加名字叫张三。
put 'student', '1001', 'info:name', 'zhangsan'
注:HBase 每次 put 只能插入一个单元格(Cell)的数据。不能像 MySQL 一下子插一整行。
get 命令专门用于:已知 Row Key (行键),去获取这一行的数据。速度极快!
语法:
get '表名', 'RowKey'
示例:获取 1001 学生的全部信息
get 'student', '1001'
如果我们不知道 Row Key,或者想看全表的数据,就要用到 scan 扫描。
全表扫描(慎用,数据量大时会卡死):
scan 'student'
范围扫描(推荐):限制起止 RowKey
scan 'student', {STARTROW => '1001', STOPROW => '1005'}
(注:包含 STARTROW,但不包含 STOPROW,即左闭右开区间)
删除某个单元格(某一行中具体某一列)的数据。
delete '表', '行键', '列族:列'
例如:抹去 1001 学生的数学成绩。
直接把这一行(RowKey 对应的所有列族、所有列)全部干掉。
deleteall '表', '行键'
例如:1001 学生退学了,清空他的所有记录。
如果不能像 MySQL 那样写 WHERE age > 18,
HBase 怎么做复杂的条件查询?
HBase 默认只能通过 RowKey 搜索。如果我想找“所有姓张的学生”或者“成绩大于 90 分的学生”,怎么办?全表 scan 后拿到客户端再挑拣吗?
这样太耗费网络带宽了!
过滤器 (Filter) 就是 HBase 为了解决复杂查询发明的机制。它允许在服务端 (RegionServer) 提前按照条件把数据过滤好,只把符合要求的数据返回给客户端。
WHERE value = 'zhangsan'。今天我们学习了 HBase 的哪些核心心法?
理论知识需要沉淀,
下节课我们将进入机房进行实操演练。
Q & A 答疑时间