-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy path54180c33.html
More file actions
482 lines (365 loc) · 42.1 KB
/
54180c33.html
File metadata and controls
482 lines (365 loc) · 42.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width">
<meta name="theme-color" content="#222"><meta name="generator" content="Hexo 6.3.0">
<link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
<link rel="icon" type="image/png" sizes="32x32" href="/images/favicon.png">
<link rel="icon" type="image/png" sizes="16x16" href="/images/favicon.png">
<link rel="mask-icon" href="/images/logo.svg" color="#222">
<link rel="stylesheet" href="/css/main.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" integrity="sha256-HtsXJanqjKTc8vVQjO4YMhiqFoXkfBsjBWcX91T1jr8=" crossorigin="anonymous">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.1.1/animate.min.css" integrity="sha256-PR7ttpcvz8qrF57fur/yAx1qXMFJeJFiA6pSzWi0OIE=" crossorigin="anonymous">
<script class="next-config" data-name="main" type="application/json">{"hostname":"tallate.github.io","root":"/","images":"/images","scheme":"Gemini","darkmode":false,"version":"8.18.0","exturl":false,"sidebar":{"position":"left","display":"post","padding":18,"offset":12},"copycode":{"enable":false,"style":null},"fold":{"enable":false,"height":500},"bookmark":{"enable":false,"color":"#222","save":"auto"},"mediumzoom":false,"lazyload":false,"pangu":false,"comments":{"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},"stickytabs":false,"motion":{"enable":true,"async":false,"transition":{"menu_item":"fadeInDown","post_block":"fadeIn","post_header":"fadeInDown","post_body":"fadeInDown","coll_header":"fadeInLeft","sidebar":"fadeInUp"}},"prism":false,"i18n":{"placeholder":"搜索...","empty":"没有找到任何搜索结果:${query}","hits_time":"找到 ${hits} 个搜索结果(用时 ${time} 毫秒)","hits":"找到 ${hits} 个搜索结果"}}</script><script src="/js/config.js"></script>
<meta name="description" content="为什么使用HBaseHBase是开源版的BigTable。 高性能的列式存储 高可靠的弹性伸缩 HBase VS RDBMS(传统关系数据库) 数据类型RDBMS:关系模型,丰富的数据类型和存储方式HBase存的数据都是字符串,用户根据自己的需要解析字符串 数据操作RDBMS:丰富的CRUD操作,多表连接HBase:不存在复杂的表与表之间的关系,只有简单的插入、查询、删除、清空等 存储模式RD">
<meta property="og:type" content="article">
<meta property="og:title" content="HBase总结">
<meta property="og:url" content="https://tallate.github.io/54180c33.html">
<meta property="og:site_name" content="Tallate">
<meta property="og:description" content="为什么使用HBaseHBase是开源版的BigTable。 高性能的列式存储 高可靠的弹性伸缩 HBase VS RDBMS(传统关系数据库) 数据类型RDBMS:关系模型,丰富的数据类型和存储方式HBase存的数据都是字符串,用户根据自己的需要解析字符串 数据操作RDBMS:丰富的CRUD操作,多表连接HBase:不存在复杂的表与表之间的关系,只有简单的插入、查询、删除、清空等 存储模式RD">
<meta property="og:locale" content="zh_CN">
<meta property="og:image" content="https://tallate.github.io/imgs/Hadoop/HBase%E7%B3%BB%E7%BB%9F%E6%9E%B6%E6%9E%84.jpg">
<meta property="og:image" content="https://tallate.github.io/imgs/Hadoop/HBase%E5%85%83%E6%95%B0%E6%8D%AE%E7%9A%84%E4%B8%89%E5%B1%82%E7%BB%93%E6%9E%84.png">
<meta property="og:image" content="https://tallate.github.io/imgs/Hadoop/Region%E5%AD%98%E5%82%A8%E7%BB%93%E6%9E%84.png">
<meta property="og:image" content="https://tallate.github.io/imgs/Hadoop/StoreFile%E7%9A%84%E5%90%88%E5%B9%B6%E5%92%8C%E5%88%86%E8%A3%82.png">
<meta property="article:published_time" content="2021-07-18T08:26:49.000Z">
<meta property="article:modified_time" content="2025-07-06T17:56:20.884Z">
<meta property="article:author" content="tallate">
<meta property="article:tag" content="Hadoop">
<meta property="article:tag" content="HBase">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="https://tallate.github.io/imgs/Hadoop/HBase%E7%B3%BB%E7%BB%9F%E6%9E%B6%E6%9E%84.jpg">
<link rel="canonical" href="https://tallate.github.io/54180c33.html">
<script class="next-config" data-name="page" type="application/json">{"sidebar":"","isHome":false,"isPost":true,"lang":"zh-CN","comments":true,"permalink":"https://tallate.github.io/54180c33.html","path":"/54180c33.html","title":"HBase总结"}</script>
<script class="next-config" data-name="calendar" type="application/json">""</script>
<title>HBase总结 | Tallate</title>
<noscript>
<link rel="stylesheet" href="/css/noscript.css">
</noscript>
</head>
<body itemscope itemtype="http://schema.org/WebPage" class="use-motion">
<div class="headband"></div>
<main class="main">
<div class="column">
<header class="header" itemscope itemtype="http://schema.org/WPHeader"><div class="site-brand-container">
<div class="site-nav-toggle">
<div class="toggle" aria-label="切换导航栏" role="button">
<span class="toggle-line"></span>
<span class="toggle-line"></span>
<span class="toggle-line"></span>
</div>
</div>
<div class="site-meta">
<a href="/" class="brand" rel="start">
<i class="logo-line"></i>
<p class="site-title">Tallate</p>
<i class="logo-line"></i>
</a>
<p class="site-subtitle" itemprop="description">该吃吃该喝喝 啥事别往心里搁</p>
</div>
<div class="site-nav-right">
<div class="toggle popup-trigger" aria-label="搜索" role="button">
<i class="fa fa-search fa-fw fa-lg"></i>
</div>
</div>
</div>
<nav class="site-nav">
<ul class="main-menu menu"><li class="menu-item menu-item-home"><a href="/" rel="section"><i class="home fa-fw"></i>首页</a></li><li class="menu-item menu-item-about"><a href="/about/" rel="section"><i class="user fa-fw"></i>关于</a></li><li class="menu-item menu-item-tags"><a href="/tags/" rel="section"><i class="tags fa-fw"></i>标签<span class="badge">84</span></a></li><li class="menu-item menu-item-categories"><a href="/categories/" rel="section"><i class="th fa-fw"></i>分类<span class="badge">25</span></a></li><li class="menu-item menu-item-archives"><a href="/archives/" rel="section"><i class="archive fa-fw"></i>归档<span class="badge">192</span></a></li>
<li class="menu-item menu-item-search">
<a role="button" class="popup-trigger"><i class="fa fa-search fa-fw"></i>搜索
</a>
</li>
</ul>
</nav>
<div class="search-pop-overlay">
<div class="popup search-popup"><div class="search-header">
<span class="search-icon">
<i class="fa fa-search"></i>
</span>
<div class="search-input-container">
<input autocomplete="off" autocapitalize="off" maxlength="80"
placeholder="搜索..." spellcheck="false"
type="search" class="search-input">
</div>
<span class="popup-btn-close" role="button">
<i class="fa fa-times-circle"></i>
</span>
</div>
<div class="search-result-container no-result">
<div class="search-result-icon">
<i class="fa fa-spinner fa-pulse fa-5x"></i>
</div>
</div>
</div>
</div>
</header>
<aside class="sidebar">
<div class="sidebar-inner sidebar-nav-active sidebar-toc-active">
<ul class="sidebar-nav">
<li class="sidebar-nav-toc">
文章目录
</li>
<li class="sidebar-nav-overview">
站点概览
</li>
</ul>
<div class="sidebar-panel-container">
<!--noindex-->
<div class="post-toc-wrap sidebar-panel">
<div class="post-toc animated"><ol class="nav"><li class="nav-item nav-level-1"><a class="nav-link" href="#%E4%B8%BA%E4%BB%80%E4%B9%88%E4%BD%BF%E7%94%A8HBase"><span class="nav-number">1.</span> <span class="nav-text">为什么使用HBase</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#HBase-VS-RDBMS%EF%BC%88%E4%BC%A0%E7%BB%9F%E5%85%B3%E7%B3%BB%E6%95%B0%E6%8D%AE%E5%BA%93%EF%BC%89"><span class="nav-number">1.1.</span> <span class="nav-text">HBase VS RDBMS(传统关系数据库)</span></a></li></ol></li><li class="nav-item nav-level-1"><a class="nav-link" href="#%E4%BD%BF%E7%94%A8HBase"><span class="nav-number">2.</span> <span class="nav-text">使用HBase</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#%E5%90%AF%E5%8A%A8HBase"><span class="nav-number">2.1.</span> <span class="nav-text">启动HBase</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E6%9F%A5%E7%9C%8B%E6%97%A5%E5%BF%97"><span class="nav-number">2.2.</span> <span class="nav-text">查看日志</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#Shell"><span class="nav-number">2.3.</span> <span class="nav-text">Shell</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#Java-API"><span class="nav-number">2.4.</span> <span class="nav-text">Java API</span></a></li></ol></li><li class="nav-item nav-level-1"><a class="nav-link" href="#%E5%8E%9F%E7%90%86"><span class="nav-number">3.</span> <span class="nav-text">原理</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#%E6%95%B0%E6%8D%AE%E6%A8%A1%E5%9E%8B"><span class="nav-number">3.1.</span> <span class="nav-text">数据模型</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E9%9D%A2%E5%90%91%E5%88%97%E5%AD%98%E5%82%A8"><span class="nav-number">3.2.</span> <span class="nav-text">面向列存储</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#HBase%E6%9E%B6%E6%9E%84"><span class="nav-number">3.3.</span> <span class="nav-text">HBase架构</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#%E5%AE%A2%E6%88%B7%E7%AB%AF"><span class="nav-number">3.3.1.</span> <span class="nav-text">客户端</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#ZooKeeper%E6%9C%8D%E5%8A%A1%E5%99%A8"><span class="nav-number">3.3.2.</span> <span class="nav-text">ZooKeeper服务器</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#Master%E6%9C%8D%E5%8A%A1%E5%99%A8"><span class="nav-number">3.3.3.</span> <span class="nav-text">Master服务器</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#Region%E6%9C%8D%E5%8A%A1%E5%99%A8"><span class="nav-number">3.3.4.</span> <span class="nav-text">Region服务器</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#Region%E7%9A%84%E5%AE%9A%E4%BD%8D-%E5%A6%82%E4%BD%95%E6%89%BE%E5%88%B0%E4%B8%80%E4%B8%AARegion"><span class="nav-number">3.3.4.1.</span> <span class="nav-text">Region的定位 - 如何找到一个Region</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#Region%E4%B8%8E%E8%A1%8C"><span class="nav-number">3.3.4.2.</span> <span class="nav-text">Region与行</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#Region%E6%9C%8D%E5%8A%A1%E5%99%A8%E7%9A%84%E5%AD%98%E5%82%A8%E7%BB%93%E6%9E%84"><span class="nav-number">3.3.4.3.</span> <span class="nav-text">Region服务器的存储结构</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#%E6%B5%81%E7%A8%8B-%E7%94%A8%E6%88%B7%E8%AF%BB%E5%86%99%E6%95%B0%E6%8D%AE"><span class="nav-number">3.3.4.4.</span> <span class="nav-text">流程 - 用户读写数据</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#%E6%B5%81%E7%A8%8B-%E7%BC%93%E5%AD%98%E5%88%B7%E6%96%B0"><span class="nav-number">3.3.4.5.</span> <span class="nav-text">流程 - 缓存刷新</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#%E6%B5%81%E7%A8%8B-StoreFile%E5%90%88%E5%B9%B6"><span class="nav-number">3.3.4.6.</span> <span class="nav-text">流程 - StoreFile合并</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#Store%E7%9A%84%E5%B7%A5%E4%BD%9C%E5%8E%9F%E7%90%86"><span class="nav-number">3.3.4.7.</span> <span class="nav-text">Store的工作原理</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#HLog%E7%9A%84%E5%B7%A5%E4%BD%9C%E5%8E%9F%E7%90%86"><span class="nav-number">3.3.4.8.</span> <span class="nav-text">HLog的工作原理</span></a></li></ol></li></ol></li></ol></li></ol></div>
</div>
<!--/noindex-->
<div class="site-overview-wrap sidebar-panel">
<div class="site-author animated" itemprop="author" itemscope itemtype="http://schema.org/Person">
<p class="site-author-name" itemprop="name">tallate</p>
<div class="site-description" itemprop="description"></div>
</div>
<div class="site-state-wrap animated">
<nav class="site-state">
<div class="site-state-item site-state-posts">
<a href="/archives/">
<span class="site-state-item-count">192</span>
<span class="site-state-item-name">日志</span>
</a>
</div>
<div class="site-state-item site-state-categories">
<a href="/categories/">
<span class="site-state-item-count">25</span>
<span class="site-state-item-name">分类</span></a>
</div>
<div class="site-state-item site-state-tags">
<a href="/tags/">
<span class="site-state-item-count">84</span>
<span class="site-state-item-name">标签</span></a>
</div>
</nav>
</div>
</div>
</div>
</div>
</aside>
</div>
<div class="main-inner post posts-expand">
<div class="post-block">
<article itemscope itemtype="http://schema.org/Article" class="post-content" lang="zh-CN">
<link itemprop="mainEntityOfPage" href="https://tallate.github.io/54180c33.html">
<span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
<meta itemprop="image" content="/images/avatar.gif">
<meta itemprop="name" content="tallate">
</span>
<span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
<meta itemprop="name" content="Tallate">
<meta itemprop="description" content="">
</span>
<span hidden itemprop="post" itemscope itemtype="http://schema.org/CreativeWork">
<meta itemprop="name" content="HBase总结 | Tallate">
<meta itemprop="description" content="">
</span>
<header class="post-header">
<h1 class="post-title" itemprop="name headline">
HBase总结
</h1>
<div class="post-meta-container">
<div class="post-meta">
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-calendar"></i>
</span>
<span class="post-meta-item-text">发表于</span>
<time title="创建时间:2021-07-18 16:26:49" itemprop="dateCreated datePublished" datetime="2021-07-18T16:26:49+08:00">2021-07-18</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-calendar-check"></i>
</span>
<span class="post-meta-item-text">更新于</span>
<time title="修改时间:2025-07-07 01:56:20" itemprop="dateModified" datetime="2025-07-07T01:56:20+08:00">2025-07-07</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-folder"></i>
</span>
<span class="post-meta-item-text">分类于</span>
<span itemprop="about" itemscope itemtype="http://schema.org/Thing">
<a href="/categories/Hadoop/" itemprop="url" rel="index"><span itemprop="name">Hadoop</span></a>
</span>
</span>
</div>
</div>
</header>
<div class="post-body" itemprop="articleBody"><h1 id="为什么使用HBase"><a href="#为什么使用HBase" class="headerlink" title="为什么使用HBase"></a>为什么使用HBase</h1><p>HBase是开源版的BigTable。</p>
<ul>
<li>高性能的列式存储</li>
<li>高可靠的弹性伸缩</li>
</ul>
<h2 id="HBase-VS-RDBMS(传统关系数据库)"><a href="#HBase-VS-RDBMS(传统关系数据库)" class="headerlink" title="HBase VS RDBMS(传统关系数据库)"></a>HBase VS RDBMS(传统关系数据库)</h2><ul>
<li>数据类型<br>RDBMS:关系模型,丰富的数据类型和存储方式<br>HBase存的数据都是字符串,用户根据自己的需要解析字符串</li>
<li>数据操作<br>RDBMS:丰富的CRUD操作,多表连接<br>HBase:不存在复杂的表与表之间的关系,只有简单的插入、查询、删除、清空等</li>
<li>存储模式<br>RDBMS:基于行模式存储,行被连续存储在磁盘页,在读取时需要顺序扫描行并筛选,如果每一行只有少量数据值对于查询是有用的,那么基于行模式的存储就会浪费许多磁盘空间和内存带宽;<br>HBase:基于列存储,每个<strong>列族</strong>都由几个文件保存,不同列族的文件是分离的,可以支持更大并发的查询,因为仅需处理查询所需的列,而不需要像RDBMS那样处理整行;同一个列族的数据会被一起进行压缩,由于同一列族内的数据相似度较高,因此可以获得较高的压缩比。</li>
<li>数据索引<br>RDBMS会根据需要构建多个索引<br>HBase只有一个索引:<strong>行键</strong></li>
<li>数据维护<br>RDBMS更新后老数据会被替换<br>HBase更新只会生成一个新版本,老版本数据仍然保留。</li>
<li>可伸缩性<br>RDBMS很难实现横向扩展。<br>HBase可以灵活地水平扩展。</li>
<li>事务<br>HBase不支持事务,不能实现跨行更新的原子性。</li>
</ul>
<h1 id="使用HBase"><a href="#使用HBase" class="headerlink" title="使用HBase"></a>使用HBase</h1><ul>
<li>Native Java API</li>
<li>HBase Shell</li>
<li>Thrift Gateway</li>
<li>REST Gateway</li>
<li>Pig</li>
<li>Hive</li>
</ul>
<h2 id="启动HBase"><a href="#启动HBase" class="headerlink" title="启动HBase"></a>启动HBase</h2><p>从官网下载HBase:<code>https://hbase.apache.org/</code><br>注意兼容性:<a target="_blank" rel="noopener" href="http://hbase.apache.org/book.html#hadoop">http://hbase.apache.org/book.html#hadoop</a><br>Hadoop安装后只包含HDFS和MapReduce,并不包含HBase,需要在Hadoop之上继续安装HBase。</p>
<p>编辑配置文件<code>conf/hbase-site.xml</code>,可以修改数据写入目录:</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><configuration></span><br><span class="line"> <property></span><br><span class="line"> <name>hbase.rootdir</name></span><br><span class="line"> <value>file:///DIRECTORY/hbase</value></span><br><span class="line"> </property></span><br><span class="line"></configuration></span><br></pre></td></tr></table></figure>
<p>将 DIRECTORY 替换成期望写文件的目录. 默认 hbase.rootdir 是指向 /tmp/hbase-${user.name} ,重启时数据会丢失。<br>编辑环境变量<code>conf/hbase-env.sh</code>:</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"># 如果JAVA_HOME已经有了就不用设置了</span><br><span class="line">export JAVA_HOME=...</span><br><span class="line"># 表示由hbase自己管理ZooKeeper,不需要单独的ZooKeeper</span><br><span class="line">export HBASE_MANAGES_ZK=true </span><br></pre></td></tr></table></figure>
<p>启动hbase:</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">./bin/start-hbase.sh</span><br></pre></td></tr></table></figure>
<p>关闭hbase:</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">./bin/stop-hbase.sh</span><br></pre></td></tr></table></figure>
<h2 id="查看日志"><a href="#查看日志" class="headerlink" title="查看日志"></a>查看日志</h2><p>如果启动失败后者后续的命令执行失败了,可以查看根目录下的日志:</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">vim logs/hbase-hgc-master-hgc-X555LD.log</span><br></pre></td></tr></table></figure>
<h2 id="Shell"><a href="#Shell" class="headerlink" title="Shell"></a>Shell</h2><p>使用shell连接HBase:</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">./bin/hbase shell</span><br></pre></td></tr></table></figure>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"># 查看命令列表,要注意的是表名,行和列需要加引号</span><br><span class="line">> help</span><br></pre></td></tr></table></figure>
<p>create - 创建表、列族:</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"># 创建表</span><br><span class="line">> create 'test', 't1'</span><br><span class="line"># 创建表t1,列族为f1,列族版本号为5</span><br><span class="line">> create 't1', {NAME => 'f1', VERSIONS => 5}</span><br><span class="line"># 创建表t1,有3个列族分别为f1、f2、f3</span><br><span class="line">> create 't1', {NAME => 'f1'}, {NAME => 'f2'}, {NAME => 'f3'}</span><br><span class="line">> create 't1', 'f1', 'f2', 'f3'</span><br><span class="line"># 创建表t1,根据分割算法HexStringSplit分布在15个Region里</span><br><span class="line">> create 't1', 'f1', {NUMREGIONS => 15, SPLITALGO => 'HexStringSplit'}</span><br><span class="line"># 创建表t1,指定切分点</span><br><span class="line">> create 't1', 'f1', {SPLIT => ['10', '20', '30', '40']}</span><br></pre></td></tr></table></figure>
<p>list - 查询表信息</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">> list</span><br></pre></td></tr></table></figure>
<p>put - 向表、行、列指定的单元格添加数据:</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"># 向表t1中的行row1和列f1:c1所对应的单元格中添加数据value1,时间戳为1421822284898</span><br><span class="line">> put 't1', 'row1', 'f1:c1', 'value1', 1421822284898</span><br></pre></td></tr></table></figure>
<p>get - 获取单元格数据</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"># 从表t1获取数据,行row1、列f1,时间范围为TIMERANGE,版本号为1的数据</span><br><span class="line">> get 't1', 'row1', {COLUMN => 'f1:c1', TIMERANGE => [0, 1421822284900], VERSIONS => 1}</span><br><span class="line"># 获取表t1、行row1、列f1上的数据</span><br><span class="line">> get 't1', 'row1', 'f1'</span><br></pre></td></tr></table></figure>
<h2 id="Java-API"><a href="#Java-API" class="headerlink" title="Java API"></a>Java API</h2><h1 id="原理"><a href="#原理" class="headerlink" title="原理"></a>原理</h1><h2 id="数据模型"><a href="#数据模型" class="headerlink" title="数据模型"></a>数据模型</h2><ul>
<li><strong>表</strong><br>HBase使用表来组织数据,表由行和列组成,列又划分为若干列族。</li>
<li><strong>行</strong><br>每个表由若干行组成,每个行由<strong>行键</strong>标识。<br>访问表中的行只能通过:单个行键、行键区间、全表扫描实现。</li>
<li><strong>列族</strong><br>列族是基本的访问控制单元。<br>列族里的数据通过<strong>列限定符</strong>或<strong>列</strong>来定位。</li>
<li><strong>单元格</strong><br>在表中,可以通过行、列族和列限定符确定一个<strong>单元格Cell</strong>。<br>单元格中存储的数据没有数据类型,总是被视为字节数组。<br>每个单元格中可以保存一个数据的多个版本,每个版本对应一个不同的时间戳。</li>
<li><strong>时间戳</strong><br>单元格中的数据通过时间戳进行索引,每次对一个单元格执行增删改操作都会隐式生成并存储一个时间戳。</li>
<li>数据坐标<br>HBase中可以根据<行键, 列族, 列限定符, 时间戳>的四元组来确定一条数据。</li>
</ul>
<h2 id="面向列存储"><a href="#面向列存储" class="headerlink" title="面向列存储"></a>面向列存储</h2><ul>
<li>行式数据库<br>行式存储将每一行连续地存储在磁盘页中,要找一行数据就要连续地扫描磁盘。<br>如果每行只有少量属性的值对查询有用,那么行式存储就会浪费非常多的磁盘空间和内存带宽。<br>行式数据库主要适合于<strong>小批量</strong>的数据处理,如联机事务型数据处理,常见实现如MySQL。</li>
<li>列式数据库<br>以列为单位进行存储,关系中多个元组的同一列值会被存储到一起,而同一个元组中不同列则通常会被分别存储到不同的磁盘页中。<br>列式数据库主要适用于<strong>批量数据处理</strong>和<strong>Ad-Hoc Query</strong>,优点是可以降低IO开销,支持大量并发用户查询,因为仅需要处理可以回答这些查询的列,而不是分类整理与特定查询无关的数据行;具有较高的数据压缩比。<br>列式数据库主要用于数据挖掘、决策支持和地理信息系统等查询密集型系统中,因为一次查询就可以得出结果,而不必每次都要遍历所有的数据库。<br>缺点1:<strong>连接操作效率低</strong>,执行连接操作时需要昂贵的元组重构代价,因为一个元组的不同属性被分散到不同磁盘页中存储,当需要一个完整的元组时,就要从多个磁盘页中读取相应字段的值来重新组合得到原来的一个元组。<br>缺点2:<strong>不适合频繁更新同一行元组的场景</strong>,理由同上,因为一个元组的不同属性分散到不同的磁盘页,因此写操作频繁会导致不能很好命中缓冲。因此HBase更适合数据被存储后不会发生修改的场景。</li>
</ul>
<h2 id="HBase架构"><a href="#HBase架构" class="headerlink" title="HBase架构"></a>HBase架构</h2><p><img src="/imgs/Hadoop/HBase%E7%B3%BB%E7%BB%9F%E6%9E%B6%E6%9E%84.jpg" alt="HBase系统架构" title="HBase系统架构"></p>
<p>HBase的实现包含3个主要的功能组件:</p>
<ul>
<li>一个Master主服务器<br>Master负责管理HBase表的分区(Region)信息<br>比如一个表包含哪些Region,这些Region被划分到哪台Region服务器上。<br>同时也负责维护Region服务器列表,实时监测集群中的Region服务器,把特定的Region分配到可用的Region服务器上,并确保整个集群内部不同Region服务器之间的负载均衡。<br>负责Region集群的故障转移,当某个Region服务器因出现故障而失效时,Master会把故障服务器上存储的Region重新分配给其他可用的Region服务器。<br>负责模式变化,如表和列族的创建。</li>
<li>许多个Region服务器<br>Region服务器负责存储和维护分配给自己的Region,处理来自客户端的读写请求。</li>
<li>库函数<br>链接到每个客户端<br>客户端并不是直接从Master上读取数据,而是先获取Region的存储位置后再直接从Region服务器上读取数据。而且需要注意的是客户端不直接和Master交互,而是从ZooKeeper上获取Region信息,这可以保证Master的负载尽可能小。</li>
</ul>
<h3 id="客户端"><a href="#客户端" class="headerlink" title="客户端"></a>客户端</h3><p>客户端会访问HBase的服务端接口,并缓存已经访问过的Region位置信息,用来提高后续访问数据的速度。</p>
<h3 id="ZooKeeper服务器"><a href="#ZooKeeper服务器" class="headerlink" title="ZooKeeper服务器"></a>ZooKeeper服务器</h3><ul>
<li>Master将Region服务器的状态注册到ZooKeeper</li>
<li>Master选举。</li>
<li>保存-ROOT-表和Master的地址,然后客户端可以根据-ROOT-表来一级一级找到所需的数据</li>
</ul>
<h3 id="Master服务器"><a href="#Master服务器" class="headerlink" title="Master服务器"></a>Master服务器</h3><ul>
<li>管理对表的CRUD操作</li>
<li>实现不同Region之间的负载均衡</li>
<li>在Region分裂或合并后,重新调整Region的分布</li>
<li>将发生故障失效的Region迁移到其他Region服务器</li>
</ul>
<h3 id="Region服务器"><a href="#Region服务器" class="headerlink" title="Region服务器"></a>Region服务器</h3><p>Region服务器的主要职责:</p>
<ul>
<li>维护分配给自己的Region</li>
<li>响应用户的读写请求</li>
</ul>
<p>Region一般采用HDFS作为底层文件存储系统,并依赖HDFS来实现<strong>数据复制</strong>和<strong>维护数据副本</strong>的功能。</p>
<h4 id="Region的定位-如何找到一个Region"><a href="#Region的定位-如何找到一个Region" class="headerlink" title="Region的定位 - 如何找到一个Region"></a>Region的定位 - 如何找到一个Region</h4><p>每个Region都有一个RegionID来标识它的唯一性,要定位一个Region可以使用<表名, 开始主键, RegionID>的三元组。<br>HBase还会维护一张<Region标识符, Region服务器>的映射表,被称为<strong>元数据表</strong>,又名 <strong>.META.表</strong>。<br>如果一个HBase表中的Region特别多,一个服务器存不下.META.表,则.META.表也会被分区存储到不同的服务器上,并用一张<strong>根数据表</strong>来维护所有元数据的具体位置,又名 <strong>-ROOT-表</strong>,-ROOT-表是不能被分割的,永远只会被存储到一个唯一的Region中。</p>
<p><img src="/imgs/Hadoop/HBase%E5%85%83%E6%95%B0%E6%8D%AE%E7%9A%84%E4%B8%89%E5%B1%82%E7%BB%93%E6%9E%84.png" alt="HBase元数据的三层结构" title="HBase元数据的三层结构"></p>
<h4 id="Region与行"><a href="#Region与行" class="headerlink" title="Region与行"></a>Region与行</h4><p>HBase中的行是根据<strong>行键</strong>的字典序进行维护的,表中包含的行的数量可能非常大,需要通过行键对表中的行进行分区(Region)。<br>Region包含了位于某个值区间内的所有数据,它是<strong>负载均衡</strong>和<strong>数据分发</strong>的基本单位,这些Region会被Master分发到不同的Region服务器上。<br>每个Region的默认大小是100MB<del>200MB,当一个Region包含的数据达到一个阈值时,会被自动<strong>分裂</strong>成两个新的Region,通常一个Region服务器上会放置10</del>1000个Region。</p>
<h4 id="Region服务器的存储结构"><a href="#Region服务器的存储结构" class="headerlink" title="Region服务器的存储结构"></a>Region服务器的存储结构</h4><p>Region服务器内部维护了一系列Region对象和一个<strong>HLog</strong>文件</p>
<ul>
<li><p>每个Region由多个<strong>Store</strong>组成,每个Store对应了表中的一个列族的存储。<br>每个Store又包含一个<strong>MemStore</strong>和若干<strong>StoreFile</strong>,前者是内存缓存,后者是磁盘文件,使用<strong>B树</strong>结构组织,底层实现方式是HDFS的HFile(会对内容进行压缩)。</p>
</li>
<li><p>HLog是磁盘上的记录文件,记录着所有的更新操作。</p>
</li>
<li><p>每个Store对应了表中一个一个<strong>列族</strong>,包含了<strong>一个MemStore</strong>和<strong>若干个StoreFile</strong>;<br>其中,MemStore是在内存中的<strong>缓存</strong>,保存最近更新的数据;StoreFile由HDFS的HFile实现,底层是磁盘中的文件,这些文件都是<strong>B树结构</strong>,方便快速读取,而且HFile的数据块通常采用压缩方式存储,可以大大减少网络和磁盘IO。<br><img src="/imgs/Hadoop/Region%E5%AD%98%E5%82%A8%E7%BB%93%E6%9E%84.png" alt="Region存储结构" title="Region存储结构"></p>
</li>
</ul>
<h4 id="流程-用户读写数据"><a href="#流程-用户读写数据" class="headerlink" title="流程 - 用户读写数据"></a>流程 - 用户读写数据</h4><ul>
<li>写入流程<br>用户写入 -> 路由Region服务器 -> HLog -> MemStore -> commit()返回给客户端<blockquote>
<p>HLog是WAL(Write Ahead Log),因此在MemStore之前写入</p>
</blockquote>
</li>
<li>读取流程<br>用户读取 -> 路由Region服务器 -> MemStore -> StoreFile</li>
</ul>
<h4 id="流程-缓存刷新"><a href="#流程-缓存刷新" class="headerlink" title="流程 - 缓存刷新"></a>流程 - 缓存刷新</h4><ul>
<li>周期性刷新<br>周期性调用Region.flushcache() -> 将MemStore缓存中的内容写到磁盘StoreFile中 -> 清空缓存 -> 在HLog中写入一个标记表示缓存已刷到StoreFile<br>每次缓存刷新都会在磁盘上生成一个新的StoreFile文件,因此每个Store会包含多个StoreFile文件</li>
<li>启动刷新<br>启动时检查HLog -> 确认最后一次刷新后是否还有发生写入 -> 如果有发生则将这些更新写入MemStore -> 刷新缓存写入到StoreFile -> 删除旧的HLog文件 -> 开始为用户提供数据访问服务<blockquote>
<p>如果最后一次刷新后没有新数据,说明所有数据已经被永久保存。</p>
</blockquote>
</li>
</ul>
<h4 id="流程-StoreFile合并"><a href="#流程-StoreFile合并" class="headerlink" title="流程 - StoreFile合并"></a>流程 - StoreFile合并</h4><p>如《缓存刷新》流程所述,每次MemStore刷新都会在磁盘上生成一个新的StoreFile,这样系统中每个Store都会有多个StoreFile,<strong>要找到Store中某个值就必须查找所有这些StoreFile文件</strong>,非常耗时。<br>因此,为了减少耗时,系统会调用Store.compact()把多个StoreFile合并成一个大文件。<br>这个合并操作比较耗费资源,因此只会在StoreFile文件的数量达到一个阈值时才会触发合并操作。</p>
<h4 id="Store的工作原理"><a href="#Store的工作原理" class="headerlink" title="Store的工作原理"></a>Store的工作原理</h4><p>如《Region存储结构》所示,Region服务器是HBase的核心模块,而Store是Region服务器的核心,每个Store对应了表中的一个列族的存储,每个Store包含一个MemStore缓存和若干个StoreFile文件。</p>
<ul>
<li>写入数据优先写入MemStore,写满时刷新到StoreFile</li>
<li>随着StoreFile数量不断增加,达到阈值时触发文件<strong>合并</strong>操作</li>
<li>当StoreFile文件越来越大,达到阈值时,会触发文件<strong>分裂</strong>操作,同时当前的一个父Region会被分裂成2个子Region,父Region会下线,新分裂出的2个子Region会被Master分配到相应的Region服务器上。</li>
</ul>
<p><img src="/imgs/Hadoop/StoreFile%E7%9A%84%E5%90%88%E5%B9%B6%E5%92%8C%E5%88%86%E8%A3%82.png" alt="StoreFile的合并和分裂" title="StoreFile的合并和分裂"></p>
<h4 id="HLog的工作原理"><a href="#HLog的工作原理" class="headerlink" title="HLog的工作原理"></a>HLog的工作原理</h4><p>在分布式环境下,系统出错可能导致数据丢失,比如Region故障导致MemStore缓存中的数据被清空了。HBase采用HLog来保证系统故障时的恢复。</p>
<ul>
<li>HLog是每个Region服务器仅配置一个<br>一个Region服务器包含多个Region,这些<strong>一台Region服务器上的Region会共用一个HLog</strong><br>这样做的好处是:一台Region服务器不需要打开多个日志文件,<strong>减少磁盘寻址次数</strong>,提高写操作性能。<br>这样的坏处是:如果一个Region服务器发生故障,为了恢复其上的Region对象,需要按所属Region对HLog进行拆分,然后分发到其他Region服务器上执行恢复操作。</li>
<li>HLog是WAL(Write Ahead Log)<br>用户数据需要先写HLog才能写入MemStore,并且直到MemStore缓存内容对应的日志已经被写入磁盘,该缓存内容才会被刷新到磁盘。</li>
<li>数据恢复<br>ZooKeeper会实时监测每个Region服务器的状态,当某个Region服务器发生故障,ZooKeeper会通知Master。<br>Master会处理该故障服务器上的HLog文件,注意HLog会包含来自多个Region对象的日志记录,系统会<strong>根据每条日志所属的Region对象对HLog数据进行拆分</strong>,分别放到对应Region对象的目录下,然后再将失效的Region重新分配到可用的Region服务器中,并把与该Region对象相关的HLog日志记录也发送给相应的Region服务器。<br>Region服务器领取到分配给自己的Region对象以及与之相关的HLog日志记录以后,会<strong>重演一遍日志记录中的操作</strong>,把日志记录中的数据写入MemStore缓存,然后刷新到磁盘的StoreFile文件中,完成数据恢复。</li>
</ul>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/kity@2.0.4/dist/kity.min.js"></script><script type="text/javascript" src="https://cdn.jsdelivr.net/npm/kityminder-core@1.4.50/dist/kityminder.core.min.js"></script><script defer="true" type="text/javascript" src="https://cdn.jsdelivr.net/npm/hexo-simple-mindmap@0.6.0/dist/mindmap.min.js"></script><link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/hexo-simple-mindmap@0.6.0/dist/mindmap.min.css">
</div>
<footer class="post-footer">
<div class="post-tags">
<a href="/tags/Hadoop/" rel="tag"># Hadoop</a>
<a href="/tags/HBase/" rel="tag"># HBase</a>
</div>
<div class="post-nav">
<div class="post-nav-item">
<a href="/e0b783b0.html" rel="prev" title="ES5_3IngestNode">
<i class="fa fa-angle-left"></i> ES5_3IngestNode
</a>
</div>
<div class="post-nav-item">
<a href="/39415219.html" rel="next" title="推荐系统总结">
推荐系统总结 <i class="fa fa-angle-right"></i>
</a>
</div>
</div>
</footer>
</article>
</div>
</div>
</main>
<footer class="footer">
<div class="footer-inner">
<div class="copyright">
©
<span itemprop="copyrightYear">2025</span>
<span class="with-love">
<i class="fa fa-heart"></i>
</span>
<span class="author" itemprop="copyrightHolder">tallate</span>
</div>
<div class="powered-by">由 <a href="https://hexo.io/" rel="noopener" target="_blank">Hexo</a> & <a href="https://theme-next.js.org/" rel="noopener" target="_blank">NexT.Gemini</a> 强力驱动
</div>
</div>
</footer>
<div class="back-to-top" role="button" aria-label="返回顶部">
<i class="fa fa-arrow-up fa-lg"></i>
<span>0%</span>
</div>
<a href="https://github.com/tallate" class="github-corner" title="在 GitHub 上关注我" aria-label="在 GitHub 上关注我" rel="noopener" target="_blank"><svg width="80" height="80" viewBox="0 0 250 250" aria-hidden="true"><path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path><path d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2" fill="currentColor" style="transform-origin: 130px 106px;" class="octo-arm"></path><path d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z" fill="currentColor" class="octo-body"></path></svg></a>
<noscript>
<div class="noscript-warning">Theme NexT works best with JavaScript enabled</div>
</noscript>
<script src="https://cdnjs.cloudflare.com/ajax/libs/animejs/3.2.1/anime.min.js" integrity="sha256-XL2inqUJaslATFnHdJOi9GfQ60on8Wx1C2H8DYiN1xY=" crossorigin="anonymous"></script>
<script src="/js/comments.js"></script><script src="/js/utils.js"></script><script src="/js/motion.js"></script><script src="/js/next-boot.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/hexo-generator-searchdb/1.4.1/search.js" integrity="sha256-1kfA5uHPf65M5cphT2dvymhkuyHPQp5A53EGZOnOLmc=" crossorigin="anonymous"></script>
<script src="/js/third-party/search/local-search.js"></script>
<script class="next-config" data-name="mermaid" type="application/json">{"enable":true,"version":"7.1.2","options":null,"js":{"url":"https://cdnjs.cloudflare.com/ajax/libs/mermaid/10.3.0/mermaid.min.js","integrity":"sha256-9y71g5Lz/KLsHjB8uXwnkuWDtAMDSzD/HdIbqhJfTAI="}}</script>
<script src="/js/third-party/tags/mermaid.js"></script>
</body>
</html>