(1)创建ns1命名空间下的t1表,列簇为f1,指定列的最大版本数为5:
hbase> create 'ns1:t1', {NAME => 'f1', VERSIONS => 5}
(2)创建t1表,拥有三个列簇f1、f2和f3:
hbase> create 't1', {NAME => 'f1'}, {NAME => 'f2'}, {NAME => 'f3'}
上面语句等价于如下简写形式:
hbase> create 't1', 'f1', 'f2', 'f3'
(3)创建t1表,列簇为f1,最大版本数为1,表的生存时间为2592000,使用blockcache缓存hbase表中读写的数据:
hbase> create 't1', {NAME => 'f1', VERSIONS => 1, TTL => 2592000, BLOCKCACHE => true}
(4)对表进行预分区:
默认情况的情况下,创建一个HBase表,自动为表分配一个Region。结合实际使用来看,无论是在测试环境还生产环境,我们创建好HBase一张表以后,需要往表中导入大量的数据。file/datas 生成 hfile 用 bulk load 工具导入到 hbase table中。 而当短时间导入大量数据时,RegionServer会负载过大,因此我们需要把数据拆分,插入不同的region中,而我们怎么知道要将哪些数据插入哪个region中呢 ? 解决方案:创建表时,多创建一些Region(结合业务,依据表的rowkey进行设计)被多个RegionServer进行管理,这样,在插入数据时,会向多个Region中分别插入对应的数据,RegionServer的负载就均衡了。而在创建表的时候,预先创建一些Region,叫做HBase 表的预分区。Region划分,依赖于rowkey,需要预先预估一些rowkey。
hbase> create 'ns1:t1', 'f1', SPLITS => ['10', '20', '30', '40'] 用指定rowkey值预分区
hbase> create 't1', 'f1', SPLITS_FILE => '/opt/moduels/hbase-0.98.6-hadoop2/splits.txt', OWNER => 'johndoe' 在文件中写入rowkey值预分区
hbase> create 't1', 'f1', {NUMREGIONS => 15, SPLITALGO => 'HexStringSplit'} 指定region数为15个,用类来预分区
(5)针对namespace的操作:
Group name: namespace
Commands: alter_namespace, create_namespace, describe_namespace, drop_namespace, list_namespace, list_namespace_tables
如何在海量数据中,获取我所需要的数据(查询的数据)? 核心思想:依据rowkey查询最快,考虑对rowkey进行范围查询,在不同的region中查询,考虑rowkey的前缀匹配。 RowKey设计的长度原则:最长64KB,一般建议:10-100个字节,不宜过长。 RowKey设计的散列原则:将多个字段进行组合,如timestamp+uuid或uuid+timestamp。也可以反转字段,如反转时间字段。 可以设计索引表的rowkey为timestamp+uuid,原表的rowkey为uuid+timestamp。难点:原表和索引表的数据同步(解决方法:协处理器,类似触发器的概念,或者一些协处理器框架:solr 、elasticsearch、终结者类endpoint、动态存储过程等)。这样可以用索引表通过时间段找所有人的通话记录,也可以用原表找某一个电话号码的在一定时间段内的通话记录。 rowkey的设计示例: (1)telphone + (starttime - endtime); (2)telphone + time; 可以设计索引表,索引表的: rowkey:timestamp_phone 列簇:info 列:原表的rowkey:phone_timestamp 然后使用get方式查询数据,get方式是最快的数据查询。
主表和索引表的数据如何同步?
微博案例 【功能需求】发微博(微博包括文字、图片、视频、链接、话题 #话题#、@用户),关注用户,粉丝,推送,关系制度。 【微博内容表】发微博 TableName:weibo-content; RowKey:uid_timestamp,用户账号结合内容发布的时间戳; Column Family:cf,因为rowkey是使用用户账号结合内容发布的时间戳,所以这里内容保存的版本只会有一个版本; Column Qualifier:theme(主题),content(内容),photo(图片)。 【用户关系表】 TableName:relations; RowKey:uid; Column Family:cf1,关注用户; Column Qualifier:使用关注用户的uid作为列标签,value也用关注用户的uid; Column Family:cf2,粉丝用户; Column Qualifier:使用粉丝用户的uid作为列标签,value也用粉丝用户的uid。 【微博接收内容邮件箱表】 TableName:receive-content-email; RowKey:uid 用户账号; Column Family:cf; Column Qualifier:以关注用户账号作为列标签,以微博内容表的rowkey作为value,保留版本数 1000(最大版本1000,最小版本1000,版本存留时间3652460*60); rowkey:uid账号。 例如:用户A关注了用户B,则Column Qualifier:B,value:B所发的所有微博在微博内容表中存储的rowkey。
(1)Haodop支持的压缩格式:
[beifeng@hadoop-senior hadoop-2.5.0]$ bin/hadoop checknative
(2)配置HBase
$ export HBASE_HOME=/opt/modules/hbase-0.98.6-cdh5.3.6 $ export HADOOP_SNAPPY_HOME=/opt/modules/hadoop-snappy-0.0.1-SNAPSHOT $ export HADOOP_HOME=/opt/modules/hadoop-2.5.0-cdh5.3.6 $ cp $HADOOP_SNAPPY_HOME/lib/hadoop-snappy-0.0.1-SNAPSHOT.jar $HBASE_HOME/lib $ mkdir $HBASE_HOME/lib/native $ ln -s $HADOOP_HOME/lib/native $HBASE_HOME/lib/native/Linux-amd64-64
(3)在hbase-site.xml中设置如下属性:
<property>
<name>hbase.regionserver.codecs</name>
<value>snappy</value>
</property>
(4)在hbase中创建表时指定压缩格式为snappy:
hbase(main):001:0> create 'test', {NAME => 'cf', COMPRESSION => 'SNAPPY'}
(1)Memstore HBase上Regionserver的内存分为两个部分,一部分作为Memstore,主要用来写;另外一部分作为BlockCache,主要用于读。 写请求会先写入Memstore,Regionserver会给每个region提供一个Memstore,当Memstore满64MB以后,会启动 flush刷新到磁盘。当Memstore的总大小超过限制时(heapsize * hbase.regionserver.global.memstore.upperLimit * 0.9),会强行启动flush进程,从最大的Memstore开始flush直到低于限制。 (2)BlockCache 将Cache分级思想的好处在于: 首先,通过inMemory类型Cache,可以有选择地将in-memory的column families放到RegionServer内存中,例如Meta元数据信息;通过区分Single和Multi类型Cache,可以防止由于Scan操作带来的Cache频繁颠簸,将最少使用的Block加入到淘汰算法中。默认配置下,对于整个BlockCache的内存,又按照以下百分比分配给Single、Multi、InMemory使用:0.25、0.50和0.25。其中InMemory队列用于保存HBase Meta表元数据信息,因此如果将数据量很大的用户表设置为InMemory的话,可能会导致Meta表缓存失效,进而对整个集群的性能产生影响。 (3)Memstore 与 BlockCache的配合
在内存中, MemStore大约占据40%的内存,主要用于写入数据,BlockCache大约占据40%的内存,主要用于读取数据,其他大约占据20%的内存。 当用户去读取数据,首先查询MemStore,然后查询BlockCache,每个RegionServer只有一个BlockCache,最后到HDFS中的hfile中查询,然后把查询到的数据进行合并,返回数据集。
读请求先到Memstore中查数据,查不到就到BlockCache中查,再查不到就会到磁盘上读,并把读的结果放入BlockCache。由于BlockCache采用的是LRU策略,因此BlockCache达到上限(heapsize * hfile.block.cache.size * 0.85)后,会启动淘汰机制,淘汰掉最老的一批数据。在注重读响应时间的应用场景下,可以将 BlockCache设置大些,Memstore设置小些,以加大缓存的命中率。
(4)Memstore和BlockCache的参数设置
属性 | 值 | 说明 |
---|---|---|
RegionServer中所有MemStore的最大大小 | hbase.regionserver.global.memstore.upperLimit=0.4(默认值) | 阻止新更新和强迫刷新前,RegionServer的所有memstore的最大大小 |
Memstore刷新的低水位线 | hbase.regionserver.global.memstore.lowerLimit=0.38(默认值) | 当memstores被迫刷新以节省内存时,请一直刷新直到达到此数量,如此数量等于hbase.regionserver.global.memstore.upperLimit,则由于memstore限制,阻止更新时,可能会最低限度地进行刷新 |
HBase Memstore刷新大小 | hbase.hregion.memstore.flush.size=128MB(默认值) | 如memstore大小超过此值(字节数),Memstore将刷新到磁盘,通过运行由hbase.server.thread.wakefrequency指定的频率的线程检查此值,如果不希望自动触发溢写,就将值调大 |
HFile块缓存大小 | hfile.block.cache.size=0.4(默认值) | 用于阻止HFile/StoreFile使用的缓存所分配的最大堆(-Xmx设置)的百分比。要禁用,请将此值设置为0。 |
HRegion中文件最大大小 | hbase.hregion.max.filesize=10737418240 | 到达最大大小触发split操作,一般建议将值调大,在期间手动去触发split |
(1)HRegoin Server上的storefile文件是被后台线程监控的,以确保这些文件保持在可控状态。磁盘上的storefile的数量会随着越来越多的memstore被刷新而变得越来越多——每次刷新都会生成一个storefile文件。当storefile数量满足一定条件时(可以通过配置参数类调整),会触发文件合并操作——minor compaction,将多个比较小的storefile合并成一个大的storefile文件,直到合并的文件大到超过单个文件配置允许的最大值时会触发一次region的自动分割,即region split操作,将一个region平分成2个。 (2)minor compaction,轻量级 minor compaction将符合条件的最早生成的几个storefile合并生成一个大的storefile文件,它不会删除被标记为“删除”的数据和以过期的数据,并且执行过一次minor合并操作后还会有多个storefile文件。 (3)major compaction,重量级 major compaction把所有的storefile合并成一个单一的storefile文件,在文件合并期间系统会删除标记为"删除"标记的数据和过期失效的数据,同时会block所有客户端对该操作所属的region的请求直到合并完毕,最后删除已合并的storefile文件。一般在企业中这个参数是禁用的,直接将值设置为0就可以了,表示禁用。
<property>
<name>hbase.hregion.majorcompaction</name>
<value>604800000</value>
</property>
(1)在hbase shell命令行执行命令文件:$ bin/hbase shell command.txt
(2)hbase优雅关闭:$ bin/graceful_stop.sh
(3)hbase重启:bin/graceful_stop.sh --restart --reload --debug servername
(4)开启RegionServer的balancer负载均衡:balance_switch true或false
数据存储在HBase中,hive 表的描述信息存储在hive中。Hive就是HBase客户端。 HBase与Hive集成的两种方式: (1)管理表 创建hive表的时候,指定数据存储在hbase表中。
CREATE TABLE hbase_table_1(key int, value string)
STORED BY 'org.apache.hadoop.hive.hbase.HBaseStorageHandler'
WITH SERDEPROPERTIES ("hbase.columns.mapping" = ":key,cf1:val")
TBLPROPERTIES ("hbase.table.name" = "xyz");
(2)外部表 现在已经存在一个HBase表,需要对表中数据进行分析。
CREATE EXTERNAL TABLE hbase_user(id int, name string,age int)
STORED BY 'org.apache.hadoop.hive.hbase.HBaseStorageHandler'
WITH SERDEPROPERTIES ("hbase.columns.mapping" = ":key,info:name,info:age")
TBLPROPERTIES ("hbase.table.name" = "user");
需要导入的jar包:
export HBASE_HOME=/opt/modules/hbase-0.98.6-hadoop2
export HIVE_HOME=/opt/modules/hive-0.13.1/lib
ln -s $HBASE_HOME/lib/hbase-server-0.98.6-hadoop2.jar $HIVE_HOME/hbase-server-0.98.6-hadoop2.jar
ln -s $HBASE_HOME/lib/hbase-client-0.98.6-hadoop2.jar $HIVE_HOME/hbase-client-0.98.6-hadoop2.jar
ln -s $HBASE_HOME/lib/hbase-protocol-0.98.6-hadoop2.jar $HIVE_HOME/hbase-protocol-0.98.6-hadoop2.jar
ln -s $HBASE_HOME/lib/hbase-it-0.98.6-hadoop2.jar $HIVE_HOME/hbase-it-0.98.6-hadoop2.jar
ln -s $HBASE_HOME/lib/htrace-core-2.04.jar $HIVE_HOME/htrace-core-2.04.jar
ln -s $HBASE_HOME/lib/hbase-hadoop2-compat-0.98.6-hadoop2.jar $HIVE_HOME/lib/hbase-hadoop2-compat-0.98.6-hadoop2.jar
ln -s $HBASE_HOME/lib/hbase-hadoop-compat-0.98.6-hadoop2.jar $HIVE_HOME/lib/hbase-hadoop-compat-0.98.6-hadoop2.jar
ln -s /opt/modules/hbase-0.98.6-hadoop2/lib/high-scale-lib-1.1.1.jar /opt/modules/hive-0.13.1/lib/high-scale-lib-1.1.1.jar
使用命令如下:
$ sqoop import \
-- connect jdbc:mysql://localhost/serviceorderdb \
-- username root -P \
-- table customercontactinfo \
-- columns "customernum, contactinfo" \
-- hbase-table customercontactinfo \
-- column-family ContactInfo \
-- hbase-row-key customernum -m 1
(1)Thrift工具
Thrift所在的包:org.apache.hadoop.hbase.thrift
启动thriftserver:$ bin/hbase-daemon.sh start thrift
停止thriftserver:$ bin/hbase-daemon.sh stop thrift
(2)编辑配置文件/opt/app/hue-3.7.0-cdh5.3.6/desktop/conf/hue.ini
[hbase]
hbase_clusters=(Cluster|hadoop-senior.ibeifeng.com:9090)
hbase_conf_dir=/opt/modules/hbase-0.98.6-hadoop2/conf
(3)重新启动hbase及hue即可。
(1)HBase集群的设计
Node Name | Master | ZooKeeper | RegionServer |
---|---|---|---|
hadoop-senior.ibeifeng.com | yes | yes | no |
hadoop-senior02.ibeifeng.com | backup | yes | yes |
hadoop-senior03.ibeifeng.com | no | yes | yes |
(2)编辑配置文件/opt/modules/hbase-0.98.6-hadoop2/conf/hbase-site.xml。
<configuration>
<property>
<name>hbase.rootdir</name>
<value>hdfs://hadoop-senior.ibeifeng.com:8020/hbase</value>
</property>
<property >
<name>hbase.tmp.dir</name>
<value>/opt/app/hbase-0.98.6-hadoop2/data/tmp</value>
</property>
<property>
<name>hbase.cluster.distributed</name>
<value>true</value>
</property>
<property>
<name>hbase.zookeeper.quorum</name>
<value>hadoop-senior.ibeifeng.com,hadoop-senior02.ibeifeng.com,hadoop-senior03.ibeifeng.com</value>
</property>
</configuration>
(3)编辑配置文件/opt/modules/hbase-0.98.6-hadoop2/conf/regionservers。
hadoop-senior.ibeifeng.com
hadoop-senior02.ibeifeng.com
hadoop-senior03.ibeifeng.com
(4)编辑配置文件/opt/modules/hbase-0.98.6-hadoop2/conf/backup-masters。
hadoop-senior02.ibeifeng.com
hadoop-senior03.ibeifeng.com
(5)清空logs和data/tmp目录下的内容。 (6)将hbase目录分发到其他节点:
$ scp -r hbase-0.98.6-hadoop2/ hadoop-senior02.ibeifeng.com:/opt/app/
$ scp -r hbase-0.98.6-hadoop2/ hadoop-senior03.ibeifeng.com:/opt/app/
(7)启动主备HMaster和HRegionServer。
使用数据库: (1)RDBMS,无法满足海量数据实时查询,保存未完成订单,每个用户没有大量数据; (2)NoSQL,海量数据存储准实时查询 — HBase,保存已完成订单,每个用户都有大量数据。 数据分开存储优势: (1)分开存储,减轻在线订单库压力; (2)统一各个系统对历史订单的查询; (3)灵活支撑各种维度历史订单的条件查询。