1. hbase 存储为什么快
从根本上讲,
hbase是列式数据库,不是以行为连续存储的,二是以列为连续存储的。因此对列可以将从磁盘上连续地读取所有记录的某一列。充分发挥IO吞吐能力,读取自然会很快;
hbase是基于HDFS存储数据块的,可以将操作分散到多个节点并行地执行;
2. 解读Hadoop Hbase适合存储哪类数据
最适合使用Hbase存储的数据是非常稀疏的数据(非结构化或者半结构化的数据)。Hbase之所以擅长存储这类数据,是因为Hbase是column-oriented列导向的存储机制,而我们熟知的RDBMS都是row- oriented行导向的存储机制(郁闷的是我看过N本关于关系数据库的介绍从来没有提到过row- oriented行导向存储这个概念)。在列导向的存储机制下对于Null值得存储是不占用任何空间的。比如,如果某个表 UserTable有10列,但在存储时只有一列有数据,那么其他空值的9列是不占用存储空间的(普通的数据库MySql是如何占用存储空间的呢?)。 Hbase适合存储非结构化的稀疏数据的另一原因是他对列集合 column families 处理机制。 打个比方,ruby和python这样的动态语言和c++、java类的编译语言有什么不同? 对于我来说,最显然的不同就是你不需要为变量预先指定一个类型。Ok ,现在Hbase为未来的DBA也带来了这个激动人心的特性,你只需要告诉你的数据存储到Hbase的那个column families 就可以了,不需要指定它的具体类型:char,varchar,int,tinyint,text等等。 Hbase还有很多特性,比如不支持join查询,但你存储时可以用:parent-child tuple 的方式来变相解决。 由于它是Google BigTable的 Java 实现,你可以参考一下:google bigtable 。
解读Hadoop Hbase适合存储哪类数据,参考:http://e.51cto.com/course/course_id-3819.html
3. java api操作hbase存储数据为16进制如何设置存储为正常数值
一般情况下,我们使用Linux的shell命令,就可以非常轻松的操作Hbase,例如一些建表,建列簇,插值,显示所有表,统计数量等等,但有时为了提高灵活性,我们也需要使用编程语言来操作Hbase,当然Hbase通过Thrift接口提供了对大多数主流编程语言的支持,例如C++,PHP,Python,Ruby等等,那么本篇,散仙给出的例子是基于Java原生的API操作Hbase,相比其他的一些编程语言,使用Java操作Hbase,会更加高效一些,因为Hbase本身就是使用Java语言编写的。转载
下面,散仙给出源码,以供参考:
package com.hbase;
import java.util.ArrayList;
import java.util.List;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.HColumnDescriptor;
import org.apache.hadoop.hbase.HTableDescriptor;
import org.apache.hadoop.hbase.KeyValue;
import org.apache.hadoop.hbase.client.Delete;
import org.apache.hadoop.hbase.client.Get;
import org.apache.hadoop.hbase.client.HBaseAdmin;
import org.apache.hadoop.hbase.client.HTable;
import org.apache.hadoop.hbase.client.Put;
import org.apache.hadoop.hbase.client.Result;
import org.apache.hadoop.hbase.client.ResultScanner;
import org.apache.hadoop.hbase.client.Scan;
import org.apache.hadoop.hbase.util.Bytes;
/**
* @author 三劫散仙
*
* **/
public class Test {
static Configuration conf=null;
static{
conf=HBaseConfiguration.create();//hbase的配置信息
conf.set("hbase.zookeeper.quorum", "10.2.143.5"); //zookeeper的地址
}
public static void main(String[] args)throws Exception {
Test t=new Test();
//t.createTable("temp", new String[]{"name","age"});
//t.insertRow("temp", "2", "age", "myage", "100");
// t.getOneDataByRowKey("temp", "2");
t.showAll("temp");
}
/***
* 创建一张表
* 并指定列簇
* */
public void createTable(String tableName,String cols[])throws Exception{
HBaseAdmin admin=new HBaseAdmin(conf);//客户端管理工具类
if(admin.tableExists(tableName)){
System.out.println("此表已经存在.......");
}else{
HTableDescriptor table=new HTableDescriptor(tableName);
for(String c:cols){
HColumnDescriptor col=new HColumnDescriptor(c);//列簇名
table.addFamily(col);//添加到此表中
}
admin.createTable(table);//创建一个表
admin.close();
System.out.println("创建表成功!");
}
}
/**
* 添加数据,
* 建议使用批量添加
* @param tableName 表名
* @param row 行号
* @param columnFamily 列簇
* @param column 列
* @param value 具体的值
*
* **/
public void insertRow(String tableName, String row,
String columnFamily, String column, String value) throws Exception {
HTable table = new HTable(conf, tableName);
Put put = new Put(Bytes.toBytes(row));
// 参数出分别:列族、列、值
put.add(Bytes.toBytes(columnFamily), Bytes.toBytes(column),
Bytes.toBytes(value));
table.put(put);
table.close();//关闭
System.out.println("插入一条数据成功!");
}
/**
* 删除一条数据
* @param tableName 表名
* @param row rowkey
* **/
public void deleteByRow(String tableName,String rowkey)throws Exception{
HTable h=new HTable(conf, tableName);
Delete d=new Delete(Bytes.toBytes(rowkey));
h.delete(d);//删除一条数据
h.close();
}
/**
* 删除多条数据
* @param tableName 表名
* @param row rowkey
* **/
public void deleteByRow(String tableName,String rowkey[])throws Exception{
HTable h=new HTable(conf, tableName);
List<Delete> list=new ArrayList<Delete>();
for(String k:rowkey){
Delete d=new Delete(Bytes.toBytes(k));
list.add(d);
}
h.delete(list);//删除
h.close();//释放资源
}
/**
* 得到一条数据
*
* @param tableName 表名
* @param rowkey 行号
* ***/
public void getOneDataByRowKey(String tableName,String rowkey)throws Exception{
HTable h=new HTable(conf, tableName);
Get g=new Get(Bytes.toBytes(rowkey));
Result r=h.get(g);
for(KeyValue k:r.raw()){
System.out.println("行号: "+Bytes.toStringBinary(k.getRow()));
System.out.println("时间戳: "+k.getTimestamp());
System.out.println("列簇: "+Bytes.toStringBinary(k.getFamily()));
System.out.println("列: "+Bytes.toStringBinary(k.getQualifier()));
//if(Bytes.toStringBinary(k.getQualifier()).equals("myage")){
// System.out.println("值: "+Bytes.toInt(k.getValue()));
//}else{
String ss= Bytes.toString(k.getValue());
System.out.println("值: "+ss);
//}
}
h.close();
}
/**
* 扫描所有数据或特定数据
* @param tableName
* **/
public void showAll(String tableName)throws Exception{
HTable h=new HTable(conf, tableName);
Scan scan=new Scan();
//扫描特定区间
//Scan scan=new Scan(Bytes.toBytes("开始行号"),Bytes.toBytes("结束行号"));
ResultScanner scanner=h.getScanner(scan);
for(Result r:scanner){
System.out.println("==================================");
for(KeyValue k:r.raw()){
System.out.println("行号: "+Bytes.toStringBinary(k.getRow()));
System.out.println("时间戳: "+k.getTimestamp());
System.out.println("列簇: "+Bytes.toStringBinary(k.getFamily()));
System.out.println("列: "+Bytes.toStringBinary(k.getQualifier()));
//if(Bytes.toStringBinary(k.getQualifier()).equals("myage")){
// System.out.println("值: "+Bytes.toInt(k.getValue()));
//}else{
String ss= Bytes.toString(k.getValue());
System.out.println("值: "+ss);
//}
}
}
h.close();
}
}
4. 传统的行存储和(HBase)列存储的区别
列存储不同于传统的关系型数据库,其数据在表中是按行存储的,列方式所带来的重要好处之一就是,由于查询中的选择规则是通过列来定义的,因此整个数据库是自动索引化的。按列存储每个字段的数据聚集存储,在查询只需要少数几个字段的时候,能大大减少读取的数据量,一个字段的数据聚集存储,那就更容易为这种聚集存储设计更好的压缩/解压算法。
传统的(Oracle)行存储和(Hbase)列存储的区别
这里写图片描a
1、数据是按行存储的
2、没有索引的查询使用大量I/O
3、建立索引和物化视图需要花费大量时间和资源
4、面对查询的需求,数据库必须被大量膨胀才能满足性能需求
这里写图片描述
1、数据按列存储–每一列单独存放
2、数据即是索引
3、只访问查询涉及的列–大量降低系统IO
4、每一列由一个线索来处理–查询的并发处理
5、数据类型一致,数据特征相似–高效压缩
5. hbase可以存储 图片吗如果可以怎么存储
hbase是分布式数据库,什么数据都能存。
hbase是没有类型的,全是二进制字节。
你去看看 habse的 client API
6. 储存框架HBase是啥
分布式数据库系统
7. HBase数据到底是怎么存储的
每个列簇对应HDFS中的一个单独文件,hbase不是按行存储,你想一行有多列族的情况下,就会把数据存在多个文件下,按行存储的意思,是会把行数据存在一个文件中,所以hbase是按列存储的。
应该说hbase和传统关系型数据库还是有些相似的地方,起码在hfile中hbase列族下一行的列是相邻存储的,这点跟传统关系型数据库应该是类似的。
8. hbase依靠什么存储底层数据
行导向的存储机制
9. 如果有几百亿条数据,如何在hbase表中存放
1、首先你有没有那么多台服务器的集群,如果只是几台,你要想够不够,你的hbase 有几百亿,那么你hdfs上的数据可能要有两个备份,你这几百亿条是如何生成的,肯定是maprece跑出来导入到hbase中把,那么原始数据你要不要留,如果留,加上备份就要三份,所以节点的多少要确定。
2、几百亿其实挺多的,hbase 的设计一定要跟你的业务相关,hbase他不能完全像关系型数据库那样去随意查询,到达一定量级,如果设计的不好也是非常之慢的,甚至将hbase搞到崩溃。所以你先去网上看看rowkey的设计原则,比如长度原则等等,然后根据自己业务,哪些查询经常用到,哪些不会用到,想要用hbase实现那种非常灵活的类似关系数据库的查询是不理智的。
3、楼上的兄弟说得对,还有region热点的问题,如果你的hbase数据不是那种每天增量的数据,建议跑个maprece对你的数据进行各评判,看看如何能将数据尽可能均匀的分配到每个region中,当然这需要预先分配region
4、几百亿条数据,如果对rowkey进行模糊过滤一定非常非常之慢,所以可以考虑二级索引或者协处理器
10. hbase 如何存储数据
HBASE中的表示按column family来存储的
建立一个有3个column family的表
create 't1', {NAME => 'f1', VERSIONS => 1}, {NAME => 'f2', VERSIONS => 1}, {NAME => 'f3', VERSIONS => 1}
定义表的时候只需要指定column family的名字,列名在put的时候动态指定
插入数据
下面插入没有指定column的名字
put 't1', 'r1', 'f1', 'v1'
put 't1', 'r2', 'f2', 'v2'
put 't1', 'r3', 'f3', 'v3'
下面插入指定column的名字
put 't1', 'r4', 'f1:c1', 'v1'
put 't1', 'r5', 'f2:c2', 'v2'
put 't1', 'r6', 'f3:c3', 'v3'
hbase(main):245:0> scan 't1'
ROW COLUMN+CELL
r1 column=f1:, timestamp=1335407967324, value=v1
r2 column=f2:, timestamp=1335408004559, value=v2
r4 column=f1:c1, timestamp=1335408640777, value=v1
r5 column=f2:c1, timestamp=1335408640822, value=v2
r6 column=f1:c6, timestamp=1335412392258, value=v3
r6 column=f2:c1, timestamp=1335412384739, value=v3
r6 column=f2:c2, timestamp=1335412374797, value=v3
插入多列的数据
put 't1', 'r7', 'f1:c4', 'v9'
put 't1', 'r7', 'f2:c3', 'v9'
put 't1', 'r7', 'f3:c2', 'v9'
手工把memstore写到Hfile中
flush 't1'
删除所有CF3的数据
deleteall 't1','r7'
flush 't1'
每次flash都会建一个新的hfile
$ ../bin/hadoop dfs -lsr /hbase/t1
数据时直接存到CF目录下的,每个CF目录下有3到4个Hfile
f1
f1/
f1/321c683f48dd91e058179486587e
f1/
f2
f2/
f2/
f2/
f3
f3/
f3/
f3/
f3/
f3都数据虽然都被删除了,由于没有合并文件都存在
手工合并hfile
hbase(main):244:0> compact 't1'
0 row(s) in 0.0550 seconds
$ ../bin/hadoop dfs -lsr /hbase/t1
f1
f1/
f2
f2/
/f3
f1和f2下就只有一个hfile,f3下面没有hfile因为数据都被删除了
一次只能put一个column
一次只能delete一个column
删除整行,用deleteall
deleteall 't1', 'r1'
了解更多开源相关,去LUPA社区看看吧。