Changes between Version 9 and Version 10 of hbase_table_design
- Timestamp:
- 09/14/2012 11:01:31 AM (14 years ago)
Legend:
- Unmodified
- Added
- Removed
- Modified
-
hbase_table_design
v9 v10 3 3 4 4 5 (1) 最大版本数:通常是3,如果对于更新比较频繁的应用完全可以设置为1,能够快速的淘汰无用数据,对于节省存储空间和提高查询速度有效果。[[BR]]5 (1) 最大版本数:通常是3,如果对于更新比较频繁的应用完全可以设置为1,能够快速的淘汰无用数据,对于节省存储空间和提高查询速度有效果。[[BR]] 6 6 7 (2) 压缩算法:尝试使用snappy算法,相对lzo来说,压缩率接近,压缩效率稍高,解压效率高很多,而且安装相对方便[[BR]]7 (2) 压缩算法:尝试使用snappy算法,相对lzo来说,压缩率接近,压缩效率稍高,解压效率高很多,而且安装相对方便[[BR]] 8 8 9 (3) inmemory:表在内存中存放,同时磁盘上也会存放,可以提高访问速度,可以设置到某个CF,HBASE并不保证数据都在内存。[[BR]]9 (3) inmemory:表在内存中存放,同时磁盘上也会存放,可以提高访问速度,可以设置到某个CF,HBASE并不保证数据都在内存。[[BR]] 10 10 11 (4) [http://blog.csdn.net/jiaomeng/article/details/1495500 bloomfilter]:开启可以提升Get和Exist的速度,根据应用来定,看需要精确到rowkey还是column。不过这里需要理解一下原理,bloomfilter的作用是对一个region下查找记录所在的hfile有用。即如果一个region下的hfile数量很多,bloomfilter的作用越明显。适合那种compaction赶不上flush速度的应用,单这种应用在我们这里比较少见。如果你在表中设置了Bloomfilter,那么HBase会在生成StoreFile时包含一份bloomfilter结构的数据,称其为MetaBlock;MetaBlock与DataBlock(真实的KeyValue数据)一起由LRUBlockCache维护。所以,开启bloomfilter会有一定的存储及内存cache开销。[[BR]]11 (4) [http://blog.csdn.net/jiaomeng/article/details/1495500 bloomfilter]:开启可以提升Get和Exist的速度,根据应用来定,看需要精确到rowkey还是column。不过这里需要理解一下原理,bloomfilter的作用是对一个region下查找记录所在的hfile有用。即如果一个region下的hfile数量很多,bloomfilter的作用越明显。适合那种compaction赶不上flush速度的应用,单这种应用在我们这里比较少见。如果你在表中设置了Bloomfilter,那么HBase会在生成StoreFile时包含一份bloomfilter结构的数据,称其为MetaBlock;MetaBlock与DataBlock(真实的KeyValue数据)一起由LRUBlockCache维护。所以,开启bloomfilter会有一定的存储及内存cache开销。[[BR]] 12 12 在0.90版,Get只是Scan的一个特殊操作,没有做特别的优化,不知道新版有没有优化。 13 13 … … 18 18 rowkey是hbase的key-value存储中的key,通常使用用户要查询的字段作为rowkey,查询结果作为value。可以通过设计满足几种不同的查询需求。[[BR]] 19 19 20 (1) 数字rowkey的从大到小排序:原生hbase只支持从小到大的排序(这里是指scanner的next方法),这样就对于排行榜一类的查询需求很尴尬。那么采用rowkey = Integer.MAX_VALUE-rowkey的方式将rowkey进行转换,最大的变最小,最小的变最大。在应用层再转回来即可完成排序需求。[[BR]]20 (1) 数字rowkey的从大到小排序:原生hbase只支持从小到大的排序(这里是指scanner的next方法),这样就对于排行榜一类的查询需求很尴尬。那么采用rowkey = Integer.MAX_VALUE-rowkey的方式将rowkey进行转换,最大的变最小,最小的变最大。在应用层再转回来即可完成排序需求。[[BR]] 21 21 22 (2) rowkey的散列原则:如果rowkey是类似时间戳的方式递增的生成,建议不要使用正序直接写入rowkey,而是采用reverse的方式反转rowkey,使得rowkey大致均衡分布,这样设计有个好处是能将regionserver的负载均衡,否则容易产生所有新数据都在一个regionserver上堆积的现象,这一点还可以结合table的预切分一起设计。[[BR]]22 (2) rowkey的散列原则:如果rowkey是类似时间戳的方式递增的生成,建议不要使用正序直接写入rowkey,而是采用reverse的方式反转rowkey,使得rowkey大致均衡分布,这样设计有个好处是能将regionserver的负载均衡,否则容易产生所有新数据都在一个regionserver上堆积的现象,这一点还可以结合table的预切分一起设计。[[BR]] 23 23 24 24 … … 32 32 33 33 34 对于column需要扩展的应用,column可以按普通的方式设计,但是对于列相对固定的应用,最好采用将一行记录封装到一个column中的方式,这样能够节省存储空间。封装的方式推荐protocolbuffer。[[BR]]34 (1) 对于column需要扩展的应用,column可以按普通的方式设计,但是对于列相对固定的应用,最好采用将一行记录封装到一个column中的方式,这样能够节省存储空间。封装的方式推荐protocolbuffer。[[BR]] 35 35 36 以下会分场景介绍一些特殊的表结构设计方法,只是一些摸索,欢迎讨论:[[BR]]36 (2) column的数目不要超过百万,不然会出现OOM。如果column过多,可以考虑将column设计到rowkey的方法解决。例如原来的rowkey是uid1,,column是uid2,uid3...。重新设计之后rowkey为<uid1>~<uid2>,<uid1>~<uid3>...,采用scan(startkey,endkey)的扫描方法来读数据[[BR]] 37 37 38 value数目过多场景下的表结构设计:[[BR]]39 38 40 目前我碰到了一种key-value的数据结构,某一个key下面包含的column很多,以致于客户端查询的时候oom,bulkload写入的时候oom,regionsplit的时候失败这三种后果。通常来讲,hbase的column数目不要超过百万这个数量级。在官方的说明和我实际的测试中都验证了这一点。[[BR]]41 42 有两种思路可以参考,第一种是单独处理这些特殊的rowkey,第二种如下:[[BR]]43 44 可以考虑将column设计到rowkey的方法解决。例如原来的rowkey是uid1,,column是uid2,uid3...。重新设计之后rowkey为<uid1>~<uid2>,<uid1>~<uid3>...当然大家会有疑问,这种方式如何查询,如果要查询uid1下面的所有uid怎么办。这里说明一下hbase并不是只有get一种随机读取的方法。而是含有scan(startkey,endkey)的扫描方法,而这种方法和get的效率相当。需要取得uid1下的记录只需要new Scan("uid1~","uid1~~")即可。45 39 46 40 … … 58 52 ---- 59 53 60 如果要为HBASE做一些索引表,或者通过其他方法提高查询速度,可以参考这篇文章[http://www.oschina.net/question/12_29726 HBase 二级索引与 Join] 54 如果要为HBASE做一些索引表,或者通过其他方法提高查询速度,可以参考这篇文章[http://www.oschina.net/question/12_29726 HBase 二级索引与 Join][[BR]] 61 55 56 57 [/wiki/hbase_table_design/HBaseSchema_HBaseCon2012.pdf HBaseSchema_HBaseCon2012]这篇文章也不错
![(please configure the [header_logo] section in trac.ini)](http://www1.pconline.com.cn/hr/2009/global/images/logo.gif)