太多column family的影响
每个 MemoryStore分配到的内存较少,进而导致过多的合并,影响性能
 

几个column family比较合适呢

推荐是:1-3个
划分column family的原则:
1、是否具有相似的数据格式
2、是否具有相似的访问类型
例子一: 相同的rowkey,有一个很大的text数据需要存储,又有一个picture数据需要存储
对于很大的text数据我们肯定是想让它Compress后再存储
而picture的数据呢,我们并不想让他压缩后存储,因为对于这种二进制的数据压缩并不能节省空间
所以,我们可以将这两个数据分成两个column family来存储
create 'table',{NAME => 't', COMPRESSION => 'SNAPPY'},
{NAME => 'p'}
 

几个column family比较合适呢

例子二: 有一张hbase表,需要存储每个用户的信息(比如名字、年龄等)和这个用户每天访问网站的信息
对于用户的信息,不经常变,而且量少
对于用户每天访问网站的信息是经常变化且数据量很大的
如果将这两种信息放在同一个column family中的话,用户每天访问网站的信息数据的增大导致会出现memory store的flush,然后会导致compaction,因为compaction是column family级别的,所以会将每个用户的信息(比如名字、年龄等)和这个用户每天访问网站的信息都合并到文件中
 
 
其实用户的信息不大,且不经常变,没必要每次compaction都要将用户的信息写到磁盘中,导致资源的浪费
所以可以将用户的信息和用户每天访问网站的信息分成两个column family来存储
 
 

Table Schema的设计

1、每一个region的大小在10到50G
2、每一个table控制在50-100个regions
3、每一个table控制在1到3个column family
4、每一个column family的命名最好要短,因为column family是会存储在数据文件中的
 
 

RowKey的设计一

 
长度原则:
rowkey的长度一般被建议在10-100个字节,不过建议是越短越好
1、数据持久化文件HFile是按照keyvalue存储的,如果rowkey过长,比如100个字节,1000万列数据光Rowkey就要占用100*1000万=10亿个字节,将近1G数据,这会极大影响HFile的存储效率
 
2、MemStore将缓存部分数据到内存,如果Rowkey字段过长内存的有效利用率会降低,系统将无法缓存更多的数据,这会降低检索效率。因此Rowkey的字节长度越短越好。
 
3、目前操作系统是都是64位系统,内存8字节对齐。如果rowkey是8字节的整数倍的话,则利用了操作系统的最佳特性。
 

RowKey的设计二

特性: rowkey是按照字典顺序进行存储的
相似的rowkey会存储在同一个Region中
比如,我们的rowkey是网站的域名,如下:
www.apache.org
mail.apache.org
jira.apache.org
 
 
 
将域名反转作为rowkey的话更好点,如下:
org.apache.www
org.apache.mail
org.apache.jira
 
 

RowKey的设计三

因为rowkey是按照字典顺序存储的,所以如果rowkey没有设计好的话,还会引发:
Hotspotting:大量的请求只发往到一个Region中
解决Hotspotting的三个方法:
1、Salting((撒盐似的)散布、加盐)
create 'test_salt', 'f',SPLITS => ['b','c','d']
 
 
原始的rowkey:
boo0001
boo0002
boo0003
boo0004
boo0005
boo0003
 
 
salting rowkey:
a-boo0001
b-boo0002
c-boo0003
d-boo0004
a-boo0005
d-boo0003
 
  1. import java.util.ArrayList;
  2. import java.util.List;
  3. import java.util.concurrent.atomic.AtomicInteger;
  4.  
  5. public class KeySalter {
  6. private AtomicInteger index = new AtomicInteger(0);
  7.  
  8. private String[] prefixes = {"a", "b", "c", "d"};
  9.  
  10. public String getRowKey(String originalKey) {
  11. StringBuilder sb = new StringBuilder(prefixes[index.incrementAndGet() % 4]);
  12. sb.append("-").append(originalKey);
  13. return sb.toString();
  14. }
  15.  
  16. public List<String> getAllRowKeys(String originalKey) {
  17. List<String> allKeys = new ArrayList<>();
  18. for (String prefix : prefixes) {
  19. StringBuilder sb = new StringBuilder(prefix);
  20. sb.append("-").append(originalKey);
  21. allKeys.add(sb.toString());
  22. }
  23. //a-boo0001
  24. //b-boo0001
  25. //c-boo0001
  26. //d-boo0001
  27. return allKeys;
  28. }
  29. }

  

  1. import org.apache.hadoop.conf.Configuration;
  2. import org.apache.hadoop.hbase.HBaseConfiguration;
  3. import org.apache.hadoop.hbase.TableName;
  4. import org.apache.hadoop.hbase.client.Connection;
  5. import org.apache.hadoop.hbase.client.ConnectionFactory;
  6. import org.apache.hadoop.hbase.client.Put;
  7. import org.apache.hadoop.hbase.client.Table;
  8. import org.apache.hadoop.hbase.util.Bytes;
  9.  
  10. import java.io.IOException;
  11. import java.util.ArrayList;
  12. import java.util.Arrays;
  13. import java.util.List;
  14.  
  15. public class SaltingTest {
  16. public static void main(String[] args) throws IOException {
  17. Configuration config = HBaseConfiguration.create();
  18.  
  19. try (Connection connection = ConnectionFactory.createConnection(config);
  20. Table table = connection.getTable(TableName.valueOf("test_salt"))) {
  21.  
  22. KeySalter keySalter = new KeySalter();
  23.  
  24. List<String> rowkeys = Arrays.asList("boo0001", "boo0002", "boo0003", "boo0004");
  25. List<Put> puts = new ArrayList<>();
  26. for (String key : rowkeys) {
  27. Put put = new Put(Bytes.toBytes(keySalter.getRowKey(key)));
  28. put.addColumn(Bytes.toBytes("f"), null, Bytes.toBytes("value" + key));
  29. puts.add(put);
  30. }
  31. table.put(puts);
  32. }
  33. }
  34.  
  35. }

  

  1. import org.apache.hadoop.conf.Configuration;
  2. import org.apache.hadoop.hbase.HBaseConfiguration;
  3. import org.apache.hadoop.hbase.TableName;
  4. import org.apache.hadoop.hbase.client.*;
  5. import org.apache.hadoop.hbase.util.Bytes;
  6.  
  7. import java.io.IOException;
  8. import java.util.ArrayList;
  9. import java.util.Arrays;
  10. import java.util.List;
  11.  
  12. public class SaltingGetter {
  13. public static void main(String[] args) throws IOException {
  14. Configuration config = HBaseConfiguration.create();
  15.  
  16. try (Connection connection = ConnectionFactory.createConnection(config);
  17. Table table = connection.getTable(TableName.valueOf("test_salt"))) {
  18. KeySalter keySalter = new KeySalter();
  19. List<String> allKeys = keySalter.getAllRowKeys("boo0001"); //读取boo001
  20. List<Get> gets = new ArrayList<>();
  21.  
  22. for (String key : allKeys) {
  23. Get get = new Get(Bytes.toBytes(key));
  24. gets.add(get);
  25. }
  26.  
  27. Result[] results = table.get(gets);
  28.  
  29. for (Result result : results) {
  30. if (result != null) {
  31. //do something
  32. }
  33. }
  34. }
  35. }
  36.  
  37. }

  RowKey的设计三

2、Hashing
create 'test_hash', 'f', { NUMREGIONS => 4, SPLITALGO => 'HexStringSplit' }
原始的rowkey:
boo0001
boo0002
boo0003
boo0004
 
md5 hash rowkey:
4b5cdf065e1ada3dbc8fb7a65f6850c4
b31e7da79decd47f0372a59dd6418ba4
d88bf133cf242e30e1b1ae69335d5812
f6f6457b333c93ed1e260dc5e22d8afa
 
  1. import org.apache.hadoop.hbase.util.MD5Hash;
  2.  
  3. public class KeyHasher {
  4.  
  5. public static String getRowKey(String originalKey) {
  6. return MD5Hash.getMD5AsHex(originalKey.getBytes());
  7. }
  8.  
  9. }

  

  1. package com.twq.hbase.rowkey.hash;
  2.  
  3. import org.apache.hadoop.conf.Configuration;
  4. import org.apache.hadoop.hbase.HBaseConfiguration;
  5. import org.apache.hadoop.hbase.TableName;
  6. import org.apache.hadoop.hbase.client.Connection;
  7. import org.apache.hadoop.hbase.client.ConnectionFactory;
  8. import org.apache.hadoop.hbase.client.Put;
  9. import org.apache.hadoop.hbase.client.Table;
  10. import org.apache.hadoop.hbase.util.Bytes;
  11.  
  12. import java.io.IOException;
  13. import java.util.ArrayList;
  14. import java.util.Arrays;
  15. import java.util.List;
  16.  
  17. public class HashingTest {
  18. public static void main(String[] args) throws IOException {
  19. Configuration config = HBaseConfiguration.create();
  20.  
  21. try (Connection connection = ConnectionFactory.createConnection(config);
  22. Table table = connection.getTable(TableName.valueOf("test_hash"))) {
  23.  
  24. List<String> rowkeys = Arrays.asList("boo0001", "boo0002", "boo0003", "boo0004");
  25. List<Put> puts = new ArrayList<>();
  26. for (String key : rowkeys) {
  27. Put put = new Put(Bytes.toBytes(KeyHasher.getRowKey(key)));
  28. put.addColumn(Bytes.toBytes("f"), null, Bytes.toBytes("value" + key));
  29. puts.add(put);
  30. }
  31. table.put(puts);
  32. }
  33. }
  34.  
  35. }

  

  1. import com.twq.hbase.rowkey.salt.KeySalter;
  2. import org.apache.hadoop.conf.Configuration;
  3. import org.apache.hadoop.hbase.Cell;
  4. import org.apache.hadoop.hbase.CellUtil;
  5. import org.apache.hadoop.hbase.HBaseConfiguration;
  6. import org.apache.hadoop.hbase.TableName;
  7. import org.apache.hadoop.hbase.client.*;
  8. import org.apache.hadoop.hbase.util.Bytes;
  9.  
  10. import java.io.IOException;
  11. import java.util.ArrayList;
  12. import java.util.List;
  13.  
  14. public class HashingGetter {
  15. public static void main(String[] args) throws IOException {
  16. Configuration config = HBaseConfiguration.create();
  17.  
  18. try (Connection connection = ConnectionFactory.createConnection(config);
  19. Table table = connection.getTable(TableName.valueOf("test_hash"))) {
  20.  
  21. Get get = new Get(Bytes.toBytes(KeyHasher.getRowKey("boo0001")));
  22.  
  23. Result results = table.get(get);
  24.  
  25. // process result...
  26. for (Cell cell : results.listCells()) {
  27. System.out.println(Bytes.toString(CellUtil.cloneRow(cell)) + "===> " +
  28. Bytes.toString(CellUtil.cloneFamily(cell)) + ":" +
  29. Bytes.toString(CellUtil.cloneQualifier(cell)) + "{" +
  30. Bytes.toString(CellUtil.cloneValue(cell)) + "}");
  31. }
  32.  
  33. }
  34. }
  35.  
  36. }

  

RowKey的设计三

3、反转rowkey
create 'test_reverse', 'f',SPLITS => ['0','1','2','3','4','5','6','7','8','9']
 
时间戳类型的rowkey:
1524536830360
1524536830362
1524536830376
 
 
反转rowkey:
0630386354251
2630386354251
6730386354251
 

  1. import org.apache.hadoop.conf.Configuration;
  2. import org.apache.hadoop.fs.Path;
  3. import org.apache.hadoop.hbase.Cell;
  4. import org.apache.hadoop.hbase.CellUtil;
  5. import org.apache.hadoop.hbase.HBaseConfiguration;
  6. import org.apache.hadoop.hbase.TableName;
  7. import org.apache.hadoop.hbase.client.*;
  8. import org.apache.hadoop.hbase.filter.*;
  9. import org.apache.hadoop.hbase.util.Bytes;
  10.  
  11. import java.io.IOException;
  12.  
  13. public class DataFilter {
  14. public static void main(String[] args) throws IOException {
  15. Configuration config = HBaseConfiguration.create();
  16. //Add any necessary configuration files (hbase-site.xml, core-site.xml)
  17. config.addResource(new Path("src/main/resources/hbase-site.xml"));
  18. config.addResource(new Path("src/main/resources/core-site.xml"));
  19.  
  20. try(Connection connection = ConnectionFactory.createConnection(config)) {
  21. Table table = connection.getTable(TableName.valueOf("sound"));
  22.  
  23. Scan scan = new Scan();
  24.  
  25. scan.setStartRow(Bytes.toBytes("00000120120901"));
  26. scan.setStopRow(Bytes.toBytes("00000120121001"));
  27.  
  28. SingleColumnValueFilter nameFilter = new SingleColumnValueFilter(Bytes.toBytes("f"), Bytes.toBytes("n"),
  29. CompareFilter.CompareOp.EQUAL, new SubstringComparator("中国好声音"));
  30.  
  31. SingleColumnValueFilter categoryFilter = new SingleColumnValueFilter(Bytes.toBytes("f"), Bytes.toBytes("c"),
  32. CompareFilter.CompareOp.EQUAL, new SubstringComparator("综艺"));
  33.  
  34. FilterList filterList = new FilterList(FilterList.Operator.MUST_PASS_ALL);
  35. filterList.addFilter(nameFilter);
  36. filterList.addFilter(categoryFilter);
  37.  
  38. scan.setFilter(filterList);
  39.  
  40. ResultScanner rs = table.getScanner(scan);
  41. try {
  42. for (Result r = rs.next(); r != null; r = rs.next()) {
  43. // process result...
  44. for (Cell cell : r.listCells()) {
  45. System.out.println(Bytes.toString(CellUtil.cloneRow(cell)) + "===> " +
  46. Bytes.toString(CellUtil.cloneFamily(cell)) + ":" +
  47. Bytes.toString(CellUtil.cloneQualifier(cell)) + "{" +
  48. Bytes.toString(CellUtil.cloneValue(cell)) + "}");
  49. }
  50. }
  51. } finally {
  52. rs.close(); // always close the ResultScanner!
  53. }
  54. }
  55. }
  56. }

  

  1. import org.apache.hadoop.conf.Configuration;
  2. import org.apache.hadoop.fs.Path;
  3. import org.apache.hadoop.hbase.HBaseConfiguration;
  4. import org.apache.hadoop.hbase.TableName;
  5. import org.apache.hadoop.hbase.client.Connection;
  6. import org.apache.hadoop.hbase.client.ConnectionFactory;
  7. import org.apache.hadoop.hbase.client.Put;
  8. import org.apache.hadoop.hbase.client.Table;
  9. import org.apache.hadoop.hbase.util.Bytes;
  10.  
  11. import java.io.BufferedReader;
  12. import java.io.IOException;
  13. import java.io.InputStream;
  14. import java.io.InputStreamReader;
  15. import java.util.ArrayList;
  16. import java.util.List;
  17.  
  18. /**
  19. * create 'sound',
  20. */
  21. public class DataPrepare {
  22. public static void main(String[] args) throws IOException {
  23. InputStream ins = DataPrepare.class.getClassLoader().getResourceAsStream("sound.txt");
  24. BufferedReader br = new BufferedReader(new InputStreamReader(ins));
  25.  
  26. List<SoundInfo> soundInfos = new ArrayList<>();
  27. String line = null;
  28. while ((line = br.readLine()) != null) {
  29. SoundInfo soundInfo = new SoundInfo();
  30. String[] arr = line.split("\\|");
  31. String rowkey = format(arr[4], 6) + arr[1] + format(arr[0], 6);
  32. soundInfo.setRowkey(rowkey);
  33. soundInfo.setName(arr[2]);
  34. soundInfo.setCategory(arr[3]);
  35. soundInfos.add(soundInfo);
  36. }
  37.  
  38. Configuration config = HBaseConfiguration.create();
  39. //Add any necessary configuration files (hbase-site.xml, core-site.xml)
  40. config.addResource(new Path("src/main/resources/hbase-site.xml"));
  41. config.addResource(new Path("src/main/resources/core-site.xml"));
  42.  
  43. try (Connection connection = ConnectionFactory.createConnection(config)) {
  44. Table table = connection.getTable(TableName.valueOf("sound"));
  45. List<Put> puts = new ArrayList<>();
  46. for (SoundInfo soundInfo : soundInfos) {
  47. Put put = new Put(Bytes.toBytes(soundInfo.getRowkey()));
  48. put.addColumn(Bytes.toBytes("f"), Bytes.toBytes("n"), Bytes.toBytes(soundInfo.getName()));
  49. put.addColumn(Bytes.toBytes("f"), Bytes.toBytes("c"), Bytes.toBytes(soundInfo.getCategory()));
  50. puts.add(put);
  51. }
  52. table.put(puts);
  53. }
  54. }
  55.  
  56. public static String format(String str, int num) {
  57. return String.format("%0" + num + "d", Integer.parseInt(str));
  58. }
  59. }

  

在建立一个scan对象后,我们setStartRow(00000120120901),setStopRow(00000120120914)。
这样,scan时只扫描userID=1的数据,且时间范围限定在这个指定的时间段内,满足了按用户以及按时间范围对结果的筛选。并且由于记录集中存储,性能很好。
然后使用 SingleColumnValueFilter(org.apache.hadoop.hbase.filter.SingleColumnValueFilter),共4个,分别约束name的上下限,与category的上下限。满足按同时按文件名以及分类名的前缀匹配。
(注意:使用SingleColumnValueFilter会影响查询性能,在真正处理海量数据时会消耗很大的资源,且需要较长的时间)
如果需要分页还可以再加一个PageFilter限制返回记录的个数。

HBase应用的更多相关文章

  1. Mapreduce的文件和hbase共同输入

    Mapreduce的文件和hbase共同输入 package duogemap;   import java.io.IOException;   import org.apache.hadoop.co ...

  2. Redis/HBase/Tair比较

    KV系统对比表 对比维度 Redis Redis Cluster Medis Hbase Tair 访问模式    支持Value大小 理论上不超过1GB(建议不超过1MB) 理论上可配置(默认配置1 ...

  3. Hbase的伪分布式安装

    Hbase安装模式介绍 单机模式 1> Hbase不使用HDFS,仅使用本地文件系统 2> ZooKeeper与Hbase运行在同一个JVM中 分布式模式– 伪分布式模式1> 所有进 ...

  4. Spark踩坑记——数据库(Hbase+Mysql)

    [TOC] 前言 在使用Spark Streaming的过程中对于计算产生结果的进行持久化时,我们往往需要操作数据库,去统计或者改变一些值.最近一个实时消费者处理任务,在使用spark streami ...

  5. Spark读写Hbase的二种方式对比

    作者:Syn良子 出处:http://www.cnblogs.com/cssdongl 转载请注明出处 一.传统方式 这种方式就是常用的TableInputFormat和TableOutputForm ...

  6. 深入学习HBase架构原理

    HBase定义 HBase 是一个高可靠.高性能.面向列.可伸缩的分布式存储系统,利用Hbase技术可在廉价PC Server上搭建 大规模结构化存储集群. HBase 是Google Bigtabl ...

  7. hbase协处理器编码实例

    Observer协处理器通常在一个特定的事件(诸如Get或Put)之前或之后发生,相当于RDBMS中的触发器.Endpoint协处理器则类似于RDBMS中的存储过程,因为它可以让你在RegionSer ...

  8. hbase集群安装与部署

    1.相关环境 centos7 hadoop2.6.5 zookeeper3.4.9 jdk1.8 hbase1.2.4 本篇文章仅涉及hbase集群的搭建,关于hadoop与zookeeper的相关部 ...

  9. 从零自学Hadoop(22):HBase协处理器

    阅读目录 序 介绍 Observer操作 示例下载 系列索引 本文版权归mephisto和博客园共有,欢迎转载,但须保留此段声明,并给出原文链接,谢谢合作. 文章是哥(mephisto)写的,Sour ...

  10. Hbase安装和错误

    集群规划情况: djt1 active Hmaster djt2 standby Hmaster djt3 HRegionServer 搭建步骤: 第一步:配置conf/regionservers d ...

随机推荐

  1. dd命令的使用

    1.dd命令的使用 dd命令用于复制文件并对源文件的内容进行转换和格式化处理,在有需要的时候可以使用dd命令对物理磁盘进行操作,使用dd对磁盘操作时,最好使用块设备文件. (1)命令语法 dd (选项 ...

  2. [转帖]Java升级那么快,多个版本如何灵活切换和管理?

    Java升级那么快,多个版本如何灵活切换和管理? https://segmentfault.com/a/1190000021037771 前言 近两年,Java 版本升级频繁,感觉刚刚掌握 Java8 ...

  3. MNIST机器学习入门(二)

    在前一个博客中,我们已经对MNIST 数据集和TensorFlow 中MNIST 数据集的载入有了基本的了解.本节将真正以TensorFlow 为工具,写一个手写体数字识别程序,使用的机器学习方法是S ...

  4. C#月份和日期转大写和C#集合分组

    //日转化为大写 private static string DaytoUpper(int day, string type) { if (day < 20) { return MonthtoU ...

  5. mysql中length与char_length字符长度函数使用方法

    在mysql中length是计算字段的长度一个汉字是算三个字符,一个数字或字母算一个字符了,与char_length是有一点区别,本文章重点介绍第一个函数. mysql里面的length函数是一个用来 ...

  6. Win10家庭版升级到企业版的方法

    一.家庭版升级企业版 1.右键单击[此电脑]——>属性 2.点击更改产品密钥 3.输入密钥:NPPR9-FWDCX-D2C8J-H872K-2YT43 4.点击下一步,验证结束后点击开始升级,然 ...

  7. jsonpath_rw操作json

    from jsonpath_rw import parse def get_key_from_data(key,data): # 定义匹配规则 json_expr=parse(key) result= ...

  8. 纯css实现省略号,兼容火狐,IE9,chrome

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  9. 激活windows去掉右下角水印

     激活windows去掉右下角水印 //需要隔一段时间执行一次 // 卸载已有的激活产品slmgr.vbs /upk // 重新按照激活产品slmgr /ipk NPPR9-FWDCX-D2C8J-H ...

  10. java实现在线预览--poi实现word、excel、ppt转html

    java实现在线预览 - -之poi实现word.excel.ppt转html 简介 java实现在线预览功能是一个大家在工作中也许会遇到的需求,如果公司有钱,直接使用付费的第三方软件或者云在线预览服 ...