1 需求分析
1.1 分析压测对象
1)什么是 ClickHouse 和 Elasticsearch
ClickHouse 是一个真正的列式数据库管理系统(MS)。在 ClickHouse 中,数据始终是列存储的,包括向量(对或列块)的执行过程。只要有可能,操作都是基于向量进行分派的,而不是实现的价值,这被称为«它有查询实际的数据处理»。
Elasticsearch 是一款开源的引擎可以使用、这样的RESTful 风格的搜索分析,它的Apache 是开源的开源引擎。
- 一个索引的索引文档存储,字段可以被与搜索
- 一个实时分析搜索引擎
- 胜上百个服务节点的扩展支持PB人物的任性或非血数据
2)为什么要对他们进行压测
是的剧集,非常多的点击屋在场景中具有出色的性能,具有复杂性的基本业务查询,但我们却有一个非常重要的查询业务场景,甚至是双十一业务的真实情况,确保大型活动具有业务能力的持续性,ClickHouse 和 Elasticsearch 的性能业务场景中是否具备性能优良的性能,通过性能压测,中压我们的任务点,进行抗压,优化设计性能。
1.2 定压测目标
会选择这个(queryOBBacklogData)接口呢?
1)从复杂度来看,接口(queryOBBacklogData)查询了5次,代码如下:
/** * 切ck-queryOBBacklogData * @param queryBO * @return */ public OutboundBacklogRespBO queryOBBacklogDataCKNew(OutboundBacklogQueryBO queryBO) { log.info(" queryOBBacklogDataCK入参:{}", JSON.toJSONString(queryBO)); // 公共条件-卡最近十天时间 String commonStartTime = DateUtils.getTime(DateUtil.format(new Date(), DateUtil.FORMAT_DATE), DateUtils.ELEVEN_AM, 1, -10); String commonEndTime = DateUtils.getTime(DateUtil.format(new Date(), DateUtil.FORMAT_DATE), DateUtils.ELEVEN_AM, 1, 1); // 越库信息-待越库件数&待越库任务数 WmsObCrossDockQueryBo wmsObCrossDockQueryBo = wmsObCrossDockQueryBoBuilder(queryBO,commonStartTime, commonEndTime); log.info("queryOBBacklogDataCK-wmsObCrossDockQueryBo: {}", JSON.toJSONString(wmsObCrossDockQueryBo)); CompletableFuture<OutboundBacklogRespBO> preCrossDockInfoCF = CompletableFuture.supplyAsync( () -> wmsObCrossDockMapper.preCrossDockInfo(wmsObCrossDockQueryBo), executor); // 集合任务信息-待分配订单 WmsObAssignOrderQueryBo wmsObAssignOrderQueryBo = wmsObAssignOrderQueryBoBuilder(queryBO, commonStartTime, commonEndTime); log.info("queryOBBacklogDataCK-wmsObAssignOrderQueryBo: {}", JSON.toJSONString(wmsObAssignOrderQueryBo)); CompletableFuture<Integer> preAssignOrderQtyCF = CompletableFuture.supplyAsync( () -> wmsObAssignOrderMapper.preAssignOrderInfo(wmsObAssignOrderQueryBo), executor); // 拣货信息-待拣货件数&待拣货任务数 WmsPickTaskQueryBo wmsPickTaskQueryBo = wmsPickTaskQueryBoBuilder(queryBO, commonStartTime, commonEndTime); log.info("queryOBBacklogDataCK-wmsPickTaskQueryBo: {}", JSON.toJSONString(wmsPickTaskQueryBo)); CompletableFuture<OutboundBacklogRespBO> prePickingInfoCF = CompletableFuture.supplyAsync( () -> wmsPickTaskMapper.pickTaskInfo(wmsPickTaskQueryBo), executor); // 分播信息-待分播件数&待分播任务 WmsCheckTaskDetailQueryBo wmsCheckTaskDetailQueryBo = wmsCheckTaskDetailQueryBoBuilder(queryBO, commonStartTime, commonEndTime); log.info("queryOBBacklogDataCK-wmsCheckTaskDetailQueryBo: {}", JSON.toJSONString(wmsCheckTaskDetailQueryBo)); CompletableFuture<OutboundBacklogRespBO> preSowInfoCF = CompletableFuture.supplyAsync( () -> wmsCheckTaskDetailMapper.checkTaskDetailInfo(wmsCheckTaskDetailQueryBo), executor); // 发货信息-待发货件数 WmsOrderSkuQueryBo wmsOrderSkuQueryBo = wmsOrderSkuQueryBoBuilder(queryBO, commonStartTime, commonEndTime); log.info("queryOBBacklogDataCK-wmsOrderSkuQueryBo: {}", JSON.toJSONString(wmsOrderSkuQueryBo)); CompletableFuture<Integer> preDispatchCF = CompletableFuture.supplyAsync( () -> wmsOrderSkuMapper.preDispatchInfo(wmsOrderSkuQueryBo), executor); return processResult(preCrossDockInfoCF, preAssignOrderQtyCF, prePickingInfoCF, preSowInfoCF, preDispatchCF); }
2)查询表(OBBacklogData),查询了5个表:
wms.wms_ob_cross_dock wms.wms_ob_assign_order wms.wms_picking_task. wms.wms_check_task_detail wms.wms_order_sku
3)查询的数据量,如下:
select (ifnull(sum(m.shouldBeCrossedDockQty), 0) - ifnull(sum(m.satisfiedCrossedDockQty), 0)) as preCrossStockSkuQty, count(m.docId) as preCrossStockTaskQty from wms.wms_ob_cross_dock m final prewhere m.createTime >= '2021-12-03 11:00:00' and m.createTime <= '2021-12-14 11:00:00' and m.warehouseNo = '279_1' and m.orderType = '10' and tenantCode = 'TC90230202' where m.deleted = 0 and m.deliveryDestination = '2' and m.shipmentOrderDeleted = 0 and m.status = 0
可以从上面的SQL截图中,查询待越库文件数&待越库任务数共读取720817行数据
select count(distinct m.orderNo) as preAssignedOrderQty from wms.wms_ob_assign_order m final prewhere m.createTime >= '2021-12-03 11:00:00' and m.createTime <= '2021-12-14 11:00:00' and m.warehouseNo = '361_0' and tenantCode = 'TC90230202' where m.taskassignStatus = 0 and m.deliveryDestination = 2 and m.stopProductionFlag = 0 and m.deleted = 0 and m.orderType = 10
上面的 SQL 截图共读取了,可以从查询任务信息 - 集合待分配订单,153118 行数据
select minus(toInt32(ifnull(sum(m.locateQty), toDecimal64(0, 4))), toInt32(ifnull(sum(m.pickedQty), toDecimal64(0, 4)))) as prePickingSkuQty, count(distinct m.taskNo) as prePickingTaskQty from wms.wms_picking_task m final prewhere m.shipmentOrderCreateTime >= '2021-12-03 11:00:00' and m.shipmentOrderCreateTime <= '2021-12-14 11:00:00' and m.warehouseNo = '286_1' and tenantCode = 'TC90230202' where m.pickingTaskDeleted = 0 and m.deliveryDestination = 2 and m.pickLocalDetailDeleted = 0 and m.shipmentOrderDeleted = 0 and m.orderType = 10 and (m.operateStatus = 0 or m.operateStatus = 1)
上面的SQL截图&可以从查询拣货任务信息-待拣货件数条,共读到2673536个数据
select minus(toInt32(ifnull(sum(m.locateQty), toDecimal64(0, 4))), toInt32(ifnull(sum(m.pickedQty), toDecimal64(0, 4)))) as prePickingSkuQty, count(distinct m.taskNo) as prePickingTaskQty from wms.wms_picking_task m final prewhere m.shipmentOrderCreateTime >= '2021-12-03 11:00:00' and m.shipmentOrderCreateTime <= '2021-12-14 11:00:00' and m.warehouseNo = '279_1' and tenantCode = 'TC90230202' where m.pickingTaskDeleted = 0 and m.deliveryDestination = 2 and m.pickLocalDetailDeleted = 0 and m.shipmentOrderDeleted = 0 and m.orderType = 10 and (m.operateStatus = 0 or m.operateStatus = 1)
以上SQL截图-可以从分查询分播信息行数待播播任务,共读148149个数据
select ifnull(sum(m.unTrackQty), 0) as unTrackQty from wms.wms_order_sku m final prewhere m.shipmentOrderCreateTime >= '2021-12-03 11:00:00' and m.shipmentOrderCreateTime <= '2021-12-14 11:00:00' and m.warehouseNo = '280_1' and m.orderType = '10' and m.deliveryDestination = '2' and tenantCode = 'TC90230202' where m.shipmentOrderDeleted <> '1' and m.ckDeliveryTaskDeleted <> '1' and m.ckDeliveryTaskDetailDeleted <> '1' and m.ckDeliveryTaskStatus in ('1','0','2')
上面的 SQL 共读取可以从查询收到的信息 - 待件数,截图 99591 行数据
基于 Spring Boot + MyBatis Plus + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能
2 测试环境准备
为了发挥压测作用,履行压测环境,应该使用其他类似的环境一致,所以我们应该使用类似的环境一致了和类似的环境
基于 Spring Cloud Alibaba + Gateway + Nacos + RocketMQ + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能
3 采集工具准备
工具监控
- http://origin.jd.com/ :监控 JVM,方法等级监控(提供秒级支持)
- http ://console.jex.jd/ :提供异常监控,火焰图监控、资源分析。
- http://x.devops.jdcloud.com/ :支持查看clickhouse/Elasticsearch 数据库服务器每个节点的cpu使用率
- http://dashboard.fireeye.jdl.cn/ :应用服务器cpu使用率、内存使用率监控
4 压测执行及结果分析
4.1 编写压测脚本工具
Forcebot(http://force.jd.com) 是一个为开发人员、测试人员提供的性能测试平台,通过编写、配置、场景任务、实时监控、日志定位、发布监控、设置报告操作的流程来完成测试,灵活的脚本配置满足同步性能、异步、集合点等各种发压模式。
帮助文档(http://doc.jd.com/forcebot/helper/)
4.2 设计压测数据
4.2.1 压测中名词解释
- DBCP:数据库连接,是apache的一个Java连接项目。DBCP通过连接池上的数据库同建立一些连接内存中(即连接池中),应用程序需要建立数据库时直接到从连接池中申请一个连接使用,使用后由回收该连接,从而达到连接复用完成,减少资源消耗的目的。
- maxTotal:是连接池中总连接的最大数量,默认值为8
- max_thread:clickhouse中配置,处理SQL请求时使用的最大线程数。数值是clickhouse服务器的核心数量。
- 协调:协调节点数,主要作用于请求,请求转发请求响应处理等轻量级
- 数据节点:主要是存储索引节点的节点,主要是对文档进行删除,聚合操作等。的时候,需要在群里添加新的节点
4.2.2 压测数据
clickhouse数据服务:32C128G6节点2副本
应用服务器:4 核 8G 2 maxTotal=16
注: 每次压测前,一定要观察每个数据节点的 cpu 使用率
注: 从上面的压测过程中,序号-12,数据库中的数据库中的数据池中的数据可以在tps 6号,但没有增加数据库中的大数据,但没有更多的变化,检查数字未配置,默认的数字是连接的8个最大的地方用户数增加至8以后,clickhouse cpu稳定在40%~50%之间不再增加,应用服务器CPU稳定在25%左右。
之后我们调整 max50,通过 max_thread 不同的值,节点 CPU 使用率保持在左右,来查看数据:服务器 CPU 使用率、TP、TP99、应用指标总比例 = 监控数。
clickhouse 数据节点,CPU 使用率:
Elasticsearch 数据服务:328G6 2 2 副本 应用服务器:4 8G 2 Elasticsearch 节点服务器保持数据库服务器 CPU 使用率达到50%左右(50%左右),重新监控 数据节点、tp99 指标:coating 节点协调数、数据节点大小
指标1:coordinating=2,数据偏差=4,poolSize=400
在测的过程中,CPU 的使用率达到 51.6%,注平均的发现率在 9% 的情况下,协调每个节点的负载率,所以需要协调每个节点
指标2:coordinating=4,数据偏差=5,poolSize=800
注: 在压测的过程中,发现CPU使用率(数据库)ES数据节点在40%左右的时候,发现一直上不去,查看日志activeCount已经达到797,需要增加poolSize值
指标3:coordinating=4,数据偏差=5,poolSize=1200
注: 压测过程中,发现协调节点支持还是需要扩容,不能现在数据节点cpu使用率达到50% Elasticsearch数据节点及协调节点,CPU使用率:
我们在压测的过程中发现一些在开发过程中没有发现的问题,首先 bdcp 数大数据应用服务器,使用的线程池数线程数为 8 时,使需求,用户增加至 8 以后,clickhouse 的 cpu CPU 20%~55%之间稳定左右稳定,CPU 40%左右稳定运行,CPU40服务器20左右,服务器使用率高,是clickhouse-jdbc解析sql效率低。
4.3 结果分析
4.3.1 测试结束
1)clickhouse对有一定的支持,通过不支持高线程,可以调整线程的增加
- max_thread=32 时,支持最大TPS 为37,相应TP99 为122
- max_thread=2 时,支持最大TPS 66,相应TP99 155
- max_thread=1 时,支持最大TPS 86,相应TP99 206
2)在很多方面,Elasticsearch 比 clickhouse 支持的更好,但相应的响应速度慢
- Elasticsearch:TPS 是 192,TP99 是 3050
- clickhouse:TPS 是 86,TP99 是 206
考考,认为clickhouse是我们普遍接受我们的业务诉求
4.3.2 优化建议
- 对 ES 协商节点进行扩容
- bigdata 应用至最大线程数调高 200
- bigdata 应用 dbcp 线程池 maxTotal 设置成 50
- 读取配置文件工具类增加内存缓存