首页 文章 精选 留言 我的

精选列表

搜索[web应用框架],共10000篇文章
优秀的个人博客,低调大师

大数据应用之HBase数据插入性能优化实测教程

引言: 大家在使用HBase的过程中,总是面临性能优化的问题,本文从HBase客户端参数设置的角度,研究HBase客户端数据批量插入性能优化的问题。事实胜于雄辩,数据比理论更有说服力,基于此,作者设计了这么一个HBase数据插入性能优化实测实验,希望大家用自己的服务器跑出的结果,给自己一个值得信服的结论。 一、客户单优化参数 1.Put List Size HBase的Put支持单条插入,也支持批量插入。 2. AutoFlush AutoFlush指的是在每次调用HBase的Put操作,是否提交到HBase Server。 默认是true,每次会提交。如果此时是单条插入,就会有更多的IO,从而降低性能 3.Write Buffer Size Write Buffer Size在AutoFlush为false的时候起作用,默认是2MB,也就是当插入数据超过2MB,就会自动提交到Server 4.WAL WAL是Write Ahead Log的缩写,指的是HBase在插入操作前是否写Log。默认是打开,关掉会提高性能,但是如果系统出现故障(负责插入的Region Server 挂掉),数据可能会丢失。 参数 默认值 说明 JVM Heap Size 平台不同值不同自行设置 AutoFlush True 默认逐条提交 Put List Size 1 支持逐条和批量 Write Buffer Size 2M 与autoflush配合使用 Write Ahead Log True 默认开启,需要手动关闭 … … 二、源码程序 1 import java.io.IOException; 2 import java.util.ArrayList; 3 import java.util.List; 4 import java.util.Random; 5 6 import org.apache.hadoop.conf.Configuration; 7 import org.apache.hadoop.hbase.HBaseConfiguration; 8 import org.apache.hadoop.hbase.HColumnDescriptor; 9 import org.apache.hadoop.hbase.HTableDescriptor; 10 import org.apache.hadoop.hbase.KeyValue; 11 import org.apache.hadoop.hbase.MasterNotRunningException; 12 import org.apache.hadoop.hbase.ZooKeeperConnectionException; 13 import org.apache.hadoop.hbase.client.Delete; 14 import org.apache.hadoop.hbase.client.Get; 15 import org.apache.hadoop.hbase.client.HBaseAdmin; 16 import org.apache.hadoop.hbase.client.HTable; 17 import org.apache.hadoop.hbase.client.Result; 18 import org.apache.hadoop.hbase.client.ResultScanner; 19 import org.apache.hadoop.hbase.client.Scan; 20 import org.apache.hadoop.hbase.client.Put; 21 import org.apache.hadoop.hbase.util.Bytes; 22 23 /* 24 * -------优化案例说明------------ 25 * 1.优化参数1:Autoflush 默认关闭,需要手动开启 26 * 2.优化参数2:put list size 支持单条与批量 27 * 3.优化参数3:JVM heap size 默认值是平台而不同,需要手动设置 28 * 4.优化参数4:Write Buffer Size 默认值2M 29 * 5.优化参数5:Write Ahead Log 默认开启,需要手动关闭 30 * */ 31 32 public class TestInsert { 33 static Configuration hbaseConfig = null; 34 35 public static void main(String[] args) throws Exception { 36 Configuration HBASE_CONFIG = new Configuration(); 37 HBASE_CONFIG.set("hbase.master", "192.168.230.133:60000"); 38 HBASE_CONFIG.set("hbase.zookeeper.quorum", "192.168.230.133"); 39 HBASE_CONFIG.set("hbase.zookeeper.property.clientPort", "2181"); 40 hbaseConfig = HBaseConfiguration.create(HBASE_CONFIG); 41 //关闭wal,autoflush,writebuffer = 24M 42 insert(false,false,1024*1024*24); 43 //开启AutoFlush,writebuffer = 0 44 insert(false,true,0); 45 //默认值,全部开启 46 insert(true,true,0); 47 } 48 49 private static void insert(boolean wal,boolean autoFlush,long writeBuffer) 50 throws IOException { 51 String tableName="etltest"; 52 HBaseAdmin hAdmin = new HBaseAdmin(hbaseConfig); 53 if (hAdmin.tableExists(tableName)) { 54 hAdmin.disableTable(tableName); 55 hAdmin.deleteTable(tableName); 56 } 57 58 HTableDescriptor t = new HTableDescriptor(tableName); 59 t.addFamily(new HColumnDescriptor("f1")); 60 t.addFamily(new HColumnDescriptor("f2")); 61 t.addFamily(new HColumnDescriptor("f3")); 62 t.addFamily(new HColumnDescriptor("f4")); 63 hAdmin.createTable(t); 64 System.out.println("table created"); 65 66 HTable table = new HTable(hbaseConfig, tableName); 67 table.setAutoFlush(autoFlush); 68 if(writeBuffer!=0){ 69 table.setWriteBufferSize(writeBuffer); 70 } 71 List<Put> lp = new ArrayList<Put>(); 72 long all = System.currentTimeMillis(); 73 74 System.out.println("start time = "+all); 75 int count = 20000; 76 byte[] buffer = new byte[128]; 77 Random r = new Random(); 78 for (int i = 1; i <= count; ++i) { 79 Put p = new Put(String.format("row d",i).getBytes()); 80 r.nextBytes(buffer); 81 p.add("f1".getBytes(), null, buffer); 82 p.add("f2".getBytes(), null, buffer); 83 p.add("f3".getBytes(), null, buffer); 84 p.add("f4".getBytes(), null, buffer); 85 p.setWriteToWAL(wal); 86 lp.add(p); 87 if(i%1000 == 0){ 88 table.put(lp); 89 lp.clear(); 90 } 91 } 92 93 System.out.println("WAL="+wal+",autoFlush="+autoFlush+",buffer="+writeBuffer+",count="+count); 94 long end = System.currentTimeMillis(); 95 System.out.println("total need time = "+ (end - all)*1.0/1000+"s"); 96 97 98 System.out.println("insert complete"+",costs:"+(System.currentTimeMillis()-all)*1.0/1000+"ms"); 99 } 100 } 三、集群配置 3.1 服务器硬件配置清单 序号 节点名称 CUP 内存 硬盘 带宽 1 HMaster 2 HregionServer1 3 HregionServer2 4 … 5 6 7 3.2 客户端硬件配置清单 设备 节点名称 Cpu 内存 硬盘 带宽 四、测试报告 数据量 JVM AutoFlush Put List Size WriteBufferSize WAL 耗时 1000 512m false 1000 1024*1024*24 false 2000 5000 10000 20000 50000 100000 200000 500000 100000 备注:该技术专题讨论正在群Hadoop高级交流群:293503507同步直播中,敬请关注。 作者:张子良 出处:http://www.cnblogs.com/hadoopdev 本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

优秀的个人博客,低调大师

数据监控体系搭建方法论:从采集到告警的完整技术框架

前几年我接过一个价格监控项目。系统刚上线时很顺,每天定时采集、清洗、入库,报表也能正常更新。运行到第三周,业务突然反馈部分商品连续两天没有数据。 排查后才发现,采集脚本没有报错,数据库也在持续写入,但目标页面的字段结构已经变化。程序把解析失败的数据当成空结果,后面的监控只检查“任务有没有完成”,所以一直显示正常。 这件事让我重新认识了数据监控:真正需要监控的不是一条脚本,而是数据从产生到使用的完整链路。 一套能长期运行的数据监控体系,至少要回答三个问题: - 数据有没有按时拿到? - 拿到的数据是否完整、可信? - 出现异常后,能不能快速定位到具体环节? ## **先定义监控对象,再考虑技术选型** 很多项目一开始就讨论用什么数据库、消息队列和告警工具,最后却说不清到底要监控什么。 我通常先把监控对象分成三层。 第一层是**任务状态**,包括任务是否启动、是否结束、运行耗时和重试次数。这一层解决的是“程序有没有正常工作”。 第二层是**数据质量**,包括采集量、空值率、重复率、字段完整率和数值波动。这一层解决的是“程序拿到的数据能不能用”。 第三层是**业务结果**,例如商品价格是否异常变化、某个地区的数据是否突然减少、更新频率是否偏离正常基线。这一层才是业务真正关心的结果。 只监控第一层,最容易出现“任务成功,数据错误”的情况。 ## **采集层要留下足够的排查线索** 采集程序不能只输出成功或失败。每次请求至少要记录任务编号、数据源、请求时间、响应状态、响应耗时和解析结果。 我习惯给每批任务生成唯一的 `task_id`,让它贯穿采集、清洗、入库和告警环节。后面查问题时,只需要拿着这个编号顺着链路找,不必在几套日志里反复对时间。 原始响应也要保留一段时间。字段规则写错、页面结构变化或者清洗逻辑误删数据时,原始数据就是复盘依据。没有原始响应,只能重新采集,碰上数据源已经更新,现场就彻底丢了。 国内公开数据采集如果需要代理接入层,我会把代理状态也记入任务日志,包括节点、连接耗时、切换次数和连续失败数。 ## **调度和采集不要绑死** 任务少的时候,用定时脚本直接启动采集没有问题。任务量增加后,调度层最好只负责分发任务,不直接承担采集逻辑。 这样做有两个好处。 一是失败任务可以单独重试,不需要把整个批次重新跑一遍。二是采集端可以水平扩展,任务多时增加执行节点,任务少时减少资源占用。 每个任务还要设置明确状态,例如: `pending → running → collected → processed → stored → completed` 如果任务停在某个状态超过预期时间,系统就能判断它卡在哪一步,而不是等到整批数据没有产出才发现问题。 ## **数据校验要分成结构和业务两道关** 结构校验负责检查字段是否存在、类型是否正确、格式能否解析。业务校验则判断数据是否符合正常规律。 例如价格字段为0,从数据类型上看完全合法,但在业务上可能需要复核;某个平台当天采集量下降30%,也不一定是采集失败,可能只是数据源本身没有更新。 我一般会同时观察四组指标: |指标组|重点指标|主要判断| | --- | --- | --- | |采集质量|成功率、超时率、响应耗时|链路是否稳定| |数据质量|空值率、重复率、字段完整率|数据是否可用| |处理状态|队列积压、消费耗时、失败批次|处理是否及时| |业务结果|新增量、变化率、更新时间|结果是否合理| 数据会说话,但要把几组指标放在一起看。采集成功率下降,同时空值率升高,问题大概率在采集链路;采集指标正常,但业务数据明显减少,则要进一步确认数据源是否发生变化。 ## **存储要为追溯和查询分别服务** 监控系统至少要保留三层数据。 **原始层**保存未经加工的响应,用于复盘和重新计算;**明细层**保存清洗后的标准记录,供业务查询;**指标层**保存已经聚合的监控结果,供仪表盘和告警规则直接读取。 这三层不要混在一张表里。 如果告警系统每分钟扫描海量明细数据,不仅查询成本高,还可能影响正常写入。更省心的做法,是提前计算成功率、异常量和延迟等指标,让告警系统只读取小体量的指标表。 原始数据也不必永久保存。保留多久,要看业务问题通常多久才会暴露。如果异常经常在一周后才被反馈,原始数据只留三天肯定不够用。 ## **告警要能指导下一步动作** “任务异常,请及时处理”不算一条合格告警。 值班人员收到告警后,首先需要知道哪个任务出问题、当前值是多少、正常基线是多少、异常持续了多久,以及从哪里开始排查。 一条能用的告警至少应该包含: - 任务名称和任务编号 - 异常指标及当前数值 - 历史基线或告警阈值 - 首次发生时间和持续时长 - 相关日志或任务详情入口 - 建议优先检查的环节 单次超时通常先重试,不必立即通知。连续多个周期失败,或者采集量、空值率和处理延迟同时异常,再升级告警。否则消息太多,真正重要的异常反而容易被忽略。 恢复通知也要保留。异常什么时候结束、持续了多久、是否经过人工处理,都是后续复盘和调整阈值的依据。 ## **监控系统本身也需要被监控** 这是搭建过程中最容易漏掉的一层。 如果告警任务自己停止运行,业务任务出错时就不会有任何提示。因此需要一条独立的心跳链路,持续检查调度服务、消息队列、指标计算和通知通道是否正常。 我通常会设置一个固定频率的测试任务,让它按完整链路产生数据并触发一条可预期记录。如果这条记录没有按时出现,就说明监控体系本身存在问题。 监控不是加几条规则就结束了。每次真实故障后,都要回头检查:为什么已有指标没有提前发现?告警是否来得太晚?排查过程缺了哪条日志?这些问题解决一次,系统才会真正稳一点。 ## **到底怎么搭?** 如果让我从零搭一套数据监控体系,我会按这个顺序推进: 先给任务和数据建立唯一标识,把整条链路串起来;然后补齐原始数据、状态日志和质量校验;再根据历史数据建立指标基线;最后配置分级告警和故障复盘机制。 代理、消息队列和数据库都是工具,不是体系本身。真正决定系统能不能长期运行的,是每个环节都可观察、每条异常都能追踪、每次故障都能留下改进结果。 实操建议也很简单:先挑一条真实任务跑完整闭环,故意制造超时、空数据、字段变化和处理积压,看看系统能不能及时发现并指出排查方向。测试环境里主动暴露的问题越多,上线以后临时翻日志的次数就越少。 ## **常见问题** **Q:小项目需要一开始就上消息队列吗?** 不一定。任务少、允许整体重跑时,定时任务配合状态表已经够用。等到采集和处理速度明显不一致,或者失败任务需要独立重试,再引入消息队列。 **Q:告警阈值没有历史数据怎么定?** 先设置相对宽松的静态阈值,运行一到两周收集基线。等数据量和波动范围稳定后,再逐步换成按时段或任务类型区分的动态阈值。 **Q:怎样区分采集失败和数据源没有更新?** 同时看请求成功率、响应体大小、字段完整率和新增数据量。技术指标正常而新增量下降,更可能是数据源本身变化;多项技术指标一起异常,则优先检查采集链路。 **Q:代理接入层应该重点监控什么?** 不要只统计IP数量,重点看有效请求成功率、响应时间、连续失败次数和节点切换情况。如果准备接入代理商,建议直接用现有脚本测试,不要为了测试单独设计一套过于简单的请求。

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册