hbase 写入性能读性能怎么样

Leave a Reply
You must be
to post a comment.hbase表操作优化
Categories:
Published on: 2012 年 07 月 24 日
Hbase表写入
1、使用批量加载工具,具体看链接: 。
2、巨量数据插入空表或小表的时候,需要注意hbase的分表原理。只有当一个region的数据打过阈值的时候才会进行分表操作。这意味着你巨量数据将会同时写入同一个region直到表大到需要分割。比较好的做法是创建表的时候预先创建多个空的region。但是不要太多,太多同样会降低程序效率,有需要的可以做下实验预留多少个空表合适。官网给出了一个例子:
public static boolean createTable(HBaseAdmin admin, HTableDescriptor table, byte[][] splits)
throws IOException {
try {
admin.createTable( table, splits );
return true;
} catch (TableExistsException e) {
logger.info(&table & + table.getNameAsString() + & already exists&);
// the table already exists...
return false;
public static byte[][] getHexSplits(String startKey, String endKey, int numRegions) {
byte[][] splits = new byte[numRegions-1][];
BigInteger lowestKey = new BigInteger(startKey, 16);
BigInteger highestKey = new BigInteger(endKey, 16);
BigInteger range = highestKey.subtract(lowestKey);
BigInteger regionIncrement = range.divide(BigInteger.valueOf(numRegions));
lowestKey = lowestKey.add(regionIncrement);
for(int i=0; i < numRegions-1;i++) {
BigInteger key = lowestKey.add(regionIncrement.multiply(BigInteger.valueOf(i)));
byte[] b = String.format(&%016x&, key).getBytes();
splits[i] = b;
return splits;
调用createTable进行表创建,getHexSplits的三个参数是起始键、结束键和分表的个数。上述程序key是十六进制,根据需要自行修改。
3、延迟日志刷新
hbase的机制是put一写入就刷新日志,如果使用延迟机制,则日志存入内存直到日志刷新周期。这样的好处不用再说,但是坏处是region如果宕机,这会造成存入内存的日志信息丢失不能进行数据回滚等行为。
该项配置可以在HTableDescriptor中设定,也可以配置参数hbase.regionserver.optionallogflushinterval,默认是 1000ms.
4、自动刷写
当你进行大量的Put的时候,要确认你的HTable的setAutoFlush是关闭着的。否则的话,每执行一个Put就要想RegionServer发一个请求。通过 htable.add(Put) 和 htable.add( Put)来将Put添加到写缓冲中。如果 autoFlush = false,要等到写缓冲都填满的时候才会发起请求。要想显式的发起请求,可以调用flushCommits。在HTable实例上进行的close操作也会发起flushCommits
5、在Puts上关闭WAL
加大puts插表的吞吐量和效率需要设定put.setWriteToWAL为false。设定为false意味着put入表前不会写日志,仅存入内存。带来的后果就是如果region宕机,数据就会丢失。你可能在实际应用中发现其他效率提升没那么明显,如果数据负载在分布式集群中。
一般都会不使用该选项,而是用bulk loading技术替代。
6、Group Puts by RegionServer
除了使用writeBuffer,puts通过regionServer分组可以减少客户端RPC每秒调用writeBuffer flush数量。有个实用的HTableUtil 能做这些。如果版本在0.90x或更早的可以拷贝使用。
7、跳过reducer步骤
如果大量数据入一个表时,如果mapper能做完,就不要使用reducer过程。当reducer过程被使用,所有的mapper输出将入磁盘,并会触发sorted和shuffled过程。但是你也有必须使用reducer的时候。
8、 Anti-Pattern: One Hot Region
If all your data is being written to one region at a time, then re-read the section on processing
Also, if you are pre-splitting regions and all your data isstill winding up in a single region even though your keys aren't monotonically increasing, confirm that your keyspace actually works with the split strategy. There are a variety of reasons that regions may appear "well split" but won't work with your data. As the HBase client communicates directly with the RegionServers, this can be obtained via.
See , as well as
一个非常棒的样例MR,其中setup会在mapper执行前调用一次,cleanup会在最后执行完毕调用一次。
import java.io.IOException;
import mons.logging.Log;
import mons.logging.LogFactory;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.conf.Configured;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.client.HTable;
import org.apache.hadoop.hbase.client.Put;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.lib.input.TextInputFormat;
import org.apache.hadoop.mapreduce.lib.output.NullOutputFormat;
import org.apache.hadoop.util.GenericOptionsParser;
import org.apache.hadoop.util.Tool;
import org.apache.hadoop.util.ToolRunner;
public class test extends Configured implements Tool {
static final Log LOG = LogFactory.getLog(test.class);
public static final String JOBNAME = &MRImport &;
public static class Map extends
Mapper&LongWritable, Text, NullWritable, NullWritable& {
Configuration configuration = null;
HTable xTable = null;
private boolean wal = true;
private Put put = null;
static long count = 0;
protected void setup(Context context) throws IOException,
InterruptedException {
super.setup(context);
configuration = context.getConfiguration();
xTable = new HTable(configuration, &testKang&);
xTable.setAutoFlush(false);
xTable.setWriteBufferSize(12 * 1024 * 1024);
wal = true;
protected void map(LongWritable key, Text value, Context context)
throws IOException, InterruptedException {
String all[] = value.toString().split(&/t&);
if (all.length == 2) {
put = new Put(Bytes.toBytes(all[0]));
put.add(Bytes.toBytes(&xxx&), Bytes.toBytes(&&),
Bytes.toBytes(all[1]));
if (!wal) {
put.setWriteToWAL(false);
xTable.put(put);
if ((++count % 100) == 0) {
context.setStatus(count + & DOCUMENTS done!&);
context.progress();
System.out.println(count + & DOCUMENTS done!&);
protected void cleanup(Context context) throws IOException,
InterruptedException {
super.cleanup(context);
xTable.flushCommits();
xTable.close();
public int run(String[] args) throws Exception {
String input = args[0];
Configuration conf = HBaseConfiguration.create(getConf());
conf.set(&hbase.master&, &m0:60000&);
Job job = new Job(conf, JOBNAME);
job.setJarByClass(test.class);
job.setMapperClass(Map.class);
job.setNumReduceTasks(0);
job.setInputFormatClass(TextInputFormat.class);
TextInputFormat.setInputPaths(job, input);
job.setOutputFormatClass(NullOutputFormat.class);
return job.waitForCompletion(true) ? 0 : 1;
public static void main(String[] args) throws IOException {
Configuration conf = new Configuration();
String[] otherArgs = new GenericOptionsParser(conf, args)
.getRemainingArgs();
int res = 1;
try {
res = ToolRunner.run(conf, new test(), otherArgs);
} catch (Exception e) {
e.printStackTrace();
System.exit(res);
Hbase表读取
1、设定scan缓存数量
默认的是scan一次读取一行数据,请求一次regionServer,设定scan.setCaching(100)适合的值非常重要,也不能过大,因为会消耗内存。
2、scan caching在mapreduce任务里要特别注意
如果caching值设置过大会造成超时异常(e.g. UnknownScannerException 、 socket timelimit之类的,我就被这点坑惨了,也没找到相关解决办法,这里看到了~T-T),即不能在设定的阈值时间范围内获取到下一个数据集。因为一般的一个map处理一行数据,但是获取的多了可能使map处理多行数据时间过久(可能map逻辑复杂、时间复杂度高),都会造成超时问题。一般这时候就设置低一些。
同样这个超时问题也可能出现在非mapreduce任务中,这种情况多出现于同时跑了mapreduce作业。
3、scan属性选择
用scan处理大量行时,注意 scan.addFamily和 scan.addColumn的选择,一般尽量选择的精确,否则会造成资源较大的浪费。
4、MapReduce - Input Splits
For MapReduce jobs that use HBase tables as a source, if there a pattern where the "slow" map tasks seem to have the same Input Split (i.e., the RegionServer serving the data), see the Troubleshooting Case Study in .
5、记得关闭 ResultScanners
这与其说是提高性能,倒不如说是避免发生性能问题。如果你忘记了关闭ResultScanners,会导致RegionServer出现问题。所以一定要把ResultScanner包含在try/catch 块中...
Scan scan = new Scan();
// set attrs...
ResultScanner rs = htable.getScanner(scan);
try {
for (Result r = rs.next(); r != null; r = rs.next()) {
// process result...
} finally {
rs.close();
// always close the ResultScanner!
htable.close();
Scan实例可以在RegionServer中使用块缓存,可以由setCacheBlocks方法控制。如果Scan是MapReduce的输入源,要将这个值设置为 false。对于经常读到的行,就建议使用块缓冲。
7、Row Keys 的负载优化
当一个表的时候, 如果仅仅需要row key(不需要no families, qualifiers, values 和 timestamps),在加入FilterList的时候,要使用Scanner的setFilter方法的时候,要填上MUST_PASS_ALL操作参数(译者注:相当于And操作符)。一个FilterList要包含一个 和一个 .通过这样的filter组合,就算在最坏的情况下,RegionServer只会从磁盘读一个值,同时最小化客户端的网络带宽占用。
8、监视数据传输
如果执行一个高并发的读取操作,监视数据的传输目标表,如果目标表局限在几个少量的region上,那么可能能进行服务的节点就会很少。
See , as well as
Hbase表删除
1、将hbase表当队列
hbase表有时用起来像queue,这种情况下必须很小心,要经常执行主要压缩程序使表紧凑。在删除很多行后建立storeFiles当需要读取的时候。删除数据只在精简程序执行的时候被清除(Tombstones only get cleaned up with major compactions.)。
2、删除的RPC行为
必须注意到htable.delete(Delete)不是使用的writeBuffer。它将执行RegionServer RPC在每次调用。如果删除大量数据考虑使用table.delete(List)。
我猜你可能也喜欢:
Share this
三江小渡 All rights reserved
Fastfood theme by
- Powered by
[put here your code]
quickbar tool -->
Recent Posts
by 三江小渡我猜你可能也喜欢:PHP实现双向链表给你的博客添加一个简易的计数器
by 三江小渡最多留言日志2011年全国数学建模B题题解和论文AboutClustering Algorithm/聚类算法[[...]
by 三江小渡最多留言日志2011年全国数学建模B题题解和论文AboutClustering Algorithm/聚类算法[[...]
by 三江小渡安装了rsync程序后,运行以下shell程序即可完成rsync服务的启动,自行修改相关的module和认证用[...]
by 三江小渡mac下没有找到好用的类似secureCRT,就自己写了个自动登录的脚本,分享一下,如果是新浪的,就基本不用修[...]
by 三江小渡协同过滤算法是推荐系统中最古老,也是最简单高效的推荐算法。简单说协同过滤就是根据以往的用户产生的数据分析,对用[...]
by 三江小渡无意中看到哲学家不解释的博客,被她的文章吸引甚深。又看了她的两篇文章:人人主站 和 哲学十二钗问答 。然后特别[...]
by 三江小渡The big difference between MySQL Table Type MyISAM and [...]
by 三江小渡最多留言日志2011年全国数学建模B题题解和论文AboutClustering Algorithm/聚类算法[[...]
by 三江小渡我猜你可能也喜欢:用于大数据的并查集(基于HBase)的java类最长回文子串算法(Manacher)密码学原[...]
Categories
( 102)Recent Posts by 三江小渡 by 三江小渡 by 三江小渡 by 三江小渡 by 三江小渡 ( 63)Recent Posts by 三江小渡 by 三江小渡 by 三江小渡 by 三江小渡 by 三江小渡 ( 44)Recent Posts by 三江小渡 by 三江小渡 by 三江小渡 by 三江小渡 by 三江小渡 ( 22)Recent Posts by 三江小渡 by 三江小渡 by 三江小渡 by 三江小渡 by 三江小渡 ( 22)Recent Posts by 三江小渡 by 三江小渡 by 三江小渡 by 三江小渡 by 三江小渡 ( 21)Recent Posts by 三江小渡 by 三江小渡 by 三江小渡 by 三江小渡 by 三江小渡 ( 20)Recent Posts by 三江小渡 by 三江小渡 by 三江小渡 by 三江小渡 by 三江小渡 ( 19)Recent Posts by 三江小渡 by 三江小渡 by 三江小渡 by 三江小渡 by 三江小渡 ( 9)Recent Posts by 三江小渡 by 三江小渡 by 三江小渡 by 三江小渡 by 三江小渡 ( 7)Recent Posts by 三江小渡 by 三江小渡 by 三江小渡 by 三江小渡 by 三江小渡
Recent Comments
三江小渡 about 对你也有用我也感到很开心~~:) 不会摇头的傻瓜 about 之前看老师推荐的相关论文,都会写稀疏性,潜意识觉得好像真的是硬伤,结果。。。 不会摇头的傻瓜 about 超级赞,最近刚好有用,!谢谢啦~ 唯美句子 about 这分析精神值得学习!! alan about 感觉很这篇科普型的文章很适合我这种读本科的刚开始学信息安全的人哈哈,以后会多看看你的博文的 三江小渡 about 万能的google 呀~~然后就是豆瓣搜书,看看评价好的 翻译过来的书,甚至会有英文版的书,
就这俩途径~ 火星十一郎--河南理工 about 大神 你好 我是河南理工张朋飞
请求您给我发一份你的标签云的代码
还有我看您对协同过滤简介比较深刻 想请教下您平时如何收集资料的?看的那些资料 如能得到您的指导 感激不尽 火星十一郎--河南理工 about “每次合并或分裂都是局部最优的,但一旦做出决策不能撤销,阻碍了局部最优解变成全局最优。”不是不能撤销,而是考虑到效率问题不进行回溯..........我博客/hxsyl/ 碚子 about 网站的特效真好,羡慕。。。 alan about 楼主。考虑如下矩阵 [10 9 10;6 8 9;7 9 9],按你的算法,6- 7- 9,长度为3,但是结果应该是10-9-8-6,长度为4。似乎还是深搜+递归才能解决。
Not logged in
Welcome , today is 星期六, 2016 年 05 月 14 日
Leave a comment
feed for comments on this post
Trackback URL
Next Post: MapReduce生成HFile入库到HBase及源码分析
Previous Post: 最长回文子串算法(Manacher)
Top of page
Bottom of pageSpark读取Hbase中的数据 – 过往记忆
欢迎关注Hadoop、Hive、Hbase、Flume等微信公共账号:iteblog_hadoop。
文章总数:598
浏览总数:5,683,863
评论:3318
分类目录:65 个
注册用户数:983
最后更新:日
欢迎关注微信公共帐号:iteblog_hadoop
关注互联网头条技术
和Flume-ng整合,可以参见本博客:
如果想及时了解、Hadoop或者相关的文章,欢迎关注微信公共帐号:iteblog_hadoop
  大家可能都知道很熟悉Spark的两种常见的数据读取方式(存放到RDD中):(1)、调用parallelize函数直接从集合中获取数据,并存入RDD中;Java版本如下:
JavaRDD&Integer& myRDD = sc.parallelize(Arrays.asList(1,2,3));
Scala版本如下:
val myRDD= sc.parallelize(List(1,2,3))
  这种方式很简单,很容易就可以将一个集合中的数据变成RDD的初始化值;更常见的是(2)、从文本中读取数据到RDD中,这个文本可以是纯文本文件、可以是sequence文件;可以存放在本地(file://)、可以存放在HDFS(hdfs://)上,还可以存放在S3上。其实对文件来说,Spark支持Hadoop所支持的所有文件类型和文件存放位置。Java版如下:
/////////////////////////////////////////////////////////////////////
User: 过往记忆
Date: 14-6-29
Time: 23:59
本文地址:/archives/1051
过往记忆博客,专注于hadoop、hive、spark、shark、flume的技术博客,大量的干货
过往记忆博客微信公共帐号:iteblog_hadoop
/////////////////////////////////////////////////////////////////////
import org.apache.spark.SparkC
import org.apache.spark.api.java.JavaRDD;
import org.apache.spark.api.java.JavaSparkC
SparkConf conf = new SparkConf().setAppName(&Simple Application&);
JavaSparkContext sc = new JavaSparkContext(conf);
sc.addFile(&wyp.data&);
JavaRDD&String& lines = sc.textFile(SparkFiles.get(&wyp.data&));
Scala版本如下:
import org.apache.spark.SparkContext
import org.apache.spark.SparkConf
val conf = new SparkConf().setAppName(&Simple Application&)
val sc = new SparkContext(conf)
sc.addFile(&spam.data&)
val inFile = sc.textFile(SparkFiles.get(&spam.data&))
  在实际情况下,我们需要的数据可能不是简单的存放在HDFS文本中,我们需要的数据可能就存放在中,那么我们如何用Spark来读取中的数据呢?本文的所有测试是基于Hadoop 2.2.0、Hbase 0.98.2、Spark 0.9.1,不同版本可能代码的编写有点不同。本文只是简单地用Spark来读取Hbase中的数据,如果需要对Hbase进行更强的操作,本文可能不能帮你。话不多说,Spark操作Hbase的核心的Java版本代码如下:
import org.apache.hadoop.conf.C
import org.apache.hadoop.hbase.HBaseC
import org.apache.hadoop.hbase.client.R
import org.apache.hadoop.hbase.client.S
import org.apache.hadoop.hbase.io.ImmutableBytesW
import org.apache.hadoop.hbase.mapreduce.TableInputF
import org.apache.hadoop.hbase.protobuf.ProtobufU
import org.apache.hadoop.hbase.protobuf.generated.ClientP
import org.apache.hadoop.hbase.util.Base64;
import org.apache.hadoop.hbase.util.B
import org.apache.spark.api.java.JavaPairRDD;
import org.apache.spark.api.java.JavaSparkC
/////////////////////////////////////////////////////////////////////
User: 过往记忆
Date: 14-6-29
Time: 23:59
本文地址:/archives/1051
过往记忆博客,专注于hadoop、hive、spark、shark、flume的技术博客,大量的干货
过往记忆博客微信公共帐号:iteblog_hadoop
/////////////////////////////////////////////////////////////////////
JavaSparkContext sc = new JavaSparkContext(master, &hbaseTest&,
System.getenv(&SPARK_HOME&), System.getenv(&JARS&));
Configuration conf = HBaseConfiguration.create();
Scan scan = new Scan();
scan.addFamily(Bytes.toBytes(&cf&));
scan.addColumn(Bytes.toBytes(&cf&), Bytes.toBytes(&airName&));
String tableName = &flight_wap_order_log&;
conf.set(TableInputFormat.INPUT_TABLE, tableName);
ClientProtos.Scan proto = ProtobufUtil.toScan(scan);
String ScanToString = Base64.encodeBytes(proto.toByteArray());
conf.set(TableInputFormat.SCAN, ScanToString);
JavaPairRDD&ImmutableBytesWritable, Result& myRDD =
sc.newAPIHadoopRDD(conf,
TableInputFormat.class,
ImmutableBytesWritable.class, Result.class);
catch (Exception e) {
e.printStackTrace();
这样本段代码段是从Hbase表名为flight_wap_order_log的数据库中读取cf列簇上的airName一列的数据,这样我们就可以对myRDD进行相应的操作:
System.out.println(myRDD.count());
本段代码需要在pom.xml文件加入以下依赖:
&dependency&
&groupId&org.apache.spark&/groupId&
&artifactId&spark-core_2.10&/artifactId&
&version&0.9.1&/version&
&/dependency&
&dependency&
&groupId&org.apache.hbase&/groupId&
&artifactId&hbase&/artifactId&
&version&0.98.2-hadoop2&/version&
&/dependency&
&dependency&
&groupId&org.apache.hbase&/groupId&
&artifactId&hbase-client&/artifactId&
&version&0.98.2-hadoop2&/version&
&/dependency&
&dependency&
&groupId&org.apache.hbase&/groupId&
&artifactId&hbase-common&/artifactId&
&version&0.98.2-hadoop2&/version&
&/dependency&
&dependency&
&groupId&org.apache.hbase&/groupId&
&artifactId&hbase-server&/artifactId&
&version&0.98.2-hadoop2&/version&
&/dependency&
Scala版如下:
import org.apache.spark._
import org.apache.spark.rdd.NewHadoopRDD
import org.apache.hadoop.hbase.{HBaseConfiguration, HTableDescriptor}
import org.apache.hadoop.hbase.client.HBaseAdmin
import org.apache.hadoop.hbase.mapreduce.TableInputFormat
/////////////////////////////////////////////////////////////////////
User: 过往记忆
Date: 14-6-29
Time: 23:59
本文地址:/archives/1051
过往记忆博客,专注于hadoop、hive、spark、shark、flume的技术博客,大量的干货
过往记忆博客微信公共帐号:iteblog_hadoop
/////////////////////////////////////////////////////////////////////
object HBaseTest {
def main(args: Array[String]) {
val sc = new SparkContext(args(0), &HBaseTest&,
System.getenv(&SPARK_HOME&), SparkContext.jarOfClass(this.getClass))
val conf = HBaseConfiguration.create()
conf.set(TableInputFormat.INPUT_TABLE, args(1))
val hBaseRDD = sc.newAPIHadoopRDD(conf, classOf[TableInputFormat],
classOf[org.apache.hadoop.hbase.io.ImmutableBytesWritable],
classOf[org.apache.hadoop.hbase.client.Result])
hBaseRDD.count()
System.exit(0)
我们需要在加入如下依赖:
libraryDependencies ++= Seq(
&org.apache.spark& % &spark-core_2.10& % &0.9.1&,
&org.apache.hbase& % &hbase& % &0.98.2-hadoop2&,
&org.apache.hbase& % &hbase-client& % &0.98.2-hadoop2&,
&org.apache.hbase& % &hbase-common& % &0.98.2-hadoop2&,
&org.apache.hbase& % &hbase-server& % &0.98.2-hadoop2&
  在测试的时候,需要配置好Hbase、Hadoop环境,否则程序会出现问题,特别是让程序找到Hbase-site.xml配置文件。
本博客文章除特别声明,全部都是原创!
尊重原创,转载请注明: 转载自
Spark性能优化:数据倾斜调优
Spark 2.0技术预览:更容易、更快速、更智能
Spark性能优化:资源调优篇
Spark性能优化:开发调优篇
Spark会把数据都载入到内存么
Apache HBase 1.2.1正式发布
Apache Flink vs Apache Spark
如何选择Apache Spark和Apache Flink
下面文章您可能感兴趣您所在的位置: &
HBase性能优化的四个要点
HBase性能优化的四个要点
今天作者石头儿将给大家介绍HBase性能优化的四个要点。比如文件应该设置多大的默认值,autoflash的设置问题。
1 hbase.hregion.max.filesize应该设置多少合适
默认值:256M
说明:Maximum HStoreFile size. If any one of a column families' HStoreFiles has grown to exceed this value, the hosting HRegion is split in two.
HStoreFile的最大值。如果任何一个Column Family(或者说HStore)的HStoreFiles的大小超过这个值,那么,其所属的HRegion就会Split成两个。
hbase中hfile的默认最大值(hbase.hregion.max.filesize)是256MB,而google的bigtable论文中对tablet的最大值也推荐为100-200MB,这个大小有什么秘密呢?
众所周知hbase中数据一开始会写入memstore,当memstore满64MB以后,会flush到disk上而成为storefile。当storefile数量超过3时,会启动compaction过程将它们合并为一个storefile。这个过程中会删除一些timestamp过期的数据,比如update的数据。而当合并后的storefile大小大于hfile默认最大值时,会触发split动作,将它切分成两个region。
lz进行了持续insert压力测试,并设置了不同的hbase.hregion.max.filesize,根据结果得到如下结论:值越小,平均吞吐量越大,但吞吐量越不稳定;值越大,平均吞吐量越小,吞吐量不稳定的时间相对更小。
为什么会这样呢?推论如下:
& a 当hbase.hregion.max.filesize比较小时,触发split的机率更大,而split的时候会将region offline,因此在split结束的时间前,访问该region的请求将被block住,客户端自我block的时间默认为1s。当大量的region同时发生split时,系统的整体访问服务将大受影响。因此容易出现吞吐量及响应时间的不稳定现象
& b 当hbase.hregion.max.filesize比较大时,单个region中触发split的机率较小,大量region同时触发split的机率也较小,因此吞吐量较之小hfile尺寸更加稳定些。但是由于长期得不到split,因此同一个region内发生多次compaction的机会增加了。compaction的原理是将原有数据读一遍并重写一遍到hdfs上,然后再删除原有数据。无疑这种行为会降低以io为瓶颈的系统的速度,因此平均吞吐量会受到一些影响而下降。
& 综合以上两种情况,hbase.hregion.max.filesize不宜过大或过小,256MB或许是一个更理想的经验参数。对于离线型的应用,调整为128MB会更加合适一些,而在线应用除非对split机制进行改造,否则不应该低于256MB
2 autoflush=false的影响
无论是官方还是很多blog都提倡为了提高hbase的写入速度而在应用代码中设置autoflush=false,然后lz认为在在线应用中应该谨慎进行该设置。原因如下:
a autoflush=false的原理是当客户端提交delete或put请求时,将该请求在客户端缓存,直到数据超过2M(hbase.client.write.buffer决定)或用户执行了hbase.flushcommits()时才向regionserver提交请求。因此即使htable.put()执行返回成功,也并非说明请求真的成功了。假如还没有达到该缓存而client崩溃,该部分数据将由于未发送到regionserver而丢失。这对于零容忍的在线服务是不可接受的。
b autoflush=true虽然会让写入速度下降2-3倍,但是对于很多在线应用来说这都是必须打开的,也正是hbase为什么让它默认值为true的原因。当该值为true时,每次请求都会发往regionserver,而regionserver接收到请求后第一件事就是写hlog,因此对io的要求是非常高的,为了提高hbase的写入速度,应该尽可能高地提高io吞吐量,比如增加磁盘、使用raid卡、减少replication因子数等
3 从性能的角度谈table中family和qualifier的设置
对于传统关系型数据库中的一张table,在业务转换到hbase上建模时,从性能的角度应该如何设置family和qualifier呢?
最极端的,①每一列都设置成一个family,②一个表仅有一个family,所有列都是其中的一个qualifier,那么有什么区别呢?
从读的方面考虑:
family越多,那么获取每一个cell数据的优势越明显,因为io和网络都减少了。
如果只有一个family,那么每一次读都会读取当前rowkey的所有数据,网络和io上会有一些损失。
当然如果要获取的是固定的几列数据,那么把这几列写到一个family中比分别设置family要更好,因为只需一次请求就能拿回所有数据。
从写的角度考虑:
首先,内存方面来说,对于一个Region,会为每一个表的每一个Family分配一个Store,而每一个Store,都会分配一个MemStore,所以更多的family会消耗更多的内存。
其次,从flush和compaction方面说,目前版本的hbase,在flush和compaction都是以region为单位的,也就是说当一个family达到flush条件时,该region的所有family所属的memstore都会flush一次,即使memstore中只有很少的数据也会触发flush而生成小文件。这样就增加了compaction发生的机率,而compaction也是以region为单位的,这样就很容易发生compaction风暴从而降低系统的整体吞吐量。
第三,从split方面考虑,由于hfile是以family为单位的,因此对于多个family来说,数据被分散到了更多的hfile中,减小了split发生的机率。这是把双刃剑。更少的split会导致该region的体积比较大,由于balance是以region的数目而不是大小为单位来进行的,因此可能会导致balance失效。而从好的方面来说,更少的split会让系统提供更加稳定的在线服务。而坏处我们可以通过在请求的低谷时间进行人工的split和balance来避免掉。
& &因此对于写比较多的系统,如果是离线应该,我们尽量只用一个family好了,但如果是在线应用,那还是应该根据应用的情况合理地分配family。
4 hbase.regionserver.handler.count
RegionServer端开启的RPC监听器实例个数,也即RegionServer能够处理的IO请求线程数。默认是10.
此参数与内存息息相关。该值设置的时候,以监控内存为主要参考。
对于 单次请求内存消耗较高的Big PUT场景(大容量单次PUT或设置了较大cache的scan,均属于Big PUT)或ReigonServer的内存比较紧张的场景,可以设置的相对较小。
对于 单次请求内存消耗低,TPS(TransactionPerSecond,每秒事务处理量)要求非常高的场景,可以设置的相对大些。
原文链接:
【编辑推荐】
【责任编辑: TEL:(010)】
关于&&的更多文章
本书主要介绍如何调优Android 应用,以使应用更健壮并提高其执行
网友评论TOP5
数据库产品
数据库综合
数据库新闻
维基百科将切换到另外一款开源数据库MariaDB
MySQL字符串的处理,也就是对于MySQL字符集的处理。主
国产数据库,顾名思义就是中国公司自行开发的数据库产
本专题将为大家介绍的MySQL日志的相关操作,日志文件
本书是Inside Microsoft SQL Server 2005系列四本著作中的一本。它详细介绍了T-SQL的内部构造,包含了非常全面的编程参考。它提
51CTO旗下网站

我要回帖

更多关于 hbase mysql 性能对比 的文章

 

随机推荐