HBase的概述架构及基本组件
概述:
1.HBase是一个构建在HDFS上的分布式列存储系统之上的表结构系统;
2.HBase是基于Google BigTable模型开发的,典型的key/value系统;
3.主要用于海量结构化非固定模式数据存储;将数据按照表、行和列进行存储。
4.与hadoop一样,Hbase目标主要依靠横向扩展,通过不断增加廉价的商用服务器,来增加计算和存储能力。
术语缩写:对于一些进程/角色名称,在本文范围内可能通过缩写形式来表述:
Hbase的结构特点
大:一个表可以有数十亿行,上百万列;
无模式:每行都必有一个可排序的主键和任意多的列,列可以根据需要动态的增加,同一张表中不同的行可以有截然不同的列;
面向列:面向列(族)的存储和权限控制,列(族)独立检索;
稀疏:空(null)列并不占用存储空间,表可以设计的非常稀疏;
数据多版本:每个单元中的数据可以有多个版本,默认情况下版本号自动分配,是单元格插入时的时间戳;
数据类型单一:Hbase中的数据都是字符串,没有类型。
namespace
在HBase中,namespace命名空间指对一组表的逻辑分组,类似RDBMS中的database,方便对表在业务上划分。Apache HBase从0.98.0, 0.95.2两个版本开始支持namespace级别的授权操作,HBase全局管理员可以创建、修改和回收namespace的授权。
HBase系统默认定义了两个缺省的namespace
- hbase:系统内建表,包括namespace和meta表
- default:用户建表时未指定namespace的表都创建在此
RowKey
由于Hbase只支持3中查询方式:
1、基于Rowkey的单行查询
2、基于Rowkey的范围扫描
3、全表扫描
RowKey用来表示唯一一行记录的主键,HBase的数据是按照RowKey的字典顺序进行全局排序的,所有的查询都只能依赖于这一个排序维度。
rowkey 行键可以是任意字符串(最大长度是 64KB,实际应用中长度一般为 10-100bytes),最好是 16。在 HBase 内部,rowkey 保存为字节数组。HBase 会对表中的数据按照 rowkey 排序 (字典顺序)
通过下面一个例子来说明一下”字典排序“的原理:
RowKey {“abc”, “a”, “bdf”, “cdf”, “defg”}按字典排序后的结果为{“a”, “abc”, “bdf”, “cdf”, “defg”}
也就是说,当两个RowKey进行排序时,先对比两个RowKey的第一个字节,如果相同,则对比第二个字节,依此类推…如果在对比到第M个字节时,已经超出了其中一个RowKey的字节长度,那么,短的RowKey要被排在另外一个RowKey的前面
底层使用稀疏矩阵方式存储数据
Region
区别于Cassandra/DynamoDB的”Hash分区”设计,HBase中采用了”Range分区”,将Key的完整区间切割成一个个的”Key Range” ,每一个”Key Range”称之为一个Region。
也可以这么理解:将HBase中拥有数亿行的一个大表,横向切割成一个个”子表“,这一个个”子表“就是Regionl,
Region是HBase中负载均衡的基本单元,当一个Region增长到一定大小以后,会自动分裂成两个。
Region虽然是分布式存储的最小单元,但并不是存储的最小单元。Region由一个或者多个Store组成,每个store保存一个columns family;每个Strore又由一个memStore和0至多个StoreFile组成,StoreFile包含HFile;memStore存储在内存中,StoreFile存储在HDFS上。
Column Family
如果将Region看成是一个表的横向切割,那么,一个Region中的数据列的纵向切割,称之为一个Column Family。每一个列,都必须归属于一个Column Family,这个归属关系是在写数据时指定的,而不是建表时预先定义
Hbase的列族不是越多越好,官方推荐的是列族最好小于或者等于3。我们使用的场景一般是1个列族。
KeyValue
KeyValue的设计不是源自Bigtable,而是要追溯至论文”The log-structured merge-tree(LSM-Tree)”。每一行中的每一列数据,都被包装成独立的拥有特定结构的KeyValue,KeyValue中包含了丰富的自我描述信息,它的结构体如下:
看的出来,KeyValue是支撑”稀疏矩阵”设计的一个关键点:一些Key相同的任意数量的独立KeyValue就可以构成一行数据。但这种设计带来的一个显而易见的缺点:每一个KeyValue所携带的自我描述信息,会带来显著的数据膨胀。
TimeStamp
TimeStamp对Hbase来说至关重要,因为它是实现Hbase多版本的关键。在Hbase中使用不同的timestame来标识相同rowkey行对应的不通版本的数据。
HBase 中通过 rowkey 和 columns 确定的为一个存储单元称为 cell。每个 cell 都保存着同一份 数据的多个版本。版本通过时间戳来索引。时间戳的类型是 64 位整型。时间戳可以由 hbase(在数据写入时自动)赋值,此时时间戳是精确到毫秒的当前系统时间。时间戳也可以由客户显式赋值。如果应用程序要避免数据版本冲突,就必须自己生成具有唯一性的时间戳。 每个 cell 中,不同版本的数据按照时间倒序排序,即最新的数据排在最前面。
为了避免数据存在过多版本造成的的管理 (包括存贮和索引)负担,hbase 提供了两种数据版 本回收方式:
保存数据的最后 n 个版本
保存最近一段时间内的版本(设置数据的生命周期 TTL)。
用户可以针对每个列簇进行设置。
单元格(Cell)
由{rowkey, column( = + ), version} 唯一确定的单元。 Cell 中的数据是没有类型的,全部是字节码形式存贮。
HBase擅长于存储结构简单的海量数据但索引能力有限,而Oracle等传统关系型数据库(RDBMS)能够提供丰富的查询能力,但却疲于应对TB级别的海量数据存储,HBase对传统的RDBMS并不是取代关系,而是一种补充。
HBase架构及基本组件
这部分安装它的业务逻辑模块分隔
**Client **
包含访问HBase的接口,并维护cache来加快对HBase的访问,比如region的位置信息.是调用服务的主要入口。
HBase Client通过RPC方式和HMaster、HRegionServer通信;在第一次需要进行三次查询获取到映射路径后会缓存到Client方的cache中,避免重复查询。
ZooKeeper集群是协调系统
用于:
1.存放整个 HBase集群的元数据以及集群的状态信息。
2.实现HMaster主从节点的failover。
Zookeeper Quorum中除了存储了-ROOT-表的地址和HMaster的地址,HRegionServer会把自己以Ephemeral方式注册到Zookeeper中,使得HMaster可以随时感知到各个HRegionServer的健康状态。此外,Zookeeper也避免了HMaster的单点问题。
这个架构图比较清晰的表达了HMaster和NameNode都支持多个热备份,使用ZooKeeper来做协调;ZooKeeper并不是云般神秘,它一般由三台机器组成一个集群,内部使用PAXOS算法支持三台Server中的一台宕机,也有使用五台机器的,此时则可以支持同时两台宕机,既少于半数的宕机,然而随着机器的增加,它的性能也会下降;RegionServer和DataNode一般会放在相同的Server上实现数据的本地化。
-ROOT-表和.META.表
你没看错,这两个表的命名有些特殊仿佛带着个帽子一样,一个是-一个是.号,这就注定了它们的特殊性。
用户表的Regions元数据被存储在.META.表中,随着Region的增多,.META.表中的数据也会增大,并分裂成多个Regions。为了定位.META.表中各个Regions的位置,把.META.表中的所有Regions的元数据保存在-ROOT-表中,最后由Zookeeper记录-ROOT-表的位置信息。所有客户端访问用户数据前,需要首先访问Zookeeper获得-ROOT-的位置,然后方位-ROOT-表获得.META.表的位置,最后根据.META.表中的信息确定用户数据存放的位置,-ROOT-表永远不会被分割,它只有一个Region,这样可以保证最多需要三次跳转就可以定位任意一个Region。为了加快访问速度,.META.表的Regions全部保存在内存中,如果.META.表中的每一行在内存中占大约1KB,且每个Region限制为128M,下图中的三层结构可以保存Regions的数目为(128M/1KB)*(128/1KB)=2^34个。
HMaster
1.管理HRegionServer,实现其负载均衡。
2.管理和分配HRegion,比如在HRegion split时分配新的HRegion;在HRegionServer退出时迁移其内的HRegion到其他HRegionServer上,监控集群中所有HRegionServer的状态(通过Heartbeat和监听ZooKeeper中的状态)。
3.实现DDL操作(Data Definition Language,namespace和table的增删改,column familiy的增删改等)。
4.管理namespace和table的元数据(实际存储在HDFS上)。
5.权限控制(ACL)。
HMaster单点故障问题,可以启动多个HMaster,通过ZooKeeper的Master Election机制保证同时只有一个HMaster出于Active状态,其他的HMaster则处于热备份状态。一般情况下会启动两个HMaster,非Active的HMaster会定期的和Active HMaster通信以获取其最新状态,从而保证它是实时更新的,因而如果启动了多个HMaster反而增加了Active HMaster的负担。前文已经介绍过了HMaster的主要用于HRegion的分配和管理,DDL(Data Definition Language,既Table的新建、删除、修改等)的实现等,既它主要有两方面的职责:
RegionServer
1.存放和管理本地HRegion。
2.读写HDFS,管理Table中的数据。
3.Client直接通过HRegionServer读写数据(从HMaster中获取元数据,找到RowKey所在的HRegion/HRegionServer后)
一个HRegionServer可以存放1000个HRegion;底层Table数据存储于HDFS中,而HRegion所处理的数据尽量和数据所在的DataNode在一起,实现数据的本地化;数据本地化并不是总能实现,比如在HRegion移动(如因Split)时,需要等下一次Compact才能继续回到本地化。
HRegion
HBase使用RowKey将表水平切割成多个HRegion,从HMaster的角度,每个HRegion都纪录了它的StartKey和EndKey(第一个HRegion的StartKey为空,最后一个HRegion的EndKey为空),由于RowKey是排序的,因而Client可以通过HMaster快速的定位每个RowKey在哪个HRegion中。HRegion由HMaster分配到相应的HRegionServer中,然后由HRegionServer负责HRegion的启动和管理,和Client的通信,负责数据的读(使用HDFS)。每个HRegionServer可以同时管理1000个左右的HRegion(这个数字怎么来的?没有从代码中看到限制,难道是出于经验?超过1000个会引起性能问题?来回答这个问题:感觉这个1000的数字是从BigTable的论文中来的(5 Implementation节):Each tablet server manages a set of tablets(typically we have somewhere between ten to a thousand tablets per tablet server)),而每个HRegion他们分别可以属于不同的Table。
HRegion由多个Store(HStore)构成,每个HStore对应了一个Table在这个HRegion中的一个Column Family,即每个Column Family就是一个集中的存储单元,因而最好将具有相近IO特性的Column存储在一个Column Family,以实现高效读取(数据局部性原理,可以提高缓存的命中率)。HStore是HBase中存储的核心,它实现了读写HDFS功能,一个HStore由一个MemStore 和0个或多个StoreFile组成。
(1).MemStore是一个写缓存(In Memory Sorted Buffer),所有数据的写在完成WAL日志写后,会 写入MemStore中,由MemStore根据一定的算法将数据Flush到地层HDFS文件中(HFile),通常每个HRegion中的每个 Column Family有一个自己的MemStore。
(2).HFile(StoreFile) 用于存储HBase的数据(Cell/KeyValue)。在HFile中的数据是按RowKey、Column Family、Column排序,对相同的Cell(即这三个值都一样),则按timestamp倒序排列。
整个查询流程
ZooKeeper–> -ROOT-(单Region)–> .META.–> 用户表
在HBase 0.96以前,HBase有两个特殊的Table:-ROOT-和.META.(如BigTable中的设计)
-ROOT-
表包含.META.表所在的region列表,该表只会有一个Region;
Zookeeper中记录了-ROOT-表的location。
.META.
表包含所有的用户空间和RegionServer的服务器地址映射的region列表,它可以被切分成多个HRegion。
0.从ZooKeeper中读取-ROOT-表所在HRegionServer;
1.然后从该HRegionServer中根据请求的TableName,RowKey读取.META. 表所在HRegionServer;
2.最后从该HRegionServer中读取.META. 表的内容而获取此次请求需要访问的HRegion所在的位置,
3.然后访问该HRegionSever获取请求的数据,1-3这需要三次请求才能找到用户Table所在的位置,然后第四次请求开始获取真正的数据。当然为了提升性能,客户端会缓存-ROOT- Table位置以及-ROOT-/.META. Table的内容。
hbase:meta表
hbase:meta表存储了所有用户HRegion的位置信息,它的RowKey是:tableName,regionStartKey,regionId,replicaId等,它只有info列族,这个列族包含三个列,他们分别是:
info:regioninfo列是RegionInfo的proto格式:regionId,tableName,startKey,endKey,offline,split,replicaId;
info:server格式:HRegionServer对应的server:port;
info:serverstartcode格式是HRegionServer的启动时间戳。
HRegionServer结构
HRegionServer一般和DataNode在同一台机器上运行,实现数据的本地性。
HRegionServer包含多个HRegion,由WAL(HLog)、BlockCache、MemStore、HFile组成。
** WAL**
即Write Ahead Log,在早期版本中称为HLog,它是HDFS上的一个文件,如其名字所表示的,所有写操作都会先保证将数据写入这个Log文件后,才会真正更新MemStore,最后写入HFile中。采用这种模式,可以保证HRegionServer宕机后,我们依然可以从该Log文件中读取数据,Replay所有的操作,而不至于数据丢失。这个Log文件会定期Roll出新的文件而删除旧的文件。HBase 1.0之后,通过HBASE-5699实现了多个WAL并行写(MultiWAL),该实现采用HDFS的多个管道写,以单个HRegion为单位。关于WAL可以参考Wikipedia的Write-Ahead Logging。
BlockCache
是一个读缓存,即“引用局部性”原理,将数据预读取到内存中,以提升读的性能。
HBase中提供两种BlockCache的实现:on-heap LruBlockCache和BucketCache(通常是off-heap)。
通常BucketCache的性能要差于LruBlockCache,然而由于GC的影响,LruBlockCache的延迟会变的不稳定,而BucketCache由于是自己管理BlockCache,而不需要GC,因而它的延迟通常比较稳定,这也是有些时候需要选用BucketCache的原因。这篇文章BlockCache101对on-heap和off-heap的BlockCache做了详细的比较
更详细的底层结构参考:
HBase容错性和Hbase使用场景、Hbase读写过程详解
https://blog.csdn.net/qq_37095882/article/details/78129295
HBase容错性
该机制用于数据的容错和恢复:
1.每个HRegionServer中都有一个HLog对象,HLog是一个实现Write Ahead Log的类,在每次用户操作写入MemStore的同时,也会写一份数据到HLog文件中(HLog文件格式见后续),HLog文件定期会滚动出新的,并删除旧的文件(已持久化到StoreFile中的数据)。
2.当HRegionServer意外终止后,HMaster会通过Zookeeper感知到,HMaster首先会处理遗留的HLog文件,
3.将其中不同Region的Log数据进行拆分,分别放到相应region的目录下,然后再将失效的region重新分配,领取到这些region的HRegionServer在Load Region的过程中,会发现有历史HLog需要处理,因此会Replay HLog中的数据到MemStore中,然后flush到StoreFiles,完成数据恢复。
Master容错:Zookeeper重新选择一个新的Master
无Master过程中,数据读取仍照常进行;
无master过程中,region切分、负载均衡等无法进行;
RegionServer容错:定时向Zookeeper汇报心跳,如果一旦时间内未出现心跳,Master将该RegionServer上的Region重新分配到其他RegionServer上,失效服务器上“预写”日志由主服务器进行分割并派送给新的RegionServer
Zookeeper容错:Zookeeper是一个可靠地服务,一般配置3或5个Zookeeper实例
问题
HBase中的数据为何不直接存放于HDFS之上?
HBase中存储的海量数据记录,通常在几百Bytes到KB级别,如果将这些数据直接存储于HDFS之上,会导致大量的小文件产生,为HDFS的元数据管理节点(NameNode)带来沉重的压力。
文件能否直接存储于HBase里面?
如果是几MB的文件,其实也可以直接存储于HBase里面,我们暂且将这类文件称之为小文件,HBase提供了一个名为MOB的特性来应对这类小文件的存储。但如果是更大的文件,强烈不建议用HBase来存储,关于这里更多的原因,希望你在详细读完本文所有内容之后能够自己解答。
HBase meta Region在哪里提供服务?
HBase是否可以保证单行操作的原子性?
Region中写WAL与写MemStore的顺序是怎样的?
你是否遇到过Region长时间处于RIT的状态? 你认为旧版本中Assignment Manager的主要问题是什么?
在面对Full GC问题时,你尝试做过哪些优化?
你是否深究过HBase Compaction带来的“写放大”有多严重?
HBase的RPC框架存在什么问题?
原文:https://blog.csdn.net/yowoyn/article/details/79765132
版权声明:本文为博主原创文章,转载请附上博文链接!
实际操作
创建表 create ‘表名称’, ‘列名称1’,’列名称2’,’列名称N’
添加记录 put ‘表名称’, ‘行名称’, ‘列名称:’, ‘值’
查看记录 get ‘表名称’, ‘行名称’
查看表中的记录总数 count ‘表名称’
删除记录 delete ‘表名’ ,’行名称’ , ‘列名称’
删除一张表 先要屏蔽该表,才能对该表进行删除,第一步 disable ‘表名称’ 第二步 drop ‘表名称’
查看所有记录 scan “表名称”
查看某个表某个列中所有数据 scan “表名称” , [‘列名称:’]
更新记录 就是重写一遍进行覆盖
namespace操作
hbase>create_namespace 'ai_ns' #创建namespace
hbase>drop_namespace 'ai_ns' #删
hbase>describe_namespace 'ai_ns' # 查看namespace
hbase>create 'ai_ns:testtable', 'fm1' #在namespace下创建表
hbase>list_namespace_tables 'ai_ns' #查看namespace下的表
权限
具备Create权限的namespace Admin可以对表创建和删除、生成和恢复快照
具备Admin权限的namespace Admin可以对表splits或major compactions
hbase>grant 'tenant-A' 'W' '@ai_ns'
hbase>revoke 'tenant-A''@ai_ns'
创建namespace并授权写操作给用户
hbase>namespace_create 'hbase_perf'
hbase>grant 'mike', 'W', '@hbase_perf'
表操作
## 创建表't1',列簇'f1'、'f2'、'f3',各项列簇属性使用默认
hbase> create 't1', 'f1', 'f2', 'f3'
## 创建表't_bamboo',列簇'f1',列簇属性(最大版本为1、TTL 时间1000s,启用 blockcache)
hbase> create 't_bamboo', {NAME => 'f1', VERSIONS => 1, TTL => 1000, BLOCKCACHE => true}
create 't_bamboo',{NAME => 'f1', VERSIONS => 2},{NAME => 'f2', VERSIONS => 2}
alter table
只放入想修改的属性即可,不用把所有属性填进去;
操作之前先 disable 表,以免出现异常;
可新增、删除、修改表的属性;
可新增/删除列簇、修改列簇的属性;
可同时操作多个列簇;
hbase> desc 't_bamboo' ## 修改表之前建议先禁用
hbase> alter 't_bamboo', NAME => 'f1', VERSIONS => 5 ## 修改列簇'f1'的最大版本为5
hbase> alter 'ns1:t_bamboo', NAME => 'f1', METHOD => 'delete' ## 删除表’ns1:t1’的列簇‘f1’
hbase> alter 't_bamboo', {NAME => 'f2', IN_MEMORY => true}, {NAME => 'f4', VERSIONS => 5} ## 同时修改列簇‘f2’,增加‘f4’
hbase> alter 't_bamboo', 'delete' => 'f1'
hbase> drop 'myHbase' ##删除表,disable 'myHbase'
添加数据
>create 'user_info',{NAME=>'base_info',VERSIONS=>3 },{NAME=>'extra_info',VERSIONS=>1 }
>list
put 'user_info', 'zhangsan_20150701_0001', 'base_info:name', 'zhangsan1'
put 'user_info', 'zhangsan_20150701_0002', 'base_info:name', 'zhangsan2'
put 'user_info', 'zhangsan_20150701_0003', 'base_info:name', 'zhangsan3'
put 'user_info', 'zhangsan_20150701_0004', 'base_info:name', 'zhangsan4'
put 'user_info', 'zhangsan_20150701_0005', 'base_info:name', 'zhangsan5'
put 'user_info', 'zhangsan_20150701_0006', 'base_info:name', 'zhangsan6'
put 'user_info', 'zhangsan_20150701_0007', 'base_info:name', 'zhangsan7'
put 'user_info', 'zhangsan_20150701_0008', 'base_info:name', 'zhangsan8'
put 'user_info', 'zhangsan_20150701_0001', 'base_info:age', '21'
put 'user_info', 'zhangsan_20150701_0002', 'base_info:age', '22'
put 'user_info', 'zhangsan_20150701_0003', 'base_info:age', '23'
put 'user_info', 'zhangsan_20150701_0004', 'base_info:age', '24'
put 'user_info', 'zhangsan_20150701_0005', 'base_info:age', '25'
put 'user_info', 'zhangsan_20150701_0006', 'base_info:age', '26'
put 'user_info', 'zhangsan_20150701_0007', 'base_info:age', '27'
put 'user_info', 'zhangsan_20150701_0008', 'base_info:age', '28'
put 'user_info', 'zhangsan_20150701_0001', 'extra_info:Hobbies', 'music'
put 'user_info', 'zhangsan_20150701_0002', 'extra_info:Hobbies', 'sport'
put 'user_info', 'zhangsan_20150701_0003', 'extra_info:Hobbies', 'music'
put 'user_info', 'zhangsan_20150701_0004', 'extra_info:Hobbies', 'sport'
put 'user_info', 'zhangsan_20150701_0005', 'extra_info:Hobbies', 'music'
put 'user_info', 'zhangsan_20150701_0006', 'extra_info:Hobbies', 'sport'
put 'user_info', 'zhangsan_20150701_0007', 'extra_info:Hobbies', 'music'
put 'user_info', 'baiyc_20150716_0001', 'base_info:name', 'baiyc1'
put 'user_info', 'baiyc_20150716_0002', 'base_info:name', 'baiyc2'
put 'user_info', 'baiyc_20150716_0003', 'base_info:name', 'baiyc3'
put 'user_info', 'baiyc_20150716_0004', 'base_info:name', 'baiyc4'
put 'user_info', 'baiyc_20150716_0005', 'base_info:name', 'baiyc5'
put 'user_info', 'baiyc_20150716_0006', 'base_info:name', 'baiyc6'
put 'user_info', 'baiyc_20150716_0007', 'base_info:name', 'baiyc7'
put 'user_info', 'baiyc_20150716_0008', 'base_info:name', 'baiyc8'
put 'user_info', 'baiyc_20150716_0001', 'base_info:age', '21'
put 'user_info', 'baiyc_20150716_0002', 'base_info:age', '22'
put 'user_info', 'baiyc_20150716_0003', 'base_info:age', '23'
put 'user_info', 'baiyc_20150716_0004', 'base_info:age', '24'
put 'user_info', 'baiyc_20150716_0005', 'base_info:age', '25'
put 'user_info', 'baiyc_20150716_0006', 'base_info:age', '26'
put 'user_info', 'baiyc_20150716_0007', 'base_info:age', '27'
put 'user_info', 'baiyc_20150716_0008', 'base_info:age', '28'
put 'user_info', 'baiyc_20150716_0001', 'extra_info:Hobbies', 'music'
put 'user_info', 'baiyc_20150716_0002', 'extra_info:Hobbies', 'sport'
put 'user_info', 'baiyc_20150716_0003', 'extra_info:Hobbies', 'music'
put 'user_info', 'baiyc_20150716_0004', 'extra_info:Hobbies', 'sport'
put 'user_info', 'baiyc_20150716_0005', 'extra_info:Hobbies', 'music'
put 'user_info', 'baiyc_20150716_0006', 'extra_info:Hobbies', 'sport'
put 'user_info', 'baiyc_20150716_0007', 'extra_info:Hobbies', 'music'
put 'user_info', 'baiyc_20150716_0008', 'extra_info:Hobbies', 'sport'
直接粘贴进去,回车即可全部插入到user_info表中,[以上数据来源于Frankdeng]
查询数据
获取 user 表中 row key 为 user0001 的所有信息
#全表的所有数据
scan 'user_info'
#查询user_info表中列簇为base_info的信息
scan 'user_info', {COLUMNS => 'base_info'}
#表row key为baiyc_20150716_0001的所有数据
get 'user_info', 'baiyc_20150716_0001' 数据
#表row key为baiyc_20150716_0001的,列标示符为base_info:name的数据
get 'user_info', 'baiyc_20150716_0001', 'base_info:name'
删delete
删除user_info表row key为baiyc_20150716_0001,列标示符为base_info:name的数据
delete 'user_info', 'zhangsan_20150701_0008', 'base_info:name'
get 'user_info', 'baiyc_20150716_0001', 'base_info:name' #已经查不到了
额外资料
hadoop
https://www.cnblogs.com/codeOfLife/category/811619.html
CDH 大数据集群集中管理安装工具使用
https://www.cnblogs.com/raphael5200/p/5294066.htmlhttps://www.cnblogs.com/raphael5200/p/5294066.html