diff --git a/docs/15.md b/docs/15.md index 3a67ee1a4cf53894f28d38a3dfac986d7ada3e96..a0bdfdf23b7ec7aaaa72844914d8d8b80f46401d 100644 --- a/docs/15.md +++ b/docs/15.md @@ -35,24 +35,24 @@ Spark 除了运行在 Mesos 或者 YARN 上以外,Spark 还提供了一个简 ./sbin/start-slave.sh ``` -在您启动一个 worker 之后,就可以通过 master 的 web UI ( 默认情况下是 [http://localhost:8080](http://localhost:8080))查看到了。您可以看到列出的新的 node (节点),以及其 CPU 的数量和数量(为操作系统留下了 1 GB 的空间)。 +在您启动一个 worker 之后,就可以通过 master 的 web UI ( 默认情况下是 [http://localhost:8080](http://localhost:8080))查看到了。您可以看到列出的新的 node(节点),以及其 CPU 的数量和数量(为操作系统留下了 1 GB 的空间)。 最后,下面的配置选项可以传递给 master 和 worker: | Argument(参数) | Meaning(含义) | | --- | --- | | `-h HOST`,`--host HOST` | 监听的 Hostname | -| `-i HOST`,`--ip HOST` | 监听的 Hostname (已弃用,请使用 -h or --host) | -| `-p PORT`,`--port PORT` | 监听的服务 Port (端口) (默认:master 是 7077, worker 是随机的) | +| `-i HOST`,`--ip HOST` | 监听的 Hostname(已弃用,请使用 -h or --host) | +| `-p PORT`,`--port PORT` | 监听的服务 Port(端口)(默认:master 是 7077, worker 是随机的) | | `--webui-port PORT` | web UI 的端口(默认:master 是 8080, worker 是 8081) | | `-c CORES`,`--cores CORES` | Spark 应用程序在机器上可以使用的全部的 CPU 核数(默认是全部可用的);这个选项仅在 worker 上可用 | | `-m MEM`,`--memory MEM` | Spark 应用程序可以使用的内存数量,格式像 1000M 或者 2G(默认情况是您的机器内存数减去 1 GB);这个选项仅在 worker 上可用 | -| `-d DIR`,`--work-dir DIR` | 用于 scratch space (暂存空间)和作业输出日志的目录(默认是:SPARK_HOME/work);这个选项仅在 worker 上可用 | +| `-d DIR`,`--work-dir DIR` | 用于 scratch space(暂存空间)和作业输出日志的目录(默认是:SPARK_HOME/work);这个选项仅在 worker 上可用 | | `--properties-file FILE` | 自定义的 Spark 配置文件加载目录(默认:conf/spark-defaults.conf) | # 集群启动脚本 -要使用启动脚本启动 Spark standalone 集群,你应该首先在 Spark 目录下创建一个叫做 conf/slaves 的文件,这个文件中必须包含所有你想要启动的 Spark workers 的机器的 hostname,每个 hostname 占一行。如果 conf/slaves 不存在,启动脚本默认启动单个机器(localhost),这对于测试是有效的。注意, master 机器通过 ssh 访问所有的 worker 机器。默认情况下,ssh 是 parallel (并行)运行的并且需要配置无密码(使用一个私钥)的访问。如果您没有设置无密码访问,您可以设置环境变量 SPARK_SSH_FOREGROUND 并且为每个 worker 提供一个密码。 +要使用启动脚本启动 Spark standalone 集群,你应该首先在 Spark 目录下创建一个叫做 conf/slaves 的文件,这个文件中必须包含所有你想要启动的 Spark workers 的机器的 hostname,每个 hostname 占一行。如果 conf/slaves 不存在,启动脚本默认启动单个机器(localhost),这对于测试是有效的。注意, master 机器通过 ssh 访问所有的 worker 机器。默认情况下,ssh 是 parallel(并行)运行的并且需要配置无密码(使用一个私钥)的访问。如果您没有设置无密码访问,您可以设置环境变量 SPARK_SSH_FOREGROUND 并且为每个 worker 提供一个密码。 一旦您创建了这个文件,您就可以启动或者停止您的集群使用下面的 shell 脚本,基于 Hadoop 的部署脚本,并在 `SPARK_HOME/sbin` 中可用: @@ -68,21 +68,21 @@ Spark 除了运行在 Mesos 或者 YARN 上以外,Spark 还提供了一个简 您可以通过在 `conf/spark-env.sh` 中设置环境变量来进一步配置集群。利用 `conf/spark-env.sh.template` 文件来创建这个文件,然后将它复制到所有的 worker 机器上使设置有效。下面的设置是可用的: -| Environment Variable (环境变量) | Meaning(含义) | +| Environment Variable(环境变量) | Meaning(含义) | | --- | --- | | `SPARK_MASTER_HOST` | 绑定 master 到一个指定的 hostname 或者 IP 地址,例如一个 public hostname 或者 IP。 | -| `SPARK_MASTER_PORT` | 在不同的端口上启动 master (默认:7077) | +| `SPARK_MASTER_PORT` | 在不同的端口上启动 master(默认:7077) | | `SPARK_MASTER_WEBUI_PORT` | master 的 web UI 的端口(默认:8080) | -| `SPARK_MASTER_OPTS` | 仅应用到 master 上的配置属性,格式是 "-Dx=y" (默认是:none)。查看下面的列表可能选项。 | +| `SPARK_MASTER_OPTS` | 仅应用到 master 上的配置属性,格式是 "-Dx=y"(默认是:none)。查看下面的列表可能选项。 | | `SPARK_LOCAL_DIRS` | Spark 中 "scratch" space(暂存空间)的目录,包括 map 的输出文件和存储在磁盘上的 RDDs。这必须在您的系统中的一个快速的,本地的磁盘上。这也可以是逗号分隔的不同磁盘上的多个目录的列表。 | | `SPARK_WORKER_CORES` | 机器上 Spark 应用程序可以使用的全部的 cores(核)的数量。(默认:全部的核可用) | | `SPARK_WORKER_MEMORY` | 机器上 Spark 应用程序可以使用的全部的内存数量,例如 `1000m`, `2g`(默认:全部的内存减去 1 GB);注意每个应用程序的_individual(独立)_内存是使用 `spark.executor.memory` 属性进行配置的。 | -| `SPARK_WORKER_PORT` | 在一个指定的 port (端口)上启动 Spark worker (默认: random(随机)) | -| `SPARK_WORKER_WEBUI_PORT` | worker 的 web UI 的 Port (端口)(默认:8081) | +| `SPARK_WORKER_PORT` | 在一个指定的 port(端口)上启动 Spark worker(默认: random(随机)) | +| `SPARK_WORKER_WEBUI_PORT` | worker 的 web UI 的 Port(端口)(默认:8081) | | `SPARK_WORKER_DIR` | 运行应用程序的目录,这个目录中包含日志和暂存空间(default:SPARK_HOME/work) | -| `SPARK_WORKER_OPTS` | 仅应用到 worker 的配置属性,格式是 "-Dx=y" (默认:none)。查看下面的列表的可能选项。 | +| `SPARK_WORKER_OPTS` | 仅应用到 worker 的配置属性,格式是 "-Dx=y"(默认:none)。查看下面的列表的可能选项。 | | `SPARK_DAEMON_MEMORY` | 分配给 Spark master 和 worker 守护进程的内存。(默认: 1g) | -| `SPARK_DAEMON_JAVA_OPTS` | Spark master 和 worker 守护进程的 JVM 选项,格式是 "-Dx=y" (默认:none) | +| `SPARK_DAEMON_JAVA_OPTS` | Spark master 和 worker 守护进程的 JVM 选项,格式是 "-Dx=y"(默认:none) | | `SPARK_PUBLIC_DNS` | Spark master 和 worker 的公开 DNS 名称。(默认:none) | **注意:** 启动脚本现在还不支持 Windows。要在 Windows 上运行一个 Spark 集群,需要手动启动 master 和 workers。 @@ -95,9 +95,9 @@ SPARK_MASTER_OPTS 支持以下系统属性: | | `spark.deploy.retainedDrivers` | 200 | 展示已完成的 drivers 的最大数量。老的 driver 会从 UI 删除掉以满足限制。 | -| `spark.deploy.spreadOut` | true | 这个选项控制 standalone 集群 manager 是应该跨界店 spread (传播)应用程序还是应该努力将应用程序整合到尽可能少的节点上。在 HDFS 中, Spreading 是数据本地化的更好的选择,但是对于计算密集型的负载,整合会更有效率。 +| `spark.deploy.spreadOut` | true | 这个选项控制 standalone 集群 manager 是应该跨界店 spread(传播)应用程序还是应该努力将应用程序整合到尽可能少的节点上。在 HDFS 中, Spreading 是数据本地化的更好的选择,但是对于计算密集型的负载,整合会更有效率。 | -| `spark.deploy.defaultCores` | (infinite) | 如果没有设置 `spark.cores.max`,在 Spark 的 standalone 模式下默认分配给应用程序的 cores (核)数。如果没有设置,应用程序将总是获得所有的可用核,除非设置了 `spark.cores.max`。在共享集群中设置较低的核数,可用于防止用户 grabbing (抓取)整个集群。 +| `spark.deploy.defaultCores` | (infinite) | 如果没有设置 `spark.cores.max`,在 Spark 的 standalone 模式下默认分配给应用程序的 cores(核)数。如果没有设置,应用程序将总是获得所有的可用核,除非设置了 `spark.cores.max`。在共享集群中设置较低的核数,可用于防止用户 grabbing(抓取)整个集群。 | | `spark.deploy.maxExecutorRetries` | 10 | 限制在 standalone 集群 manager 删除一个不正确地应用程序之前可能发生的 back-to-back 执行器失败的最大次数。如果一个应用程序有任何正在运行的执行器,则它永远不会被删除。如果一个应用程序经历过超过 `spark.deploy.maxExecutorRetries` 次的连续失败,没有执行器成功开始运行在这些失败之间,并且应用程序没有运行着的执行器,然后 standalone 集群 manager 将会移除这个应用程序并将它标记为失败。要禁用这个自动删除功能,设置`spark.deploy.maxExecutorRetries` 为 `-1`。 | @@ -122,7 +122,7 @@ SPARK_WORKER_OPTS 支持以下的系统属性: ./bin/spark-shell --master spark://IP:PORT ``` -您还可以传递一个选项 `--total-executor-cores <numCores>` 来控制 spark-shell 在集群上使用的 cores (核)数。 +您还可以传递一个选项 `--total-executor-cores <numCores>` 来控制 spark-shell 在集群上使用的 cores(核)数。 # 启动 Spark 应用程序 @@ -140,7 +140,7 @@ SPARK_WORKER_OPTS 支持以下的系统属性: # Resource Scheduling(资源调度) -standalone 集群模式当前只支持一个简单的跨应用程序的 FIFO 调度。然而,为了允许多个并发的用户,您可以控制每个应用程序能用的最大资源数。默认情况下,它将获取集群中的 _all_ cores (核),这只有在某一时刻只允许一个应用程序运行时才有意义。您可以通过 `spark.cores.max` 在 [SparkConf](configuration.html#spark-properties) 中设置 cores (核)的数量。例如: +standalone 集群模式当前只支持一个简单的跨应用程序的 FIFO 调度。然而,为了允许多个并发的用户,您可以控制每个应用程序能用的最大资源数。默认情况下,它将获取集群中的 _all_ cores(核),这只有在某一时刻只允许一个应用程序运行时才有意义。您可以通过 `spark.cores.max` 在 [SparkConf](configuration.html#spark-properties) 中设置 cores(核)的数量。例如: ``` val conf = new SparkConf() @@ -180,7 +180,7 @@ Spark 对网络的需求比较高,并且一些环境对于使用严格的防 **概述** -使用 ZooKeeper 提供的 leader election (领导选举)和一些 state storage (状态存储),在连接到同一 ZooKeeper 实例的集群中启动多个 Masters。一个节点将被选举为 “leader” 并且其他节点将会维持备用模式。如果当前的 leader 宕掉了,另一个 Master 将会被选举,恢复老的 Master 的状态,并且恢复调度。整个恢复过程(从第一个 leader 宕掉开始)应该会使用 1 到 2 分钟。注意此延迟仅仅影响调度 _new_ 应用程序 – 在 Master 故障切换期间已经运行的应用程序不受影响。 +使用 ZooKeeper 提供的 leader election(领导选举)和一些 state storage(状态存储),在连接到同一 ZooKeeper 实例的集群中启动多个 Masters。一个节点将被选举为 “leader” 并且其他节点将会维持备用模式。如果当前的 leader 宕掉了,另一个 Master 将会被选举,恢复老的 Master 的状态,并且恢复调度。整个恢复过程(从第一个 leader 宕掉开始)应该会使用 1 到 2 分钟。注意此延迟仅仅影响调度 _new_ 应用程序 – 在 Master 故障切换期间已经运行的应用程序不受影响。 详细了解如何开始使用 ZooKeeper [这里](http://zookeeper.apache.org/doc/trunk/zookeeperStarted.html)。 @@ -196,7 +196,7 @@ Spark 对网络的需求比较高,并且一些环境对于使用严格的防 为了调度新的应用程序或者添加新的 Worker 到集群中,他们需要知道当前的 leader 的 IP 地址。这可以通过简单地传递一个您在一个单一的进程中传递的 Masters 的列表来完成。例如,您可以启动您的 SparkContext 指向 `spark://host1:port1,host2:port2`。这将导致您的 SparkContext 尝试去注册两个 Masters – 如果 `host1` 宕掉,这个配置仍然是正确地,因为我们将会发现新的 leader `host2`。 -在 “registering with a Master (使用 Master 注册)” 与正常操作之间有一个重要的区别。当启动的时候,一个应用程序或者 Worker 需要使用当前的 lead Master 找到并且注册。一旦它成功注册,它就是 “in the system(在系统中)”了(即存储在了 ZooKeeper 中)。如果发生故障切换,新的 leader 将会联系所有值钱已经注册的应用程序和 Workers 来通知他们领导层的变化,所以他们甚至不知道新的 Master 在启动时的存在。 +在 “registering with a Master(使用 Master 注册)” 与正常操作之间有一个重要的区别。当启动的时候,一个应用程序或者 Worker 需要使用当前的 lead Master 找到并且注册。一旦它成功注册,它就是 “in the system(在系统中)”了(即存储在了 ZooKeeper 中)。如果发生故障切换,新的 leader 将会联系所有值钱已经注册的应用程序和 Workers 来通知他们领导层的变化,所以他们甚至不知道新的 Master 在启动时的存在。 由于这个属性,新的 Masters 可以在任何时间创建,唯一需要担心的是,_new_ 应用程序和 Workers 可以找到它注册,以防其成为 leader。一旦注册了之后,您将被照顾。 @@ -219,4 +219,4 @@ ZooKeeper 是生产级别的高可用性的最佳方法,但是如果您只是 * 该解决方案可以与像 [monit](http://mmonit.com/monit/) 这样的过程 monitor/manager 一起使用,或者只是通过重新启动手动恢复。 * 尽管文件系统恢复似乎比完全没有任何恢复更好,但是对于某些特定的开发或者实验目的,此模式可能不太适合。特别是,通过 stop-master.sh 杀死 master 并不会清除其恢复状态,所以每当重新启动一个新的 Master 时,它将进入恢复模式。如果需要等待所有先前注册的 Worker/clients 超时,这可能会将启动时间增加 1 分钟。 -* 虽然没有正式的支持,你也可以挂载 NFS 目录作为恢复目录。如果 original Master w安全地死亡,则您可以在不同的节点上启动 Master,这将正确恢复所有以前注册的 Workers/applications (相当于 ZooKeeper 恢复)。然而,未来的应用程序必须能够找到新的 Master 才能注册。 \ No newline at end of file +* 虽然没有正式的支持,你也可以挂载 NFS 目录作为恢复目录。如果 original Master w安全地死亡,则您可以在不同的节点上启动 Master,这将正确恢复所有以前注册的 Workers/applications(相当于 ZooKeeper 恢复)。然而,未来的应用程序必须能够找到新的 Master 才能注册。 \ No newline at end of file diff --git a/docs/16.md b/docs/16.md index 4aa6343db023acc35087635b2a9ece59c7b406d4..e68590e529abde474859895e6c8722d9353d2cdb 100644 --- a/docs/16.md +++ b/docs/16.md @@ -24,8 +24,8 @@ Spark 可以运行在 [Apache Mesos](http://mesos.apache.org/) 管理的硬件 使用 Mesos 部署 Spark 的优点包括: -* Spark 与其他的 [frameworks(框架)](https://mesos.apache.org/documentation/latest/mesos-frameworks/) 之间的 dynamic partitioning (动态分区) -* 在 Spark 的多个实例之间的 scalable partitioning (可扩展分区) +* Spark 与其他的 [frameworks(框架)](https://mesos.apache.org/documentation/latest/mesos-frameworks/) 之间的 dynamic partitioning(动态分区) +* 在 Spark 的多个实例之间的 scalable partitioning(可扩展分区) # 运行原理 @@ -33,7 +33,7 @@ Spark 可以运行在 [Apache Mesos](http://mesos.apache.org/) 管理的硬件 ![Spark 集群组件](img/1b193ef9791313508d0c806587f136fd.jpg "Spark 集群组件") -现在当 driver 创建一个作业并开始执行调度任务时, Mesos 会决定什么机器处理什么任务。因为 Mesos 调度这些短期任务时会将其他的框架考虑在内,多个框架可以共存在同一个集群上,而不需要求助于一个 static partitioning of resources (资源的静态分区)。 +现在当 driver 创建一个作业并开始执行调度任务时, Mesos 会决定什么机器处理什么任务。因为 Mesos 调度这些短期任务时会将其他的框架考虑在内,多个框架可以共存在同一个集群上,而不需要求助于一个 static partitioning of resources(资源的静态分区)。 要开始,请按照以下步骤安装 Mesos 并通过 Mesos 部署 Spark 作业。 @@ -43,7 +43,7 @@ Spark 2.2.0 专门为 Mesos 1.0.0 或更新的版本并且不需要 Mesos 的任 如果您已经有一个 Mesos 集群正在运行着,您可以跳过这个 Mesos 安装的步骤。 -否则,安装 Mesos for Spark 与安装 Mesos for 其他框架是没有区别的。您可以通过源码或者 prebuilt packages (预构建软件安装包)来安装 Mesos。 +否则,安装 Mesos for Spark 与安装 Mesos for 其他框架是没有区别的。您可以通过源码或者 prebuilt packages(预构建软件安装包)来安装 Mesos。 ## 从源码安装 @@ -56,9 +56,9 @@ Spark 2.2.0 专门为 Mesos 1.0.0 或更新的版本并且不需要 Mesos 的任 ## 第三方软件包 -Apache Mesos 只发布了源码的发行版本,而不是 binary packages (二进制包)。但是其他的第三方项目发布了 binary releases (二进制发行版本),可能对设置 Mesos 有帮助。 +Apache Mesos 只发布了源码的发行版本,而不是 binary packages(二进制包)。但是其他的第三方项目发布了 binary releases(二进制发行版本),可能对设置 Mesos 有帮助。 -其中之一是 Mesosphere。使用 Mesosphere 提供的 binary releases (二进制发行版本)安装 Mesos: +其中之一是 Mesosphere。使用 Mesosphere 提供的 binary releases(二进制发行版本)安装 Mesos: 1. 从 [下载页面](http://mesosphere.io/downloads/) 下载 Mesos 安装包 2. 按照他们的说明进行安装和配置 @@ -73,15 +73,15 @@ Mesosphere 安装文档建议安装 ZooKeeper 来处理 Mesos master 故障切 要使用 Spark 中的 Mesos,您需要一个 Spark 的二进制包放到 Mesos 可以访问的地方,然后一个 Spark driver 程序配置来连接 Mesos。 -或者,您也可以将 Spark 安装在所有 Mesos slaves 中的相同位置,并且配置 `spark.mesos.executor.home` (默认是 SPARK_HOME)来指向该位置。 +或者,您也可以将 Spark 安装在所有 Mesos slaves 中的相同位置,并且配置 `spark.mesos.executor.home`(默认是 SPARK_HOME)来指向该位置。 ## 上传 Spark 包 -当 Mesos 第一次在 Mesos slave 上运行任务的时候,这个 slave 必须有一个 Spark binary package (Spark 二进制包)用于执行 Spark Mesos executor backend (执行器后端)。Spark 软件包可以在任何 Hadoop 可访问的 URI 上托管,包括 HTTP 通过 `http://`,[Amazon Simple Storage Service](http://aws.amazon.com/s3) 通过 `s3n://`,或者 HDFS 通过 `hdfs://`。 +当 Mesos 第一次在 Mesos slave 上运行任务的时候,这个 slave 必须有一个 Spark binary package(Spark 二进制包)用于执行 Spark Mesos executor backend(执行器后端)。Spark 软件包可以在任何 Hadoop 可访问的 URI 上托管,包括 HTTP 通过 `http://`,[Amazon Simple Storage Service](http://aws.amazon.com/s3) 通过 `s3n://`,或者 HDFS 通过 `hdfs://`。 要使用预编译的包: -1. 从 Spark 的 [下载页面](https://spark.apache.org/downloads.html) 下载一个 Spark binary package (Spark 二进制包) +1. 从 Spark 的 [下载页面](https://spark.apache.org/downloads.html) 下载一个 Spark binary package(Spark 二进制包) 2. 上传到 hdfs/http/s3 要托管在 HDFS 上,使用 Hadoop fs put 命令:`hadoop fs -put spark-2.2.0.tar.gz /path/to/spark-2.2.0.tar.gz` @@ -89,7 +89,7 @@ Mesosphere 安装文档建议安装 ZooKeeper 来处理 Mesos master 故障切 或者如果您正在使用着一个自定义编译的 Spark 版本,您将需要使用 在 Spark 源码中的 tarball/checkout 的 `dev/make-distribution.sh` 脚本创建一个包。 1. 按照说明 [这里](index.html) 来下载并构建 Spark。 -2. 使用 `./dev/make-distribution.sh --tgz` 创建一个 binary package (二进制包) +2. 使用 `./dev/make-distribution.sh --tgz` 创建一个 binary package(二进制包) 3. 将归档文件上传到 http/s3/hdfs ## 使用 Mesos Master URL @@ -127,15 +127,15 @@ val sc = new SparkContext(conf) ## Cluster mode(集群模式) -Spark on Mesos 还支持 cluster mode (集群模式),其中 driver 在集群中启动并且 client(客户端)可以在 Mesos Web UI 中找到 driver 的 results。 +Spark on Mesos 还支持 cluster mode(集群模式),其中 driver 在集群中启动并且 client(客户端)可以在 Mesos Web UI 中找到 driver 的 results。 -要使用集群模式,你必须在您的集群中通过 `sbin/start-mesos-dispatcher.sh` 脚本启动 `MesosClusterDispatcher`,传入 Mesos master URL (例如:mesos://host:5050)。这将启动 `MesosClusterDispatcher` 作为在主机上运行的守护程序。 +要使用集群模式,你必须在您的集群中通过 `sbin/start-mesos-dispatcher.sh` 脚本启动 `MesosClusterDispatcher`,传入 Mesos master URL(例如:mesos://host:5050)。这将启动 `MesosClusterDispatcher` 作为在主机上运行的守护程序。 -如果您喜欢使用 Marathon 来运行 `MesosClusterDispatcher`,您需要在 foreground (前台)运行 `MesosClusterDispatcher` (即 `bin/spark-class org.apache.spark.deploy.mesos.MesosClusterDispatcher`)。注意,`MesosClusterDispatcher` 尚不支持 HA 的多个实例。 +如果您喜欢使用 Marathon 来运行 `MesosClusterDispatcher`,您需要在 foreground(前台)运行 `MesosClusterDispatcher`(即 `bin/spark-class org.apache.spark.deploy.mesos.MesosClusterDispatcher`)。注意,`MesosClusterDispatcher` 尚不支持 HA 的多个实例。 -`MesosClusterDispatcher` 还支持将 recovery state (恢复状态)写入 Zookeeper。这将允许 `MesosClusterDispatcher` 能够在重新启动时恢复所有提交和运行的 containers (容器)。为了启用这个恢复模式,您可以在 spark-env 中通过配置 `spark.deploy.recoveryMode` 来设置 SPARK_DAEMON_JAVA_OPTS 和相关的 spark.deploy.zookeeper.* 配置。有关这些配置的更多信息,请参阅配置 [doc](configurations.html#deploy)。 +`MesosClusterDispatcher` 还支持将 recovery state(恢复状态)写入 Zookeeper。这将允许 `MesosClusterDispatcher` 能够在重新启动时恢复所有提交和运行的 containers(容器)。为了启用这个恢复模式,您可以在 spark-env 中通过配置 `spark.deploy.recoveryMode` 来设置 SPARK_DAEMON_JAVA_OPTS 和相关的 spark.deploy.zookeeper.* 配置。有关这些配置的更多信息,请参阅配置 [doc](configurations.html#deploy)。 -从客户端,您可以提交一个作业到 Mesos 集群,通过执行 `spark-submit` 并指定 `MesosClusterDispatcher` 的 master URL (例如:mesos://dispatcher:7077)。您可以在 Spark cluster Web UI 查看 driver 的状态。 +从客户端,您可以提交一个作业到 Mesos 集群,通过执行 `spark-submit` 并指定 `MesosClusterDispatcher` 的 master URL(例如:mesos://dispatcher:7077)。您可以在 Spark cluster Web UI 查看 driver 的状态。 例如: @@ -169,9 +169,9 @@ Spark 可以以两种模式运行 Mesos: “coarse-grained(粗粒度)” 当应用程序启动时,执行器就会高涨,直到达到 `spark.cores.max`。如果您没有设置 `spark.cores.max`,Spark 应用程序将会保留 Mesos 提供的所有的资源,因此我们当然会敦促您在任何类型的多租户集群上设置此变量,包括运行多个并发 Spark 应用程序的集群。 -调度程序将会在提供的 Mesos 上启动执行器循环给它,但是没有 spread guarantees (传播保证),因为 Mesos 不提供这样的保证在提供流上。 +调度程序将会在提供的 Mesos 上启动执行器循环给它,但是没有 spread guarantees(传播保证),因为 Mesos 不提供这样的保证在提供流上。 -在这个模式下 spark 执行器将遵守 port (端口)分配如果这些事由用户提供的。特别是如果用户在 Spark 配置中定义了 `spark.executor.port` 或者 `spark.blockManager.port`,mesos 调度器将检查有效端口的可用 offers 包含端口号。如果没有这样的 range 可用,它会不启动任何任务。如果用户提供的端口号不受限制,临时端口像往常一样使用。如果用户定义了一个端口,这个端口实现意味着 one task per host (每个主机一个任务)。在未来网络中,isolation 将被支持。 +在这个模式下 spark 执行器将遵守 port(端口)分配如果这些事由用户提供的。特别是如果用户在 Spark 配置中定义了 `spark.executor.port` 或者 `spark.blockManager.port`,mesos 调度器将检查有效端口的可用 offers 包含端口号。如果没有这样的 range 可用,它会不启动任何任务。如果用户提供的端口号不受限制,临时端口像往常一样使用。如果用户定义了一个端口,这个端口实现意味着 one task per host(每个主机一个任务)。在未来网络中,isolation 将被支持。 粗粒度模式的好处是开销要低得多,但是在应用程序的整个持续时间内保留 Mesos 资源的代价。要配置您的作业以动态调整资源需求,请参阅 [动态分配](#dynamic-resource-allocation-with-mesos)。 @@ -179,7 +179,7 @@ Spark 可以以两种模式运行 Mesos: “coarse-grained(粗粒度)” **注意:** Spark 2.0.0 中的细粒度模式已弃用。为了一些优点,请考虑使用 [动态分配](#dynamic-resource-allocation-with-mesos) 有关完整的解释,请参阅 [SPARK-11857](https://issues.apache.org/jira/browse/SPARK-11857)。 -在细粒度模式下,Spark 执行器中的每个 Spark 任务作为单独的 Mesos 任务运行。这允许 Spark 的多个实例(和其他框架)以非常细的粒度来共享 cores (内核),其中每个应用程序在其上升和下降时获得更多或更少的核。但是它在启动每个任务时增加额外的开销。这种模式可能不适合低延迟要求,如交互式查询或者提供 web 请求。 +在细粒度模式下,Spark 执行器中的每个 Spark 任务作为单独的 Mesos 任务运行。这允许 Spark 的多个实例(和其他框架)以非常细的粒度来共享 cores(内核),其中每个应用程序在其上升和下降时获得更多或更少的核。但是它在启动每个任务时增加额外的开销。这种模式可能不适合低延迟要求,如交互式查询或者提供 web 请求。 请注意,尽管细粒度的 Spark 任务在它们终止时将放弃内核,但是他们不会放弃内存,因为 JVM 不会将内存回馈给操作系统。执行器在空闲时也不会终止。 @@ -205,11 +205,11 @@ Spark 可以通过在您的 [SparkConf](configuration.html#spark-properties) 中 需要 Mesos 的 0.20.1 版本或者更高版本。 -请注意,默认情况下,如果 agent (代理程序中)的 Mesos 代理已经存在,则 Mesos agents 将不会 pull 图像。如果您使用 mutable image tags (可变图像标签)可以将 `spark.mesos.executor.docker.forcePullImage` 设置为 `true`,以强制 agent 总是在运行执行器之前拉取 image。Force pulling images (强制拉取图像)仅在 Mesos 0.22 版本及以上版本中可用。 +请注意,默认情况下,如果 agent(代理程序中)的 Mesos 代理已经存在,则 Mesos agents 将不会 pull 图像。如果您使用 mutable image tags(可变图像标签)可以将 `spark.mesos.executor.docker.forcePullImage` 设置为 `true`,以强制 agent 总是在运行执行器之前拉取 image。Force pulling images(强制拉取图像)仅在 Mesos 0.22 版本及以上版本中可用。 # 集成 Hadoop 运行 -您可以在现有的 Hadoop 集群集成运行 Spark 和 Mesos,只需要在机器上启动他们作为分开的服务即可。要从 Spark 访问 Hadoop 数据,需要一个完整的 `hdfs://` URL (通常为 `hdfs://<namenode>:9000/path`),但是您可以在 Hadoop Namenode web UI 上找到正确的 URL。 +您可以在现有的 Hadoop 集群集成运行 Spark 和 Mesos,只需要在机器上启动他们作为分开的服务即可。要从 Spark 访问 Hadoop 数据,需要一个完整的 `hdfs://` URL(通常为 `hdfs://<namenode>:9000/path`),但是您可以在 Hadoop Namenode web UI 上找到正确的 URL。 此外,还可以在 Mesos 上运行 Hadoop MapReduce,以便在两者之间实现更好的资源隔离和共享。在这种情况下,Mesos 将作为统一的调度程序,将 Core 核心分配给 Hadoop 或 Spark,而不是通过每个节点上的 Linux 调度程序共享资源。请参考 [Hadoop on Mesos](https://github.com/mesos/hadoop)。 @@ -231,7 +231,7 @@ Mesos 仅支持使用粗粒度模式的动态分配,这可以基于应用程 | --- | --- | --- | | `spark.mesos.coarse` | true | 如果设置为`true`,则以 “粗粒度” 共享模式在 Mesos 集群上运行,其中 Spark 在每台计算机上获取一个长期存在的 Mesos 任务。如果设置为`false`,则以 “细粒度” 共享模式在 Mesos 集群上运行,其中每个 Spark 任务创建一个 Mesos 任务。['Mesos Run Modes'](running-on-mesos.html#mesos-run-modes) 中的详细信息。 | | `spark.mesos.extra.cores` | `0` | 设置执行程序公布的额外核心数。这不会导致分配更多的内核。它代替意味着执行器将“假装”它有更多的核心,以便驱动程序将发送更多的任务。使用此来增加并行度。此设置仅用于 Mesos 粗粒度模式。 | -| `spark.mesos.mesosExecutor.cores` | `1.0` | (仅限细粒度模式)给每个 Mesos 执行器的内核数。这不包括用于运行 Spark 任务的核心。换句话说,即使没有运行 Spark 任务,每个 Mesos 执行器将占用这里配置的内核数。该值可以是浮点数。 | +| `spark.mesos.mesosExecutor.cores` | `1.0` |(仅限细粒度模式)给每个 Mesos 执行器的内核数。这不包括用于运行 Spark 任务的核心。换句话说,即使没有运行 Spark 任务,每个 Mesos 执行器将占用这里配置的内核数。该值可以是浮点数。 | | `spark.mesos.executor.docker.image` | (none) | 设置 Spark 执行器将运行的 docker 映像的名称。所选映像必须安装 Spark,以及兼容版本的 Mesos 库。Spark 在图像中的安装路径可以通过 `spark.mesos.executor.home` 来指定; 可以使用 `spark.executorEnv.MESOS_NATIVE_JAVA_LIBRARY` 指定 Mesos 库的安装路径。 | | `spark.mesos.executor.docker.forcePullImage` | false | 强制 Mesos 代理拉取 `spark.mesos.executor.docker.image` 中指定的图像。     默认情况下,Mesos 代理将不会拉取已经缓存的图像。 | | `spark.mesos.executor.docker.parameters` | (none) | 在使用 docker 容器化器在 Mesos 上启动 Spark 执行器时,设置将被传递到 `docker run` 命令的自定义参数的列表。此属性的格式是逗号分隔的列表      键/值对。例: @@ -272,7 +272,7 @@ key1=val1,key2=val2,key3=val3 | `spark.mesos.dispatcher.historyServer.url` | `(none)` | 设置[history server](http://spark.apache.org/docs/latest/monitoring.html#viewing-after-the-fact)。然后,dispatcher 将链接每个驱动程序到其条目在历史服务器中。 | | `spark.mesos.gpus.max` | `0` | 设置要为此作业获取的 GPU 资源的最大数量。请注意,当没有找到 GPU 资源时,执行器仍然会启动因为这个配置只是一个上限,而不是保证数额。 | | `spark.mesos.network.name` | `(none)` | 将 containers 附加到给定的命名网络。如果这个作业是在集群模式下启动,同时在给定的命令中启动驱动程序网络。查看 [Mesos CNI 文档](http://mesos.apache.org/documentation/latest/cni/)了解更多细节。 | -| `spark.mesos.fetcherCache.enable` | `false` | 如果设置为 `true`,则所有 URI (例如:`spark.executor.uri`,      `spark.mesos.uris`)将被<a     HREF = "http://mesos.apache.org/documentation/latest/fetcher/"> Mesos      Fetcher Cache</a> | +| `spark.mesos.fetcherCache.enable` | `false` | 如果设置为 `true`,则所有 URI(例如:`spark.executor.uri`,      `spark.mesos.uris`)将被<a     HREF = "http://mesos.apache.org/documentation/latest/fetcher/"> Mesos      Fetcher Cache</a> | # 故障排查和调试 diff --git a/docs/17.md b/docs/17.md index f4ecdc702dd401a7923db0f3ffec1c902c6eee6c..95a56bed5a05cc224f79295ff1166b5d75478eae 100644 --- a/docs/17.md +++ b/docs/17.md @@ -53,7 +53,7 @@ $ ./bin/spark-submit --class my.main.Class \ # 准备 -在 YARN 上运行 Spark 需要使用 YARN 支持构建的二进制分布式的 Spark (a binary distribution of Spark)。二进制文件(binary distributions)可以从项目网站的 [下载页面](http://spark.apache.org/downloads.html) 下载。要自己构建 Spark,请参考 [构建 Spark](building-spark.html)。 +在 YARN 上运行 Spark 需要使用 YARN 支持构建的二进制分布式的 Spark(a binary distribution of Spark)。二进制文件(binary distributions)可以从项目网站的 [下载页面](http://spark.apache.org/downloads.html) 下载。要自己构建 Spark,请参考 [构建 Spark](building-spark.html)。 要使 Spark 运行时 jars 可以从 YARN 端访问,您可以指定 `spark.yarn.archive` 或者 `spark.yarn.jars`。更多详细的信息,请参阅 [Spark 属性](running-on-yarn.html#spark-properties)。如果既没有指定 `spark.yarn.archive` 也没有指定 `spark.yarn.jars`,Spark 将在 `$SPARK_HOME/jars` 目录下创建一个包含所有 jar 的 zip 文件,并将其上传到 distributed cache(分布式缓存)中。 @@ -71,7 +71,7 @@ yarn logs -applicationId 将打印来自给定的应用程序的所有容器(containers)的所有的日志文件的内容。你还可以使用 HDFS shell 或者 API 直接在 HDFS 中查看容器日志文件(container log files)。可以通过查看您的 YARN 配置(`yarn.nodemanager.remote-app-log-dir` 和 `yarn.nodemanager.remote-app-log-dir-suffix`)找到它们所在的目录。日志还可以在 Spark Web UI 的 “执行程序(Executors)”选项卡下找到。您需要同时运行 Spark 历史记录服务器(Spark history server) 和 MapReduce 历史记录服务器(MapReduce history server),并在 `yarn-site.xm`l 文件中正确配置 `yarn.log.server.url`。Spark 历史记录服务器 UI 上的日志将重定向您到 MapReduce 历史记录服务器以显示聚合日志(aggregated logs)。 -当未启用日志聚合时,日志将在每台计算机上的本地保留在 `YARN_APP_LOGS_DIR 目录下`,通常配置为 `/tmp/logs` 或者 `$HADOOP_HOME/logs/userlogs`,具体取决于 Hadoop 版本和安装。查看容器(container)的日志需要转到包含它们的主机并在此目录中查看它们。子目录根据应用程序 ID (application ID)和 容器 ID (container ID)组织日志文件。日志还可以在 Spark Web UI 的 “执行程序(Executors)”选项卡下找到,并且不需要运行 MapReduce history server。 +当未启用日志聚合时,日志将在每台计算机上的本地保留在 `YARN_APP_LOGS_DIR 目录下`,通常配置为 `/tmp/logs` 或者 `$HADOOP_HOME/logs/userlogs`,具体取决于 Hadoop 版本和安装。查看容器(container)的日志需要转到包含它们的主机并在此目录中查看它们。子目录根据应用程序 ID(application ID)和 容器 ID(container ID)组织日志文件。日志还可以在 Spark Web UI 的 “执行程序(Executors)”选项卡下找到,并且不需要运行 MapReduce history server。 要查看每个 container(容器)的启动环境,请将 `yarn.nodemanager.delete.debug-delay-sec` 增加到一个较大的值(例如 `36000`),然后通过 `yarn.nodemanager.local-dirs` 访问应用程序缓存,在容器启动的节点上。此目录包含启动脚本(launch script), JARs,和用于启动每个容器的所有的环境变量。这个过程对于调试 classpath 问题特别有用。(请注意,启用此功能需要集群设置的管理员权限并且还需要重新启动所有的 node managers,因此这不适用于托管集群)。 @@ -79,7 +79,7 @@ yarn logs -applicationId * 使用 `spark-submit` 上传一个自定义的 `log4j.properties`,通过将 spark-submit 添加到要与应用程序一起上传的文件的 –files 列表中。 * add `-Dlog4j.configuration=<location of configuration file>` to `spark.driver.extraJavaOptions` (for the driver) or `spark.executor.extraJavaOptions` (for executors). Note that if using a file, the `file:` protocol should be explicitly provided, and the file needs to exist locally on all the nodes. -* 添加 `-Dlog4j.configuration=<配置文件的位置>` 到 `spark.driver.extraJavaOptions`(对于驱动程序)或者 containers (对于执行者)。请注意,如果使用文件,文件:协议(protocol )应该被显式提供,并且该文件需要在所有节点的本地存在。 +* 添加 `-Dlog4j.configuration=<配置文件的位置>` 到 `spark.driver.extraJavaOptions`(对于驱动程序)或者 containers(对于执行者)。请注意,如果使用文件,文件:协议(protocol )应该被显式提供,并且该文件需要在所有节点的本地存在。 * 更新 `$SPARK_CONF_DIR/log4j.properties` 文件,并且它将与其他配置一起自动上传。请注意,如果指定了多个选项,其他 2 个选项的优先级高于此选项。 请注意,对于第一个选项,executors 和 application master 将共享相同的 log4j 配置,这当它们在同一个节点上运行的时候,可能会导致问题(例如,试图写入相同的日志文件)。 diff --git a/docs/20.md b/docs/20.md index 1533039b8dc306d9367322cce73fb4b4b07bf4f6..8dcfb6716b76cf0b7220a745ed7c34831187f2ed 100644 --- a/docs/20.md +++ b/docs/20.md @@ -6,29 +6,29 @@ * [可用属性](#可用属性) * [应用程序属性](#应用程序属性) * [运行环境](#运行环境) - * [Shuffle Behavior (Shuffle 行为)](#shuffle-behavior-shuffle-行为) + * [Shuffle Behavior(Shuffle 行为)](#shuffle-behavior-shuffle-行为) * [Spark UI](#spark-ui) - * [Compression and Serialization (压缩和序列化)](#compression-and-serialization-压缩和序列化) - * [Memory Management (内存管理)](#memory-management-内存管理) - * [Execution Behavior (执行行为)](#execution-behavior-执行行为) - * [Networking (网络)](#networking-网络) - * [Scheduling (调度)](#scheduling-调度) - * [Dynamic Allocation (动态分配)](#dynamic-allocation-动态分配) - * [Security (安全)](#security-安全) + * [Compression and Serialization(压缩和序列化)](#compression-and-serialization-压缩和序列化) + * [Memory Management(内存管理)](#memory-management-内存管理) + * [Execution Behavior(执行行为)](#execution-behavior-执行行为) + * [Networking(网络)](#networking-网络) + * [Scheduling(调度)](#scheduling-调度) + * [Dynamic Allocation(动态分配)](#dynamic-allocation-动态分配) + * [Security(安全)](#security-安全) * [TLS / SSL](#tls--ssl) * [Spark SQL](#spark-sql) * [Spark Streaming](#spark-streaming) * [SparkR](#sparkr) * [GraphX](#graphx) - * [Deploy (部署)](#deploy-部署) - * [Cluster Managers (集群管理器)](#cluster-managers-集群管理器) + * [Deploy(部署)](#deploy-部署) + * [Cluster Managers(集群管理器)](#cluster-managers-集群管理器) * [](#yarn)[YARN](running-on-yarn.html#configuration) * [](#mesos)[Mesos](running-on-mesos.html#configuration) * [](#standalone-mode)[Standalone Mode](spark-standalone.html#cluster-launch-scripts) -* [Environment Variables (环境变量)](#environment-variables-环境变量) -* [Configuring Logging (配置 Logging)](#configuring-logging-配置-logging) -* [Overriding configuration directory (覆盖配置目录)](#overriding-configuration-directory-覆盖配置目录) -* [Inheriting Hadoop Cluster Configuration (继承 Hadoop 集群配置)](#inheriting-hadoop-cluster-configuration-继承-hadoop-集群配置) +* [Environment Variables(环境变量)](#environment-variables-环境变量) +* [Configuring Logging(配置 Logging)](#configuring-logging-配置-logging) +* [Overriding configuration directory(覆盖配置目录)](#overriding-configuration-directory-覆盖配置目录) +* [Inheriting Hadoop Cluster Configuration(继承 Hadoop 集群配置)](#inheriting-hadoop-cluster-configuration-继承-hadoop-集群配置) Spark 提供了三个位置来配置系统: @@ -38,7 +38,7 @@ Spark 提供了三个位置来配置系统: # Spark 属性 -Spark 属性控制大多数应用程序设置,并为每个应用程序单独配置。这些属性可以直接在 [SparkConf](api/scala/index.html#org.apache.spark.SparkConf) 上设置并传递给您的 `SparkContext`。`SparkConf` 可以让你配置一些常见的属性(例如 master URL 和应用程序名称),以及通过 `set()` 方法来配置任意 key-value pairs (键值对)。例如,我们可以使用两个线程初始化一个应用程序,如下所示: +Spark 属性控制大多数应用程序设置,并为每个应用程序单独配置。这些属性可以直接在 [SparkConf](api/scala/index.html#org.apache.spark.SparkConf) 上设置并传递给您的 `SparkContext`。`SparkConf` 可以让你配置一些常见的属性(例如 master URL 和应用程序名称),以及通过 `set()` 方法来配置任意 key-value pairs(键值对)。例如,我们可以使用两个线程初始化一个应用程序,如下所示: 请注意,我们运行 local[2],意思是两个线程 - 代表 “最小” 并行性,这可以帮助检测在只存在于分布式环境中运行时的错误. @@ -49,7 +49,7 @@ val conf = new SparkConf() val sc = new SparkContext(conf) ``` -注意,本地模式下,我们可以使用多个线程,而且在像 Spark Streaming 这样的场景下,我们可能需要多个线程来防止任一类型的类似 starvation issues (线程饿死) 这样的问题。配置时间段的属性应该写明时间单位,如下格式都是可接受的: +注意,本地模式下,我们可以使用多个线程,而且在像 Spark Streaming 这样的场景下,我们可能需要多个线程来防止任一类型的类似 starvation issues(线程饿死) 这样的问题。配置时间段的属性应该写明时间单位,如下格式都是可接受的: ``` 25ms (milliseconds) @@ -60,7 +60,7 @@ val sc = new SparkContext(conf) 1y (years) ``` -指定 byte size (字节大小)的属性应该写明单位。如下格式都是可接受的: +指定 byte size(字节大小)的属性应该写明单位。如下格式都是可接受的: ``` 1b (bytes) @@ -86,9 +86,9 @@ val sc = new SparkContext(new SparkConf()) --conf "spark.executor.extraJavaOptions=-XX:+PrintGCDetails -XX:+PrintGCTimeStamps" myApp.jar ``` -Spark shell 和 [`spark-submit`](submitting-applications.html) 工具支持两种动态加载配置的方法。第一种,通过命令行选项,如:上面提到的 `--master`。`spark-submit` 可以使用 `--conf` flag 来接受任何 Spark 属性标志,但对于启动 Spark 应用程序的属性使用 special flags (特殊标志)。运行 `./bin/spark-submit --help` 可以展示这些选项的完整列表. +Spark shell 和 [`spark-submit`](submitting-applications.html) 工具支持两种动态加载配置的方法。第一种,通过命令行选项,如:上面提到的 `--master`。`spark-submit` 可以使用 `--conf` flag 来接受任何 Spark 属性标志,但对于启动 Spark 应用程序的属性使用 special flags(特殊标志)。运行 `./bin/spark-submit --help` 可以展示这些选项的完整列表. -`bin/spark-submit` 也支持从 `conf/spark-defaults.conf` 中读取配置选项,其中每行由一个 key (键)和一个由 whitespace (空格)分隔的 value (值)组成,如下: +`bin/spark-submit` 也支持从 `conf/spark-defaults.conf` 中读取配置选项,其中每行由一个 key(键)和一个由 whitespace(空格)分隔的 value(值)组成,如下: ``` spark.master spark://5.6.7.8:7077 @@ -97,19 +97,19 @@ spark.eventLog.enabled true spark.serializer org.apache.spark.serializer.KryoSerializer ``` -指定为 flags (标志)或属性文件中的任何值都将传递给应用程序并与通过 SparkConf 指定的那些值 merge (合并)。属性直接在 SparkConf 上设置采取最高优先级,然后 flags (标志)传递给 `spark-submit` 或 `spark-shell`,然后选项在 `spark-defaults.conf` 文件中。自从 Spark 版本的早些时候,一些 configuration keys (配置键)已被重命名 ; 在这种情况下,旧的 key names (键名)仍然被接受,但要比较新的 key 优先级都要低一些. +指定为 flags(标志)或属性文件中的任何值都将传递给应用程序并与通过 SparkConf 指定的那些值 merge(合并)。属性直接在 SparkConf 上设置采取最高优先级,然后 flags(标志)传递给 `spark-submit` 或 `spark-shell`,然后选项在 `spark-defaults.conf` 文件中。自从 Spark 版本的早些时候,一些 configuration keys(配置键)已被重命名 ; 在这种情况下,旧的 key names(键名)仍然被接受,但要比较新的 key 优先级都要低一些. ## 查看 Spark 属性 -在应用程序的 web UI `http://<driver>:4040` 中,“Environment” tab (“环境”选项卡)中列出了 Spark 的属性。这是一个检查您是否正确设置了您的属性的一个非常有用的地方。注意,只有显示地通过 `spark-defaults.conf`,`SparkConf` 或者命令行设置的值将会出现。对于所有其他配置属性,您可以认为使用的都是默认值. +在应用程序的 web UI `http://<driver>:4040` 中,“Environment” tab(“环境”选项卡)中列出了 Spark 的属性。这是一个检查您是否正确设置了您的属性的一个非常有用的地方。注意,只有显示地通过 `spark-defaults.conf`,`SparkConf` 或者命令行设置的值将会出现。对于所有其他配置属性,您可以认为使用的都是默认值. ## 可用属性 -大多数控制 internal settings (内部设置) 的属性具有合理的默认值。一些常见的选项是: +大多数控制 internal settings(内部设置) 的属性具有合理的默认值。一些常见的选项是: ### 应用程序属性 -| Property Name (属性名称) | Default (默认值) | Meaning (含义) | +| Property Name(属性名称) | Default(默认值) | Meaning(含义) | | --- | --- | --- | | `spark.app.name` | (none) | Spark 应用的名字。会在 SparkUI 和日志中出现。 | | `spark.driver.cores` | 1 | 在 cluster 模式下,用几个 core 运行 driver 进程。 | @@ -128,14 +128,14 @@ Apart from these, the following properties are also available, and may be useful ### 运行环境 -| Property Name (属性名称) | Default (默认值) | Meaning (含义) | +| Property Name(属性名称) | Default(默认值) | Meaning(含义) | | --- | --- | --- | | `spark.driver.extraClassPath` | (none) | 额外的classpath条目需预先添加到驱动程序 classpath中。注意:在客户端模式下,这一套配置不能通过 SparkConf 直接在应用在应用程序中,因为 JVM 驱动已经启用了。相反,请在配置文件中通过设置 --driver-class-path 选项或者选择默认属性。 | | `spark.driver.extraJavaOptions` | (none) | 一些额外的 JVM 属性传递给驱动。例如,GC 设置或其他日志方面设置。注意,设置最大堆大小(-Xmx)是不合法的。最大堆大小设置可以通过在集群模式下设置 `spark.driver.memory` 选项,并且可以通过`--driver-memory` 在客户端模式设置。 _注意:_ 在客户端模式下,这一套配置不能通过 `SparkConf` 直接应用在应用程序中,因为 JVM 驱动已经启用了。相反,请在配置文件中通过设置 `--driver-java-options` 选项或者选择默认属性。 | | `spark.driver.extraLibraryPath` | (none) | 当启动 JVM 驱动程序时设置一个额外的库路径。 _注意:_ 在客户端模式下,这一套配置不能通过 `SparkConf` 直接在应用在应用程序中,因为 JVM 驱动已经启用了。相反,请在配置文件中通过设置 `--driver-library-path` 选项或者选择默认属性。 | -| `spark.driver.userClassPathFirst` | false | (实验)在驱动程序加载类库时,用户添加的 Jar 包是否优先于 Spark 自身的 Jar 包。这个特性可以用来缓解冲突引发的依赖性和用户依赖。目前只是实验功能。这是仅用于集群模式。 | +| `spark.driver.userClassPathFirst` | false |(实验)在驱动程序加载类库时,用户添加的 Jar 包是否优先于 Spark 自身的 Jar 包。这个特性可以用来缓解冲突引发的依赖性和用户依赖。目前只是实验功能。这是仅用于集群模式。 | | `spark.executor.extraClassPath` | (none) | 额外的类路径要预先考虑到 executor 的 classpath。这主要是为与旧版本的 Spark 向后兼容。用户通常不应该需要设置这个选项。 | | `spark.executor.extraJavaOptions` | (none) | 一些额外的 JVM 属性传递给 executor。例如,GC 设置或其他日志方面设置。注意,设置最大堆大小(-Xmx)是不合法的。Spark 应该使用 SparkConf 对象或 Spark 脚本中使用的 spark-defaults.conf 文件中设置。最大堆大小设置可以在 spark.executor.memory 进行设置。 | | `spark.executor.extraLibraryPath` | (none) | 当启动 JVM 的可执行程序时设置额外的类库路径。 | @@ -144,7 +144,7 @@ _注意:_ 在客户端模式下,这一套配置不能通过 `SparkConf` 直接 | `spark.executor.logs.rolling.maxSize` | (none) | 设置最大文件的大小,以字节为单位日志将被回滚。默认禁用。见 `spark.executor.logs.rolling.maxRetainedFiles` 旧日志的自动清洗。 | | `spark.executor.logs.rolling.strategy` | (none) | 设置 executor 日志的回滚策略。它可以被设置为 “时间”(基于时间的回滚)或 “大小”(基于大小的回滚)。对于 “时间”,使用 `spark.executor.logs.rolling.time.interval` 设置回滚间隔。用 `spark.executor.logs.rolling.maxSize` 设置最大文件大小回滚。 | | `spark.executor.logs.rolling.time.interval` | daily | 设定的时间间隔,executor 日志将回滚。默认情况下是禁用的。有效值是`每天`,`每小时`,`每分钟`或任何时间间隔在几秒钟内。见 `spark.executor.logs.rolling.maxRetainedFiles` 旧日志的自动清洗。 | -| `spark.executor.userClassPathFirst` | false | (实验)与 `spark.driver.userClassPathFirst` 相同的功能,但适用于执行程序的实例。 | +| `spark.executor.userClassPathFirst` | false |(实验)与 `spark.driver.userClassPathFirst` 相同的功能,但适用于执行程序的实例。 | | `spark.executorEnv.[EnvironmentVariableName]` | (none) | 通过添加指定的环境变量 `EnvironmentVariableName` 给 executor 进程。用户可以设置多个环境变量。 | | `spark.redaction.regex` | (?i)secret|password | Regex to decide which Spark configuration properties and environment variables in driver and executor environments contain sensitive information. When this regex matches a property key or value, the value is redacted from the environment UI and various logs like YARN and event logs. | | `spark.python.profile` | false | 启用在 python 中的 profile。结果将由 `sc.show_profiles()` 显示,或者它将会在驱动程序退出后显示。它还可以通过 `sc.dump_profiles(path)` dump 到磁盘。如果一些 profile 文件的结果已经显示,那么它们将不会再驱动程序退出后再次显示。默认情况下,`pyspark.profiler.BasicProfiler` 将被使用,但这可以通过传递一个 profile 类作为一个参数到 `SparkContext` 中进行覆盖。 | @@ -161,18 +161,18 @@ _注意:_ 在客户端模式下,这一套配置不能通过 `SparkConf` 直接 | `spark.pyspark.driver.python` | | Python binary executable to use for PySpark in driver. (default is `spark.pyspark.python`) | | `spark.pyspark.python` | | Python binary executable to use for PySpark in both driver and executors. | -### Shuffle Behavior (Shuffle 行为) +### Shuffle Behavior(Shuffle 行为) -| Property Name (属性名称) | Default (默认值) | Meaning (含义) | +| Property Name(属性名称) | Default(默认值) | Meaning(含义) | | --- | --- | --- | | `spark.reducer.maxSizeInFlight` | 48m | 从每个 Reduce 任务中并行的 fetch 数据的最大大小。因为每个输出都要求我们创建一个缓冲区,这代表要为每一个 Reduce 任务分配一个固定大小的内存。除非内存足够大否则尽量设置小一点。 | | `spark.reducer.maxReqsInFlight` | Int.MaxValue | 在集群节点上,这个配置限制了远程 fetch 数据块的连接数目。当集群中的主机数量的增加时候,这可能导致大量的到一个或多个节点的主动连接,导致负载过多而失败。通过限制获取请求的数量,可以缓解这种情况。 | | `spark.shuffle.compress` | true | 是否要对 map 输出的文件进行压缩。默认为 true,使用 `spark.io.compression.codec`。 | | `spark.shuffle.file.buffer` | 32k | 每个 shuffle 文件输出流的内存大小。这些缓冲区的数量减少了磁盘寻道和系统调用创建的 shuffle 文件。 | -| `spark.shuffle.io.maxRetries` | 3 | (仅适用于 Netty)如果设置了非 0 值,与 IO 异常相关失败的 fetch 将自动重试。在遇到长时间的 GC 问题或者瞬态网络连接问题时候,这种重试有助于大量 shuffle 的稳定性。 | -| `spark.shuffle.io.numConnectionsPerPeer` | 1 | (仅Netty)重新使用主机之间的连接,以减少大型集群的连接建立。 对于具有许多硬盘和少量主机的群集,这可能导致并发性不足以使所有磁盘饱和,因此用户可考虑增加此值。 | -| `spark.shuffle.io.preferDirectBufs` | true | (仅适用于 Netty)堆缓冲区用于减少在 shuffle 和缓存块传输中的垃圾回收。对于严格限制的堆内存环境中,用户可能希望把这个设置关闭,以强制Netty的所有分配都在堆上。 | -| `spark.shuffle.io.retryWait` | 5s | (仅适用于 Netty)fetch 重试的等待时长。默认 15s。计算公式是 `maxRetries * retryWait`。 | +| `spark.shuffle.io.maxRetries` | 3 |(仅适用于 Netty)如果设置了非 0 值,与 IO 异常相关失败的 fetch 将自动重试。在遇到长时间的 GC 问题或者瞬态网络连接问题时候,这种重试有助于大量 shuffle 的稳定性。 | +| `spark.shuffle.io.numConnectionsPerPeer` | 1 |(仅Netty)重新使用主机之间的连接,以减少大型集群的连接建立。 对于具有许多硬盘和少量主机的群集,这可能导致并发性不足以使所有磁盘饱和,因此用户可考虑增加此值。 | +| `spark.shuffle.io.preferDirectBufs` | true |(仅适用于 Netty)堆缓冲区用于减少在 shuffle 和缓存块传输中的垃圾回收。对于严格限制的堆内存环境中,用户可能希望把这个设置关闭,以强制Netty的所有分配都在堆上。 | +| `spark.shuffle.io.retryWait` | 5s |(仅适用于 Netty)fetch 重试的等待时长。默认 15s。计算公式是 `maxRetries * retryWait`。 | | `spark.shuffle.service.enabled` | false | 启用外部随机播放服务。此服务保留由执行者编写的随机播放文件,以便可以安全地删除执行程序。如果`spark.dynamicAllocation.enabled` 为 "true",则必须启用此功能。必须设置外部随机播放服务才能启用它。有关详细信息,请参阅 [动态分配配置和设置文档](job-scheduling.html#configuration-and-setup)。 | | `spark.shuffle.service.port` | 7337 | 外部 shuffle 的运行端口。 | | `spark.shuffle.service.index.cache.entries` | 1024 | Max number of entries to keep in the index cache of the shuffle service. | @@ -185,7 +185,7 @@ _注意:_ 在客户端模式下,这一套配置不能通过 `SparkConf` 直接 ### Spark UI -| Property Name (属性名称) | Default (默认值) | Meaning (含义) | +| Property Name(属性名称) | Default(默认值) | Meaning(含义) | | --- | --- | --- | | `spark.eventLog.compress` | false | 是否压缩记录的事件,如果 `spark.eventLog.enabled` 为true。压缩将使用`spark.io.compression.codec`。 | | `spark.eventLog.dir` | file:///tmp/spark-events | Spark 事件日志的文件路径。如果 `spark.eventLog.enabled` 为 true。在这个基本目录下,Spark 为每个应用程序创建一个二级目录,日志事件特定于应用程序的目录。用户可能希望设置一个统一的文件目录像一个 HDFS 目录那样,所以历史文件可以从历史文件服务器中读取。 | @@ -205,9 +205,9 @@ _注意:_ 在客户端模式下,这一套配置不能通过 `SparkConf` 直接 | `spark.streaming.ui.retainedBatches` | 1000 | 在垃圾回收前,Spark UI 和 API 有多少 batch 已经完成。 | | `spark.ui.retainedDeadExecutors` | 100 | 在垃圾回收前,Spark UI 和 API 有多少 dead executors。 | -### Compression and Serialization (压缩和序列化) +### Compression and Serialization(压缩和序列化) -| Property Name (属性名称) | Default (默认值) | Meaning (含义) | +| Property Name(属性名称) | Default(默认值) | Meaning(含义) | | --- | --- | --- | | `spark.broadcast.compress` | true | 是否在发送之前压缩广播变量。一般是个好主意压缩将使用 `spark.io.compression.codec`。 | | `spark.io.compression.codec` | lz4 | 内部数据使用的压缩编解码器,如 RDD 分区,广播变量和混洗输出。默认情况下,Spark 提供三种编解码器:`lz4`,`lzf`,和 `snappy`。您还可以使用完全限定类名来指定编码解码器, 例如:`org.apache.spark.io.LZ4CompressionCodec`, `org.apache.spark.io.LZFCompressionCodec`, 和 `org.apache.spark.io.SnappyCompressionCodec`。 | @@ -225,9 +225,9 @@ _注意:_ 在客户端模式下,这一套配置不能通过 `SparkConf` 直接 JavaSerializer | 用于序列化将通过网络发送或需要以序列化形式缓存的对象的类。Java 序列化的默认值与任何Serializable Java对象一起使用,但速度相当慢,所以我们建议您在需要速度时使用 [使用 `org.apache.spark.serializer.KryoSerializer` 并配置 Kryo 序列化](tuning.html)。可以是 [`org.apache.spark.Serializer`](api/scala/index.html#org.apache.spark.serializer.Serializer) 的任何子类。 | | `spark.serializer.objectStreamReset` | 100 | 当正使用 org.apache.spark.serializer.JavaSerializer 序列化时,序列化器缓存对象虽然可以防止写入冗余数据,但是却停止这些缓存对象的垃圾回收。通过调用 'reset' 你从序列化程序中清除该信息,并允许收集旧的对象。要禁用此周期性重置,请将其设置为 -1。默认情况下,序列化器会每过 100 个对象被重置一次。 | -### Memory Management (内存管理) +### Memory Management(内存管理) -| Property Name (属性名称) | Default (默认值) | Meaning (含义) | +| Property Name(属性名称) | Default(默认值) | Meaning(含义) | | --- | --- | --- | | `spark.memory.fraction` | 0.6 | 用于执行和存储的(堆空间 - 300MB)的分数。这个值越低,溢出和缓存数据逐出越频繁。此配置的目的是在稀疏、异常大的记录的情况下为内部元数据,用户数据结构和不精确的大小估计预留内存。推荐使用默认值。有关更多详细信息,包括关于在增加此值时正确调整 JVM 垃圾回收的重要信息,请参阅 [this description](tuning.html#memory-management-overview)。 | | `spark.memory.storageFraction` | 0.5 | 不会被逐出内存的总量,表示为 `s​park.memory.fraction` 留出的区域大小的一小部分。这个越高,工作内存可能越少,执行和任务可能更频繁地溢出到磁盘。推荐使用默认值。有关更多详细信息,请参阅 [this description](tuning.html#memory-management-overview)。 | @@ -236,14 +236,14 @@ JavaSerializer | 用于序列化将通过网络发送或需要以序列化形式 | `spark.memory.useLegacyMode` | false | 是否启用 Spark 1.5 及以前版本中使用的传统内存管理模式。传统模式将堆空间严格划分为固定大小的区域,如果未调整应用程序,可能导致过多溢出。必须启用本参数,以下选项才可用:`spark.shuffle.memoryFraction` `spark.storage.memoryFraction` `spark.storage.unrollFraction` | -| `spark.shuffle.memoryFraction` | 0.2 | (过时)只有在启用 `spark.memory.useLegacyMode` 时,此属性才是可用的。混洗期间用于聚合和 cogroups 的 Java 堆的分数。在任何给定时间,用于混洗的所有内存映射的集合大小不会超过这个上限,超过该限制的内容将开始溢出到磁盘。如果溢出频繁,请考虑增加此值,但这以 `spark.storage.memoryFraction` 为代价。 | -| `spark.storage.memoryFraction` | 0.6 | (过时)只有在启用 `spark.memory.useLegacyMode` 时,此属性才是可用的。Java 堆的分数,用于 Spark 的内存缓存。这个值不应该大于 JVM 中老生代(old generation) 对象所占用的内存,默认情况下,它提供 0.6 的堆,但是如果配置你所用的老生代对象大小,你可以增加它。 | -| `spark.storage.unrollFraction` | 0.2 | (过时)只有在启用 `spark.memory.useLegacyMode` 时,此属性才是可用的。`spark.storage.memoryFraction` 用于在内存中展开块的分数。当没有足够的空闲存储空间来完全展开新块时,通过删除现有块来动态分配。 | +| `spark.shuffle.memoryFraction` | 0.2 |(过时)只有在启用 `spark.memory.useLegacyMode` 时,此属性才是可用的。混洗期间用于聚合和 cogroups 的 Java 堆的分数。在任何给定时间,用于混洗的所有内存映射的集合大小不会超过这个上限,超过该限制的内容将开始溢出到磁盘。如果溢出频繁,请考虑增加此值,但这以 `spark.storage.memoryFraction` 为代价。 | +| `spark.storage.memoryFraction` | 0.6 |(过时)只有在启用 `spark.memory.useLegacyMode` 时,此属性才是可用的。Java 堆的分数,用于 Spark 的内存缓存。这个值不应该大于 JVM 中老生代(old generation) 对象所占用的内存,默认情况下,它提供 0.6 的堆,但是如果配置你所用的老生代对象大小,你可以增加它。 | +| `spark.storage.unrollFraction` | 0.2 |(过时)只有在启用 `spark.memory.useLegacyMode` 时,此属性才是可用的。`spark.storage.memoryFraction` 用于在内存中展开块的分数。当没有足够的空闲存储空间来完全展开新块时,通过删除现有块来动态分配。 | | `spark.storage.replication.proactive` | false | Enables proactive block replication for RDD blocks. Cached RDD block replicas lost due to executor failures are replenished if there are any existing available replicas. This tries to get the replication level of the block to the initial number. | -### Execution Behavior (执行行为) +### Execution Behavior(执行行为) -| Property Name (属性名称) | Default (默认行为) | Meaning (含义) | +| Property Name(属性名称) | Default(默认行为) | Meaning(含义) | | --- | --- | --- | | `spark.broadcast.blockSize` | 4m | `TorrentBroadcastFactory` 的一个块的每个分片大小。过大的值会降低广播期间的并行性(更慢了); 但是,如果它过小,`BlockManager` 可能会受到性能影响。 | | `spark.executor.cores` | 在 YARN 模式下默认为 1,standlone 和 Mesos 粗粒度模型中的 worker 节点的所有可用的 core。 | 在每个 executor(执行器)上使用的 core 数。在 standlone 和 Mesos 的粗粒度模式下,设置此参数允许应用在相同的 worker 上运行多个 executor(执行器),只要该 worker 上有足够的 core。否则,每个 application(应用)在单个 worker 上只会启动一个 executor(执行器)。 | @@ -265,9 +265,9 @@ JavaSerializer | 用于序列化将通过网络发送或需要以序列化形式 | `spark.storage.memoryMapThreshold` | 2m | 当从磁盘读取块时,Spark 内存映射的块大小。这会阻止 Spark 从内存映射过小的块。通常,存储器映射对于接近或小于操作系统的页大小的块具有高开销。 | | `spark.hadoop.mapreduce.fileoutputcommitter.algorithm.version` | 1 | The file output committer algorithm version, valid algorithm version number: 1 or 2. Version 2 may have better performance, but version 1 may handle failures better in certain situations, as per [MAPREDUCE-4815](https://issues.apache.org/jira/browse/MAPREDUCE-4815). | -### Networking (网络) +### Networking(网络) -| Property Name (属性名称) | Default (默认值) | Meaning (含义) | +| Property Name(属性名称) | Default(默认值) | Meaning(含义) | | --- | --- | --- | | `spark.rpc.message.maxSize` | 128 | 在 “control plane” 通信中允许的最大消息大小(以 MB 为单位); 一般只适用于在 executors 和 driver 之间发送的映射输出大小信息。如果您正在运行带有数千个 map 和 reduce 任务的作业,并查看有关 RPC 消息大小的消息,请增加此值。 | | `spark.blockManager.port` | (random) | 所有块管理器监听的端口。这些都存在于 driver 和 executors 上。 | @@ -283,9 +283,9 @@ It also allows a different address from the local one to be advertised to execut | `spark.rpc.askTimeout` | `spark.network.timeout` | RPC 请求操作在超时前等待的持续时间。 | | `spark.rpc.lookupTimeout` | 120s | RPC 远程端点查找操作在超时之前等待的持续时间。 | -### Scheduling (调度) +### Scheduling(调度) -| Property Name (属性名称) | Default (默认值) | Meaning (含义) | +| Property Name(属性名称) | Default(默认值) | Meaning(含义) | | --- | --- | --- | | `spark.cores.max` | (not set) | 当以 “coarse-grained(粗粒度)” 共享模式在 [standalone deploy cluster](spark-standalone.html) 或 [Mesos cluster in "coarse-grained" sharing mode](running-on-mesos.html#mesos-run-modes) 上运行时,从集群(而不是每台计算机)请求应用程序的最大 CPU 内核数量。如果未设置,默认值将是 Spar k的 standalone deploy 管理器上的 `spark.deploy.defaultCores`,或者 Mesos上的无限(所有可用核心)。 | | `spark.locality.wait` | 3s | 等待启动本地数据任务多长时间,然后在较少本地节点上放弃并启动它。相同的等待将用于跨越多个地点级别(process-local,node-local,rack-local 等所有)。也可以通过设置 `spark.locality.wait.node` 等来自定义每个级别的等待时间。如果任务很长并且局部性较差,则应该增加此设置,但是默认值通常很好。 | @@ -294,7 +294,7 @@ It also allows a different address from the local one to be advertised to execut | `spark.locality.wait.rack` | spark.locality.wait | 自定义 rack locality 等待时间。 | | `spark.scheduler.maxRegisteredResourcesWaitingTime` | 30s | 在调度开始之前等待资源注册的最大时间量。 | | `spark.scheduler.minRegisteredResourcesRatio` | 0.8 for YARN mode; 0.0 for standalone mode and Mesos coarse-grained mode | 注册资源(注册资源/总预期资源)的最小比率(资源是 yarn 模式下的执行程序,standalone 模式下的 CPU 核心和 Mesos coarsed-grained 模式 'spark.cores.max' 值是 Mesos coarse-grained 模式下的总体预期资源])在调度开始之前等待。指定为 0.0 和 1.0 之间的双精度。无论是否已达到资源的最小比率,在调度开始之前将等待的最大时间量由配置`spark.scheduler.maxRegisteredResourcesWaitingTime` 控制。 | -| `spark.scheduler.mode` | FIFO | 作业之间的 [scheduling mode (调度模式)](job-scheduling.html#scheduling-within-an-application) 提交到同一个 SparkContext。可以设置为 `FAIR` 使用公平共享,而不是一个接一个排队作业。对多用户服务有用。 | +| `spark.scheduler.mode` | FIFO | 作业之间的 [scheduling mode(调度模式)](job-scheduling.html#scheduling-within-an-application) 提交到同一个 SparkContext。可以设置为 `FAIR` 使用公平共享,而不是一个接一个排队作业。对多用户服务有用。 | | `spark.scheduler.revive.interval` | 1s | 调度程序复活工作资源去运行任务的间隔长度。 | | `spark.blacklist.enabled` | false | If set to "true", prevent Spark from scheduling tasks on executors that have been blacklisted due to too many task failures. The blacklisting algorithm can be further controlled by the other "spark.blacklist" configuration options. | | `spark.blacklist.timeout` | 1h | (Experimental) How long a node or executor is blacklisted for the entire application, before it is unconditionally removed from the blacklist to attempt running new tasks. | @@ -317,9 +317,9 @@ It also allows a different address from the local one to be advertised to execut | `spark.task.reaper.killTimeout` | -1 | When `spark.task.reaper.enabled = true`, this setting specifies a timeout after which the executor JVM will kill itself if a killed task has not stopped running. The default value, -1, disables this mechanism and prevents the executor from self-destructing. The purpose of this setting is to act as a safety-net to prevent runaway uncancellable tasks from rendering an executor unusable. | | `spark.stage.maxConsecutiveAttempts` | 4 | Number of consecutive stage attempts allowed before a stage is aborted. | -### Dynamic Allocation (动态分配) +### Dynamic Allocation(动态分配) -| Property Name (属性名称) | Default (默认值) | Meaning (含义) | +| Property Name(属性名称) | Default(默认值) | Meaning(含义) | | --- | --- | --- | | `spark.dynamicAllocation.enabled` | false | 是否使用动态资源分配,它根据工作负载调整为此应用程序注册的执行程序数量。有关更多详细信息,请参阅 [here](job-scheduling.html#dynamic-resource-allocation) 的说明。这需要设置 `spark.shuffle.service.enabled`。以下配置也相关:`spark.dynamicAllocation.minExecutors`,`spark.dynamicAllocation.maxExecutors` 和`spark.dynamicAllocation.initialExecutors`。 | | `spark.dynamicAllocation.executorIdleTimeout` | 60s | 如果启用动态分配,并且执行程序已空闲超过此持续时间,则将删除执行程序。有关更多详细信息,请参阅此[description](job-scheduling.html#resource-allocation-policy)。 | @@ -330,14 +330,14 @@ It also allows a different address from the local one to be advertised to execut | `spark.dynamicAllocation.schedulerBacklogTimeout` | 1s | 如果启用动态分配,并且有超过此持续时间的挂起任务积压,则将请求新的执行者。有关更多详细信息,请参阅此 [description](job-scheduling.html#resource-allocation-policy)。 | | `spark.dynamicAllocation.sustainedSchedulerBacklogTimeout` | `schedulerBacklogTimeout` | 与 `spark.dynamicAllocation.schedulerBacklogTimeout` 相同,但仅用于后续执行者请求。有关更多详细信息,请参阅此 [description](job-scheduling.html#resource-allocation-policy)。 | -### Security (安全) +### Security(安全) -| Property Name (属性名称) | Default (默认值) | Meaning (含义) | +| Property Name(属性名称) | Default(默认值) | Meaning(含义) | | --- | --- | --- | | `spark.acls.enable` | false | 是否开启 Spark acls。如果开启了,它检查用户是否有权限去查看或修改 job。Note this requires the user to be known, so if the user comes across as null no checks are done. UI 利用使用过滤器验证和设置用户。 | | `spark.admin.acls` | Empty | 逗号分隔的用户或者管理员列表,列表中的用户或管理员有查看和修改所有 Spark job 的权限。如果你运行在一个共享集群,有一组管理员或开发者帮助 debug,这个选项有用。 | | `spark.admin.acls.groups` | Empty | 具有查看和修改对所有Spark作业的访问权限的组的逗号分隔列表。如果您有一组帮助维护和调试的 administrators 或 developers 可以使用此功能基础设施。在列表中输入 "*" 表示任何组中的任何用户都可以使用 admin 的特权。用户组是从 groups mapping provider 的实例获得的。由 `spark.user.groups.mapping` 指定。检查 entry `spark.user.groups.mapping` 了解更多详细信息。 | -| `spark.user.groups.mapping` | `org.apache.spark.security.ShellBasedGroupsMappingProvider` | 用户的组列表由特征定义的 group mapping service 决定可以通过此属性配置的org.apache.spark.security.GroupMappingServiceProvider. 提供了基于 unix shell 的默认实现 `org.apache.spark.security.ShellBasedGroupsMappingProvider` 可以指定它来解析用户的组列表。     _注意:_ 此实现仅支持基于 Unix/Linux 的环境。Windows 环境是      目前 **不** 支持。但是,通过实现可以支持新的 platform/protocol (平台/协议) trait `org.apache.spark.security.GroupMappingServiceProvider`。 | +| `spark.user.groups.mapping` | `org.apache.spark.security.ShellBasedGroupsMappingProvider` | 用户的组列表由特征定义的 group mapping service 决定可以通过此属性配置的org.apache.spark.security.GroupMappingServiceProvider. 提供了基于 unix shell 的默认实现 `org.apache.spark.security.ShellBasedGroupsMappingProvider` 可以指定它来解析用户的组列表。     _注意:_ 此实现仅支持基于 Unix/Linux 的环境。Windows 环境是      目前 **不** 支持。但是,通过实现可以支持新的 platform/protocol(平台/协议) trait `org.apache.spark.security.GroupMappingServiceProvider`。 | | `spark.authenticate` | false | 是否 Spark 验证其内部连接。如果不是运行在 YARN 上,请看 `spark.authenticate.secret`。 | | `spark.authenticate.secret` | None | 设置密钥用于 spark 组件之间进行身份验证。这需要设置 不启用运行在 yarn 和身份验证。 | | `spark.network.crypto.enabled` | false | Enable encryption using the commons-crypto library for RPC and block transfer service. Requires `spark.authenticate` to be enabled. | @@ -345,18 +345,18 @@ It also allows a different address from the local one to be advertised to execut | `spark.network.crypto.keyFactoryAlgorithm` | PBKDF2WithHmacSHA1 | The key factory algorithm to use when generating encryption keys. Should be one of the algorithms supported by the javax.crypto.SecretKeyFactory class in the JRE being used. | | `spark.network.crypto.saslFallback` | true | Whether to fall back to SASL authentication if authentication fails using Spark's internal mechanism. This is useful when the application is connecting to old shuffle services that do not support the internal Spark authentication protocol. On the server side, this can be used to block older clients from authenticating against a new shuffle service. | | `spark.network.crypto.config.*` | None | Configuration values for the commons-crypto library, such as which cipher implementations to use. The config name should be the name of commons-crypto configuration without the "commons.crypto" prefix. | -| `spark.authenticate.enableSaslEncryption` | false | 身份验证时启用加密通信。这是 block transfer service (块传输服务)和支持 RPC 的端点。 | +| `spark.authenticate.enableSaslEncryption` | false | 身份验证时启用加密通信。这是 block transfer service(块传输服务)和支持 RPC 的端点。 | | `spark.network.sasl.serverAlwaysEncrypt` | false | 禁用未加密的连接服务,支持 SASL 验证。这是目前支持的外部转移服务。 | -| `spark.core.connection.ack.wait.timeout` | `spark.network.timeout` | 连接在 timing out (超时)和 giving up (放弃)之前等待 ack occur 的时间。为了避免长时间 pause (暂停),如 GC,导致的不希望的超时,你可以设置较大的值。 | +| `spark.core.connection.ack.wait.timeout` | `spark.network.timeout` | 连接在 timing out(超时)和 giving up(放弃)之前等待 ack occur 的时间。为了避免长时间 pause(暂停),如 GC,导致的不希望的超时,你可以设置较大的值。 | | `spark.modify.acls` | Empty | 逗号分隔的用户列表,列表中的用户有查看 Spark web UI 的权限。默认情况下,只有启动 Spark job 的用户有修改(比如杀死它)权限。在列表中加入 "*" 意味着任何用户可以访问以修改它。 | | `spark.modify.acls.groups` | Empty | 具有对 Spark job 的修改访问权限的组的逗号分隔列表。如果你可以使用这个有一组来自同一个 team 的 administrators 或 developers 可以访问控制工作。在列表中放置 "*" 表示任何组中的任何用户都有权修改 Spark job。用户组是从 `spark.user.groups.mapping` 指定的 groups mapping 提供者的实例获得的。查看 entry `spark.user.groups.mapping` 来了解更多细节。 | -| `spark.ui.filters` | None | 应用到 Spark web UI 的用于 filter class (过滤类)名的逗号分隔的列表。过滤器必须是标准的 [javax servlet Filter](http://docs.oracle.com/javaee/6/api/javax/servlet/Filter.html)。每个过滤器的参数也可以通过设置一个 java 系统属性来指定 spark。java 系统属性: +| `spark.ui.filters` | None | 应用到 Spark web UI 的用于 filter class(过滤类)名的逗号分隔的列表。过滤器必须是标准的 [javax servlet Filter](http://docs.oracle.com/javaee/6/api/javax/servlet/Filter.html)。每个过滤器的参数也可以通过设置一个 java 系统属性来指定 spark。java 系统属性: `spark.<class name of filter>.params='param1=value1,param2=value2'` 例如: `-Dspark.ui.filters=com.test.filter1` `-Dspark.com.test.filter1.params='param1=foo,param2=testing'` | | `spark.ui.view.acls` | Empty | 逗号分隔的可以访问 Spark web ui 的用户列表。默认情况下只有启动 Spark job 的用户具有 view 访问权限。在列表中放入 "*" 表示任何用户都可以具有访问此 Spark job 的 view。 -| `spark.ui.view.acls.groups` | Empty | 逗号分隔的列表,可以查看访问 Spark web ui 的组,以查看 Spark Job 细节。如果您有一组 administrators 或 developers 或可以使用的用户,则可以使用此功能 monitor (监控)提交的 Spark job。在列表中添加 "*" 表示任何组中的任何用户都可以查看 Spark web ui 上的 Spark 工作详细信息。用户组是从 由 `spark.user.groups.mapping` 指定的 groups mapping provider (组映射提供程序)实例获得的。查看 entry `spark.user.groups.mapping` 来了解更多细节。 | +| `spark.ui.view.acls.groups` | Empty | 逗号分隔的列表,可以查看访问 Spark web ui 的组,以查看 Spark Job 细节。如果您有一组 administrators 或 developers 或可以使用的用户,则可以使用此功能 monitor(监控)提交的 Spark job。在列表中添加 "*" 表示任何组中的任何用户都可以查看 Spark web ui 上的 Spark 工作详细信息。用户组是从 由 `spark.user.groups.mapping` 指定的 groups mapping provider(组映射提供程序)实例获得的。查看 entry `spark.user.groups.mapping` 来了解更多细节。 | ### TLS / SSL @@ -407,7 +407,7 @@ showDF(properties, numRows = 200, truncate = FALSE) ### Spark Streaming -| Property Name (属性名称) | Default (默认值) | Meaning (含义) | +| Property Name(属性名称) | Default(默认值) | Meaning(含义) | | --- | --- | --- | | `spark.streaming.backpressure.enabled` | false | 开启或关闭 Spark Streaming 内部的 backpressure mecheanism(自 1.5 开始)。基于当前批次调度延迟和处理时间,这使得 Spark Streaming 能够控制数据的接收率,因此,系统接收数据的速度会和系统处理的速度一样快。从内部来说,这动态地设置了 receivers 的最大接收率。这个速率上限通过 `spark.streaming.receiver.maxRate` 和 `spark.streaming.kafka.maxRatePerPartition` 两个参数设定(如下)。 | | `spark.streaming.backpressure.initialRate` | not set | 当 backpressure mecheanism 开启时,每个 receiver 接受数据的初始最大值。 | @@ -415,7 +415,7 @@ showDF(properties, numRows = 200, truncate = FALSE) | `spark.streaming.receiver.maxRate` | not set | 每秒钟每个 receiver 将接收的数据的最大速率(每秒钟的记录数目)。有效的情况下,每个流每秒将最多消耗这个数目的记录。设置这个配置为 0 或者 -1 将会不作限制。细节参见 Spark Streaming 编程指南的 [deployment guide](streaming-programming-guide.html#deploying-applications) 一节。 | | `spark.streaming.receiver.writeAheadLog.enable` | false | 为 receiver 启用 write ahead logs。所有通过接收器接收输入的数据将被保存到 write ahead logs,以便它在驱动程序故障后进行恢复。见星火流编程指南部署指南了解更多详情。细节参见 Spark Streaming 编程指南的 [deployment guide](streaming-programming-guide.html#deploying-applications) 一节。 | | `spark.streaming.unpersist` | true | 强制通过 Spark Streaming 生成并持久化的 RDD 自动从 Spark 内存中非持久化。通过 Spark Streaming 接收的原始输入数据也将清除。设置这个属性为 false 允许流应用程序访问原始数据和持久化 RDD,因为它们没有被自动清除。但是它会造成更高的内存花费。 | -| `spark.streaming.stopGracefullyOnShutdown` | false | 如果为 `true`,Spark 将 gracefully (缓慢地)关闭在 JVM 运行的 StreamingContext,而非立即执行。 | +| `spark.streaming.stopGracefullyOnShutdown` | false | 如果为 `true`,Spark 将 gracefully(缓慢地)关闭在 JVM 运行的 StreamingContext,而非立即执行。 | | `spark.streaming.kafka.maxRatePerPartition` | not set | 在使用新的 Kafka direct stream API 时,从每个 kafka 分区读到的最大速率(每秒的记录数目)。详见 [Kafka Integration guide](streaming-kafka-integration.html)。 | | `spark.streaming.kafka.maxRetries` | 1 | driver 连续重试的最大次数,以此找到每个分区 leader 的最近的(latest)的偏移量(默认为 1 意味着 driver 将尝试最多两次)。仅应用于新的 kafka direct stream API。 | | `spark.streaming.ui.retainedBatches` | 1000 | 在垃圾回收之前,Spark Streaming UI 和状态API 所能记得的 批处理(batches)数量。 | @@ -424,7 +424,7 @@ showDF(properties, numRows = 200, truncate = FALSE) ### SparkR -| Property Name (属性名称) | Default (默认值) | Meaning (含义) | +| Property Name(属性名称) | Default(默认值) | Meaning(含义) | | --- | --- | --- | | `spark.r.numRBackendThreads` | 2 | 使用 RBackend 处理来自 SparkR 包中的 RPC 调用的线程数。 | | `spark.r.command` | Rscript | 在 driver 和 worker 两种集群模式下可执行的 R 脚本。 | @@ -439,15 +439,15 @@ showDF(properties, numRows = 200, truncate = FALSE) | --- | --- | --- | | `spark.graphx.pregel.checkpointInterval` | -1 | Checkpoint interval for graph and message in Pregel. It used to avoid stackOverflowError due to long lineage chains after lots of iterations. The checkpoint is disabled by default. | -### Deploy (部署) +### Deploy(部署) -| Property Name (属性名称) | Default (默认值) | Meaning (含义) | +| Property Name(属性名称) | Default(默认值) | Meaning(含义) | | --- | --- | --- | | `spark.deploy.recoveryMode` | NONE | 集群模式下,Spark jobs 执行失败或者重启时,恢复提交 Spark jobs 的恢复模式设定。 | | `spark.deploy.zookeeper.url` | None | 当 `spark.deploy.recoveryMode` 被设定为 ZOOKEEPER,这一配置被用来连接 zookeeper URL。 | | `spark.deploy.zookeeper.dir` | None | 当 `spark.deploy.recoveryMode` 被设定为 ZOOKEEPER,这一配置被用来设定 zookeeper 目录为 store recovery state。 | -### Cluster Managers (集群管理器) +### Cluster Managers(集群管理器) Spark 中的每个集群管理器都有额外的配置选项,这些配置可以在每个模式的页面中找到: @@ -457,12 +457,12 @@ Spark 中的每个集群管理器都有额外的配置选项,这些配置可 #### [Standalone Mode](spark-standalone.html#cluster-launch-scripts) -# Environment Variables (环境变量) +# Environment Variables(环境变量) -通过环境变量配置特定的 Spark 设置。环境变量从 Spark 安装目录下的 `conf/spark-env.sh` 脚本读取(或者是 window 环境下的 `conf/spark-env.cmd` )。在 Standalone 和 Mesos 模式下,这个文件可以指定机器的特定信息,比如 hostnames。它也可以为正在运行的 Spark Application 或者提交脚本提供 sourced (来源). +通过环境变量配置特定的 Spark 设置。环境变量从 Spark 安装目录下的 `conf/spark-env.sh` 脚本读取(或者是 window 环境下的 `conf/spark-env.cmd` )。在 Standalone 和 Mesos 模式下,这个文件可以指定机器的特定信息,比如 hostnames。它也可以为正在运行的 Spark Application 或者提交脚本提供 sourced(来源). 注意,当 Spark 被安装,默认情况下 `conf/spark-env.sh` 是不存在的。但是,你可以通过拷贝 `conf/spark-env.sh.template` 来创建它。确保你的拷贝文件时可执行的。`spark-env.sh`:中有有以下变量可以被设置 : -| Environment Variable (环境变量) | Meaning (含义) | +| Environment Variable(环境变量) | Meaning(含义) | | --- | --- | | `JAVA_HOME` | Java 的安装路径(如果不在你的默认 `PATH` 下)。 | | `PYSPARK_PYTHON` | 在 driver 和 worker 中 PySpark 用到的 Python 二进制可执行文件(如何有默认为 `python2.7`,否则为 `python` )。如果设置了属性 `spark.pyspark.python`,则会优先考虑。 | @@ -475,21 +475,21 @@ Spark 中的每个集群管理器都有额外的配置选项,这些配置可 因为 `spark-env.sh` 是 shell 脚本,一些可以通过程序的方式来设置,比如你可以通过特定的网络接口来计算 `SPARK_LOCAL_IP` . -注意:当以 `cluster` mode (集群模式)运行 Spark on YARN 时,环境变量需要通过在您的 `conf/spark-defaults.conf` 文件中 `spark.yarn.appMasterEnv.[EnvironmentVariableName]` 来设定。`cluster` mode (集群模式)下,`spark-env.sh` 中设定的环境变量将不会在 YARN Application Master 过程中反应出来。详见 [YARN-related Spark Properties](running-on-yarn.html#spark-properties). +注意:当以 `cluster` mode(集群模式)运行 Spark on YARN 时,环境变量需要通过在您的 `conf/spark-defaults.conf` 文件中 `spark.yarn.appMasterEnv.[EnvironmentVariableName]` 来设定。`cluster` mode(集群模式)下,`spark-env.sh` 中设定的环境变量将不会在 YARN Application Master 过程中反应出来。详见 [YARN-related Spark Properties](running-on-yarn.html#spark-properties). -# Configuring Logging (配置 Logging) +# Configuring Logging(配置 Logging) Spark 用 [log4j](http://logging.apache.org/log4j/) 生成日志,你可以通过在 `conf` 目录下添加 `log4j.properties` 文件来配置.一种方法是拷贝 `log4j.properties.template` 文件. -# Overriding configuration directory (覆盖配置目录) +# Overriding configuration directory(覆盖配置目录) 如果你想指定不同的配置目录,而不是默认的 “SPARK_HOME/conf”,你可以设置 SPARK_CONF_DIR。Spark 将从这一目录下读取文件( spark-defaults.conf,spark-env.sh,log4j.properties 等) -# Inheriting Hadoop Cluster Configuration (继承 Hadoop 集群配置) +# Inheriting Hadoop Cluster Configuration(继承 Hadoop 集群配置) 如果你想用 Spark 来读写 HDFS,在 Spark 的 classpath 就需要包括两个 Hadoop 配置文件: -* `hdfs-site.xml`,为 HDFS client 提供 default behaviors (默认的行为). +* `hdfs-site.xml`,为 HDFS client 提供 default behaviors(默认的行为). * `core-site.xml`,设定默认的文件系统名称. 这些配置文件的位置因 Hadoop 版本而异,但是一个常见的位置在 `/etc/hadoop/conf` 内。一些工具创建配置 on-the-fly,但提供了一种机制来下载它们的副本. diff --git a/docs/22.md b/docs/22.md index 3e1c220915f96d5e1cdf974f5411ad99eef6cf44..fcd55cc6ba7f37a3a78a138e09764a4029051495 100644 --- a/docs/22.md +++ b/docs/22.md @@ -63,7 +63,7 @@ Spark 中的内存使用大部分属于两类:执行和存储。执行存储 虽然有两种相关配置,但典型用户不需要调整它们,因为默认值适用于大多数工作负载: * `spark.memory.fraction` 表示大小 `M`(JVM堆空间 - 300MB)(默认为0.6)的一小部分。剩余的空间(40%)保留用于用户数据结构,Spark中的内部元数据,并且在稀疏和异常大的记录的情况下保护OOM错误。 -* `spark.memory.storageFraction` 表示大小 `R` 为 `M` (默认为0.5)的一小部分。`R` 是 `M` 缓存块中的缓存被执行驱逐的存储空间。 +* `spark.memory.storageFraction` 表示大小 `R` 为 `M`(默认为0.5)的一小部分。`R` 是 `M` 缓存块中的缓存被执行驱逐的存储空间。 `spark.memory.fraction` 应该设置值,以便在 JVM 的旧版或”终身”版本中舒适地适应这一堆堆空间。有关详细信息,请参阅下面高级 GC 调优的讨论。 diff --git a/docs/27.md b/docs/27.md index a02308afb327aca2c4741f13672847cccd9e4a6e..f78dc8dbac5680cdc8e9eae033bedf69bd9a570e 100644 --- a/docs/27.md +++ b/docs/27.md @@ -99,7 +99,7 @@ Spark 现在与一个独立的 Maven 安装包封装到了一起,以便从位 ## 打包没有 Hadoop 依赖关系的 YARN -默认情况下,由 `mvn package` 生成的 assembly directory (组件目录)将包含所有的Spark 依赖,包括 Hadoop 及其一些生态系统项目。在 YARN 部署中,导致这些的多个版本显示在执行器 classpaths 上: Spark 组件的打包的版本和每个节点上的版本,包含在 `yarn.application.classpath` 中。`hadoop-provided` 配置文件构建了不包括 Hadoop 生态系统项目的组件,就像 ZooKeeper 和 Hadoop 本身。 +默认情况下,由 `mvn package` 生成的 assembly directory(组件目录)将包含所有的Spark 依赖,包括 Hadoop 及其一些生态系统项目。在 YARN 部署中,导致这些的多个版本显示在执行器 classpaths 上: Spark 组件的打包的版本和每个节点上的版本,包含在 `yarn.application.classpath` 中。`hadoop-provided` 配置文件构建了不包括 Hadoop 生态系统项目的组件,就像 ZooKeeper 和 Hadoop 本身。 ## 使用 Mesos 构建 @@ -140,7 +140,7 @@ Spark 现在与一个独立的 Maven 安装包封装到了一起,以便从位 这里应该运行连续编译(即等待更改)。然而这并没有得到广泛的测试。有几个需要注意的事情: -* 它只扫描路径 `src/main` 和 `src/test` (查看 [docs](http://scala-tools.org/mvnsites/maven-scala-plugin/usage_cc.html)),所以其只对含有该结构的某些子模块起作用。 +* 它只扫描路径 `src/main` 和 `src/test`(查看 [docs](http://scala-tools.org/mvnsites/maven-scala-plugin/usage_cc.html)),所以其只对含有该结构的某些子模块起作用。 * 您通常需要在工程的根目录运行 `mvn install` 在编译某些特定子模块时。这是因为依赖于其他子模块的子模块需要通过 `spark-parent` 模块实现。 @@ -164,7 +164,7 @@ Maven 是推荐用于打包 Spark 的官方构建工具,是 _build of referenc ## 加速编译 -经常编译 Spark 的开发人员可能希望加快编译速度; 例如通过使用 Zinc(对于使用 Maven 构建的开发人员)或避免重新编译组件 JAR (对于使用 SBT 构建的开发人员)。有关如何执行此操作的更多信息,请参阅 [有用的开发工具页面](http://spark.apache.org/developer-tools.html#reducing-build-times)。 +经常编译 Spark 的开发人员可能希望加快编译速度; 例如通过使用 Zinc(对于使用 Maven 构建的开发人员)或避免重新编译组件 JAR(对于使用 SBT 构建的开发人员)。有关如何执行此操作的更多信息,请参阅 [有用的开发工具页面](http://spark.apache.org/developer-tools.html#reducing-build-times)。 ## 加密文件系统 @@ -254,7 +254,7 @@ R -e "install.packages(c('knitr', 'rmarkdown', 'testthat', 'e1071', 'survival'), ## 运行基于 Docker 的集成测试套装 -为了运行 Docker 集成测试,你必须在你的 box 上安装 `docker` engine (引擎)。有关安装说明,请参见 [Docker 站点](https://docs.docker.com/engine/installation/)。一旦安装,如果还没有运行 Docker 服务,`docker` service 就需要启动。在 Linux 上,这可以通过 `sudo service docker start` 来完成。 +为了运行 Docker 集成测试,你必须在你的 box 上安装 `docker` engine(引擎)。有关安装说明,请参见 [Docker 站点](https://docs.docker.com/engine/installation/)。一旦安装,如果还没有运行 Docker 服务,`docker` service 就需要启动。在 Linux 上,这可以通过 `sudo service docker start` 来完成。 ``` ./build/mvn install -DskipTests diff --git a/docs/4.md b/docs/4.md index 418b44b10e13c75b66d1e8d74a8636efdf49198f..c7f9ba71dce8a9046f25f8de6a7c636d9a1691fa 100644 --- a/docs/4.md +++ b/docs/4.md @@ -717,7 +717,7 @@ We could also use `counts.sortByKey()`, for example, to sort the pairs alphabeti (Java and Scala) | 将 dataset 中的元素以 Hadoop SequenceFile 的形式写入到本地文件系统、HDFS 或其它 Hadoop 支持的文件系统指定的路径中。该操作可以在实现了 Hadoop 的 Writable 接口的键值对(key-value pairs)的 RDD 上使用。在 Scala 中,它还可以隐式转换为 Writable 的类型(Spark 包括了基本类型的转换,例如 Int,Double,String 等等)。 | **saveAsObjectFile**(_path_) (Java and Scala) | 使用 Java 序列化(serialization)以简单的格式(simple format)编写数据集的元素,然后使用 `SparkContext.objectFile()` 进行加载。 -| **countByKey**() | 仅适用于(K,V)类型的 RDD。返回具有每个 key 的计数的 (K , Int)pairs 的 hashmap。 +| **countByKey**() | 仅适用于(K,V)类型的 RDD。返回具有每个 key 的计数的(K , Int)pairs 的 hashmap。 | **foreach**(_func_) | 对 dataset 中每个元素运行函数 _func_。这通常用于副作用(side effects),例如更新一个 [Accumulator](#accumulators)(累加器)或与外部存储系统(external storage systems)进行交互。**Note**:修改除 `foreach()`之外的累加器以外的变量(variables)可能会导致未定义的行为(undefined behavior)。详细介绍请阅读 [Understanding closures(理解闭包)](#understanding-closures-a-nameclosureslinka) 部分。 该 Spark RDD API 还暴露了一些 actions(操作)的异步版本,例如针对 `foreach` 的 `foreachAsync`,它们会立即返回一个`FutureAction` 到调用者,而不是在完成 action 时阻塞。这可以用于管理或等待 action 的异步执行。. diff --git a/docs/6.md b/docs/6.md index 0fd0e61aec2dbc8b33987ec129fca536e3851a38..b88e1b215f7b59d6a38da3f315a1b07ef2df371a 100644 --- a/docs/6.md +++ b/docs/6.md @@ -15,12 +15,12 @@ * [Checkpointing](#checkpointing) * [Accumulators,Broadcast 变量,和 Checkpoint](#accumulators-broadcast-变量-和-checkpoint) * [应用程序部署](#应用程序部署) - * [Monitoring Applications (监控应用程序)](#monitoring-applications-监控应用程序) -* [Performance Tuning (性能调优)](#performance-tuning-性能调优) - * [Reducing the Batch Processing Times (减少批处理时间)](#reducing-the-batch-processing-times-减少批处理时间) - * [Setting the Right Batch Interval (设置正确的批次间隔)](#setting-the-right-batch-interval-设置正确的批次间隔) - * [Memory Tuning (内存调优)](#memory-tuning-内存调优) -* [Fault-tolerance Semantics (容错语义)](#fault-tolerance-semantics-容错语义) + * [Monitoring Applications(监控应用程序)](#monitoring-applications-监控应用程序) +* [Performance Tuning(性能调优)](#performance-tuning-性能调优) + * [Reducing the Batch Processing Times(减少批处理时间)](#reducing-the-batch-processing-times-减少批处理时间) + * [Setting the Right Batch Interval(设置正确的批次间隔)](#setting-the-right-batch-interval-设置正确的批次间隔) + * [Memory Tuning(内存调优)](#memory-tuning-内存调优) +* [Fault-tolerance Semantics(容错语义)](#fault-tolerance-semantics-容错语义) * [快速链接](#快速链接) # 概述 @@ -499,7 +499,7 @@ Python API 从 Spark 2.2.0 开始,在 Python API 中的 Kafka,Kinesis 和 Fl Python API 在 Python 中还不支持这一功能. -Input DStreams 也可以从自定义数据源中创建。如果您想这样做,需要实现一个用户自定义的 **receiver** (看下一节以了解它是什么),它可以从自定义的 sources(数据源)中接收数据并且推送它到 Spark。更多细节请参阅 [自定义 Receiver 指南](streaming-custom-receivers.html). +Input DStreams 也可以从自定义数据源中创建。如果您想这样做,需要实现一个用户自定义的 **receiver**(看下一节以了解它是什么),它可以从自定义的 sources(数据源)中接收数据并且推送它到 Spark。更多细节请参阅 [自定义 Receiver 指南](streaming-custom-receivers.html). ### Receiver Reliability(接收器的可靠性) @@ -595,7 +595,7 @@ runningCounts = pairs.updateStateByKey(updateFunction) The update function will be called for each word, with `newValues` having a sequence of 1’s (from the `(word, 1)` pairs) and the `runningCount` having the previous count. For the complete Python code, take a look at the example [stateful_network_wordcount.py](https://github.com/apache/spark/blob/v2.2.0/examples/src/main/python/streaming/stateful_network_wordcount.py). -请注意,使用 `updateStateByKey` 需要配置的 `checkpoint` (检查点)的目录,这里是更详细关于讨论 [checkpointing](#checkpointing) 的部分. +请注意,使用 `updateStateByKey` 需要配置的 `checkpoint`(检查点)的目录,这里是更详细关于讨论 [checkpointing](#checkpointing) 的部分. #### Transform Operation(转换操作) @@ -1026,7 +1026,7 @@ words.foreachRDD(process) 请参阅完整的 [源代码](https://github.com/apache/spark/blob/v2.2.0/examples/src/main/python/streaming/sql_network_wordcount.py). -您还可以对来自不同线程的流数据(即异步运行的 StreamingContext )上定义的表运行 SQL 查询。只需确保您将 StreamingContext 设置为记住足够数量的流数据,以便查询可以运行。否则,不知道任何异步 SQL 查询的 StreamingContext 将在查询完成之前删除旧的流数据。例如,如果要查询最后一个批次,但是您的查询可能需要5分钟才能运行,则可以调用 `streamingContext.remember(Minutes(5))` (以 Scala 或其他语言的等价物). +您还可以对来自不同线程的流数据(即异步运行的 StreamingContext )上定义的表运行 SQL 查询。只需确保您将 StreamingContext 设置为记住足够数量的流数据,以便查询可以运行。否则,不知道任何异步 SQL 查询的 StreamingContext 将在查询完成之前删除旧的流数据。例如,如果要查询最后一个批次,但是您的查询可能需要5分钟才能运行,则可以调用 `streamingContext.remember(Minutes(5))`(以 Scala 或其他语言的等价物). 有关DataFrames的更多信息,请参阅 [DataFrames 和 SQL 指南](sql-programming-guide.html). @@ -1344,38 +1344,38 @@ wordCounts.foreachRDD(echo) * * * -## Monitoring Applications (监控应用程序) +## Monitoring Applications(监控应用程序) -除了 Spark 的 [monitoring capabilities(监控功能)](monitoring.html),还有其他功能特定于 Spark Streaming .当使用 StreamingContext 时,[Spark web UI](monitoring.html#web-interfaces) 显示一个额外的 `Streaming` 选项卡,显示 running receivers (运行接收器)的统计信息(无论是 receivers (接收器)是否处于 active (活动状态),接收到的 records (记录)数,receiver error (接收器错误)等)并完成 batches (批次)(batch processing times (批处理时间),queueing delays (排队延迟)等).这可以用来监视 streaming application (流应用程序)的进度. +除了 Spark 的 [monitoring capabilities(监控功能)](monitoring.html),还有其他功能特定于 Spark Streaming .当使用 StreamingContext 时,[Spark web UI](monitoring.html#web-interfaces) 显示一个额外的 `Streaming` 选项卡,显示 running receivers(运行接收器)的统计信息(无论是 receivers(接收器)是否处于 active(活动状态),接收到的 records(记录)数,receiver error(接收器错误)等)并完成 batches(批次)(batch processing times(批处理时间),queueing delays(排队延迟)等).这可以用来监视 streaming application(流应用程序)的进度. -web UI 中的以下两个 metrics (指标)特别重要: +web UI 中的以下两个 metrics(指标)特别重要: -* _Processing Time (处理时间)_ - 处理每 batch (批)数据的时间 . -* _Scheduling Delay (调度延迟)_ - batch (批处理)在 queue (队列)中等待处理 previous batches (以前批次)完成的时间. +* _Processing Time(处理时间)_ - 处理每 batch(批)数据的时间 . +* _Scheduling Delay(调度延迟)_ - batch(批处理)在 queue(队列)中等待处理 previous batches(以前批次)完成的时间. -如果 batch processing time (批处理时间)始终 more than (超过) batch interval (批间隔) and/or queueing delay (排队延迟)不断增加,表示系统是无法快速 process the batches (处理批次),并且正在 falling behind (落后)。在这种情况下,请考虑 [reducing (减少)](#reducing-the-batch-processing-times) batch processing time (批处理时间). +如果 batch processing time(批处理时间)始终 more than(超过) batch interval(批间隔) and/or queueing delay(排队延迟)不断增加,表示系统是无法快速 process the batches(处理批次),并且正在 falling behind(落后)。在这种情况下,请考虑 [reducing(减少)](#reducing-the-batch-processing-times) batch processing time(批处理时间). -Spark Streaming 程序的进展也可以使用 [StreamingListener](api/scala/index.html#org.apache.spark.streaming.scheduler.StreamingListener) 接口,这允许您获得 receiver status (接收器状态)和 processing times (处理时间).请注意,这是一个开发人员 API 并且将来可能会改善(即,更多的信息报告). +Spark Streaming 程序的进展也可以使用 [StreamingListener](api/scala/index.html#org.apache.spark.streaming.scheduler.StreamingListener) 接口,这允许您获得 receiver status(接收器状态)和 processing times(处理时间).请注意,这是一个开发人员 API 并且将来可能会改善(即,更多的信息报告). * * * * * * -# Performance Tuning (性能调优) +# Performance Tuning(性能调优) -在集群上的 Spark Streaming application 中获得最佳性能需要一些调整.本节介绍了可调整的多个 parameters (参数)和 configurations (配置)提高你的应用程序性能.在高层次上,你需要考虑两件事情: +在集群上的 Spark Streaming application 中获得最佳性能需要一些调整.本节介绍了可调整的多个 parameters(参数)和 configurations(配置)提高你的应用程序性能.在高层次上,你需要考虑两件事情: -1. 通过有效利用集群资源,Reducing the processing time of each batch of data (减少每批数据的处理时间). +1. 通过有效利用集群资源,Reducing the processing time of each batch of data(减少每批数据的处理时间). -2. 设置正确的 batch size (批量大小),以便 batches of data (批量的数据)可以像 received (被接收)处理一样快(即 data processing (数据处理)与 data ingestion (数据摄取)保持一致). +2. 设置正确的 batch size(批量大小),以便 batches of data(批量的数据)可以像 received(被接收)处理一样快(即 data processing(数据处理)与 data ingestion(数据摄取)保持一致). -## Reducing the Batch Processing Times (减少批处理时间) +## Reducing the Batch Processing Times(减少批处理时间) -在 Spark 中可以进行一些优化,以 minimize the processing time of each batch (最小化每批处理时间).这些已在 [Tuning Guide (调优指南)](tuning.html) 中详细讨论过.本节突出了一些最重要的. +在 Spark 中可以进行一些优化,以 minimize the processing time of each batch(最小化每批处理时间).这些已在 [Tuning Guide(调优指南)](tuning.html) 中详细讨论过.本节突出了一些最重要的. -### Level of Parallelism in Data Receiving (数据接收中的并行级别) +### Level of Parallelism in Data Receiving(数据接收中的并行级别) -通过网络接收数据(如Kafka,Flume,socket 等)需要 deserialized (反序列化)数据并存储在 Spark 中.如果数据接收成为系统的瓶颈,那么考虑一下 parallelizing the data receiving (并行化数据接收).注意每个 input DStream 创建接收 single stream of data (单个数据流)的 single receiver (单个接收器)(在 work machine 上运行)。因此,可以通过创建多个 input DStreams 来实现 Receiving multiple data streams (接收多个数据流)并配置它们以从 source(s) 接收 data stream (数据流)的 different partitions (不同分区).例如,接收 two topics of data (两个数据主题)的单个Kafka input DStream 可以分为两个 Kafka input streams (输入流),每个只接收一个 topic (主题).这将运行两个 receivers (接收器),允许 in parallel (并行)接收数据,从而提高 overall throughput (总体吞吐量).这些 multiple DStreams 可以 unioned (联合起来)创建一个 single DStream .然后 transformations (转化)为应用于 single input DStream 可以应用于 unified stream .如下这样做. +通过网络接收数据(如Kafka,Flume,socket 等)需要 deserialized(反序列化)数据并存储在 Spark 中.如果数据接收成为系统的瓶颈,那么考虑一下 parallelizing the data receiving(并行化数据接收).注意每个 input DStream 创建接收 single stream of data(单个数据流)的 single receiver(单个接收器)(在 work machine 上运行)。因此,可以通过创建多个 input DStreams 来实现 Receiving multiple data streams(接收多个数据流)并配置它们以从 source(s) 接收 data stream(数据流)的 different partitions(不同分区).例如,接收 two topics of data(两个数据主题)的单个Kafka input DStream 可以分为两个 Kafka input streams(输入流),每个只接收一个 topic(主题).这将运行两个 receivers(接收器),允许 in parallel(并行)接收数据,从而提高 overall throughput(总体吞吐量).这些 multiple DStreams 可以 unioned(联合起来)创建一个 single DStream .然后 transformations(转化)为应用于 single input DStream 可以应用于 unified stream .如下这样做. ``` val numStreams = 5 @@ -1401,65 +1401,65 @@ unifiedStream = streamingContext.union(*kafkaStreams) unifiedStream.pprint() ``` -应考虑的另一个参数是 receiver’s block interval (接收器的块间隔),这由[configuration parameter (配置参数)](configuration.html#spark-streaming) 的 `spark.streaming.blockInterval` 决定.对于大多数 receivers (接收器),接收到的数据 coalesced (合并)在一起存储在 Spark 内存之前的 blocks of data (数据块).每个 batch (批次)中的 blocks (块)数确定将用于处理接收到的数据以 map-like (类似与 map 形式的) transformation (转换)的 task (任务)的数量.每个 receiver (接收器)每 batch (批次)的任务数量将是大约( batch interval (批间隔)/ block interval (块间隔)).例如,200 ms的 block interval (块间隔)每 2 秒 batches (批次)创建 10 个 tasks (任务).如果 tasks (任务)数量太少(即少于每个机器的内核数量),那么它将无效,因为所有可用的内核都不会被使用处理数据.要增加 given batch interval (给定批间隔)的 tasks (任务)数量,请减少 block interval (块间​​隔).但是,推荐的 block interval (块间隔)最小值约为 50ms,低于此任务启动开销可能是一个问题. +应考虑的另一个参数是 receiver’s block interval(接收器的块间隔),这由[configuration parameter(配置参数)](configuration.html#spark-streaming) 的 `spark.streaming.blockInterval` 决定.对于大多数 receivers(接收器),接收到的数据 coalesced(合并)在一起存储在 Spark 内存之前的 blocks of data(数据块).每个 batch(批次)中的 blocks(块)数确定将用于处理接收到的数据以 map-like(类似与 map 形式的) transformation(转换)的 task(任务)的数量.每个 receiver(接收器)每 batch(批次)的任务数量将是大约( batch interval(批间隔)/ block interval(块间隔)).例如,200 ms的 block interval(块间隔)每 2 秒 batches(批次)创建 10 个 tasks(任务).如果 tasks(任务)数量太少(即少于每个机器的内核数量),那么它将无效,因为所有可用的内核都不会被使用处理数据.要增加 given batch interval(给定批间隔)的 tasks(任务)数量,请减少 block interval(块间​​隔).但是,推荐的 block interval(块间隔)最小值约为 50ms,低于此任务启动开销可能是一个问题. -使用 multiple input streams (多个输入流)/ receivers (接收器)接收数据的替代方法是明确 repartition (重新分配) input data stream (输入数据流)(使用 `inputStream.repartition(<number of partitions>)` )。这会在 further processing (进一步处理)之前将 received batches of data (收到的批次数据) distributes (分发)到集群中指定数量的计算机. +使用 multiple input streams(多个输入流)/ receivers(接收器)接收数据的替代方法是明确 repartition(重新分配) input data stream(输入数据流)(使用 `inputStream.repartition(<number of partitions>)` )。这会在 further processing(进一步处理)之前将 received batches of data(收到的批次数据) distributes(分发)到集群中指定数量的计算机. -### Level of Parallelism in Data Processing (数据处理中的并行度水平) +### Level of Parallelism in Data Processing(数据处理中的并行度水平) -如果在任何 computation (计算)阶段中使用 number of parallel tasks (并行任务的数量),则 Cluster resources (集群资源)可能未得到充分利用。例如,对于 distributed reduce (分布式 reduce)操作,如 `reduceByKey` 和 `reduceByKeyAndWindow`,默认并行任务的数量由 `spark.default.parallelism` [configuration property](configuration.html#spark-properties) 控制。您 可以通过 parallelism (并行度)作为参数(见 [`PairDStreamFunctions`](api/scala/index.html#org.apache.spark.streaming.dstream.PairDStreamFunctions) 文档 ),或设置 `spark.default.parallelism` [configuration property](configuration.html#spark-properties) 更改默认值. +如果在任何 computation(计算)阶段中使用 number of parallel tasks(并行任务的数量),则 Cluster resources(集群资源)可能未得到充分利用。例如,对于 distributed reduce(分布式 reduce)操作,如 `reduceByKey` 和 `reduceByKeyAndWindow`,默认并行任务的数量由 `spark.default.parallelism` [configuration property](configuration.html#spark-properties) 控制。您 可以通过 parallelism(并行度)作为参数(见 [`PairDStreamFunctions`](api/scala/index.html#org.apache.spark.streaming.dstream.PairDStreamFunctions) 文档 ),或设置 `spark.default.parallelism` [configuration property](configuration.html#spark-properties) 更改默认值. -### Data Serialization (数据序列化) +### Data Serialization(数据序列化) -可以通过调优 serialization formats (序列化格式)来减少数据 serialization (序列化)的开销.在 streaming 的情况下,有两种类型的数据被 serialized (序列化). +可以通过调优 serialization formats(序列化格式)来减少数据 serialization(序列化)的开销.在 streaming 的情况下,有两种类型的数据被 serialized(序列化). -* **Input data (输入数据)**:默认情况下,通过 Receivers 接收的 input data (输入数据)通过 [StorageLevel.MEMORY_AND_DISK_SER_2](api/scala/index.html#org.apache.spark.storage.StorageLevel$) 存储在 executors 的内存中.也就是说,将数据 serialized (序列化)为 bytes (字节)以减少 GC 开销,并复制以容忍 executor failures (执行器故障).此外,数据首先保留在内存中,并且只有在内存不足以容纳 streaming computation (流计算)所需的所有输入数据时才会 spilled over (溢出)到磁盘.这个 serialization (序列化)显然具有开销 - receiver (接收器)必须使接收的数据 deserialize (反序列化),并使用 Spark 的 serialization format (序列化格式)重新序列化它. +* **Input data(输入数据)**:默认情况下,通过 Receivers 接收的 input data(输入数据)通过 [StorageLevel.MEMORY_AND_DISK_SER_2](api/scala/index.html#org.apache.spark.storage.StorageLevel$) 存储在 executors 的内存中.也就是说,将数据 serialized(序列化)为 bytes(字节)以减少 GC 开销,并复制以容忍 executor failures(执行器故障).此外,数据首先保留在内存中,并且只有在内存不足以容纳 streaming computation(流计算)所需的所有输入数据时才会 spilled over(溢出)到磁盘.这个 serialization(序列化)显然具有开销 - receiver(接收器)必须使接收的数据 deserialize(反序列化),并使用 Spark 的 serialization format(序列化格式)重新序列化它. -* **Persisted RDDs generated by Streaming Operations (流式操作生成的持久 RDDs)**:通过 streaming computations (流式计算)生成的 RDD 可能会持久存储在内存中.例如,window operations (窗口操作)会将数据保留在内存中,因为它们将被处理多次.但是,与 [StorageLevel.MEMORY_ONLY](api/scala/index.html#org.apache.spark.storage.StorageLevel$) 的 Spark Core 默认情况不同,通过流式计算生成的持久化 RDD 将以 [StorageLevel.MEMORY_ONLY_SER](api/scala/index.html#org.apache.spark.storage.StorageLevel$) (即序列化),以最小化 GC 开销. +* **Persisted RDDs generated by Streaming Operations(流式操作生成的持久 RDDs)**:通过 streaming computations(流式计算)生成的 RDD 可能会持久存储在内存中.例如,window operations(窗口操作)会将数据保留在内存中,因为它们将被处理多次.但是,与 [StorageLevel.MEMORY_ONLY](api/scala/index.html#org.apache.spark.storage.StorageLevel$) 的 Spark Core 默认情况不同,通过流式计算生成的持久化 RDD 将以 [StorageLevel.MEMORY_ONLY_SER](api/scala/index.html#org.apache.spark.storage.StorageLevel$)(即序列化),以最小化 GC 开销. -在这两种情况下,使用 Kryo serialization (Kryo 序列化)可以减少 CPU 和内存开销.有关详细信息,请参阅 [Spark Tuning Guide](tuning.html#data-serialization) .对于 Kryo,请考虑 registering custom classes,并禁用对象引用跟踪(请参阅 [Configuration Guide](configuration.html#compression-and-serialization) 中的 Kryo 相关配置). +在这两种情况下,使用 Kryo serialization(Kryo 序列化)可以减少 CPU 和内存开销.有关详细信息,请参阅 [Spark Tuning Guide](tuning.html#data-serialization) .对于 Kryo,请考虑 registering custom classes,并禁用对象引用跟踪(请参阅 [Configuration Guide](configuration.html#compression-and-serialization) 中的 Kryo 相关配置). -在 streaming application 需要保留的数据量不大的特定情况下,可以将数据(两种类型)作为 deserialized objects (反序列化对象)持久化,而不会导致过多的 GC 开销.例如,如果您使用几秒钟的 batch intervals (批次间隔)并且没有 window operations (窗口操作),那么可以通过明确地相应地设置 storage level (存储级别)来尝试禁用 serialization in persisted data (持久化数据中的序列化).这将减少由于序列化造成的 CPU 开销,潜在地提高性能,而不需要太多的 GC 开销. +在 streaming application 需要保留的数据量不大的特定情况下,可以将数据(两种类型)作为 deserialized objects(反序列化对象)持久化,而不会导致过多的 GC 开销.例如,如果您使用几秒钟的 batch intervals(批次间隔)并且没有 window operations(窗口操作),那么可以通过明确地相应地设置 storage level(存储级别)来尝试禁用 serialization in persisted data(持久化数据中的序列化).这将减少由于序列化造成的 CPU 开销,潜在地提高性能,而不需要太多的 GC 开销. -### Task Launching Overheads (任务启动开销) +### Task Launching Overheads(任务启动开销) -如果每秒启动的任务数量很高(比如每秒 50 个或更多),那么这个开销向 slaves 发送任务可能是重要的,并且将难以实现 sub-second latencies (次要的延迟).可以通过以下更改减少开销: +如果每秒启动的任务数量很高(比如每秒 50 个或更多),那么这个开销向 slaves 发送任务可能是重要的,并且将难以实现 sub-second latencies(次要的延迟).可以通过以下更改减少开销: -* **Execution mode (执行模式)**:以 Standalone mode (独立模式)或 coarse-grained Mesos 模式运行 Spark 比 fine-grained Mesos 模式更好的任务启动时间.有关详细信息,请参阅 [Running on Mesos guide](running-on-mesos.html) . +* **Execution mode(执行模式)**:以 Standalone mode(独立模式)或 coarse-grained Mesos 模式运行 Spark 比 fine-grained Mesos 模式更好的任务启动时间.有关详细信息,请参阅 [Running on Mesos guide](running-on-mesos.html) . -这些更改可能会将 batch processing time (批处理时间)缩短 100 毫秒,从而允许 sub-second batch size (次秒批次大小)是可行的. +这些更改可能会将 batch processing time(批处理时间)缩短 100 毫秒,从而允许 sub-second batch size(次秒批次大小)是可行的. * * * -## Setting the Right Batch Interval (设置正确的批次间隔) +## Setting the Right Batch Interval(设置正确的批次间隔) -对于在集群上稳定地运行的 Spark Streaming application,该系统应该能够处理数据尽可能快地被接收.换句话说,应该处理批次的数据就像生成它们一样快.这是否适用于 application 可以在 [monitoring](#monitoring-applications) streaming web UI 中的 processing times 中被找到,processing time (批处理处理时间)应小于 batch interval (批间隔). +对于在集群上稳定地运行的 Spark Streaming application,该系统应该能够处理数据尽可能快地被接收.换句话说,应该处理批次的数据就像生成它们一样快.这是否适用于 application 可以在 [monitoring](#monitoring-applications) streaming web UI 中的 processing times 中被找到,processing time(批处理处理时间)应小于 batch interval(批间隔). -取决于 streaming computation (流式计算)的性质,使用的 batch interval (批次间隔)可能对处理由应用程序持续一组固定的 cluster resources (集群资源)的数据速率有重大的影响.例如,让我们考虑早期的 WordCountNetwork 示例.对于特定的 data rate (数据速率),系统可能能够跟踪每 2 秒报告 word counts (即 2 秒的 batch interval (批次间隔)),但不能每 500 毫秒.因此,需要设置 batch interval (批次间隔),使预期的数据速率在生产可以持续. +取决于 streaming computation(流式计算)的性质,使用的 batch interval(批次间隔)可能对处理由应用程序持续一组固定的 cluster resources(集群资源)的数据速率有重大的影响.例如,让我们考虑早期的 WordCountNetwork 示例.对于特定的 data rate(数据速率),系统可能能够跟踪每 2 秒报告 word counts(即 2 秒的 batch interval(批次间隔)),但不能每 500 毫秒.因此,需要设置 batch interval(批次间隔),使预期的数据速率在生产可以持续. -为您的应用程序找出正确的 batch size (批量大小)的一个好方法是使用进行测试 conservative batch interval (保守的批次间隔)(例如 5-10 秒)和 low data rate (低数据速率).验证是否系统能够跟上 data rate (数据速率),可以检查遇到的 end-to-end delay (端到端延迟)的值通过每个 processed batch (处理的批次)(在 Spark driver log4j 日志中查找 “Total delay”,或使用 [StreamingListener](api/scala/index.html#org.apache.spark.streaming.scheduler.StreamingListener) 接口)。如果 delay (延迟)保持与 batch size (批量大小)相当,那么系统是稳定的.除此以外,如果延迟不断增加,则意味着系统无法跟上,因此不稳定.一旦你有一个 stable configuration (稳定的配置)的想法,你可以尝试增加 data rate and/or 减少 batch size .请注意,momentary increase (瞬时增加)由于延迟暂时增加只要延迟降低到 low value (低值),临时数据速率增加就可以很好(即,小于 batch size (批量大小)). +为您的应用程序找出正确的 batch size(批量大小)的一个好方法是使用进行测试 conservative batch interval(保守的批次间隔)(例如 5-10 秒)和 low data rate(低数据速率).验证是否系统能够跟上 data rate(数据速率),可以检查遇到的 end-to-end delay(端到端延迟)的值通过每个 processed batch(处理的批次)(在 Spark driver log4j 日志中查找 “Total delay”,或使用 [StreamingListener](api/scala/index.html#org.apache.spark.streaming.scheduler.StreamingListener) 接口)。如果 delay(延迟)保持与 batch size(批量大小)相当,那么系统是稳定的.除此以外,如果延迟不断增加,则意味着系统无法跟上,因此不稳定.一旦你有一个 stable configuration(稳定的配置)的想法,你可以尝试增加 data rate and/or 减少 batch size .请注意,momentary increase(瞬时增加)由于延迟暂时增加只要延迟降低到 low value(低值),临时数据速率增加就可以很好(即,小于 batch size(批量大小)). * * * -## Memory Tuning (内存调优) +## Memory Tuning(内存调优) -调整 Spark 应用程序的内存使用情况和 GC behavior 已经有很多的讨论在 [Tuning Guide](tuning.html#memory-tuning) 中.我们强烈建议您阅读一下.在本节中,我们将在 Spark Streaming applications 的上下文中讨论一些 tuning parameters (调优参数). +调整 Spark 应用程序的内存使用情况和 GC behavior 已经有很多的讨论在 [Tuning Guide](tuning.html#memory-tuning) 中.我们强烈建议您阅读一下.在本节中,我们将在 Spark Streaming applications 的上下文中讨论一些 tuning parameters(调优参数). -Spark Streaming application 所需的集群内存量在很大程度上取决于所使用的 transformations 类型.例如,如果要在最近 10 分钟的数据中使用 window operation (窗口操作),那么您的集群应该有足够的内存来容纳内存中 10 分钟的数据.或者如果要使用大量 keys 的 `updateStateByKey`,那么必要的内存将会很高.相反,如果你想做一个简单的 map-filter-store 操作,那么所需的内存就会很低. +Spark Streaming application 所需的集群内存量在很大程度上取决于所使用的 transformations 类型.例如,如果要在最近 10 分钟的数据中使用 window operation(窗口操作),那么您的集群应该有足够的内存来容纳内存中 10 分钟的数据.或者如果要使用大量 keys 的 `updateStateByKey`,那么必要的内存将会很高.相反,如果你想做一个简单的 map-filter-store 操作,那么所需的内存就会很低. -一般来说,由于通过 receivers (接收器)接收的数据与 StorageLevel.MEMORY_AND_DISK_SER_2 一起存储,所以不适合内存的数据将会 spill over (溢出)到磁盘上.这可能会降低 streaming application (流式应用程序)的性能,因此建议您提供足够的 streaming application (流量应用程序)所需的内存.最好仔细查看内存使用量并相应地进行估算. +一般来说,由于通过 receivers(接收器)接收的数据与 StorageLevel.MEMORY_AND_DISK_SER_2 一起存储,所以不适合内存的数据将会 spill over(溢出)到磁盘上.这可能会降低 streaming application(流式应用程序)的性能,因此建议您提供足够的 streaming application(流量应用程序)所需的内存.最好仔细查看内存使用量并相应地进行估算. -memory tuning (内存调优)的另一个方面是 garbage collection (垃圾收集).对于需要低延迟的 streaming application,由 JVM Garbage Collection 引起的大量暂停是不希望的. +memory tuning(内存调优)的另一个方面是 garbage collection(垃圾收集).对于需要低延迟的 streaming application,由 JVM Garbage Collection 引起的大量暂停是不希望的. -有几个 parameters (参数)可以帮助您调整 memory usage (内存使用量)和 GC 开销: +有几个 parameters(参数)可以帮助您调整 memory usage(内存使用量)和 GC 开销: -* **Persistence Level of DStreams (DStreams 的持久性级别)**:如前面在 [Data Serialization](#data-serialization) 部分中所述,input data 和 RDD 默认保持为 serialized bytes (序列化字节).与 deserialized persistence (反序列化持久性)相比,这减少了内存使用量和 GC 开销.启用 Kryo serialization 进一步减少了 serialized sizes (序列化大小)和 memory usage (内存使用).可以通过 compression (压缩)来实现内存使用的进一步减少(参见Spark配置 `spark.rdd.compress` ),代价是 CPU 时间. +* **Persistence Level of DStreams(DStreams 的持久性级别)**:如前面在 [Data Serialization](#data-serialization) 部分中所述,input data 和 RDD 默认保持为 serialized bytes(序列化字节).与 deserialized persistence(反序列化持久性)相比,这减少了内存使用量和 GC 开销.启用 Kryo serialization 进一步减少了 serialized sizes(序列化大小)和 memory usage(内存使用).可以通过 compression(压缩)来实现内存使用的进一步减少(参见Spark配置 `spark.rdd.compress` ),代价是 CPU 时间. -* **Clearing old data (清除旧数据)**:默认情况下,DStream 转换生成的所有 input data 和 persisted RDDs 将自动清除。Spark Streaming 决定何时根据所使用的 transformations (转换)来清除数据.例如,如果您使用 10 分钟的 window operation (窗口操作),则 Spark Streaming 将保留最近 10 分钟的数据,并主动丢弃旧数据。数据可以通过设置 `streamingContext.remember` 保持更长的持续时间(例如交互式查询旧数据). +* **Clearing old data(清除旧数据)**:默认情况下,DStream 转换生成的所有 input data 和 persisted RDDs 将自动清除。Spark Streaming 决定何时根据所使用的 transformations(转换)来清除数据.例如,如果您使用 10 分钟的 window operation(窗口操作),则 Spark Streaming 将保留最近 10 分钟的数据,并主动丢弃旧数据。数据可以通过设置 `streamingContext.remember` 保持更长的持续时间(例如交互式查询旧数据). -* **CMS Garbage Collector (CMS垃圾收集器)**:强烈建议使用 concurrent mark-and-sweep GC,以保持 GC 相关的暂停始终如一.即使 concurrent GC 已知可以减少 系统的整体处理吞吐量,其使用仍然建议实现更多一致的 batch processing times (批处理时间).确保在 driver (使用 `--driver-java-options` 在 `spark-submit` 中 )和 executors (使用 [Spark configuration](configuration.html#runtime-environment) `spark.executor.extraJavaOptions` )中设置 CMS GC. +* **CMS Garbage Collector(CMS垃圾收集器)**:强烈建议使用 concurrent mark-and-sweep GC,以保持 GC 相关的暂停始终如一.即使 concurrent GC 已知可以减少 系统的整体处理吞吐量,其使用仍然建议实现更多一致的 batch processing times(批处理时间).确保在 driver(使用 `--driver-java-options` 在 `spark-submit` 中 )和 executors(使用 [Spark configuration](configuration.html#runtime-environment) `spark.executor.extraJavaOptions` )中设置 CMS GC. -* **Other tips (其他提示)**:为了进一步降低 GC 开销,以下是一些更多的提示. +* **Other tips(其他提示)**:为了进一步降低 GC 开销,以下是一些更多的提示. * 使用 `OFF_HEAP` 存储级别的保持 RDDs .在 [Spark Programming Guide](programming-guide.html#rdd-persistence) 中查看更多详细信息. * 使用更小的 heap sizes 的 executors.这将降低每个 JVM heap 内的 GC 压力. @@ -1468,115 +1468,115 @@ memory tuning (内存调优)的另一个方面是 garbage collection (垃 ##### Important points to remember(要记住的要点): -* DStream 与 single receiver (单个接收器)相关联.为了获得读取并行性,需要创建多个 receivers,即 multiple DStreams .receiver 在一个 executor 中运行.它占据一个 core (内核).确保在 receiver slots are booked 后有足够的内核进行处理,即 `spark.cores.max` 应该考虑 receiver slots。receivers 以循环方式分配给 executors . +* DStream 与 single receiver(单个接收器)相关联.为了获得读取并行性,需要创建多个 receivers,即 multiple DStreams .receiver 在一个 executor 中运行.它占据一个 core(内核).确保在 receiver slots are booked 后有足够的内核进行处理,即 `spark.cores.max` 应该考虑 receiver slots。receivers 以循环方式分配给 executors . -* 当从 stream source 接收到数据时,receiver 创建数据 blocks (块).每个 blockInterval 毫秒生成一个新的数据块.在 N = batchInterval/blockInterval 的 batchInterval 期间创建 N 个数据块.这些块由当前 executor 的 BlockManager 分发给其他执行程序的 block managers .之后,在驱动程序上运行的 Network Input Tracker (网络输入跟踪器)通知有关进一步处理的块位置 +* 当从 stream source 接收到数据时,receiver 创建数据 blocks(块).每个 blockInterval 毫秒生成一个新的数据块.在 N = batchInterval/blockInterval 的 batchInterval 期间创建 N 个数据块.这些块由当前 executor 的 BlockManager 分发给其他执行程序的 block managers .之后,在驱动程序上运行的 Network Input Tracker(网络输入跟踪器)通知有关进一步处理的块位置 -* 在驱动程序中为在 batchInterval 期间创建的块创建一个 RDD .在 batchInterval 期间生成的块是 RDD 的 partitions .每个分区都是一个 spark 中的 task。blockInterval == batchinterval 意味着创建 single partition (单个分区),并且可能在本地进行处理. +* 在驱动程序中为在 batchInterval 期间创建的块创建一个 RDD .在 batchInterval 期间生成的块是 RDD 的 partitions .每个分区都是一个 spark 中的 task。blockInterval == batchinterval 意味着创建 single partition(单个分区),并且可能在本地进行处理. -* 除非 non-local scheduling (非本地调度)进行,否则块上的 map tasks (映射任务)将在 executors (接收 block,复制块的另一个块)中进行处理.具有更大的 block interval (块间隔)意味着更大的块。`spark.locality.wait` 的高值增加了处理 local node (本地节点)上的块的机会.需要在这两个参数之间找到平衡,以确保在本地处理较大的块. +* 除非 non-local scheduling(非本地调度)进行,否则块上的 map tasks(映射任务)将在 executors(接收 block,复制块的另一个块)中进行处理.具有更大的 block interval(块间隔)意味着更大的块。`spark.locality.wait` 的高值增加了处理 local node(本地节点)上的块的机会.需要在这两个参数之间找到平衡,以确保在本地处理较大的块. -* 而不是依赖于 batchInterval 和 blockInterval,您可以通过调用 `inputDstream.repartition(n)` 来定义 number of partitions (分区数).这样可以随机重新组合 RDD 中的数据,创建 n 个分区.是的,为了更大的 parallelism (并行性).虽然是 shuffle 的代价。RDD 的处理由 driver’s jobscheduler 作为一项工作安排.在给定的时间点,只有一个 job 是 active 的.因此,如果一个作业正在执行,则其他作业将排队. +* 而不是依赖于 batchInterval 和 blockInterval,您可以通过调用 `inputDstream.repartition(n)` 来定义 number of partitions(分区数).这样可以随机重新组合 RDD 中的数据,创建 n 个分区.是的,为了更大的 parallelism(并行性).虽然是 shuffle 的代价。RDD 的处理由 driver’s jobscheduler 作为一项工作安排.在给定的时间点,只有一个 job 是 active 的.因此,如果一个作业正在执行,则其他作业将排队. -* 如果您有两个 dstream,将会有两个 RDD 形成,并且将创建两个将被安排在另一个之后的作业.为了避免这种情况,你可以联合两个 dstream .这将确保为 dstream 的两个 RDD 形成一个 unionRDD .这个 unionRDD 然后被认为是一个 single job (单一的工作).但 RDD 的 partitioning (分区)不受影响. +* 如果您有两个 dstream,将会有两个 RDD 形成,并且将创建两个将被安排在另一个之后的作业.为了避免这种情况,你可以联合两个 dstream .这将确保为 dstream 的两个 RDD 形成一个 unionRDD .这个 unionRDD 然后被认为是一个 single job(单一的工作).但 RDD 的 partitioning(分区)不受影响. -* 如果 batch processing time (批处理时间)超过 batchinterval (批次间隔),那么显然 receiver 的内存将会开始填满,最终会抛出 exceptions (最可能是 BlockNotFoundException ).目前没有办法暂停 receiver .使用 SparkConf 配置 `spark.streaming.receiver.maxRate`,receiver 的 rate 可以受到限制. +* 如果 batch processing time(批处理时间)超过 batchinterval(批次间隔),那么显然 receiver 的内存将会开始填满,最终会抛出 exceptions(最可能是 BlockNotFoundException ).目前没有办法暂停 receiver .使用 SparkConf 配置 `spark.streaming.receiver.maxRate`,receiver 的 rate 可以受到限制. * * * * * * -# Fault-tolerance Semantics (容错语义) +# Fault-tolerance Semantics(容错语义) 在本节中,我们将讨论 Spark Streaming applications 在该 event 中的行为的失败. ## Background(背景) -要了解 Spark Streaming 提供的语义,请记住 Spark 的 RDD 的基本 fault-tolerance semantics (容错语义). +要了解 Spark Streaming 提供的语义,请记住 Spark 的 RDD 的基本 fault-tolerance semantics(容错语义). 1. RDD 是一个不可变的,确定性地可重新计算的分布式数据集.每个RDD 记住在容错输入中使用的确定性操作的 lineage 数据集创建它. -2. 如果 RDD 的任何 partition 由于工作节点故障而丢失,则该分区可以是 从 original fault-tolerant dataset (原始容错数据集)中使用业务流程重新计算. +2. 如果 RDD 的任何 partition 由于工作节点故障而丢失,则该分区可以是 从 original fault-tolerant dataset(原始容错数据集)中使用业务流程重新计算. 3. 假设所有的 RDD transformations 都是确定性的,最后的数据被转换,无论 Spark 集群中的故障如何,RDD 始终是一样的. -Spark 运行在容错文件系统(如 HDFS 或 S3 )中的数据上.因此,从容错数据生成的所有 RDD 也都是容错的.但是,这不是在大多数情况下,Spark Streaming 作为数据的情况通过网络接收(除非 `fileStream` 被使用).为了为所有生成的 RDD 实现相同的 fault-tolerance properties (容错属性),接收的数据在集群中的工作节点中的多个 Spark executors 之间进行复制(默认 replication factor (备份因子)为 2).这导致了发生故障时需要恢复的系统中的两种数据: +Spark 运行在容错文件系统(如 HDFS 或 S3 )中的数据上.因此,从容错数据生成的所有 RDD 也都是容错的.但是,这不是在大多数情况下,Spark Streaming 作为数据的情况通过网络接收(除非 `fileStream` 被使用).为了为所有生成的 RDD 实现相同的 fault-tolerance properties(容错属性),接收的数据在集群中的工作节点中的多个 Spark executors 之间进行复制(默认 replication factor(备份因子)为 2).这导致了发生故障时需要恢复的系统中的两种数据: -1. _Data received and replicated (数据接收和复制)_ - 这个数据在单个工作节点作为副本的故障中幸存下来,它存在于其他节点之一上. -2. _Data received but buffered for replication (接收数据但缓冲进行复制)_ - 由于不复制,恢复此数据的唯一方法是从 source 重新获取. +1. _Data received and replicated(数据接收和复制)_ - 这个数据在单个工作节点作为副本的故障中幸存下来,它存在于其他节点之一上. +2. _Data received but buffered for replication(接收数据但缓冲进行复制)_ - 由于不复制,恢复此数据的唯一方法是从 source 重新获取. 此外,我们应该关注的有两种 failures: -1. _Failure of a Worker Node (工作节点的故障)_ - 运行 executors 的任何工作节点都可能会故障,并且这些节点上的所有内存中数据将丢失.如果任何 receivers 运行在失败节点,则它们的 buffered (缓冲)数据将丢失. -2. _Failure of the Driver Node (Driver 节点的故障)_ - 如果运行 Spark Streaming application 的 driver node 发生了故障,那么显然 SparkContext 丢失了,所有的 executors 和其内存中的数据也一起丢失了. +1. _Failure of a Worker Node(工作节点的故障)_ - 运行 executors 的任何工作节点都可能会故障,并且这些节点上的所有内存中数据将丢失.如果任何 receivers 运行在失败节点,则它们的 buffered(缓冲)数据将丢失. +2. _Failure of the Driver Node(Driver 节点的故障)_ - 如果运行 Spark Streaming application 的 driver node 发生了故障,那么显然 SparkContext 丢失了,所有的 executors 和其内存中的数据也一起丢失了. -有了这个基础知识,让我们了解 Spark Streaming 的 fault-tolerance semantics (容错语义). +有了这个基础知识,让我们了解 Spark Streaming 的 fault-tolerance semantics(容错语义). -## Definitions (定义) +## Definitions(定义) -streaming systems (流系统)的语义通常是通过系统可以处理每个记录的次数来捕获的.系统可以在所有可能的操作条件下提供三种类型的保证(尽管有故障等). +streaming systems(流系统)的语义通常是通过系统可以处理每个记录的次数来捕获的.系统可以在所有可能的操作条件下提供三种类型的保证(尽管有故障等). -1. _At most once (最多一次)_:每个 record (记录)将被处理一次或根本不处理. -2. _At least once (至少一次)_:每个 record (记录)将被处理一次或多次.这比_at-most once_,因为它确保没有数据将丢失.但可能有重复. -3. _Exactly once(有且仅一次)_:每个 record (记录) 将被精确处理一次 - 没有数据丢失,数据不会被多次处理.这显然是三者的最强保证. +1. _At most once(最多一次)_:每个 record(记录)将被处理一次或根本不处理. +2. _At least once(至少一次)_:每个 record(记录)将被处理一次或多次.这比_at-most once_,因为它确保没有数据将丢失.但可能有重复. +3. _Exactly once(有且仅一次)_:每个 record(记录) 将被精确处理一次 - 没有数据丢失,数据不会被多次处理.这显然是三者的最强保证. -## Basic Semantics (基本语义) +## Basic Semantics(基本语义) -在任何 stream processing system (流处理系统)中,广义上说,处理数据有三个步骤. +在任何 stream processing system(流处理系统)中,广义上说,处理数据有三个步骤. -1. _Receiving the data (接收数据)_:使用 Receivers 或其他方式从数据源接收数据. +1. _Receiving the data(接收数据)_:使用 Receivers 或其他方式从数据源接收数据. -2. _Transforming the data (转换数据)_:使用 DStream 和 RDD transformations 来 transformed (转换)接收到的数据. +2. _Transforming the data(转换数据)_:使用 DStream 和 RDD transformations 来 transformed(转换)接收到的数据. -3. _Pushing out the data (推出数据)_:最终的转换数据被推出到 external systems (外部系统),如 file systems (文件系统),databases (数据库),dashboards (仪表板)等. +3. _Pushing out the data(推出数据)_:最终的转换数据被推出到 external systems(外部系统),如 file systems(文件系统),databases(数据库),dashboards(仪表板)等. -如果 streaming application 必须实现 end-to-end exactly-once guarantees (端到端的一次且仅一次性保证),那么每个步骤都必须提供 exactly-once guarantee .也就是说,每个记录必须被精确地接收一次,转换完成一次,并被推送到下游系统一次.让我们在 Spark Streaming 的上下文中了解这些步骤的语义. +如果 streaming application 必须实现 end-to-end exactly-once guarantees(端到端的一次且仅一次性保证),那么每个步骤都必须提供 exactly-once guarantee .也就是说,每个记录必须被精确地接收一次,转换完成一次,并被推送到下游系统一次.让我们在 Spark Streaming 的上下文中了解这些步骤的语义. -1. _Receiving the data (接收数据)_:不同的 input sources 提供不同的保证.这将在下一小节中详细讨论. +1. _Receiving the data(接收数据)_:不同的 input sources 提供不同的保证.这将在下一小节中详细讨论. -2. _Transforming the data (转换数据)_:所有已收到的数据都将被处理 _exactly once_,这得益于 RDD 提供的保证.即使存在故障,只要接收到的输入数据可访问,最终变换的 RDD 将始终具有相同的内容. +2. _Transforming the data(转换数据)_:所有已收到的数据都将被处理 _exactly once_,这得益于 RDD 提供的保证.即使存在故障,只要接收到的输入数据可访问,最终变换的 RDD 将始终具有相同的内容. -3. _Pushing out the data (推出数据)_:默认情况下的输出操作确保 _at-least once_ 语义,因为它取决于输出操作的类型( idempotent (幂等))或 downstream system (下游系统)的语义(是否支持 transactions (事务)).但用户可以实现自己的事务机制来实现 _exactly-once_ 语义.这将在本节后面的更多细节中讨论. +3. _Pushing out the data(推出数据)_:默认情况下的输出操作确保 _at-least once_ 语义,因为它取决于输出操作的类型( idempotent(幂等))或 downstream system(下游系统)的语义(是否支持 transactions(事务)).但用户可以实现自己的事务机制来实现 _exactly-once_ 语义.这将在本节后面的更多细节中讨论. -## Semantics of Received Data (接收数据的语义) +## Semantics of Received Data(接收数据的语义) -不同的 input sources (输入源)提供不同的保证,范围从 _at-least once_ 到 _exactly once_ . +不同的 input sources(输入源)提供不同的保证,范围从 _at-least once_ 到 _exactly once_ . ### With Files -如果所有的 input data (输入数据)都已经存在于 fault-tolerant file system (容错文件系统)中 HDFS,Spark Streaming 可以随时从任何故障中恢复并处理所有数据.这给了 _exactly-once_ 语义,意味着无论什么故障,所有的数据将被精确处理一次. +如果所有的 input data(输入数据)都已经存在于 fault-tolerant file system(容错文件系统)中 HDFS,Spark Streaming 可以随时从任何故障中恢复并处理所有数据.这给了 _exactly-once_ 语义,意味着无论什么故障,所有的数据将被精确处理一次. -### With Receiver-based Sources (使用基于接收器的数据源) +### With Receiver-based Sources(使用基于接收器的数据源) -对于基于 receivers (接收器)的 input sources (输入源),容错语义取决于故障场景和接收器的类型。正如我们 [earlier](#receiver-reliability) 讨论的,有两种类型的 receivers (接收器): +对于基于 receivers(接收器)的 input sources(输入源),容错语义取决于故障场景和接收器的类型。正如我们 [earlier](#receiver-reliability) 讨论的,有两种类型的 receivers(接收器): -1. _Reliable Receiver (可靠的接收器)_ - 这些 receivers (接收机)只有在确认收到的数据已被复制之后确认 reliable sources (可靠的源).如果这样的接收器出现故障,source 将不会被接收对于 buffered (unreplicated) data (缓冲(未复制)数据)的确认.因此,如果 receiver 是重新启动,source 将重新发送数据,并且不会由于故障而丢失数据. -2. _Unreliable Receiver (不可靠的接收器)_ - 这样的接收器 _不会_ 发送确认,因此_可能_ 丢失数据,由于 worker 或 driver 故障. +1. _Reliable Receiver(可靠的接收器)_ - 这些 receivers(接收机)只有在确认收到的数据已被复制之后确认 reliable sources(可靠的源).如果这样的接收器出现故障,source 将不会被接收对于 buffered (unreplicated) data(缓冲(未复制)数据)的确认.因此,如果 receiver 是重新启动,source 将重新发送数据,并且不会由于故障而丢失数据. +2. _Unreliable Receiver(不可靠的接收器)_ - 这样的接收器 _不会_ 发送确认,因此_可能_ 丢失数据,由于 worker 或 driver 故障. -根据使用的 receivers 类型,我们实现以下语义。如果 worker node 出现故障,则 reliable receivers 没有数据丢失.unreliable receivers,收到但未复制的数据可能会丢失.如果 driver node 失败,那么除了这些损失之外,在内存中接收和复制的所有过去的数据将丢失.这将影响 stateful transformations (有状态转换)的结果. +根据使用的 receivers 类型,我们实现以下语义。如果 worker node 出现故障,则 reliable receivers 没有数据丢失.unreliable receivers,收到但未复制的数据可能会丢失.如果 driver node 失败,那么除了这些损失之外,在内存中接收和复制的所有过去的数据将丢失.这将影响 stateful transformations(有状态转换)的结果. -为避免过去收到的数据丢失,Spark 1.2 引入了 _write ahead logs_ 将接收到的数据保存到 fault-tolerant storage (容错存储).用[write ahead logs enabled](#deploying-applications) 和 reliable receivers,数据没有丢失.在语义方面,它提供 at-least once guarantee (至少一次保证). +为避免过去收到的数据丢失,Spark 1.2 引入了 _write ahead logs_ 将接收到的数据保存到 fault-tolerant storage(容错存储).用[write ahead logs enabled](#deploying-applications) 和 reliable receivers,数据没有丢失.在语义方面,它提供 at-least once guarantee(至少一次保证). 下表总结了失败的语义: -| Deployment Scenario (部署场景) | Worker Failure (Worker 故障) | Driver Failure (Driver 故障) | +| Deployment Scenario(部署场景) | Worker Failure(Worker 故障) | Driver Failure(Driver 故障) | | --- | --- | --- | -| _Spark 1.1 或更早版本,_ 或者
_Spark 1.2 或者没有 write ahead logs 的更高的版本_ | Buffered data lost with unreliable receivers(unreliable receivers 的缓冲数据丢失)
Zero data loss with reliable receivers (reliable receivers 的零数据丢失)
At-least once semantics (至少一次性语义) | Buffered data lost with unreliable receivers (unreliable receivers 的缓冲数据丢失)
Past data lost with all receivers (所有的 receivers 的过去的数据丢失)
Undefined semantics (未定义语义) | -| _Spark 1.2 或者带有 write ahead logs 的更高版本_ | Zero data loss with reliable receivers(reliable receivers 的零数据丢失)
At-least once semantics (至少一次性语义) | Zero data loss with reliable receivers and files (reliable receivers 和 files 的零数据丢失)
At-least once semantics (至少一次性语义) | +| _Spark 1.1 或更早版本,_ 或者
_Spark 1.2 或者没有 write ahead logs 的更高的版本_ | Buffered data lost with unreliable receivers(unreliable receivers 的缓冲数据丢失)
Zero data loss with reliable receivers(reliable receivers 的零数据丢失)
At-least once semantics(至少一次性语义) | Buffered data lost with unreliable receivers(unreliable receivers 的缓冲数据丢失)
Past data lost with all receivers(所有的 receivers 的过去的数据丢失)
Undefined semantics(未定义语义) | +| _Spark 1.2 或者带有 write ahead logs 的更高版本_ | Zero data loss with reliable receivers(reliable receivers 的零数据丢失)
At-least once semantics(至少一次性语义) | Zero data loss with reliable receivers and files(reliable receivers 和 files 的零数据丢失)
At-least once semantics(至少一次性语义) | | | | | -### With Kafka Direct API (使用 Kafka Direct API) +### With Kafka Direct API(使用 Kafka Direct API) -在 Spark 1.3 中,我们引入了一个新的 Kafka Direct API,可以确保所有的 Kafka 数据都被 Spark Streaming exactly once (一次)接收.与此同时,如果您实现 exactly-once output operation (一次性输出操作),您可以实现 end-to-end exactly-once guarantees (端到端的一次且仅一次性保证).在 [Kafka Integration Guide](streaming-kafka-integration.html) 中进一步讨论了这种方法. +在 Spark 1.3 中,我们引入了一个新的 Kafka Direct API,可以确保所有的 Kafka 数据都被 Spark Streaming exactly once(一次)接收.与此同时,如果您实现 exactly-once output operation(一次性输出操作),您可以实现 end-to-end exactly-once guarantees(端到端的一次且仅一次性保证).在 [Kafka Integration Guide](streaming-kafka-integration.html) 中进一步讨论了这种方法. -## Semantics of output operations (输出操作的语义) +## Semantics of output operations(输出操作的语义) -Output operations (输出操作)(如 `foreachRDD` )具有 _at-least once_ 语义,也就是说,transformed data (变换后的数据)可能会不止一次写入 external entity (外部实体)在一个 worker 故障事件中.虽然这是可以接受的使用 `saveAs***Files`操作(因为文件将被相同的数据简单地覆盖) 保存到文件系统,可能需要额外的努力来实现 exactly-once (一次且仅一次)语义.有两种方法. +Output operations(输出操作)(如 `foreachRDD` )具有 _at-least once_ 语义,也就是说,transformed data(变换后的数据)可能会不止一次写入 external entity(外部实体)在一个 worker 故障事件中.虽然这是可以接受的使用 `saveAs***Files`操作(因为文件将被相同的数据简单地覆盖) 保存到文件系统,可能需要额外的努力来实现 exactly-once(一次且仅一次)语义.有两种方法. -* _Idempotent updates (幂等更新)_:多次尝试总是写入相同的数据.例如,`saveAs***Files` 总是将相同的数据写入生成的文件. +* _Idempotent updates(幂等更新)_:多次尝试总是写入相同的数据.例如,`saveAs***Files` 总是将相同的数据写入生成的文件. -* _Transactional updates (事务更新)_:所有更新都是事务性的,以便更新完全按原子进行.这样做的一个方法如下. +* _Transactional updates(事务更新)_:所有更新都是事务性的,以便更新完全按原子进行.这样做的一个方法如下. - * 使用批处理时间(在 `foreachRDD` 中可用)和 RDD 的 partition index (分区索引)来创建 identifier (标识符).该标识符唯一地标识 streaming application 中的 blob 数据. - * 使用该 identifier (标识符)blob transactionally (blob 事务地)更新 external system (外部系统)(即,exactly once,atomically (一次且仅一次,原子性地)).也就是说,如果 identifier (标识符)尚未提交,则以 atomically (原子方式)提交 partition data (分区数据)和 identifier (标识符).否则,如果已经提交,请跳过更新. + * 使用批处理时间(在 `foreachRDD` 中可用)和 RDD 的 partition index(分区索引)来创建 identifier(标识符).该标识符唯一地标识 streaming application 中的 blob 数据. + * 使用该 identifier(标识符)blob transactionally(blob 事务地)更新 external system(外部系统)(即,exactly once,atomically(一次且仅一次,原子性地)).也就是说,如果 identifier(标识符)尚未提交,则以 atomically(原子方式)提交 partition data(分区数据)和 identifier(标识符).否则,如果已经提交,请跳过更新. ``` dstream.foreachRDD { (rdd, time) => diff --git a/docs/7.md b/docs/7.md index de4716e6172002641e30d70c1541362d39bbf6ed..bfa5ec3de8ca63c8dd8a9a254d8b76d5aee46941 100644 --- a/docs/7.md +++ b/docs/7.md @@ -16,22 +16,22 @@ * [Aggregations](#aggregations) * [Untyped User-Defined Aggregate Functions](#untyped-user-defined-aggregate-functions) * [Type-Safe User-Defined Aggregate Functions](#type-safe-user-defined-aggregate-functions) -* [Data Sources (数据源)](#data-sources-数据源) - * [Generic Load/Save Functions (通用 加载/保存 功能)](#generic-loadsave-functions-通用-加载保存-功能) - * [Manually Specifying Options (手动指定选项)](#manually-specifying-options-手动指定选项) - * [Run SQL on files directly (直接在文件上运行 SQL)](#run-sql-on-files-directly-直接在文件上运行-sql) - * [Save Modes (保存模式)](#save-modes-保存模式) - * [Saving to Persistent Tables (保存到持久表)](#saving-to-persistent-tables-保存到持久表) - * [Bucketing, Sorting and Partitioning (分桶,排序和分区)](#bucketing-sorting-and-partitioning-分桶-排序和分区) +* [Data Sources(数据源)](#data-sources-数据源) + * [Generic Load/Save Functions(通用 加载/保存 功能)](#generic-loadsave-functions-通用-加载保存-功能) + * [Manually Specifying Options(手动指定选项)](#manually-specifying-options-手动指定选项) + * [Run SQL on files directly(直接在文件上运行 SQL)](#run-sql-on-files-directly-直接在文件上运行-sql) + * [Save Modes(保存模式)](#save-modes-保存模式) + * [Saving to Persistent Tables(保存到持久表)](#saving-to-persistent-tables-保存到持久表) + * [Bucketing, Sorting and Partitioning(分桶,排序和分区)](#bucketing-sorting-and-partitioning-分桶-排序和分区) * [Parquet Files](#parquet-files) - * [Loading Data Programmatically (以编程的方式加载数据)](#loading-data-programmatically-以编程的方式加载数据) - * [Partition Discovery (分区发现)](#partition-discovery-分区发现) - * [Schema Merging (模式合并)](#schema-merging-模式合并) - * [Hive metastore Parquet table conversion (Hive metastore Parquet table 转换)](#hive-metastore-parquet-table-conversion-hive-metastore-parquet-table-转换) + * [Loading Data Programmatically(以编程的方式加载数据)](#loading-data-programmatically-以编程的方式加载数据) + * [Partition Discovery(分区发现)](#partition-discovery-分区发现) + * [Schema Merging(模式合并)](#schema-merging-模式合并) + * [Hive metastore Parquet table conversion(Hive metastore Parquet table 转换)](#hive-metastore-parquet-table-conversion-hive-metastore-parquet-table-转换) * [Hive/Parquet Schema Reconciliation](#hiveparquet-schema-reconciliation) - * [Metadata Refreshing (元数据刷新)](#metadata-refreshing-元数据刷新) - * [Configuration (配置)](#configuration-配置) - * [JSON Datasets (JSON 数据集)](#json-datasets-json-数据集) + * [Metadata Refreshing(元数据刷新)](#metadata-refreshing-元数据刷新) + * [Configuration(配置)](#configuration-配置) + * [JSON Datasets(JSON 数据集)](#json-datasets-json-数据集) * [Hive 表](#hive-表) * [指定 Hive 表的存储格式](#指定-hive-表的存储格式) * [与不同版本的 Hive Metastore 进行交互](#与不同版本的-hive-metastore-进行交互) @@ -1377,11 +1377,11 @@ result.show(); Find full example code at "examples/src/main/java/org/apache/spark/examples/sql/JavaUserDefinedTypedAggregation.java" in the Spark repo. -# Data Sources (数据源) +# Data Sources(数据源) -Spark SQL 支持通过 DataFrame 接口对各种 data sources (数据源)进行操作。DataFrame 可以使用 relational transformations (关系转换)操作,也可用于创建 temporary view (临时视图)。将 DataFrame 注册为 temporary view (临时视图)允许您对其数据运行 SQL 查询。本节 描述了使用 Spark Data Sources 加载和保存数据的一般方法,然后涉及可用于 built-in data sources (内置数据源)的 specific options (特定选项). +Spark SQL 支持通过 DataFrame 接口对各种 data sources(数据源)进行操作。DataFrame 可以使用 relational transformations(关系转换)操作,也可用于创建 temporary view(临时视图)。将 DataFrame 注册为 temporary view(临时视图)允许您对其数据运行 SQL 查询。本节 描述了使用 Spark Data Sources 加载和保存数据的一般方法,然后涉及可用于 built-in data sources(内置数据源)的 specific options(特定选项). -## Generic Load/Save Functions (通用 加载/保存 功能) +## Generic Load/Save Functions(通用 加载/保存 功能) 在最简单的形式中,默认数据源(`parquet`,除非另有配置 `spark.sql.sources.default` )将用于所有操作. @@ -1414,9 +1414,9 @@ write.df(select(df, "name", "favorite_color"), "namesAndFavColors.parquet") Find full example code at "examples/src/main/r/RSparkSQLExample.R" in the Spark repo. -### Manually Specifying Options (手动指定选项) +### Manually Specifying Options(手动指定选项) -您还可以 manually specify (手动指定)将与任何你想传递给 data source 的其他选项一起使用的 data source。Data sources 由其 fully qualified name (完全限定名称)(即 `org.apache.spark.sql.parquet` ),但是对于 built-in sources (内置的源),你也可以使用它们的 shortnames (短名称)(`json`,`parquet`,`jdbc`,`orc`,`libsvm`,`csv`,`text`).从任何 data source type (数据源类型)加载 DataFrames 可以使用此 syntax (语法)转换为其他类型. +您还可以 manually specify(手动指定)将与任何你想传递给 data source 的其他选项一起使用的 data source。Data sources 由其 fully qualified name(完全限定名称)(即 `org.apache.spark.sql.parquet` ),但是对于 built-in sources(内置的源),你也可以使用它们的 shortnames(短名称)(`json`,`parquet`,`jdbc`,`orc`,`libsvm`,`csv`,`text`).从任何 data source type(数据源类型)加载 DataFrames 可以使用此 syntax(语法)转换为其他类型. ``` val peopleDF = spark.read.format("json").load("examples/src/main/resources/people.json") @@ -1448,7 +1448,7 @@ write.df(namesAndAges, "namesAndAges.parquet", "parquet") Find full example code at "examples/src/main/r/RSparkSQLExample.R" in the Spark repo. -### Run SQL on files directly (直接在文件上运行 SQL) +### Run SQL on files directly(直接在文件上运行 SQL) 不使用读取 API 将文件加载到 DataFrame 并进行查询,也可以直接用 SQL 查询该文件. @@ -1477,33 +1477,33 @@ df <- sql("SELECT * FROM parquet.`examples/src/main/resources/users.parquet`") Find full example code at "examples/src/main/r/RSparkSQLExample.R" in the Spark repo. -### Save Modes (保存模式) +### Save Modes(保存模式) -Save operations (保存操作)可以选择使用 `SaveMode`,它指定如何处理现有数据如果存在的话。重要的是要意识到,这些 save modes (保存模式)不使用任何 locking (锁定)并且不是 atomic (原子)。另外,当执行 `Overwrite` 时,数据将在新数据写出之前被删除. +Save operations(保存操作)可以选择使用 `SaveMode`,它指定如何处理现有数据如果存在的话。重要的是要意识到,这些 save modes(保存模式)不使用任何 locking(锁定)并且不是 atomic(原子)。另外,当执行 `Overwrite` 时,数据将在新数据写出之前被删除. | Scala/Java | Any Language | Meaning | | --- | --- | --- | -| `SaveMode.ErrorIfExists` (default) | `"error"` (default) | 将 DataFrame 保存到 data source (数据源)时,如果数据已经存在,则会抛出异常。 -| `SaveMode.Append` | `"append"` | 将 DataFrame 保存到 data source (数据源)时,如果 data/table 已存在,则 DataFrame 的内容将被 append (附加)到现有数据中。 -| `SaveMode.Overwrite` | `"overwrite"` | Overwrite mode (覆盖模式)意味着将 DataFrame 保存到 data source (数据源)时,如果 data/table 已经存在,则预期 DataFrame 的内容将 overwritten (覆盖)现有数据。 -| `SaveMode.Ignore` | `"ignore"` | Ignore mode (忽略模式)意味着当将 DataFrame 保存到 data source (数据源)时,如果数据已经存在,则保存操作预期不会保存 DataFrame 的内容,并且不更改现有数据。这与 SQL 中的 `CREATE TABLE IF NOT EXISTS` 类似。 +| `SaveMode.ErrorIfExists` (default) | `"error"` (default) | 将 DataFrame 保存到 data source(数据源)时,如果数据已经存在,则会抛出异常。 +| `SaveMode.Append` | `"append"` | 将 DataFrame 保存到 data source(数据源)时,如果 data/table 已存在,则 DataFrame 的内容将被 append(附加)到现有数据中。 +| `SaveMode.Overwrite` | `"overwrite"` | Overwrite mode(覆盖模式)意味着将 DataFrame 保存到 data source(数据源)时,如果 data/table 已经存在,则预期 DataFrame 的内容将 overwritten(覆盖)现有数据。 +| `SaveMode.Ignore` | `"ignore"` | Ignore mode(忽略模式)意味着当将 DataFrame 保存到 data source(数据源)时,如果数据已经存在,则保存操作预期不会保存 DataFrame 的内容,并且不更改现有数据。这与 SQL 中的 `CREATE TABLE IF NOT EXISTS` 类似。 -### Saving to Persistent Tables (保存到持久表) +### Saving to Persistent Tables(保存到持久表) -`DataFrames` 也可以使用 `saveAsTable` 命令作为 persistent tables (持久表)保存到 Hive metastore 中。请注意,existing Hive deployment (现有的 Hive 部署)不需要使用此功能。Spark 将为您创建默认的 local Hive metastore (本地 Hive metastore)(使用 Derby )。与 `createOrReplaceTempView` 命令不同,`saveAsTable` 将 materialize (实现) DataFrame 的内容,并创建一个指向 Hive metastore 中数据的指针。即使您的 Spark 程序重新启动,Persistent tables (持久性表)仍然存在,因为您保持与同一个 metastore 的连接。可以通过使用表的名称在 `SparkSession` 上调用 `table` 方法来创建 persistent tabl (持久表)的 DataFrame . +`DataFrames` 也可以使用 `saveAsTable` 命令作为 persistent tables(持久表)保存到 Hive metastore 中。请注意,existing Hive deployment(现有的 Hive 部署)不需要使用此功能。Spark 将为您创建默认的 local Hive metastore(本地 Hive metastore)(使用 Derby )。与 `createOrReplaceTempView` 命令不同,`saveAsTable` 将 materialize(实现) DataFrame 的内容,并创建一个指向 Hive metastore 中数据的指针。即使您的 Spark 程序重新启动,Persistent tables(持久性表)仍然存在,因为您保持与同一个 metastore 的连接。可以通过使用表的名称在 `SparkSession` 上调用 `table` 方法来创建 persistent tabl(持久表)的 DataFrame . -对于 file-based (基于文件)的 data source (数据源),例如 text,parquet,json等,您可以通过 `path` 选项指定 custom table path (自定义表路径),例如 `df.write.option("path", "/some/path").saveAsTable("t")`。当表被 dropped (删除)时,custom table path (自定义表路径)将不会被删除,并且表数据仍然存在。如果未指定自定义表路径,Spark 将把数据写入 warehouse directory (仓库目录)下的默认表路径。当表被删除时,默认的表路径也将被删除. +对于 file-based(基于文件)的 data source(数据源),例如 text,parquet,json等,您可以通过 `path` 选项指定 custom table path(自定义表路径),例如 `df.write.option("path", "/some/path").saveAsTable("t")`。当表被 dropped(删除)时,custom table path(自定义表路径)将不会被删除,并且表数据仍然存在。如果未指定自定义表路径,Spark 将把数据写入 warehouse directory(仓库目录)下的默认表路径。当表被删除时,默认的表路径也将被删除. -从 Spark 2.1 开始,persistent datasource tables (持久性数据源表)将 per-partition metadata (每个分区元数据)存储在 Hive metastore 中。这带来了几个好处: +从 Spark 2.1 开始,persistent datasource tables(持久性数据源表)将 per-partition metadata(每个分区元数据)存储在 Hive metastore 中。这带来了几个好处: -* 由于 metastore 只能返回查询的必要 partitions (分区),因此不再需要将第一个查询上的所有 partitions discovering 到表中. +* 由于 metastore 只能返回查询的必要 partitions(分区),因此不再需要将第一个查询上的所有 partitions discovering 到表中. * Hive DDLs 如 `ALTER TABLE PARTITION ... SET LOCATION` 现在可用于使用 Datasource API 创建的表. -请注意,创建 external datasource tables (外部数据源表)(带有 `path` 选项)的表时,默认情况下不会收集 partition information (分区信息)。要 sync (同步) metastore 中的分区信息,可以调用 `MSCK REPAIR TABLE` . +请注意,创建 external datasource tables(外部数据源表)(带有 `path` 选项)的表时,默认情况下不会收集 partition information(分区信息)。要 sync(同步) metastore 中的分区信息,可以调用 `MSCK REPAIR TABLE` . -### Bucketing, Sorting and Partitioning (分桶,排序和分区) +### Bucketing, Sorting and Partitioning(分桶,排序和分区) -对于 file-based data source (基于文件的数据源),也可以对 output (输出)进行 bucket 和 sort 或者 partition。Bucketing 和 sorting 仅适用于 persistent tables : +对于 file-based data source(基于文件的数据源),也可以对 output(输出)进行 bucket 和 sort 或者 partition。Bucketing 和 sorting 仅适用于 persistent tables : ``` peopleDF.write.bucketBy(42, "name").sortBy("age").saveAsTable("people_bucketed") @@ -1564,7 +1564,7 @@ CREATE TABLE users_by_favorite_color( ) USING csv PARTITIONED BY(favorite_color); ``` -可以为 single table (单个表)使用 partitioning 和 bucketing: +可以为 single table(单个表)使用 partitioning 和 bucketing: ``` peopleDF @@ -1607,13 +1607,13 @@ PARTITIONED BY (favorite_color) CLUSTERED BY(name) SORTED BY (favorite_numbers) INTO 42 BUCKETS; ``` -`partitionBy` 创建一个 directory structure (目录结构),如 [Partition Discovery](#partition-discovery) 部分所述。因此,对 cardinality (基数)较高的 columns 的适用性有限。相反,`bucketBy` 可以在固定数量的 buckets 中分配数据,并且可以在 a number of unique values is unbounded (多个唯一值无界时)使用数据. +`partitionBy` 创建一个 directory structure(目录结构),如 [Partition Discovery](#partition-discovery) 部分所述。因此,对 cardinality(基数)较高的 columns 的适用性有限。相反,`bucketBy` 可以在固定数量的 buckets 中分配数据,并且可以在 a number of unique values is unbounded(多个唯一值无界时)使用数据. ## Parquet Files -[Parquet](http://parquet.io) 是许多其他数据处理系统支持的 columnar format (柱状格式)。Spark SQL 支持读写 Parquet 文件,可自动保留 schema of the original data (原始数据的模式)。当编写 Parquet 文件时,出于兼容性原因,所有 columns 都将自动转换为可空. +[Parquet](http://parquet.io) 是许多其他数据处理系统支持的 columnar format(柱状格式)。Spark SQL 支持读写 Parquet 文件,可自动保留 schema of the original data(原始数据的模式)。当编写 Parquet 文件时,出于兼容性原因,所有 columns 都将自动转换为可空. -### Loading Data Programmatically (以编程的方式加载数据) +### Loading Data Programmatically(以编程的方式加载数据) 使用上面例子中的数据: @@ -1742,9 +1742,9 @@ OPTIONS ( SELECT * FROM parquetTable ``` -### Partition Discovery (分区发现) +### Partition Discovery(分区发现) -Table partitioning (表分区)是在像 Hive 这样的系统中使用的常见的优化方法。在 partitioned table (分区表)中,数据通常存储在不同的目录中,partitioning column values encoded (分区列值编码)在每个 partition directory (分区目录)的路径中。Parquet data source (Parquet 数据源)现在可以自动 discover (发现)和 infer (推断)分区信息。例如,我们可以使用以下 directory structure (目录结构)将所有以前使用的 population data (人口数据)存储到 partitioned table (分区表)中,其中有两个额外的列 `gender` 和 `country` 作为 partitioning columns (分区列): +Table partitioning(表分区)是在像 Hive 这样的系统中使用的常见的优化方法。在 partitioned table(分区表)中,数据通常存储在不同的目录中,partitioning column values encoded(分区列值编码)在每个 partition directory(分区目录)的路径中。Parquet data source(Parquet 数据源)现在可以自动 discover(发现)和 infer(推断)分区信息。例如,我们可以使用以下 directory structure(目录结构)将所有以前使用的 population data(人口数据)存储到 partitioned table(分区表)中,其中有两个额外的列 `gender` 和 `country` 作为 partitioning columns(分区列): ``` path @@ -1770,7 +1770,7 @@ path -通过将 `path/to/table` 传递给 `SparkSession.read.parquet` 或 `SparkSession.read.load`,Spark SQL 将自动从路径中提取 partitioning information (分区信息)。现在返回的 DataFrame 的 schema (模式)变成: +通过将 `path/to/table` 传递给 `SparkSession.read.parquet` 或 `SparkSession.read.load`,Spark SQL 将自动从路径中提取 partitioning information(分区信息)。现在返回的 DataFrame 的 schema(模式)变成: ``` root @@ -1780,18 +1780,18 @@ root |-- country: string (nullable = true) ``` -请注意,会自动 inferred (推断) partitioning columns (分区列)的 data types (数据类型).目前,支持 numeric data types (数字数据类型)和 string type (字符串类型).有些用户可能不想自动推断 partitioning columns (分区列)的数据类型.对于这些用例,automatic type inference (自动类型推断)可以由 `spark.sql.sources.partitionColumnTypeInference.enabled` 配置,默认为 `true` .当禁用 type inference (类型推断)时,string type (字符串类型)将用于 partitioning columns (分区列). +请注意,会自动 inferred(推断) partitioning columns(分区列)的 data types(数据类型).目前,支持 numeric data types(数字数据类型)和 string type(字符串类型).有些用户可能不想自动推断 partitioning columns(分区列)的数据类型.对于这些用例,automatic type inference(自动类型推断)可以由 `spark.sql.sources.partitionColumnTypeInference.enabled` 配置,默认为 `true` .当禁用 type inference(类型推断)时,string type(字符串类型)将用于 partitioning columns(分区列). -从 Spark 1.6.0 开始,默认情况下,partition discovery (分区发现)只能找到给定路径下的 partitions (分区).对于上述示例,如果用户将 `path/to/table/gender=male` 传递给 `SparkSession.read.parquet` 或 `SparkSession.read.load`,则 `gender` 将不被视为 partitioning column (分区列).如果用户需要指定 partition discovery (分区发现)应该开始的基本路径,则可以在数据源选项中设置 `basePath`.例如,当 `path/to/table/gender=male` 是数据的路径并且用户将 `basePath` 设置为 `path/to/table/`,`gender` 将是一个 partitioning column (分区列). +从 Spark 1.6.0 开始,默认情况下,partition discovery(分区发现)只能找到给定路径下的 partitions(分区).对于上述示例,如果用户将 `path/to/table/gender=male` 传递给 `SparkSession.read.parquet` 或 `SparkSession.read.load`,则 `gender` 将不被视为 partitioning column(分区列).如果用户需要指定 partition discovery(分区发现)应该开始的基本路径,则可以在数据源选项中设置 `basePath`.例如,当 `path/to/table/gender=male` 是数据的路径并且用户将 `basePath` 设置为 `path/to/table/`,`gender` 将是一个 partitioning column(分区列). -### Schema Merging (模式合并) +### Schema Merging(模式合并) -像 ProtocolBuffer,Avro 和 Thrift 一样,Parquet 也支持 schema evolution (模式演进)。用户可以从一个 simple schema (简单的架构)开始,并根据需要逐渐向 schema 添加更多的 columns (列)。以这种方式,用户可能会使用不同但相互兼容的 schemas 的 multiple Parquet files (多个 Parquet 文件)。Parquet data source (Parquet 数据源)现在能够自动检测这种情况并 merge (合并)所有这些文件的 schemas . +像 ProtocolBuffer,Avro 和 Thrift 一样,Parquet 也支持 schema evolution(模式演进)。用户可以从一个 simple schema(简单的架构)开始,并根据需要逐渐向 schema 添加更多的 columns(列)。以这种方式,用户可能会使用不同但相互兼容的 schemas 的 multiple Parquet files(多个 Parquet 文件)。Parquet data source(Parquet 数据源)现在能够自动检测这种情况并 merge(合并)所有这些文件的 schemas . -由于 schema merging (模式合并)是一个 expensive operation (相对昂贵的操作),并且在大多数情况下不是必需的,所以默认情况下从 1.5.0 开始。你可以按照如下的方式启用它: +由于 schema merging(模式合并)是一个 expensive operation(相对昂贵的操作),并且在大多数情况下不是必需的,所以默认情况下从 1.5.0 开始。你可以按照如下的方式启用它: -1. 读取 Parquet 文件时,将 data source option (数据源选项) `mergeSchema` 设置为 `true` (如下面的例子所示),或 -2. 将 global SQL option (全局 SQL 选项) `spark.sql.parquet.mergeSchema` 设置为 `true` . +1. 读取 Parquet 文件时,将 data source option(数据源选项) `mergeSchema` 设置为 `true`(如下面的例子所示),或 +2. 将 global SQL option(全局 SQL 选项) `spark.sql.parquet.mergeSchema` 设置为 `true` . ``` // This is used to implicitly convert an RDD to a DataFrame. @@ -1943,29 +1943,29 @@ printSchema(df3) Find full example code at "examples/src/main/r/RSparkSQLExample.R" in the Spark repo. -### Hive metastore Parquet table conversion (Hive metastore Parquet table 转换) +### Hive metastore Parquet table conversion(Hive metastore Parquet table 转换) -当读取和写入 Hive metastore Parquet 表时,Spark SQL 将尝试使用自己的 Parquet support (Parquet 支持),而不是 Hive SerDe 来获得更好的性能。此 behavior (行为)由 `spark.sql.hive.convertMetastoreParquet` 配置控制,默认情况下 turned on (打开). +当读取和写入 Hive metastore Parquet 表时,Spark SQL 将尝试使用自己的 Parquet support(Parquet 支持),而不是 Hive SerDe 来获得更好的性能。此 behavior(行为)由 `spark.sql.hive.convertMetastoreParquet` 配置控制,默认情况下 turned on(打开). #### Hive/Parquet Schema Reconciliation -从 table schema processing (表格模式处理)的角度来说,Hive 和 Parquet 之间有两个关键的区别. +从 table schema processing(表格模式处理)的角度来说,Hive 和 Parquet 之间有两个关键的区别. 1. Hive 不区分大小写,而 Parquet 不是 -2. Hive 认为所有 columns (列)都可以为空,而 Parquet 中的可空性是 significant (重要)的. +2. Hive 认为所有 columns(列)都可以为空,而 Parquet 中的可空性是 significant(重要)的. 由于这个原因,当将 Hive metastore Parquet 表转换为 Spark SQL Parquet 表时,我们必须调整 metastore schema 与 Parquet schema。reconciliation 规则是: -1. 在两个 schema 中具有 same name (相同名称)的 Fields (字段)必须具有 same data type (相同的数据类型),而不管 nullability (可空性)。reconciled field 应具有 Parquet 的数据类型,以便 nullability (可空性)得到尊重. +1. 在两个 schema 中具有 same name(相同名称)的 Fields(字段)必须具有 same data type(相同的数据类型),而不管 nullability(可空性)。reconciled field 应具有 Parquet 的数据类型,以便 nullability(可空性)得到尊重. -2. reconciled schema (调和模式)正好包含 Hive metastore schema 中定义的那些字段. +2. reconciled schema(调和模式)正好包含 Hive metastore schema 中定义的那些字段. - * 只出现在 Parquet schema 中的任何字段将被 dropped (删除)在 reconciled schema 中. - * 仅在 Hive metastore schema 中出现的任何字段在 reconciled schema 中作为 nullable field (可空字段)添加. + * 只出现在 Parquet schema 中的任何字段将被 dropped(删除)在 reconciled schema 中. + * 仅在 Hive metastore schema 中出现的任何字段在 reconciled schema 中作为 nullable field(可空字段)添加. -#### Metadata Refreshing (元数据刷新) +#### Metadata Refreshing(元数据刷新) -Spark SQL 缓存 Parquet metadata 以获得更好的性能。当启用 Hive metastore Parquet table conversion (转换)时,这些 converted tables (转换表)的 metadata (元数据)也被 cached (缓存)。如果这些表由 Hive 或其他外部工具更新,则需要手动刷新以确保 consistent metadata (一致的元数据). +Spark SQL 缓存 Parquet metadata 以获得更好的性能。当启用 Hive metastore Parquet table conversion(转换)时,这些 converted tables(转换表)的 metadata(元数据)也被 cached(缓存)。如果这些表由 Hive 或其他外部工具更新,则需要手动刷新以确保 consistent metadata(一致的元数据). ``` // spark is an existing SparkSession @@ -1986,28 +1986,28 @@ spark.catalog.refreshTable("my_table") REFRESH TABLE my_table; ``` -### Configuration (配置) +### Configuration(配置) 可以使用 `SparkSession` 上的 `setConf` 方法或使用 SQL 运行 `SET key = value` 命令来完成 Parquet 的配置. -| Property Name (参数名称) | Default(默认) | Meaning(含义) | +| Property Name(参数名称) | Default(默认) | Meaning(含义) | | --- | --- | --- | -| `spark.sql.parquet.binaryAsString` | false | 一些其他 Parquet-producing systems (Parquet 生产系统),特别是 Impala,Hive 和旧版本的 Spark SQL,在 writing out (写出) Parquet schema 时,不区分 binary data (二进制数据)和 strings (字符串)。该 flag 告诉 Spark SQL 将 binary data (二进制数据)解释为 string (字符串)以提供与这些系统的兼容性。 +| `spark.sql.parquet.binaryAsString` | false | 一些其他 Parquet-producing systems(Parquet 生产系统),特别是 Impala,Hive 和旧版本的 Spark SQL,在 writing out(写出) Parquet schema 时,不区分 binary data(二进制数据)和 strings(字符串)。该 flag 告诉 Spark SQL 将 binary data(二进制数据)解释为 string(字符串)以提供与这些系统的兼容性。 | `spark.sql.parquet.int96AsTimestamp` | true | 一些 Parquet-producing systems,特别是 Impala 和 Hive,将 Timestamp 存入INT96。该 flag 告诉 Spark SQL 将 INT96 数据解析为 timestamp 以提供与这些系统的兼容性。 | `spark.sql.parquet.cacheMetadata` | true | 打开 Parquet schema metadata 的缓存。可以加快查询静态数据。 -| `spark.sql.parquet.compression.codec` | snappy | 在编写 Parquet 文件时设置 compression codec (压缩编解码器)的使用。可接受的值包括:uncompressed,snappy,gzip,lzo。 +| `spark.sql.parquet.compression.codec` | snappy | 在编写 Parquet 文件时设置 compression codec(压缩编解码器)的使用。可接受的值包括:uncompressed,snappy,gzip,lzo。 | `spark.sql.parquet.filterPushdown` | true | 设置为 true 时启用 Parquet filter push-down optimization。 | `spark.sql.hive.convertMetastoreParquet` | true | 当设置为 false 时,Spark SQL 将使用 Hive SerDe 作为 parquet tables,而不是内置的支持。 -| `spark.sql.parquet.mergeSchema` | false | 当为 true 时,Parquet data source (Parquet 数据源) merges (合并)从所有 data files (数据文件)收集的 schemas,否则如果没有可用的 summary file,则从 summary file 或 random data file 中挑选 schema。 -| `spark.sql.optimizer.metadataOnly` | true | 如果为 true,则启用使用表的 metadata 的 metadata-only query optimization 来生成 partition columns (分区列)而不是 table scans (表扫描)。当 scanned (扫描)的所有 columns (列)都是 partition columns (分区列)并且 query (查询)具有满足 distinct semantics (不同语义)的 aggregate operator (聚合运算符)时,它将适用。 +| `spark.sql.parquet.mergeSchema` | false | 当为 true 时,Parquet data source(Parquet 数据源) merges(合并)从所有 data files(数据文件)收集的 schemas,否则如果没有可用的 summary file,则从 summary file 或 random data file 中挑选 schema。 +| `spark.sql.optimizer.metadataOnly` | true | 如果为 true,则启用使用表的 metadata 的 metadata-only query optimization 来生成 partition columns(分区列)而不是 table scans(表扫描)。当 scanned(扫描)的所有 columns(列)都是 partition columns(分区列)并且 query(查询)具有满足 distinct semantics(不同语义)的 aggregate operator(聚合运算符)时,它将适用。 -## JSON Datasets (JSON 数据集) +## JSON Datasets(JSON 数据集) -Spark SQL 可以 automatically infer (自动推断)JSON dataset 的 schema,并将其作为 `Dataset[Row]` 加载。这个 conversion (转换)可以在 `Dataset[String]` 上使用 `SparkSession.read.json()` 来完成,或 JSON 文件. +Spark SQL 可以 automatically infer(自动推断)JSON dataset 的 schema,并将其作为 `Dataset[Row]` 加载。这个 conversion(转换)可以在 `Dataset[String]` 上使用 `SparkSession.read.json()` 来完成,或 JSON 文件. -请注意,以 _a json file_ 提供的文件不是典型的 JSON 文件。每行必须包含一个 separate (单独的),self-contained valid (独立的有效的)JSON 对象。有关更多信息,请参阅 [JSON Lines text format, also called newline-delimited JSON](http://jsonlines.org/) . +请注意,以 _a json file_ 提供的文件不是典型的 JSON 文件。每行必须包含一个 separate(单独的),self-contained valid(独立的有效的)JSON 对象。有关更多信息,请参阅 [JSON Lines text format, also called newline-delimited JSON](http://jsonlines.org/) . -对于 regular multi-line JSON file (常规的多行 JSON 文件),将 `multiLine` 选项设置为 `true` . +对于 regular multi-line JSON file(常规的多行 JSON 文件),将 `multiLine` 选项设置为 `true` . ``` // Primitive types (Int, String, etc) and Product types (case classes) encoders are @@ -2052,11 +2052,11 @@ otherPeople.show() Find full example code at "examples/src/main/scala/org/apache/spark/examples/sql/SQLDataSourceExample.scala" in the Spark repo. -Spark SQL 可以 automatically infer (自动推断)JSON dataset 的 schema,并将其作为 `Dataset<Row>` 加载。这个 conversion (转换)可以在 `Dataset<String>` 上使用 `SparkSession.read.json()` 来完成,或 JSON 文件. +Spark SQL 可以 automatically infer(自动推断)JSON dataset 的 schema,并将其作为 `Dataset<Row>` 加载。这个 conversion(转换)可以在 `Dataset<String>` 上使用 `SparkSession.read.json()` 来完成,或 JSON 文件. -请注意,以 _a json file_ 提供的文件不是典型的 JSON 文件。每行必须包含一个 separate (单独的),self-contained valid (独立的有效的)JSON 对象。有关更多信息,请参阅 [JSON Lines text format, also called newline-delimited JSON](http://jsonlines.org/) +请注意,以 _a json file_ 提供的文件不是典型的 JSON 文件。每行必须包含一个 separate(单独的),self-contained valid(独立的有效的)JSON 对象。有关更多信息,请参阅 [JSON Lines text format, also called newline-delimited JSON](http://jsonlines.org/) -对于 regular multi-line JSON file (常规的多行 JSON 文件),将 `multiLine` 选项设置为 `true` . +对于 regular multi-line JSON file(常规的多行 JSON 文件),将 `multiLine` 选项设置为 `true` . ``` import org.apache.spark.sql.Dataset; @@ -2100,11 +2100,11 @@ anotherPeople.show(); Find full example code at "examples/src/main/java/org/apache/spark/examples/sql/JavaSQLDataSourceExample.java" in the Spark repo. -Spark SQL 可以 automatically infer (自动推断)JSON dataset 的 schema,并将其作为 DataFrame 加载。可以使用 JSON 文件中的 `SparkSession.read.json` 进行此 conversion (转换). +Spark SQL 可以 automatically infer(自动推断)JSON dataset 的 schema,并将其作为 DataFrame 加载。可以使用 JSON 文件中的 `SparkSession.read.json` 进行此 conversion(转换). -请注意,以 _a json file_ 提供的文件不是典型的 JSON 文件。每行必须包含一个 separate (单独的),self-contained valid (独立的有效的)JSON 对象。有关更多信息,请参阅 [JSON Lines text format, also called newline-delimited JSON](http://jsonlines.org/) +请注意,以 _a json file_ 提供的文件不是典型的 JSON 文件。每行必须包含一个 separate(单独的),self-contained valid(独立的有效的)JSON 对象。有关更多信息,请参阅 [JSON Lines text format, also called newline-delimited JSON](http://jsonlines.org/) -对于 regular multi-line JSON file (常规的多行 JSON 文件),将 `multiLine` 选项设置为 `true` . +对于 regular multi-line JSON file(常规的多行 JSON 文件),将 `multiLine` 选项设置为 `true` . ``` # spark is from the previous example. @@ -2148,11 +2148,11 @@ otherPeople.show() Find full example code at "examples/src/main/python/sql/datasource.py" in the Spark repo. -Spark SQL 可以 automatically infer (自动推断)JSON dataset 的 schema,并将其作为 DataFrame 加载。使用 `read.json()` 函数,它从 JSON 文件的目录中加载数据,其中每一行文件都是一个 JSON 对象. +Spark SQL 可以 automatically infer(自动推断)JSON dataset 的 schema,并将其作为 DataFrame 加载。使用 `read.json()` 函数,它从 JSON 文件的目录中加载数据,其中每一行文件都是一个 JSON 对象. -请注意,以 _a json file_ 提供的文件不是典型的 JSON 文件。每行必须包含一个 separate (单独的),self-contained valid (独立的有效的)JSON 对象。有关更多信息,请参阅 [JSON Lines text format, also called newline-delimited JSON](http://jsonlines.org/). +请注意,以 _a json file_ 提供的文件不是典型的 JSON 文件。每行必须包含一个 separate(单独的),self-contained valid(独立的有效的)JSON 对象。有关更多信息,请参阅 [JSON Lines text format, also called newline-delimited JSON](http://jsonlines.org/). -对于 regular multi-line JSON file (常规的多行 JSON 文件),将 `multiLine` 选项设置为 `true` . +对于 regular multi-line JSON file(常规的多行 JSON 文件),将 `multiLine` 选项设置为 `true` . ``` # A JSON dataset is pointed to by path. @@ -2193,7 +2193,7 @@ SELECT * FROM jsonTable Spark SQL 还支持读取和写入存储在 [Apache Hive](http://hive.apache.org/) 中的数据。但是,由于 Hive 具有大量依赖关系,因此这些依赖关系不包含在默认 Spark 分发中。如果在类路径中找到 Hive 依赖项,Spark 将自动加载它们。请注意,这些 Hive 依赖关系也必须存在于所有工作节点上,因为它们将需要访问 Hive 序列化和反序列化库 (SerDes),以访问存储在 Hive 中的数据。 -通过将 `hive-site.xml`,`core-site.xml`(用于安全配置)和 `hdfs-site.xml` (用于 HDFS 配置)文件放在 `conf/` 中来完成配置。 +通过将 `hive-site.xml`,`core-site.xml`(用于安全配置)和 `hdfs-site.xml`(用于 HDFS 配置)文件放在 `conf/` 中来完成配置。 当使用 Hive 时,必须用 Hive 支持实例化 `SparkSession`,包括连接到持续的 Hive 转移,支持 Hive serdes 和 Hive 用户定义的功能。没有现有 Hive 部署的用户仍然可以启用 Hive 支持。当 `hive-site.xml` 未配置时,上下文会自动在当前目录中创建 `metastore_db`,并创建由 `spark.sql.warehouse.dir` 配置的目录,该目录默认为Spark应用程序当前目录中的 `spark-warehouse` 目录 开始了 请注意,自从2.0.0以来,`hive-site.xml` 中的 `hive.metastore.warehouse.dir` 属性已被弃用。而是使用 `spark.sql.warehouse.dir` 来指定仓库中数据库的默认位置。您可能需要向启动 Spark 应用程序的用户授予写权限。å @@ -2498,7 +2498,7 @@ Spark SQL 的 Hive 支持的最重要的部分之一是与 Hive metastore 进行 org.postgresql, com.microsoft.sqlserver, oracle.jdbc` | 使用逗号分隔的类前缀列表,应使用在 Spark SQL 和特定版本的 Hive 之间共享的类加载器来加载。一个共享类的示例就是用来访问 Hive metastore 的 JDBC driver。其它需要共享的类,是需要与已经共享的类进行交互的。例如,log4j 使用的自定义 appender。 | -| `spark.sql.hive.metastore.barrierPrefixes` | `(empty)` | 一个逗号分隔的类前缀列表,应该明确地为 Spark SQL 正在通信的 Hive 的每个版本重新加载。例如,在通常将被共享的前缀中声明的 Hive UDF (即: `org.apache.spark.*`)。 | +| `spark.sql.hive.metastore.barrierPrefixes` | `(empty)` | 一个逗号分隔的类前缀列表,应该明确地为 Spark SQL 正在通信的 Hive 的每个版本重新加载。例如,在通常将被共享的前缀中声明的 Hive UDF(即: `org.apache.spark.*`)。 | ## JDBC 连接其它数据库 diff --git a/docs/paper.md b/docs/paper.md index a05fd40c3d589e6fb5e8118b7c2bda83cc401a18..93fa13dfcb6ad7af4a00860c5befef184586e95d 100644 --- a/docs/paper.md +++ b/docs/paper.md @@ -52,7 +52,7 @@ 在设计 RDDs 的时候,最大的挑战是定义一个可以高效容错的编程接口。已经存在的分布式内存抽象系统比如 distributed shared memory、key-value stores、databases 以及 Poccolo,都是提供了基于粒度的更新可变状态(比如 table 中的 cells)的接口,基于这种接口下,保证容错的方式无非是将数据复备份到多台机器或者在多台机器上记录更新的日志,这两种方式在数据密集性的工作任务中都是非常的耗时的,因为需要通过网络传输在机器节点间复制大量的数据,宽带传输数据的速度远远比 RAM 内存慢,而这两种方式会占用大量的存储空间. -与这些系统相反,RDDs 提供了基于粗粒度转换(比如 map,filter 以及 join)的接口,这些接口可以对多的数据条目应用相同的操作.这样就可以通过记录来生成某个数据集的一系列转换 (就是这个数据集 lineage)而不是记录真实的数据来达到提供高效的容错机制。这个 RDD 就有足够的信息知道它是从哪 RDDs 转换计算来的,如果一个 RDD 的分区数据丢失掉了,那么重新计算这个 RDD 所依赖的那个 RDD 对应的区就行了。因此可以很快且不用通过复制备份方式来恢复丢失的数据. +与这些系统相反,RDDs 提供了基于粗粒度转换(比如 map,filter 以及 join)的接口,这些接口可以对多的数据条目应用相同的操作.这样就可以通过记录来生成某个数据集的一系列转换(就是这个数据集 lineage)而不是记录真实的数据来达到提供高效的容错机制。这个 RDD 就有足够的信息知道它是从哪 RDDs 转换计算来的,如果一个 RDD 的分区数据丢失掉了,那么重新计算这个 RDD 所依赖的那个 RDD 对应的区就行了。因此可以很快且不用通过复制备份方式来恢复丢失的数据. 虽然基于粗粒度的转换一开始看起来受限制,但是 RDDs 非常适合很多并行计算的应用,因为这些应用基都是在大量的数据元素上应用相同的操作方法。事实上,我们分析表明 RDDs 不仅可以高效的表达出目前括 MapReduce,DryadLINQ,SQL,Pregel 以及 HaLoop 等系统提出的分布式编程模型,而且还能表达它们表达不了的新的应用的计算模型,比如交互型数据挖掘。我们相信,RDDs 解决那些新的框架提出来计算需求的能力将会成为是 RDD 抽象强大的最有力证据. @@ -129,7 +129,7 @@ errors.filter(_.contains("HDFS")) | 容错 | 利用lineage达到细粒度且低延迟的容错 | 需要应用checkpoints(就是需要写磁盘) 并且需要程序回滚 | | 计算慢的任务 | 可以利用备份的任务来解决 | 很难做到 | -| 计算数据的位置 | 自动的机遇数据本地性 | 取决于app (runtime是以透明为目标的) | +| 计算数据的位置 | 自动的机遇数据本地性 | 取决于app(runtime是以透明为目标的) | | 内存不足时的行为 | 和已经存在的数据流处理系统一样,写磁盘 | 非常糟糕的性能(需要内存的交换?) | 表一:RDDs 和 Distributed shared memory 对比 @@ -226,7 +226,7 @@ Spark 中的这些 RDDs 的通用接口使的实现很多 transformations 操作 * map:对任意的 RDDs 调用 map 操作将会返回一个 MappedRDD 对象.这个对象含有和其父亲 RDDs 相同的分区信息和数据存储节点信息,但是在 iterator 中对父亲的所有输出数据记录应用传给 map 的函数. * union:对两个 RDDs 调用 union 操作将会返回一个新的 RDD,这个 RDD 的分区数是他所有父亲 RDDs 的所有分区数的总数.每一个子分区通过相对应的窄依赖的父亲分区计算得到. * sample:sampling 和 mapping 类似,除了 sample RDD 中为每一个分区存储了一个随机数,作为从父亲分区数据中抽样的种子. -* join:对两个 RDDs 进行 join 操作,可能导致两个窄依赖(如果两个 RDDs 都是事先经过相同的 hash/range 分区器进行分区),或者导致两个宽依赖,或者一个窄依赖一个宽依赖(一个父亲 RDD 经过分区而另一个没有分区).在上面所有的恶场景中,join 之后的输出 RDD 会有一个 partitioner (从父亲 RDD 中继承过来的或者是一个默认的 hash partitioner). +* join:对两个 RDDs 进行 join 操作,可能导致两个窄依赖(如果两个 RDDs 都是事先经过相同的 hash/range 分区器进行分区),或者导致两个宽依赖,或者一个窄依赖一个宽依赖(一个父亲 RDD 经过分区而另一个没有分区).在上面所有的恶场景中,join 之后的输出 RDD 会有一个 partitioner(从父亲 RDD 中继承过来的或者是一个默认的 hash partitioner). ## 5 实现 @@ -240,7 +240,7 @@ Spark 可以利用已经存在的 hadoop 的 api 组件读取任何的 hadoop spark 的调度器依赖我们在第 4 章中讨论的 RDDs 的表达. -从总体上看,我们的调度系统有点和 Dryad 相似,但是它还考虑了被存储的 RDDs 的哪些分区还在内存中.当一个用户对某个 RDD 调用了 action 操作(比如 count 或者 save )的时候调度器会检查这个 RDD 的血缘关系图,然后根据这个血缘关系图构建一个含有 stages 的有向无环图( DAG ),最后按照步骤执行这个 DAG 中的 stages,如图 5 的说明.每一个 stage 包含了尽可能多的带有窄依赖的 transformations 操作。这个 stage 的划分是根据需要 shuffle 操作的宽依赖或者任何可以切断对父亲 RDD 计算的某个操作(因为这些父亲 RDD 的分区已经计算过了)。然后调度器可以调度启动 tasks 来执行没有父亲 stage 的 stage (或者父亲 stage 已经计算好了的 stage ),一直到计算完我们的最后的目标 RDD . +从总体上看,我们的调度系统有点和 Dryad 相似,但是它还考虑了被存储的 RDDs 的哪些分区还在内存中.当一个用户对某个 RDD 调用了 action 操作(比如 count 或者 save )的时候调度器会检查这个 RDD 的血缘关系图,然后根据这个血缘关系图构建一个含有 stages 的有向无环图( DAG ),最后按照步骤执行这个 DAG 中的 stages,如图 5 的说明.每一个 stage 包含了尽可能多的带有窄依赖的 transformations 操作。这个 stage 的划分是根据需要 shuffle 操作的宽依赖或者任何可以切断对父亲 RDD 计算的某个操作(因为这些父亲 RDD 的分区已经计算过了)。然后调度器可以调度启动 tasks 来执行没有父亲 stage 的 stage(或者父亲 stage 已经计算好了的 stage ),一直到计算完我们的最后的目标 RDD . ![](img/9a1ca367603942cde5c30e70396e8fa3.jpg) 图五:怎么计算 spark job stage 的例子.实现的方框表示 RDDs ,带有颜色的方形表示分区,黑色的是表示这个分区的数据存储在内存中,对 RDD G 调用 action 操作,我们根据宽依赖生成很多 stages,且将窄依赖的 transformations 操作放在 stage 中.在这个场景中,stage 1 的输出结果已经在内存中,所以我们开始运行 stage 2,然后是 stage 3. @@ -248,7 +248,7 @@ spark 的调度器依赖我们在第 4 章中讨论的 RDDs 的表达. 对于宽依赖(比如 shuffle 依赖),我们将中间数据写入到节点的磁盘中以利于从错误中恢复,这个和 MapReduce 将 map 后的结果写入到磁盘中是很相似的. -只要一个任务所在的 stage 的父亲 stage 还是有效的话,那么当这个 task 失败的时候,我们就可以在其他的机器节点中重新跑这个任务。如果一些 stages 变的无效的话(比如因为一个 shuffle 过程中 map 端的一个输出结果丢失了),我们需要重新并行提交没有父亲 stage 的 stage (或者父亲 stage 已经计算好了的 stage )的计算任务。虽然备份 RDD 的血缘关系图示比较容易的,但是我们还不能容忍调度器调度失败的场景. +只要一个任务所在的 stage 的父亲 stage 还是有效的话,那么当这个 task 失败的时候,我们就可以在其他的机器节点中重新跑这个任务。如果一些 stages 变的无效的话(比如因为一个 shuffle 过程中 map 端的一个输出结果丢失了),我们需要重新并行提交没有父亲 stage 的 stage(或者父亲 stage 已经计算好了的 stage )的计算任务。虽然备份 RDD 的血缘关系图示比较容易的,但是我们还不能容忍调度器调度失败的场景. 虽然目前 spark 中所有的计算都是响应 driver 程序中调用的 action 操作,但是我们也是需要尝试在集群中调用 lookup 操作,这种操作是根据 key 来随机访问已经 hash 分区过的 RDD 所有元素以获取相应的 value。在这种场景中,如果一个分区没有计算的话,那么 task 需要将这个信息告诉调度器. @@ -273,7 +273,7 @@ Scala 解释器通常是将用户输入的每一行代码编译成一个类, Spark 在持久化 RDDs 的时候提供了 3 种存储选:存在内存中的非序列化的 java 对象、存在内存中的序列化的数据以及存储在磁盘中。第一种选择的性能是最好的,因为 java VM 可以很快的访问 RDD 的每一个元素。第二种选择是在内存有限的情况下,使的用户可以以很低的性能代价而选择的比 java 对象图更加高效的内存存储的方式。如果内存完全不够存储的下很大的 RDDs,而且计算这个 RDD 又很费时的,那么选择第三种方式. -为了管理有限的内存资源,我们在 RDDs 的层面上采用 LRU (最近最少使用)回收策略。当一个新的 RDD 分区被计算但是没有足够的内存空间来存储这个分区的数据的时候,我们回收掉最近很少使用的 RDD 的分区数据的占用内存,如果这个 RDD 和这个新的计算分区的 RDD 时同一个 RDD 的时候,我们则不对这个分区数据占用的内存做回收。在这种情况下,我们将相同的 RDD 的老分区的数据保存在内存中是为了不让老是重新计算这些分区的数据,这点事非常重要的,因为很多操作都是对整个 RDD 的所有的 tasks 进行计算的,所以非常有必要将后续要用到的数据保存在内存中.到目前为止,我们发现这种默认的机制在所有的应用中工作的很好,但是我们还是将持久每一个 RDD 数据的策略的控制权交给用户. +为了管理有限的内存资源,我们在 RDDs 的层面上采用 LRU(最近最少使用)回收策略。当一个新的 RDD 分区被计算但是没有足够的内存空间来存储这个分区的数据的时候,我们回收掉最近很少使用的 RDD 的分区数据的占用内存,如果这个 RDD 和这个新的计算分区的 RDD 时同一个 RDD 的时候,我们则不对这个分区数据占用的内存做回收。在这种情况下,我们将相同的 RDD 的老分区的数据保存在内存中是为了不让老是重新计算这些分区的数据,这点事非常重要的,因为很多操作都是对整个 RDD 的所有的 tasks 进行计算的,所以非常有必要将后续要用到的数据保存在内存中.到目前为止,我们发现这种默认的机制在所有的应用中工作的很好,但是我们还是将持久每一个 RDD 数据的策略的控制权交给用户. 最后,在一个集群中的每一个 spark 实例的内存空间都是分开的,我们以后打算通过统一内存管理达到在 spark 实例之间共享 RDDs. @@ -281,9 +281,9 @@ Spark 在持久化 RDDs 的时候提供了 3 种存储选:存在内存中的 虽然我们总是可以使用 RDDs 的血缘关系来恢复失败的 RDDs 的计算,但是如果这个血缘关系链很长的话,则恢复是需要耗费不少时间的.因此,将一些 RDDs 的数据持久化到稳定存储系统中是有必要的 -一般来说,checkpointing 对具有很长的血缘关系链且包含了宽依赖的 RDDs 是非常有用的,比如我们在 3.2.2 小节中提到的 PageRank 的例子。在这些场景下,集群中的某个节点的失败会导致每一个父亲 RDD 的一些数据的丢失,进而需要重新所有的计算。与此相反的,对于存储在稳定存储系统中且是窄依赖的 RDDs (比如 3.2.1 小节中线性回归例子中的 points 和 PageRank 中的 link 列表数据),checkpointing 可能一点用都没有。如果一个节点失败了,我们可以在其他的节点中并行的重新计算出丢失了数据的分区,这个成本只是备份整个 RDD 的成本的一点点而已. +一般来说,checkpointing 对具有很长的血缘关系链且包含了宽依赖的 RDDs 是非常有用的,比如我们在 3.2.2 小节中提到的 PageRank 的例子。在这些场景下,集群中的某个节点的失败会导致每一个父亲 RDD 的一些数据的丢失,进而需要重新所有的计算。与此相反的,对于存储在稳定存储系统中且是窄依赖的 RDDs(比如 3.2.1 小节中线性回归例子中的 points 和 PageRank 中的 link 列表数据),checkpointing 可能一点用都没有。如果一个节点失败了,我们可以在其他的节点中并行的重新计算出丢失了数据的分区,这个成本只是备份整个 RDD 的成本的一点点而已. -spark 目前提供了一个 checkpointing 的 api ( persist 中的标识为 REPLICATE,还有 checkpoint()),但是需要将哪些数据需要 checkpointing 的决定权留给了用户。然而,我们也在调查怎么样自动的 checkpoing,因为我们的调度系统知道数据集的大小以及第一次计算这个数据集花的时间,所以有必要选择一些最佳的 RDDs 来进行 checkpointing,来达到最小化恢复时间 +spark 目前提供了一个 checkpointing 的 api( persist 中的标识为 REPLICATE,还有 checkpoint()),但是需要将哪些数据需要 checkpointing 的决定权留给了用户。然而,我们也在调查怎么样自动的 checkpoing,因为我们的调度系统知道数据集的大小以及第一次计算这个数据集花的时间,所以有必要选择一些最佳的 RDDs 来进行 checkpointing,来达到最小化恢复时间 最后,需要知道的事 RDDs 天生的只读的特性使的他们比一般的共享内存系统做 checkpointing 更简单了。因为不用考虑数据的一致性,我们可以不终止程序或者 take 快照,然后在后台将 RDDs 的数据写入到存储系统中. @@ -296,7 +296,7 @@ spark 目前提供了一个 checkpointing 的 api ( persist 中的标识为 RE * 当节点失败的时候,spark 可以通过重新计算失去的 rdd 分区数据达到快速的恢复. * spark 在查询 1 TB 的数据的时候的延迟可以控制在 5 到 7 秒. -我们通过和 hadoop 对比,展示迭代式机器学习( 6.1 节)和 PageRank ( 6.2 节)的基准测试.然后我们评估了 spark 的错误恢复机制( 6.3 节)以及当内存不足以存储一个数据集的行为( 6.4 节),最后我们讨论了用户应用( 6.5 节)和交互式数据挖掘( 6.6 节)的结果 除非另外声明,我们都是用类型为 m 1.xlarge 的 EC 2 节点,4 核以及 15 GB 内存。我们是有数据块大小为 256 M 的 HDFS 存储系统。在每一次测试之前,我们都会清理 OS 的缓存,以达到准确的测量 IO 成本的目的 +我们通过和 hadoop 对比,展示迭代式机器学习( 6.1 节)和 PageRank( 6.2 节)的基准测试.然后我们评估了 spark 的错误恢复机制( 6.3 节)以及当内存不足以存储一个数据集的行为( 6.4 节),最后我们讨论了用户应用( 6.5 节)和交互式数据挖掘( 6.6 节)的结果 除非另外声明,我们都是用类型为 m 1.xlarge 的 EC 2 节点,4 核以及 15 GB 内存。我们是有数据块大小为 256 M 的 HDFS 存储系统。在每一次测试之前,我们都会清理 OS 的缓存,以达到准确的测量 IO 成本的目的 ### 6.1 迭代式机器学习应用 @@ -324,7 +324,7 @@ spark 目前提供了一个 checkpointing 的 api ( persist 中的标识为 RE 最后,为了测试第 3 个因素,我们在单机上做了一个微型的基准测试,就是针对不同文件类型的 256 M 数据来跑线性回归计算。我们特别的对比了分别从 HDFS 文件( HDFS 技术栈的耗时将会很明显)和本地内存文件(内核可以很高效的将数据传输给应用程序)中处理文本和二进制类型数据所话的时间、 -图九中是我们我们测试结果的展示。从 In - memory HDFS (数据是在本地机器中的内存中)中读数据比从本地内存文件中读数据要多花费 2 秒中.解析文本文件要比解析二进制文件多花费 7 秒钟。最后,即使从本地内存文件中读数据,但是将预先解析了二进制数据转换成 java 对象也需要 3 秒钟,这个对于线性回归来说也是一个非常耗时的操作。Spark 将 RDDs 所有元素以 java 对象的形式存储在内存中,进而避免了上述说的所有的耗时 +图九中是我们我们测试结果的展示。从 In - memory HDFS(数据是在本地机器中的内存中)中读数据比从本地内存文件中读数据要多花费 2 秒中.解析文本文件要比解析二进制文件多花费 7 秒钟。最后,即使从本地内存文件中读数据,但是将预先解析了二进制数据转换成 java 对象也需要 3 秒钟,这个对于线性回归来说也是一个非常耗时的操作。Spark 将 RDDs 所有元素以 java 对象的形式存储在内存中,进而避免了上述说的所有的耗时 ### 6.2 PageRank @@ -354,7 +354,7 @@ spark 目前提供了一个 checkpointing 的 api ( persist 中的标识为 RE **内存中分析**: Conviva Inc 是一个视频提供商,他们用 spark 来加速之前在 hadoop 上运行的几个数据报表分析。比如,其中一个报表是运行一系列的 Hive 查询来计算一个用户的各种统计信息。这些查询都是基于相同的数据子集(基于自定义的过滤器过滤出来的数据)但是需要很多 MapReduce 任务来为分组字段进行聚合运算(平均值、百分位数值以及 count distinct)。将这些数据子集创建成一个可以共享的 spark 中的 RDD 来实现这些查询使的这个报表的速度提升了 40 倍。对 200 GB 已经压缩的数据在 hadoop 集群上跑这个报表花了 20 个小时,但是利用 2 台机器的 spark 只用了 30 分钟而已。此外,spark 程序只花了 96 G 的内存,因为只需要将报表关心的列数据存储在内存中进行共享就行,而不是所有的解压后的数据. -**交通模型**:伯克利分校的 Mobile Millennium 项目组的研究员在收集到的零星的汽车的 GPS 信息上并行运行一个机器学习算法试图推断出道路交通是否拥挤。在都市区域道路网络中的 10000 条道路和 600000 个装有 GPS 设备的汽车点对点的旅行时间(每一条路线的旅行时间可能包含了多条道路)样本是数据源。利用交通模型可以估算出通过每一条独立的道路需要多长时间。研究人员利用 EM 算法来训练模型,这个算法在迭代的过程中重复执行 map 和 reduceByKey 步骤。这个应用近似线性的将机器规模从 20 台扩展到 80 台,每台机器 4 个 cores,如图 13 ( a )所示. +**交通模型**:伯克利分校的 Mobile Millennium 项目组的研究员在收集到的零星的汽车的 GPS 信息上并行运行一个机器学习算法试图推断出道路交通是否拥挤。在都市区域道路网络中的 10000 条道路和 600000 个装有 GPS 设备的汽车点对点的旅行时间(每一条路线的旅行时间可能包含了多条道路)样本是数据源。利用交通模型可以估算出通过每一条独立的道路需要多长时间。研究人员利用 EM 算法来训练模型,这个算法在迭代的过程中重复执行 map 和 reduceByKey 步骤。这个应用近似线性的将机器规模从 20 台扩展到 80 台,每台机器 4 个 cores,如图 13( a )所示. ![](img/c4abf9f69923cfef574f0e484b041d61.jpg) 图十三:两个用 spark 实现的用户应用的每次迭代的时间,误差线表示标准误差 @@ -402,7 +402,7 @@ Pregel 在每一次迭代中都是对所有顶点应用相同的用户定义的 * 第一,像 MapReduce,Dryad 以及 Ciel 一样支持一系列处理数据的操作,并且需要通过稳定的存储系统来共享数据,RDDs 表达了一种比稳定存储系统更高效的数据共享抽象,因为它避免了数据备份、 I / O 以及序列化的成本. -* 第二,几个数据流系统的高层面上的编程接口,包括 DryadLINQ 和 FlumeJava ,它们提供了语言集成 api,使的用户可以通过像 map 和 join 等操作来操作并行的集合.然而,在这些系统中,并行的集合是指在磁盘上的文件或者一个查询计划表达的临时数据集.虽然这些系统在相同的查询中的操作之间组装数据的 pipeline (比如,一个 map 操作后跟另外一个 map ),但是它们不能在查询之间进行高效的数据共享.我们在并行集合模式上建立 spark api,是由于它的便利性以及在集成语言接口上不要求新颖性,但是我们基于在这些接口背后以 RDDs 作为存储抽象,就可以使的 spark 支持大量类型的应用了. +* 第二,几个数据流系统的高层面上的编程接口,包括 DryadLINQ 和 FlumeJava ,它们提供了语言集成 api,使的用户可以通过像 map 和 join 等操作来操作并行的集合.然而,在这些系统中,并行的集合是指在磁盘上的文件或者一个查询计划表达的临时数据集.虽然这些系统在相同的查询中的操作之间组装数据的 pipeline(比如,一个 map 操作后跟另外一个 map ),但是它们不能在查询之间进行高效的数据共享.我们在并行集合模式上建立 spark api,是由于它的便利性以及在集成语言接口上不要求新颖性,但是我们基于在这些接口背后以 RDDs 作为存储抽象,就可以使的 spark 支持大量类型的应用了. * 第三种系统为许多专门的需要数据共享的应用提供了高层的接口.比如,pregel 支持迭代式的图计算应用、 Twister 和 HaLoop 支持迭代式的 MapReduce .然而,这些框架只是为他们支持的计算模型隐式的共享数据,并没有提供可以让用户根据自己的需求显式的共享数据的通用抽象.比如,一个用户不能用 Pregel 或者 Twister 将数据加载到内存中然后决定在数据集上面跑什么样的查询。RDDs 提供了一个显式的分布式存储抽象,因此可以支持那些特殊系统不能支持的应用,比如交互式数据挖掘. 最后,一些系统暴露共享可变状态以使的用户可以执行内存计算。比如,Piccolo 使的用户通过分布式的函数来读取和更新分布式 hash 表中的单元格数据。DSM 和像 RAMCloud 这样的 key - value 存储系统提供了类似的模型。RDDs 和这些系统有两个方面的不同,第一,RDDs 基于像 map,sot 以及 join 等操作提供了高层的编程接口,然而,在 Piccolo 和 DSM 中的接口只是读取和更新表的单元格数据。第二,Piccolo 和 DSM 通过 checkpoint 和回滚机制实现容错,在许多应用中这种机制比机遇血缘机制的 RDDs 的容错的成本更大。最后,如 2.3 小节讨论的,相对于 DSM,RDDs 还提供了其他的优势功能,比如执行慢的 task 的处理机制