Java代码实现对dubbo服务的查询压力测试(Hbase数据库)

本文分享了一次针对HBase查询性能的优化经历,通过分析底层数据库查询逻辑,调整表结构及分区数量,显著提高了查询的QPS。并总结了影响HBase QPS的因素。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

测试简介

底层数据库采用Hbase,可视化工具使用的是Phoenix。
作业由来:甲方想通过jmete对hbase进行压测,但是上线的两个接口并没有封装成http协议,没办法直接调用,百度的dubbo-jmeter-plugin添加之后也没有连接成功,一番挣扎之后放弃了,所以就准备自己写个并发程序去测试一下。
测试主要是看查询的QPS(每秒查询效率),计算公式:总请求数/总执行时间(总请求数是为测试数据量)。废话不多说直接上测试代码。

代码

程序入口:

/**
 * 自己编写Java高并发对dubbo服务接口的查询功能进行压力测试
 * @author Lenovo
 *
 */
public class MainApplication {
	private static ClassPathXmlApplicationContext context;
	private static AtomicInteger atomicInteger;
	
	//dubbo消费者的启动入口
    public static void main( String[] args )
    {
         context = new ClassPathXmlApplicationContext("dubbo-consumer.xml");
         //此处为自己的接口
         Test test = context.getBean("Test");
         context.start();
         
         //读取测试数据文件
         File file = new File("F:\\test_data\\book\\data.txt");
         BufferedReader bufferedReader;
         LineNumberReader lineNumberReader;
         List<String> list;
         try {
        	 bufferedReader = new BufferedReader(new FileReader(file));
        	 lineNumberReader = new LineNumberReader(bufferedReader);
        	 String str = "";
        	 list = new ArrayList<String>();
        	 while((str = lineNumberReader.readLine()) != null) {
        		 list.add(str);
        	 }
		} finally {
			bufferedReader.close();
			lineNumberReader.close();
		}
         //将读取进来的数据打乱
         Collections.shuffle(list);
         
         //初始化线程池
         ExecutorService executorService = Executors.newFixedThreadPool(32);
         //开始记录调用接口到所有数据查询完毕的时间
         Long currentTime = System.currentTimeMillis();
         for(int i = 0; i<list.size();i++) {
        	 Runnable runnable = execute(test,list.get(i).split(","));
        	 executorService.execute(runnable);
         }
         //关闭线程池
         executorService.shutdown();
         //等待线程池中的所有线程执行完再执行主函数
         while(!executorService.isTerminated()) {}
         
         Long stillTime = System.currentTimeMillis()-currentTime;
         System.out.println("总执行时间(ms):"+stillTime);
         System.out.println("总数据量"+atomicInteger);
         System.out.println("QPS为:"+(atomicInteger.longValue())/stillTime);
    }

	private static Runnable execute(Test test,String[] value) {
		Runnable runnable = new Runnable() {
			
			@Override
			public void run() {
				test.get(value[0],value[1],value[2]);
				atomicInteger.addAndGet(1);
			}
		};
		return runnable;
	}
}

配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
        http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
    
    <!-- 消费方的应用名,用于计算依赖关系,不是匹配条件,不要与消费方一致 -->
    <dubbo:application name="test"></dubbo:application>
    <!-- 走的zk注册中心,即dubbo服务注册的zk地址 -->
    <dubbo:registry protocol="zookeeper" address="127.0.0.1"/>

    <dubbo:annotation package="com.bigdata.test"/>
    <dubbo:reference id="TestSearch" interface="com.bigdata.test.api.TestSearch" />

</beans>

测试结果分析

最终的测试结果QPS只有几十,并没有达到我们的预期,所以接下来就开始找到底是哪里有问题了。
1.首先将关联查询的sql单独拆开,也就是单表查询。内层的单表速度非常快,因为查询的条件是走的row_key精准查询,QPS在2000以上。接下来就开始找外层的sql,果不其然,QPS非常的低。
2.外层的查询条件走了row_key联合索引的第一个,那我们就考虑可不可以直接将row_key改为,直接否定了,因为这样会导致部分数据丢失,那我们又开始考虑是不是对表加盐加多了,导致数据过于散列。
3.我们试着将分区从100改为了10,QPS一下就上去了,提升了大概有百倍。

总结

导致QPS低的原因有很多,常见的有:
1.数据库表从建表的时候考虑不周到,没有很好的建立row_key;
2.设置分区不合理,导致数据过于散列;
3.服务器的性能比较差;
由于本人经验不足,可能分析的比较浅显,如果表达有不对的地方,希望各位大佬可以指教。
Doe 发布 [V1.0.0] 前段时间排查某问题的时候,想要快速知道某些dubbo接口(三无)的响应结果,但不想启动项目(因为这些项目不是你负责的,不会部署而且超级笨重),也不想新建一个dubbo客户端项目(占地方),也不想开telnet客户端连接口(麻烦而且有限制)。所以扣了dubbo的netty模块源码,封装了个收发客户端集成一个工具,可以快速调试dubbo接口。源码地址:https://github.com/VIPJoey/doe 极简模式 普通模式 目录结构 mmc-dubbo-api 接口项目,主要用于测试。 mmc-dubbo-provider dubbo提供者项目,主要用于测试。 mmc-dubbo-doe 主项目,实现dubbo接口调试。 deploy 部署文档 功能特性 极简模式:通过dubbo提供的telnet协议收发数据。 普通模式:通过封装netty客户端收发数据。 用例模式:通过缓存数据,方便下一次操作,依赖普通模式。 增加依赖:通过调用maven命令,下载jar包和热加载到系统,主要用来分析接口方法参数,主要作用在普通模式。 依赖列表:通过分析pom文件,展示已经加载的jar包。 其它特性 springboot 整合 redis,支持spring el 表达式。 springboot 整合 thymeleaf。 springboot 整合 logback。 netty rpc 实现原理。 开发环境 jdk 1.8 maven 3.5.3 dubbo 2.6.1 lombok 1.16.20 idea 2018 windows 7 安装步骤 安装jdk 安装maven,并设置好环境变量,仓库目录。 进入mmc-dubbo-api目录,执行mvn clean install命令,省api的jar包。 进入mmc-dubbo-doe目录,执行mvn clean install 命令,在target目录生成dubbo-doe-1.0.0-RELEASE.jar 在F盘(可以任意盘)创建目录F:\app\doe 把dubbo-doe-1.0.0-RELEASE.jar拷贝到F:\app\doe 把deploy目录中的所有文件拷贝到F:\app\doe 如果您电脑安装了git bash,可以在bash窗口运行 ./deploy.sh start,否则如果没有安装git bash,只能打开cmd切换到F:\app\doe目录,然后执行java -jar dubbo-doe-1.0.0-RELEASE.jar --spring.profiles.active=prd 打开浏览器,访问地址:http://localhost:9876/doe/home/index 全剧终
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值