CarbonData与商业列存DB性能对比

本文描述了CarbonData与某商业列存DB的查询性能对比,通过此对比可以看出CarbonData的优势和特点。本文的测试场景是基于某聚合查询业务(分析报表),测试结果只代表该特定查询场景下的性能对比。

1. 测试环境

商业列存DB使用SSD硬盘,配置一台查询节点。CarbonData6个DataNode,配置STAT硬盘,但是查询队列设置1/6的资源,等同于1台商业DB服务器对比1台CarbonData服务器的查询性能。同时CarbonData使用的服务器的磁盘是STAT盘,成本比某商业列存DB服务器低。

集群CPUvCoreMemory硬盘描述
某商业列存DB集群Gold 6132 CPU@2.60GZ56256GBSSD3节点,一个节点作为查询节点
Hadoop集群Gold 6132 CPU@2.60GZ56256GBSATA2个namenode,6个datanode, 查询队列分配1/6的资源,等同于一个节点

2. SQL测试语句介绍

Spark SQL的查询语句:

SELECT 
  COALESCE(SUM(COLUMN_A), 0) + COALESCE(SUM(COLUMN_B), 0) AS COLUMN_C , 
  COALESCE(SUM(COLUMN_A), 0) AS COLUMN_A_A ,
  COALESCE(SUM(COLUMN_B), 0) AS COLUMN_B_B , 
  COALESCE(SUM(COLUMN_D), 0) + COALESCE(SUM(COLUMN_E), 0) AS COLUMN_F , 
  COALESCE(SUM(COLUMN_D), 0) AS COLUMN_D_D , 
  COALESCE(SUM(COLUMN_E), 0) AS COLUMN_E_E ,
  (COALESCE(SUM(COLUMN_A), 0) + COALESCE(SUM(COLUMN_B), 0)) * delta AS COLUMN_F , 
  COALESCE(SUM(COLUMN_A), 0) * delta AS COLUMN_G , 
  COALESCE(SUM(COLUMN_B), 0) * delta AS COLUMN_H , 
  MT.`TEMP` AS `TEMP` 
FROM ( 
	SELECT 
		`COLUMN_1_A` AS COLUMN_A, 
		`COLUMN_1_E` AS COLUMN_E, 
		`COLUMN_1_B` AS COLUMN_B, 
		`COLUMN_1_D` AS COLUMN_D, 
		TABLE_A.`TEMP` AS `TEMP` 
	FROM TABLE_B LEFT JOIN ( 
			SELECT 
				`COLUMN_CSI` AS `TEMP2` , 
				CASE WHEN `TYPE_ID` = 2 THEN `COLUMN_CSI` END AS `TEMP` , 
				CASE WHEN `TYPE_ID` = 2 THEN `COLUMN_NAME` END AS NAME_TEMP 
			FROM DIMENSION_TABLE 
			GROUP BY 
				`COLUMN_CSI`, 
				CASE WHEN `TYPE_ID` = 2 THEN `COLUMN_CSI` END, 
				CASE WHEN `TYPE_ID` = 2 THEN `COLUMN_NAME` END
	) TABLE_A 
	ON `COLUMN_CSI` = TABLE_A.`TEMP2` 
	WHERE 
		TABLE_A.NAME_TEMP IS NOT NULL AND 
		`TIME` >= A AND `TIME` < B 
) MT 
GROUP BY MT.`TEMP` 
ORDER BY COLUMN_C DESC 
LIMIT 5000

其中一个SUM后面称为一个counter

3. CarbonData主要配置参数

主要配置

CarbonData主要配置参数值描述
carbon.inmemory.record.size480000查询每个表需要加载到内存的总行数。
carbon.number.of.cores.while.loading15carbon数据加载过程中并行扫描的线程数。
carbon.sort.file.buffer.size20在合并排序(读/写)操作时存储每个临时过程文件的所使用的总缓存大小。单位为MB
carbon.sort.size500000在数据加载操作时,每次被排序的记录数。
Spark主要配置
spark.sql.shuffle.partitions70配置汇聚时shuffle的分区数
spark.executor.instances6executor实例的个数,6台服务器每台一个实例
spark.executor.cores13每一个实例的核数,这里配置13核
spark.locality.wait0配置数据本地化的等待时间为不等待
spark.executor.memory30Gexecutor的内存配置
spark.driver.cores3driver程序的CPU内核数量,设置为3
spark.driver.memory50Gdriver进程使用的内存数
spark.sql.codegen.wholeStageTrue打开codegen开关,该开关默认也是开启的
spark.sql.codegen.hugeMethodLimit8000codegen应用的方法的长度限制,这里应该配置的与JDK相同

4. 不同数量量的查询性能对比

某商业列存DB与CarbonData的查询均为取多次求平均值。

表的分类:数据量+counter个数表记录数(条)counter 个数某商业列存DB 5次 查询平均耗时(s)CarbonData 5次查询平均耗时(s)
100K_9Counter100K9Counter0.913.53
100K_18Counter100K18Counter1.303.81
100K_36Counter100K36Counter1.874.29
100K_72Counter100K72Counter3.825.09
500K_9Counter500K9Counter1.474.04
500K_18Counter500K18Counter1.984.61
500K_36Counter500K36Counter2.995.63
500K_72Counter500K72Counter5.677.53
1M_9Counter1M9Counter4.724.24
1M_18Counter1M18Counter5.134.84
1M_36Counter1M36Counter6.555.83
1M_72Counter1M72Counter10.837.90
5M_9Counter5M9Counter5.824.59
5M_18Counter5M18Counter7.705.26
5M_36Counter5M36Counter11.326.73
5M_72Counter5M72Counter21.789.27
10M_9Counter10M9Counter7.985.32
10M_18Counter10M18Counter11.396.03
10M_36Counter10M36Counter17.407.43
10M_72Counter10M72Counter34.5010.48
50M_9Counter50M9Counter16.898.95
50M_18Counter50M18Counter25.5010.42
50M_36Counter50M36Counter268.1012.78
50M_72Counter50M72Counter554.1618.79
100M_9Counter100M9Counter25.1313.19
100M_18Counter100M18Counter35.5714.87
100M_36Counter100M36Counter299.4318.96
100M_72Counter100M72Counter678.7228.12
1B_9Counter1B9Counter167.5047.95
1B_18Counter1B18Counter261.2055.79
1B_36Counter1B36Counter654.9973.14
1B_72Counter1B72Counter1575.81116.63

5. 总结

通过上面的测试结果可以看出:

  1. 在同等CPU内存资源及使用SATA盘劣势资源的情况下,CarbonData的查询性能要高于某商业列存DB。
  2. 在百万级及以上数据量的查询中CarbonData的查询性能明显高于商业列存DB,整体查询性能有了较高的提升,平均查询性能提升1.5-10倍。
  3. 在百万级数据以上,随着数据量的增大,CarbonData的查询优势越来越明显。