目前,我正在研究将Cassandra与Spark和Tableau结合使用进行数据分析的可能性。但是,我目前使用此设置遇到的性能非常差,我无法想象将其用于生产目的。当我读到Cassandra + Spark的组合性能有多棒时,我显然做错了什么,但我找不到什么。
我的测试数据:
我的测试设置:
调查结果:
以下是用于查询的表定义:
CREATE TABLE key.activity (
interval timestamp,
id bigint,
activity_name text,
begin_ts timestamp,
busy_ms bigint,
container_code text,
duration_ms bigint,
end_location_code text,
end_ts timestamp,
pallet_code text,
src_location_code text,
start_location_code text,
success boolean,
tgt_location_code text,
transporter_name text,
PRIMARY KEY (interval, id)
) WITH CLUSTERING ORDER BY (id ASC)
AND bloom_filter_fp_chance = 0.01
AND caching = '{"keys":"ALL", "rows_per_partition":"ALL"}'
AND comment = ''
AND compaction = {'class': 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy'}
AND compression = {'sstable_compression': 'org.apache.cassandra.io.compress.LZ4Compressor'}
AND dclocal_read_repair_chance = 0.1
AND default_time_to_live = 0
AND gc_grace_seconds = 864000
AND max_index_interval = 2048
AND memtable_flush_period_in_ms = 0
AND min_index_interval = 128
AND read_repair_chance = 0.0
AND speculative_retry = '99.0PERCENTILE';
CREATE INDEX activity_activity_name_idx ON key.activity (activity_name);
CREATE INDEX activity_success_idx ON key.activity (success);
CREATE INDEX activity_transporter_name_idx ON key.activity (transporter_name);
以下是Tableau生成的查询示例:
INFO 2016-02-10 20:22:21 org.apache.spark.sql.hive.thriftserver.SparkExecuteStatementOperation: Running query 'SELECT CASE WHEN 4 >= 0 THEN SUBSTRING(`activity`.`transporter_name`,1,CAST(4 AS INT)) ELSE NULL END AS `calculation_185421691185008640`,
AVG(CAST(`activity`.`busy_ms` AS DOUBLE)) AS `avg_busy_ms_ok`,
CAST((MONTH(`activity`.`interval`) - 1) / 3 + 1 AS BIGINT) AS `qr_interval_ok`,
`activity`.`transporter_name` AS `transporter_name`,
YEAR(`activity`.`interval`) AS `yr_interval_ok`
FROM `key`.`activity` `activity`
GROUP BY CASE WHEN 4 >= 0 THEN SUBSTRING(`activity`.`transporter_name`,1,CAST(4 AS INT)) ELSE NULL END,
CAST((MONTH(`activity`.`interval`) - 1) / 3 + 1 AS BIGINT),
`activity`.`transporter_name`,
YEAR(`activity`.`interval`)'
以下是52s查询统计信息的示例:
Spark statistics on query taken 52 secs. to complete
我已尝试使用其他帖子中提到的分区键,但没有看到显着差异。我也尝试启用行缓存(Cassandra config + table属性),但这也没有任何效果(虽然我可能忽略了那些东西)。
我希望开箱即用的性能至少提高10倍到20倍,即使没有摆弄所有这些参数,我也没想到该做什么。
我做错了什么?我应该期待什么表现?
答案 0 :(得分:2)
由于您未在帖子中定义的变量,回答您的问题并不容易。您提到存储在一个节点上的数据,这很好,但您没有描述如何构建表/列系列。你也没有提到cassandra缓存命中率。您还必须考虑Cassandra Compaction,如果在繁重的读/写操作期间压缩正在运行,它将减慢速度。
您似乎也有一个SSD,在这种情况下,您将在同一物理驱动器上拥有Data目录和commitlogs以及缓存目录。即使它不是旋转光盘,除非您从commitlogs / cache目录中拆分数据目录,否则您将看到性能下降。通过将Data dir拆分到自己的物理SSD上,我看到了性能提升了50%。
此外,最后,您在Vbox中的笔记本电脑主机上的VM中运行了。这里最大的瓶颈是1.1 GHz CPU。在运行中型作业的VMWare上的cassandra环境中,我看到16GB RAM上的4 X 2内核几乎占用了99%的CPU。我的数据目录在SSD上,而我的提交日志和缓存目录在磁盘上。我的性能很好,但我调整了我的环境以达到这一点,我接受了非生产环境提供的延迟。
看看HERE并尝试更好地了解如何使用Cassandra以及如何实现更好的开箱即用性能。分布式系统只是......分布式和有原因的。您在单台计算机上无法使用的共享资源。
希望这能更多地解释你的目标。
修改强>
您的表定义看起来很好。您使用的是Tableau Spark连接器吗?你的性能问题可能出在cassandra / Spark方面。
看看这个article,它描述了从缓存中读取时与压缩相关的问题。基本上在压缩后的2.1.2之前的cassandra版本中,你现在已经丢失了缓存,因为一旦压缩完成,Cassandra会抛弃文件(和缓存)。一旦你开始阅读你,你会立即得到一个错过的缓存命中和cassandra然后回到光盘。这在2.1.2之后的版本中得到修复。在运行Spark / Cassandra时,其他一切看起来都很正常。
答案 1 :(得分:0)
虽然查询时间确实有点高,但我看到的一些事情可能会导致问题。
我注意到你正在使用MacBook。漂亮的电脑,但不适合Spark。我相信那些正在使用双核Intel M处理器。如果您转到Spark Master UI,它将显示可用内核。它可能显示4(包括vCPU)。 运行此查询的性质不允许大量并行(如果有)。在这种情况下,你基本上没有得到Spark的优势,因为你在一个非常小的虚拟机上运行而且你在一个节点上运行(CPU有限)。可视化工具尚未真正赶上Spark。
要记住的另一件事是Spark并非设计为“adhoc查询”工具。您可以将SparkSQL视为适当Spark Batch的抽象。与Oracle相比,在这种规模下,不会产生您期望的结果。您会注意到Spark的“最低”性能阈值。一旦您将数据和节点扩展到足够远的距离,您就会开始看到完成时间和数据大小不是线性的,并且当您添加更多数据时,处理时间仍然相对平缓。
我建议在SparkSQL REPL dse spark-sql
中尝试该查询,看看是否有类似的时间。如果你这样做,那么你知道这是你当前设置的最佳选择。如果Tableau比REPL慢很多,我猜它在那一点就结束了。