snappy能减少new region参数数吗

他的最新文章
他的热门文章
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字) 调整参数  入门级的调优可以从调整参数开始。投入小,回报快。  1. Write Buffer Size  快速配置  Java代码  HTable htable = new HTable(config, tablename); htable.setWriteBufferSize(6 * 1024 * 1024); htable.setAutoFlush(false);  设置buffer的容量,例子中设置了6MB的buffer容量。  * 必须禁止auto flush。  * 6MB是经验值,可以上下微调以适应不同的写场景。  原理  HBase Client会在数据累积到设置的阈值后才提交Region Server。这样做的好处在于可以减少RPC连接次数。  2. RPC Handler  快速配置  修改hbase-site.xml的hbase.regionserver.handler.count配置项:  Xml代码   hbase.regionserver.handler.count 100&  原理  该配置定义了每个Region Server上的RPC Handler的数量。Region Server通过RPC Handler接收外部请求并加以处理。所以提升RPC Handler的数量可以一定程度上提高HBase接收请求的能力。当然,handler数量也不是越大越好,这要取决于节点的硬件情况。  3. Compression  快速配置  Java代码  HColumnDescriptor hcd = new HColumnDescriptor(familyName); hcd.setCompressionType(Algorithm.SNAPPY);  原理  数据量大,边压边写也会提升性能的,毕竟IO是大数据的最严重的瓶颈,哪怕使用了SSD也是一样。众多的压缩方式中,推荐使用SNAPPY。从压缩率和压缩速度来看,性价比最高。  4. WAL  快速配置  Put put = new Put(rowKey); put.setWriteToWAL(false);  原理  其实不推荐关闭WAL,不过关了的确可以提升性能...因为HBase在写数据前会先把操作持久化在WAL中,以保证在异常情况下,HBase可以按照WAL的记录来恢复还未持久化的数据。  5. Replication  虽然推荐replica=3,不过当数据量很夸张的时候,一般会把replica降低到2。当然也不推荐随便降低replica。  6. Compaction  在插数据时,打开HMaster的web界面,查看每个region server的request数量。确保大部分时间,写请求在region server层面大致平均分布。在此前提下,我们再考虑compaction的问题。继续观察request数量,你会发现在某个时间段,若干region server接收的请求数为0(当然这也可能是client根本没有向这个region server写数据,所以之前说,要确保请求在各region server大致平均分布)。这很有可能是region server在做compaction导致。compaction的过程会block写。 优化的思路有两种,一是提高compaction的效率,二是减少compaction发生的频率。  提高以下两个属性的值,以增加执行compaction的线程数:  hbase.regionserver.thread.compaction.large  hbase.regionserver.thread.compaction.small  推荐设置为2。  优化Client设计  以上都是些常见的参数调整。但是写性能差一般是源于Client端的糟糕设计。  1. 避免region split  不得不说,region split是提升写性能的一大障碍。减少region split次数可以从两方面入手。首先是预分配region。  预分配region  不在此重复region split的原理,请参见http://blog.sina.com.cn/s/blog_9cee0fd.html。按数据量,row key的规则预先设计并分配好region,可以大幅降低region split的次数, 甚至不split。这点非常重要。  适当提升hbase.hregion.max.filesize  提升region的file容量也可以减少split的次数。具体的值需要按照你的数据量,region数量,row key分布等情况具体考量。一般来说,3~4G是不错的选择。  2. 均匀分布每个Region Server的写压力  之前也提到了RPC Handler的概念。好的Data Loader需要保证每个RPC Handlder都有活干,每个handler忙,但不至超载。注意region的压力不能过大,否则会导致反复重试,并伴有超时异常(可以提高超时的时间设置)。  如何保证每个Region Server的压力均衡呢?这和region 数量,startKey设计, client数据插入顺序有关。  一般来说,简单的数据插入程序应该是多线程实现。让每个线程负责一部分的row key范围,而row key范围又和region相关,所以可以在数据插入时,程序控制每个region的压力,不至于有些region闲着没事干。  那么,如何设计row key呢?举个比较实际的例子,如果有张HBase表来记录每天某城市的通话记录, 常规思路下的row key是由电话号码 + yyyyMMddHHmmSS + ... 组成。按电话号码的规律来划分region。但是这样很容易导致数据插入不均匀(因为电话通话呈随机性)。但是,如果把电话号码倒序,数据在region层面的分布情况就大有改观。  3. 分布式的数据插入程序  HBase客户端在单节点上运行,即使使用多线程,也受限于单节点的硬件资源,写入速度不可能很快。典型的思路是将客户端部署在多个节点上运行,提高写的并发度。MapReduce是个很好的选择。使用MapReduce把写入程序分布到集群的各个节点上,并在每个mapper中运行多线程的插入程序。这样可以很好的提高写并发度。  注意,不要使用reducer。mapper到reducer需要走网络,受限于集群带宽。其次,实际的应用场景一般是用户从关系型数据库中导出了文本类型的数据,然后希望能把导出的数据写到HBase里。在这种情况下,需要小心谨慎地设计和实现file split逻辑。  4. HBase Client太慢?BulkLoad!  请拿出HBase的API读读,HFileOutputFomart里有个叫configureIncrementalLoad的方法。API是这么介绍的:  Configure a MapReduce Job to perform an incremental load into the given table. This  Inspects the table to configure a total order partitioner  Uploads the partitions file to the cluster and adds it to the DistributedCache  Sets the number of reduce tasks to match the current number of regions  Sets the output key/value class to match HFileOutputFormat's requirements  Sets the reducer up to perform the appropriate sorting (either KeyValueSortReducer or PutSortReducer)  The user should be sure to set the map output value class to either KeyValue or Put before running this function.  这是HBase提供的一种基于MapReduce的数据导入方案,完美地绕过了HBase Client(上一节的分布式插入方法也是用mapreduce实现的,不过本质上还是用hbase client来写数据)  网上有不少文章叙述了使用命令行方式运行BulkLoad,比如  但是,不得不说,实际生产环境上很难使用这种方式。毕竟源数据不可能直接用来写HBase。在数据迁移的过程中会涉及到数据清洗、整理归并等许多额外的工作。这显然不是命令行可以做到的事情。按照API的描述, 可行的方案是自定义一个Mapper在mapper中清洗数据,Mapper的输出value为HBase的Put类型,Reducer选用PutSortReducer。然后使用HFileOutputFormat#configureIncrementalLoad(Job, HTable);解决剩余工作。  不过,这种实现也存在局限性。毕竟Mapper到Reducer比较吃网络。  至此,本文介绍了三种HBase数据写入的方法(1种多线程,2种mapreduce),并介绍了性能调优的方法。希望能对大家有所帮助。本文提供的所有数据导入方法,作者均亲手实现并使用TB级数据测试。限于篇幅,在此只提供实现思路。原文出自【比特网】,转载请保留原文链接:http://soft.chinabyte.com/database/13/.shtml
作者的其他最新日志
评论 ( 个评论)
站长推荐 /2
会员注册不成功的原因
新手获取积分方法
Powered by《HBase权威指南》读书笔记11:第十一章 性能优化
垃圾回收优化master基本不会遇到垃圾回收的问题。由于memstore的刷写机制是不连续的,所以java虚拟机的堆内存会出现孔洞。快速刷写到磁盘的数据会被划分到新生代,这种空间会被优先回收数据停留的时间太长,会被划分到老生代甚至终生代。而且老生代和终生代一般占据了好几个G,而新生代一般就几百M而已新生代空间由此得出新生代的空间一般的分配如下-XX:MaxNewSize=128m -XX:NewSize=128m可以缩写为-Xmn128m设定好之后观察是否合理如果不合理你会发现服务器的CPU使用量急剧上升,因为新生代的回收很占CPU新生代的设定如果调大,会带来的好处:则生存期较长的对象不会过快的划分为老生代。如果太大,回收会产生较长时间停顿gc日志如果JRE中孔洞太多,空间不够的时候,就需要压缩堆内存碎片,如果压缩内存碎片失败会出现失败日志。所以要通过以下参数开启jvm的gc日志-verbose:gc -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -Xloggc:$HBASE_HOME/logs/gc-${hostname}-hbase.log日志中会出现 "concurrent mode failure" 或者 "promotion failed" 信息注意:不过这个日志不会自动滚动,会越来越大你的手动用linux的每日滚动去做手动清理回收策略垃圾回收策略是可以切换的,建议用以下策略-XX:+UseParNewGC and -XX:+UseConcMarkSweepGC第一个选项是设置年轻代用 Parallel New Collector 回收策略:停止jvm去清空年轻代。因为年轻代很小,所以这个过程很快,一般不到一秒,所以这个暂停是可以接受的CMS策略但是老生代不能用这个策略,因为老生代很大,暂停会很久,如果大于zk的会话超时,就会引起朱丽叶暂停问题。所以老生代用 并行标记回收器(Concurrent Mark-Sweep Collector, CMS)来缓解。这种策略尽量异步实现垃圾回收,但是cpu占用率高。不过如果回收失败的话,还是会让jvm暂停来进行内存整理。使用了CMS策略有一个额外的参数设定什么时候开始进行并发标记-XX:CMSInitiatingOccupancyFraction=70这个值设定了一个百分比。70%是一个比较好的值,因为它比region的堆占用率60%略大(20%块缓存+40%memstore)这样在堆空间被占完之前就开始并行回收不会太小而导致回收频繁进行优化原则块缓存+memstore 不能 大于 100%要留空间给其他操作,所以 块缓存+memstore = 60% 比较合理本地memstore分配缓冲区(MSLAB)MSLAB=Memstore-Local Allocation Buffers
本地memstore分配缓冲区jvm孔洞(碎片)如果太多会触发 stop-the-world 垃圾回收,就是把整个jvm停掉回收垃圾。所以MSLAB致力于减少碎片。方法是:每次分配固定大小的对象,当这些对象被回收的时候,会留下固定大小的孔洞,之后如果新对象的大小也相同就可以直接用这些孔洞了,就不会引发 promotion fail,就不会触发 stop-the-world 过程MSLAB默认是开启的,如果没有就设置 hbase.hregion.memstore.mslab.enabled来开启hbase.hregion.memstore.mslab.chunksize 可以设定之前所说的固定大小孔洞的大小,默认是2MB。如果你存储的东西都很大,那就调大这个值如果你要存的东西大于存储缓冲区的上边界 hbase.hregion.memstore.mslab.max.allocation 默认值是256K。任何大于该值的单元格不会使用mslab特性,而是直接向jvm申请空间。MSLAB的代价是空间的浪费,就算你没用到缓冲区的最后一个字节,缓冲区依然是那么大。所以你必须权衡利弊(我个人建议是浪费就浪费,总比引起jvm暂停好)使用缓冲区需要额外的内存复制工作,所以会比直接使用KeyValue实例要慢一点压缩推荐使用snappy 。不过要在一开始就使用,中间切换不好搞优化拆分和合并管理拆分拆分/合并风暴当用户的region大小以恒定的速度保持增长时,region拆分会在同一时间发生,因为同时需要压缩region中的存储文件,这个过程会重写拆分后的region,这将会引起IO上升。建议:关闭自动拆分,然后手动调用split和major_compact 命令如何关闭自动拆分?将 hbase.hregion.max.filesize 调的非常大,但是不要大过 Long.MAX_VALUE (即 4775807),建议为100G手动运行还有一个好处,可以在不同时间段不同的region上执行,分散压力。用户可以做成cron的job定时执行这些操作手动拆分可以避免:当你做troubleshooting 的时候自动拆分有可能会把你正在看的region拆掉,这样就不好了region热点注意不要用类似时间戳这样的递增的东西做主键,防止出现region热点预拆分region在建立表的时候通过 SPLITS 属性可以直接定义各个region的范围,进行region的预拆分负载均衡master有一个内置的均衡器。默认情况下,均衡器每五分钟运行一次,这是通过 hbase.balancer.period 属性设置的。它会尝试均匀分配region到所有region服务器。启动均衡器,均衡器首先会确定一个region分配计划,该计划用于描述region如何移动。然后通过迭代调用管理API中的 unassign() 方法开始移动region。均衡器有一个可以限制自身运行时间的上限,通过 hbase.balancer.max.balancing 属性来配置,默认设置为均衡器运行时间间隔周期的一半,即两分半钟。合并region用 hbase org.apache.hadoop.hbase.util.Merge testtable 可以合并多个region删除大量数据的时候,可以合并region,让region不会那么多客户端API:最佳实践禁止自动刷写如果有大量的写入操作时,使用setAutoFlush(false) ,否则 Put 实例会被逐个传送到region服务器。禁止了自动刷写就可以等到写缓冲区被填满的时候一次性批量的发送。你可以可以使用 flushCommits() 方法显式刷写数据用 HTable 的 close 方法也会隐式的调用刷写使用扫描缓存如果HBase被作为一个MapReduce 作业的输入源,就可以用 setCache() 设置一个比1大的多的数值,可以开启扫描缓存。这样可以一次从region取多条(比如500条)到客户端来处理。不过传输数据的开销和内存开销都会增大。所以不是越大越好限定扫描范围当Scan被用来处理大量行时(比如作为MapReduce输入源时)最好只设定指定的列,如果用addFamily() 会把整个family的所有列都加载进来。(其实就是跟传统SQL建议大家不要 SELECT * 一回事)关闭ResultScanner一定要记得及时关闭 ResultScanner (其实跟传统数据库要记得关闭连接一回事)在finally 里面关闭 ResultScanner块缓存用法Scan可以通过设置 setCacheBlocks() 来设置使用region服务器中的块缓存。如果在MapReduce中,这个应该被设置成false如果某些行被频繁访问,这个应该被设置成true优化获取行键的方式如果你只是进行某些简单的行统计之类不需要获取所有列的操作,记得在 FilterList中添加 FirstKeyFilter 或者 KeyOnlyFilter ,这样就可以只返回第一个KeyValue行键,极大的减少了网络传输关闭Put上的WALPut 的 writeToWAL(false) 可以关闭WAL,可以大幅提高吞吐量,但是副作用就是region如果出问题就会丢失数据。其实如果数据是在集群间分布均匀后,其实关闭日志不会提升多少性能所以最好不要关闭WAL。要是真的要提高吞吐量的话就用 批量导入 (bulk load) 技术。这个在 12.2.3 中会进行介绍配置减少ZooKeeper超时的发生默认的region和zk之间的超时时间是3分钟。推荐设置为1分钟,这样可以更快的发现这一个故障默认时间那么长是为了避免大数据到导入时出问题,如果没有大数据的导入情况就可以把超时设置短一点12.5.3中“稳定性问题”会介绍一个方法来检测这种停顿个人认为没有太大必要,要挂就是一直挂,快那么2分钟也没什么用增加处理线程hbase.regionserver.handler.count 定义了响应外部用户访问数据表请求的线程数,默认是10,有点偏小。这是为了防止用户在客户端高并发使用较大的缓冲区的情况下服务器端过载。但是当单次请求开销较小时,可以设定的高一点设置太高,会对region的内存造成压力,甚至会导致 OutOfMemoryError。而且可用内存过低的话又会触发垃圾回收,造成全面暂停增加堆大小在 hbase-env.sh 中 调整 HBASE_HEAPSIZE ,增大为8G不过最好用 HBASE_REGIONSERVER_OPTS 而不是 HBASE_HEAPSIZE 可以单独调大region的堆大小,master不需要太大的堆大小,1G就够用了启用数据压缩推荐snappy,如果没有snappy就用LZO压缩增加region大小更大的region可以减少region数量少region可以让集群运行更平稳如果一个region变热点就手动拆分它默认的region是256M,可以配置成1G或者更大region太大的话高负载下的合并会停顿很长时间通过 hbase.hregion.max.filesize 设置region的大小调整块缓存大小默认块缓存是20%(即0.2)通过 perf.hfile.block.cache.size 属性可以设置这个百分比如果根据10.2.3节提到的 evicted(LV) 参数发现有许多块被换出。这样就需要增加块缓存大小来容纳更多的块如果用户负载基本都是读请求,也可以增加块缓存块缓存+memstore上限不能超过100%。默认他们的和是60%,只有当用户确认有必要并且不会造成副作用时才调整调整memstore限制通过 hbase.regionserver.global.memstore.upperLimit
设置上限。默认是0.4hbase.regionserver.global.memstore.lowerLimit 设置下限。默认是0.35把上下限设置的接近一点来避免过度刷写如果主要处理读请求,可以考虑同时减少memstore的上下限来增加块缓存的空间。如果刷写的数据量很小,比如只有5MB,就可以增加存储限制来降低IO操作增加阻塞是存储文件数目hbase.hstore.blockingStoreFiles 设置,决定了当存储文件的数据达到阀值时,所有更新操作(put,delete)等会被阻塞。然后执行合并操作。默认值是7如果文件数一直很高,就不要提高该配置项,因为这样只会延迟问题的发生,而不能避免增加阻塞倍率hbase.hregion.memstore.block.multiplier 的默认值为2 。当memstore达到属性 multiplier
乘以 flush 的大小限制时会阻止进一步的更新当有足够的存储空间时,用户可以增加这个值来增加平滑的处理写入突发流量减少最大日志设置 hbase.regionserver.maxlogs 属性是的用户基于磁盘的WAL文件数目,控制刷写频率。默认值是32对于写压力比较大的应用来说要把这个值调低,可以让数据更频繁的写到硬盘上,这样已经刷写到硬盘上的日志就可以被丢弃负载测试PEHBase有自带的压力测试工具名叫 PE(Performance Evaluation)YCSBYahoo 推出的云服务基准测试工具。比PE更好用,可以对hbase进行压力测试YCSB提供了更多的选项,并且能够将读写负载混合在一起
看过本文的人也看了:
我要留言技术领域:
取消收藏确定要取消收藏吗?
删除图谱提示你保存在该图谱下的知识内容也会被删除,建议你先将内容移到其他图谱中。你确定要删除知识图谱及其内容吗?
删除节点提示无法删除该知识节点,因该节点下仍保存有相关知识内容!
删除节点提示你确定要删除该知识节点吗?环境如下: Centos6.5 Apache Hadoop2.7.1 Apache Hbase0.98.12 Apache
Zookeeper3.4.6 JDK1.7 Ant1.9.5 Maven3.0.5
最近在测Hbase的压缩,Hadoop安装了lzo和snappy,插入50条文本数据,每条数据大约4M,来看他们的压缩率对比,
然后在测的过程中,发现用java客户端去scan这50条数据时,regionserver频繁宕机看hbase的log发现并无明显异常,查看datanode的log发现如下异常:
Java代码 &
java.io.IOException:&Premature&EOF&from&inputStream
&&&&&&&&at&org.apache.hadoop.io.IOUtils.readFully(IOUtils.java:201) &&
&&&&&&&&at&org.apache.hadoop.hdfs.protocol.datatransfer.PacketReceiver.doReadFully(PacketReceiver.java:213) &&
&&&&&&&&at&org.apache.hadoop.hdfs.protocol.datatransfer.PacketReceiver.doRead(PacketReceiver.java:134) &&
&&&&&&&&at&org.apache.hadoop.hdfs.protocol.datatransfer.PacketReceiver.receiveNextPacket(PacketReceiver.java:109) &&
&&&&&&&&at&org.apache.hadoop.hdfs.server.datanode.BlockReceiver.receivePacket(BlockReceiver.java:472) &&
&&&&&&&&at&org.apache.hadoop.hdfs.server.datanode.BlockReceiver.receiveBlock(BlockReceiver.java:849) &&
&&&&&&&&at&org.apache.hadoop.hdfs.server.datanode.DataXceiver.writeBlock(DataXceiver.java:804) &&
&&&&&&&&at&org.apache.hadoop.hdfs.protocol.datatransfer.Receiver.opWriteBlock(Receiver.java:137) &&
&&&&&&&&at&org.apache.hadoop.hdfs.protocol.datatransfer.Receiver.processOp(Receiver.java:74) &&
&&&&&&&&at&org.apache.hadoop.hdfs.server.datanode.DataXceiver.run(DataXceiver.java:251) &&
&&&&&&&&at&java.lang.Thread.run(Thread.java:745)&&
java.io.IOException: Premature EOF from inputStream
at org.apache.hadoop.io.IOUtils.readFully(IOUtils.java:201)
at org.apache.hadoop.hdfs.protocol.datatransfer.PacketReceiver.doReadFully(PacketReceiver.java:213)
at org.apache.hadoop.hdfs.protocol.datatransfer.PacketReceiver.doRead(PacketReceiver.java:134)
at org.apache.hadoop.hdfs.protocol.datatransfer.PacketReceiver.receiveNextPacket(PacketReceiver.java:109)
at org.apache.hadoop.hdfs.server.datanode.BlockReceiver.receivePacket(BlockReceiver.java:472)
at org.apache.hadoop.hdfs.server.datanode.BlockReceiver.receiveBlock(BlockReceiver.java:849)
at org.apache.hadoop.hdfs.server.datanode.DataXceiver.writeBlock(DataXceiver.java:804)
at org.apache.hadoop.hdfs.protocol.datatransfer.Receiver.opWriteBlock(Receiver.java:137)
at org.apache.hadoop.hdfs.protocol.datatransfer.Receiver.processOp(Receiver.java:74)
at org.apache.hadoop.hdfs.server.datanode.DataXceiver.run(DataXceiver.java:251)
at java.lang.Thread.run(Thread.java:745)
截图如下,好吧,出异常了,就拿这个异常google查找结果,发现并没有明确的答案,大部分都是说链接超时,或者是句柄数满了,导致链接中断等等,然后就按这些答案,改了若干配置,发现依然没有生效,这领我感到十分奇怪
,得出一个错误的结论,hbase不支持多种压缩类型并存的表,然后我去掉了其他类型用来压缩测试的表,再次测试,发现问题依旧,这再次令我十分诧异,会不会是环境的问题?因为我实在想不出来可能的问题所在了,然后就在本机虚拟机上进行测试,
虚拟机的环境,因为是自己用,所以JDK版本是1.8 和 Centos版本是7,Hbase,Hadoop,Zookeeper版本则保持一致,
搭建完毕后,继续测试,发现问题依旧,这下令人更迷惑了,看的出来非环境的问题了,不过这次有了点新的线索,由于用的是JDK8,在Hbase的log里面发现出现了大量的full
gc日志,意思就是内存严重不足,导致垃圾收集时间出现了4,5秒,这下我才有点头绪,hbase是个吃内存的玩意,内存给的少,确实有可能导致regionserver挂掉,于是我查看hbase的堆内存分配情况,发现是默认的1G,这下确实跟这个有很大关系,50条数据占存储200M,如果每次scan一次,hbase会将其缓存在cache里面,第二次继续scan不同压缩类型的表,会导致内存膨胀,继而引发,regionserver宕机,而给出的异常提示,并不是非常明确,所以才定位问题比较困难,知道了大概原因所在,然后把hbase的堆内存调到4G,并分发到所有节点上,再次启动,用java
客户端,扫描全表测试,这次非常稳定,regionserver没有出现过再次挂掉的情况。
最后给出测试压缩的一个结论:总共测了4种压缩比较,原始数据200M (1)不用压缩&&
占空间 128.1 M& (2)gz压缩&&&&&& 占920.3 K (3)snappy压缩 占 13.2M
(4)lzo压缩&&&&&& 占8M
以上可以看出,gz的压缩比最高,lzo次之,snappy第三,当然不同的压缩适用于不用的业务场景,这里不能就简简单单的
总结必须用什么,这里面snappy和lzo在目前大多数互联网公司用的比较多,所以大家可以根据具体业务,来选择合适的压缩方案。&
阅读(...) 评论()

我要回帖

更多关于 hbase region数量 的文章

 

随机推荐