Spark Cassandra Connector具有糟糕的读取性能,由kworker生成大量磁盘写入

时间:2017-02-13 16:14:29

标签: scala apache-spark cassandra

底部的一些跟进

我有一个Spark和Cassandra的测试安装,我有6个节点,每个节点有128GiB和16个CPU核心。每个节点都运行Spark和Cassandra。我使用SimpleStrategy设置了密钥空间,复制因子为3(即相当标准)。

我的表很简单,就像这样:

create table if not exists mykeyspace.values (channel_id timeuuid, day int, time bigint, value double, primary key ((channel_id, day), time)) with clustering order by (time asc)

time只是一个以纳秒为单位的unix时间戳(值来自的测量设备是精确的,需要这种精度),day是以天为单位的时间戳(即1970年以来的天数) 01-01)。

我现在为大约400个频道插入了大约200 GiB的值并测试了一个非常简单的事情 - 计算每个频道的10分钟平均值:

sc.
  cassandraTable("mykeyspace", "values").
  map(r => (r.getLong("time"), r.getUUID("channel_id"), r.getDouble("value"))).
  map(t => (t._1 / 600L / 1000000000L, t._2) -> (t._3, 1.0)).
  reduceByKey((a, b) => (a._1 + b._1) -> (a._2 + b._2)).
  map(t => (t._1._1 * 600L * 1000000000L, t._1._2, t._2._1 / t._2._2))

当我现在进行此计算时,即使不保存结果(即使用简单的count()),这也需要很长时间,并且读取性能非常差。

当我在节点上执行top时,Cassandra的java进程占用大约800%的CPU,这是可以的,因为这大约是节点可以承担的负载的一半;另一半是Spark。

然而,我注意到一件奇怪的事情:

当我运行iotop时,我希望看到很多磁盘读取,但我看到很多磁盘 WRITE ,所有这些都来自kworker。< / p>

当我iostat -x -t 10时,我也看到很多写作正在进行中。

禁用交换。

当我直接在CSV文件上运行类似的计算时,数据来自HDFS并通过sc.newAPIHadoopFile以自定义输入格式加载,过程完成得更快(计算大约需要一个小时)使用Cassandra但使用来自HDFS的文件大约需要5分钟。

那么我在哪里可以开始进行故障排除和调整?

跟进1

在RussS的帮助下(见评论),我发现日志记录设置为DEBUG。我禁用了此功能,将日志记录设置为ERROR,并且还禁用了GC日志记录,但这并没有改变任何内容。

我也尝试keyBy,正如同一位用户指出的那样,但这也没有改变任何内容。

我也试过在本地做过,我从.net尝试过一次,从Scala尝试一次,在这里,数据库按预期访问,即没有写入。

后续2

我想我明白了。有一次,我没有看到森林的树木,因为我之前提到的200GiB的时间仍然是56 MiB / s的吞吐量。由于我运行安装的硬件远不是可选的(它是运行Microsoft HyperV的高性能服务器,后者又虚拟地运行节点,而且这台机器的硬盘速度很慢)这确实是我期望的吞吐量。由于主机只是一台具有一个RAID阵列的机器,其中节点的磁盘是虚拟HDD,我不能指望性能神奇地通过屋顶。

我还尝试运行Spark standalone,它稍微改善了性能(我现在大约提高了75 MiB / s),并且常量写入也没有了 - 我只是因为改组而偶尔会出现尖峰。

对于CSV文件要快得多,原因是CSV中的原始数据大约为50 GiB,我的自定义FileInputFormat读取它,逐行进行,并且还使用非常快的字符串-to-double解析器,它只知道US格式,但比Java parseDouble或Scala toDouble更快。通过这种特殊的调整,我在YARN模式下获得了大约170MiB / s的速度。

所以我想我应该一次改进我的CQL查询以限制读取的数据,并尝试调整一些YARN设置。

0 个答案:

没有答案