返回介绍

14.5 自动化的特殊工具

发布于 2024-01-27 21:43:11 字数 17900 浏览 0 评论 0 收藏 0

Python 提供了许多用于自动化的特殊工具。我们会查看一些使用 Python 管理自动化程序的方法,同时也会使用其他的机器和服务器完成任务。我们还会讨论怎样使用一些内置的 Python 工具管理脚本的输入,自动化看起来需要人工输入的事情。

14.5.1 使用本地文件、参数及配置文件

根据脚本的工作情况,你可能需要存储在数据库或 API 之外的参数或输入。当有一个简单的输入或输出时,你可以使用本地文件和参数来传递数据。

01. 本地文件

使用本地文件作为输入和输出时,你需要确保脚本可以每天运行在相同的机器上,或者可以简单地与输入和输出文件一起迁移。随着脚本的开发,很可能需要同时移动并改变脚本和所用文件。

我们之前使用过本地文件,但是让我们看一下如何从更加函数式的代码的角度来使用它。这段代码给了你使用标准数据类型打开和写文件的能力,并且根据脚本的需求,其复用性和扩展性很好。

from csv import reader, writer
 
 
def read_local_file(file_name):
  if '.csv' in file_name: ➊
    rdr = reader(open(file_name, 'rb'))
    return rdr
  return open(file_name, 'rb') ➋
 
 
def write_local_file(file_name, data):
  with open(file_name, 'wb') as open_file: ➌
    if type(data) is list: ➍
      wr = writer(open_file)
      for line in data:
        wr.writerow(line)
    else:
      open_file.write(data) ➎

❶ 这行代码测试文件是否适合使用 csv 模块打开。如果文件以 .csv 结尾,之后可以使用 CSV 读取器来打开它。

❷ 如果没有返回 CSV 读取器,这段代码返回打开的文件。如果想要根据文件扩展类型,构建一系列不同的方式来打开并解析文件,也可以做到(例如,为 JSON 文件使用 json 模块,或者为 PDF 文件使用 pdfminer)。

❸ 这段代码使用 with...as 返回 open 函数的输出,将其赋值给 open_file 变量。当缩进的代码块结束时,Python 会自动地关闭文件。

❹ 如果正在处理列表,这一行代码使用 CSV 输出器输出每一行列表对象为一行数据。如果有字典,可以使用 DictWriter 类。

❺ 我们想要一个好的备选计划,以防数据不是列表。因此,要将原始数据写到文件中。此外,根据数据类型的不同,还可以写不同的代码。

看一个例子,我们需要文件夹中最近使用的文件,这在按照日期解析日志文件,或者查看最近的网络爬虫运行结果时很有用处。

import os

def get_latest(folder):
  files = [os.path.join(folder, f) for f in os.listdir(folder)] ➊
  files.sort(key=lambda x: os.path.getmtime(x), reverse=True) ➋
  return files[0] ➌

❶ 使用 Python 内置的 os 模块列出每一个文件(listdir 方法),之后使用 path 模块的 join 方法创建一个长字符串,表示一个完整的文件路径。这是获取文件夹中所有文件的一种简单方式,只需要传递一个字符串(文件夹路径)。

❷ 通过最后修改时间来为文件排序。因为 files 是一个列表,所以我们可以调用 sort 方法,并且给它一个键作为排序的依据。这段代码传递完整的文件路径给 getmtime 函数,这是 os 模块“获取修改时间”的方法。reverse 参数确保最近的文件出现在列表的顶部。

❸ 返回最近的文件。

这段代码返回最近使用的文件夹,但是如果想要返回整个以最近使用文件开始的文件列表,我们可以直接修改代码,不返回第一个索引,而是返回整个列表或一个切片。

 os 库有很多强有力的工具来查找、修改和改变本地文件(或者服务器的本地文件)。在 Stack Overflow 上直接搜索会返回很多答案,例如如何找到过去 7 天内唯一修改的文件,或者过去一个月中唯一修改的 .csv 文件,等等。使用本地文件,特别是当你需要的数据已经存在时(或者很容易使用 wget 拿到),是一个很棒的简化自动化程序的方式。

02. 配置文件

为敏感信息创建本地配置文件是必需的。正像 Twelve-Factor 应用(http://12factor.net/config)中声称的那样,在代码主干之外保存配置(例如密码、登录名、邮件地址和其他的敏感信息)是成为一个好的开发者的一部分。如果你连接到数据库,发送一封邮件,使用 API 或保存支付信息,这些敏感数据应该保存在一个配置文件中。

通常情况下,我们在仓库内的一个独立文件夹存储配置文件(例如,config/)。仓库中的所有代码都会访问这些文件,但是通过使用 .gitignore 文件(见 8.4 节),可以保持这些配置文件在版本控制之外。如果有其他开发者或服务器需要这些文件,你需要手动复制它们。

 建议在仓库的 README.md 中使用一个小节,介绍特殊配置文件的位置以及如何处理它们,这样新用户和合作者知道向谁索要合适的文件。

使用文件夹而不是文件允许你在运行脚本的不同机器或环境中有不同的配置。你可能想要在测试环境中有一个配置文件,使用测试的 API key,并且在生产环境使用生产环境的配置文件。你可能想要根据脚本使用的机器使用多个数据库。你可以使用一个 .cfg 文件保存这些特殊信息,如下。

# 示例配置文件
[address] ➊
name = foo ➋
email = myemail@bar.com
postalcode = 10177
street = Schlangestr. 4
city = Berlin
telephone = 015745738292950383

[auth_login]
user = test@mysite.com
pass = goodpassword

[db]
name = my_awesome_db
user = script_user
password = 7CH+89053FJKwjker)
host = my.host.io

[email]
user = script.email@gmail.com
password = 788Fksjelwi&

❶ 每一小节用一对方括号和放置于方括号中间的一个容易阅读的字符串表示。

❷ 每一行包含一个 key = value 的序对。ConfigParser 将这些序对作为字符串解释。值可以包含任何的字符,包括特殊字符,但是键必需遵循 PEP-8 易于阅读的语法和结构。

在配置中有小节、键和值,这允许我们使用小节的名字和键访问配置的值。这增加了 Python 脚本的清晰度,而不会变得晦涩。一旦你有了一个类似前面示例中创建的配置文件,使用 Python 解析以及在脚本中使用和自动化就很简单了。下面是一个示例。

import ConfigParser
from some_api import get_client ➊
 
 
def get_config(env):
  config = ConfigParser.ConfigParser() ➋
  if env == 'PROD':
    return config.read(['config/production.cfg']) ➌
  elif env == 'TEST':
    return config.read(['config/test.cfg'])
  return config.read(['config/development.cfg']) ➍
 
 
def api_login():
  config = get_config('PROD') ➎
  my_client = get_client(config.get('api_login', 'user'),
               config.get('api_login', 'auth_key')) ➏
  return my_client

❶ 这是一个导入 API 客户端钩子的示例。

❷ 这段代码通过调用 ConfigParser 类初始化一个配置对象。现在这是一个空的配置对象。

❸ 这行代码调用配置解析器对象的 read 方法,并且传递一个配置文件的列表给这个函数。这里,在项目根目录下名为 config 的文件夹下保存所有的文件。

❹ 如果传递的环境变量不匹配生产环境或测试环境,则永远返回开发配置。在配置代码中做类似的判断是一个很好的做法,以防止定义环境变量失败的情况。

❺ 我们假设示例需要生产环境的 API,所以这行代码试图获取 PROD 配置。你同样可以保存这些不同环境的类型到 bash 环境中,并且使用内置的 os.environ 方法(https://docs.python.org/2/library/os.html#process-parameters)读取它们。

❻ 这行代码调用小节名称和键名称访问存储在配置中的值。这会将值作为字符串返回,所以如果你需要整数或者其他的类型,你需要转换它们。

内置的 ConfigParser 库使我们能够简单地访问配置文件中存储的小节、键和值。如果希望在不同的文件中存储不同的信息,并且为每个特定的脚本解析一个文件列表,你的代码应该类似这样:

config = ConfigParser.ConfigParser()
config.read(['config/email.cfg', 'config/database.cfg', 'config/staging.cfg'])

根据需求,由你组织代码和配置。访问配置值的语法很简单,只是使用配置中小节的名称(即 [section_name])和键的名称。所以,类似下面的配置文件:

[email]
user = test@mydomain.org
pass = my_super_password

可以通过下面的方式访问:

email_addy = config.get('email', 'user')
email_pass = config.get('email', 'pass')

 配置文件是一个将所有的敏感信息保存到一个地方的简单的工具。如果你更倾向于使用 .yml 或其他扩展类型的文件,Python 也有这些文件类型的读取器。确保使用某种手段将认证、敏感信息同代码分开存储。

03. 命令行参数

Python 让我们能够在自动化程序中传递命令行参数。这些参数传递关于脚本应该如何运行的信息。举个例子,如果需要脚本知道我们希望它使用开发配置运行,可以这样做:

python my_script.py DEV

我们正在使用相同的语法在命令行中运行一个文件,调用 python,之后是脚本名称,然后在这一行的最后添加 DEV。怎样才能使用 Python 解析额外的参数呢?让我们编写下面的代码:

from import_config import get_config
import sys
 
 
def main(env):
  config = get_config(env)
  print config
 
 
if __name__ == '__main__':
  if len(sys.argv) > 1: ➊
    env = sys.argv(1) ➋
  else:
    env = 'TEST'
  main(env) ➌

❶ 内置的 sys 模块,帮助完成系统任务,包括解析命令行参数。如果命令行参数列表的长度大于 1,这里存在额外的参数。第一个参数永远保存着脚本的名称(所以如果参数长度为 1,脚本名称是唯一的参数)。

❷ 为了得到参数的值,传递参数的索引到 sys 模块的 argv 方法。这行代码设置 env 为参数的值。记住,argv 方法的索引 0 永远是 Python 的脚本名称,所以从索引 1 开始解析参数。

❸ 这行代码使用解析后的参数,根据命令行参数修改代码。

 如果想要解析多个额外变量,可以测试参数的长度,来确保我们有足够的参数,之后再继续解析。你可以将任何数量的参数组合到一个字符串中,但是我们建议保持在 4 个以下。如果你需要 4 个以上的参数,考虑编写一些逻辑到脚本中(例如,在星期二只执行测试,所以如果今天是星期二,使用测试部分的代码,等等)。

参数变量在你需要重新使用相同的代码执行不同的任务或者在不同的环境下运行时很有用。或许你有一个脚本来收集或分析数据,并且希望能够切换使用的环境。你或许会像下面这样运行脚本:

python my_script.py DEV ANALYSIS
python my_script.py PROD COLLECTION

或者你可能有一个脚本需要同最近更新的文件夹进行交互,抓取最新的日志——比如从多个地方抓取日志:

python my_script.py DEV /var/log/apache2/
python my_script.py PROD /var/log/nginx/

有了命令行参数,参数变量的简单变化可以创建一个可移植和健壮的自动化程序。不是每一个脚本都需要使用这些额外的变量,但是有这样一个内置到标准库中的解决方案是很棒的,它同时提供了灵活性。

除了这些相当简单直接的方式来解析数据,给脚本额外的信息,你也可以使用更加复杂和分布式的方式,比如基于云计算的数据和数据存储。我们会在下面查看这部分内容。

14.5.2 在数据处理中使用云

这个名词通常用来代表一个资源共享池,例如服务器。有许多公司提供云服务——亚马逊网络服务(AWS),是最著名的云服务提供商之一。

 云这个词经常被过度使用。如果你正在云服务器上运行代码,最好说“我正在一个服务器上执行它”,而不是“我在云上执行它”。

什么时候适合使用云?如果数据太大,不能在自己的计算机上执行,或者程序需要很长的时间执行,云都是一个很好的处理方式。将大多数想要自动化的任务放到云上执行,这样你不用担心电脑打开或关闭时脚本是否在运行。

如果选择 AWS,第一次登录后会看到许多不同的服务选择。在数据处理中你只需要几种服务(见表 14-1)。

表14-1:AWS云服务

服务

在数据处理中的目的

简单存储服务(S3)

一个简单的文件存储服务,用来备份数据文件(JSON、XML 等)

弹性计算(EC2)

一个按需分配的服务器。这是运行脚本的地方

弹性 MapReduce(EMR)

通过一个托管的 Hadoop 框架提供分布式的数据处理进程

这些是你需要熟悉的基本的 AWS 服务。还有各种各样的竞争者,包括 IBM 的 Bluemix 和沃特森开发者云(让你得以使用各种大型数据平台,包括沃特森的逻辑和自然语言处理能力)。你还可以使用 DigitalOcean 或 Rackspace,它们提供了廉价的云资源。

无论使用什么,你都需要在云服务器上部署代码。为此,我们建议使用 Git(https://git-scm.com)。

使用Git部署Python

如果想让自动化程序运行在本地机器之外的地方,你需要部署 Python 脚本。我们会介绍几种简单的方式,然后介绍一些稍微复杂的方式。

 版本控制让你的团队在同一个仓库上并行工作,不会在每个人之间产生问题。Git 允许创建不同的分支,这样你或者团队中的其他人可以在特定的需求集合上工作,或者各自完成新的集成,然后将它们合并回代码主干,而不会丢失任何核心功能。它还能确保每个人有最新的代码(包括服务器和远程机器)。

部署 Python 最简单和直观的方式是使用 Git 把仓库置于版本控制之下,用 Git 部署钩子将代码移到远程机器上。首先,需要安装 Git(https://git-scm.com/book/en/v2/Getting-Started-Installing-Git)。

如果你是 Git 新手,建议你参加 GitHub 上的 Code School 入门教程(https://try.github.io/levels/1/challenges/1)或者浏览 Atlassian 上的 Git 入门教程(https://www.atlassian.com/git/tutorials/)。上手 Git 相当简单,你会很快掌握常用命令。如果你独自在仓库上工作,不用过于担心拉取远程变化的问题,但是设置一个清晰的工作日程总是好的。

一旦 Git 安装完成,在项目代码文件夹下运行下面这些命令。

git init . ➊
git add my_script.py ➋
git commit -a ➌

❶ 初始化当前工作目录为 Git 仓库的根目录。

❷ 添加 my_script.py 到仓库中。使用来自仓库的文件名或文件夹名称——不是配置文件!

❸ 将这些改变连同任何其他运行改变(-a)提交到仓库。

收到提示后,编写一个提交信息,简短地解释你做出的改变,这段解释应该明确并且清晰。你可能在之后需要找到哪个提交对应代码中的哪个改变。如果信息始终编写得很清晰,这会帮助你搜索和找到这些提交。这同样会帮助团队中的其他人或者合作者理解你的代码和提交。

 习惯于使用 git fetch 拉取远程变化,或使用 git pull --rebase 命令通过新的提交更新本地仓库。之后,在代码上工作,提交工作,推送提交到活跃的分支。当适合合并分支到主干时,你可以发送一个拉取请求(https://help.github.com/articles/using-pull-requests/),让其他人检查合并的代码,之后直接合并到主干。不要忘记删除没有用处的老的分支。

创建一个 .gitignore 文件是必需的,在这个文件中列出所有想让 Git 在推送 / 拉取时忽略的文件模式,正像在 8.4 节附注栏“Git 和 .gitignore”中讨论的那样。你可以在每个文件夹下使用一个文件,也可以只在仓库的基目录下使用一个。大多数的 Python .gitignore 文件类似于这样:

*.pyc
*.csv
*.log
config/*

这个文件会阻止仓库存储编译过的 Python 文件、CSV 文件、日志文件和配置文件。根据仓库文件夹中存在的其他文件类型,你可能想要添加更多的模式。

你可以在一些站点上挂载仓库。GitHub(https://github.com/)提供了免费的公开仓库,但是没有私有仓库。如果你需要代码是私有的,Bitbucket(https://bitbucket.org/)有免费的私有仓库。如果你已经开始在本地使用 Git,推送已有的 Git 仓库到 GitHub(https://help.github.com/articles/set-up-git/)或 Bitbucket(http://bit.ly/create_bitbucket_repo)是很简单的。

一旦创建了仓库,使用 Git 设置远程端点(服务器或服务器集群,http://git-scm.com/docs/git-remote)很简单。如果你正在部署一个使用 ssh 访问的目录,下面是一个示例。

git remote add deploy ssh://user@342.165.22.33/home/user/my_script

在推送代码到服务器之前,你需要以一些命令设置接收端的文件夹。在计划进行开发的服务器文件夹下运行这些命令:

git init .
git config core.worktree `pwd`
git config receive.denycurrentbranch ignore

这里初始化了一个空的仓库来从本地机器发送代码,同时定义了一些简单的配置,这样 Git 知道它是一个远程端点。你还需要创建一个推送—接收钩子。通过在刚刚初始化的文件夹 .git/hooks 下创建一个名为 post-receive 的可执行文件(通过许可),你可以创建一个钩子。这个文件会在部署端点接收到任何的 Git 推送后执行。它应该包含你需要在每一次推送后执行的所有任务,例如同步数据库、清理缓存或者重启任何的进程。至少,它会需要更新端点。

一个简单的 .git/hooks/post-receive 文件看起来类似于这样:

#!/bin/sh
git checkout -f
git reset --hard

这会重置所有本地的变化(在远程机器上)并且更新代码。

 你需要在本地机器上做出所有的修改,测试它们,之后推送它们到部署端点。从一开始就使用这种方式是好的习惯。通过这种方式,所有代码都在版本控制之下,你可以确保没有由于直接在服务器上修改代码而导致的断断续续的 bug 或错误。

一旦远程端点设置完成,你可以直接在本地仓库运行下面的命令,使用所有最新的提交更新服务器上的代码:

git push deploy master

这样做是一个非常棒的管理仓库和服务器或远程机器的方式;很容易使用和设置,也让迁移(如果需要的话)变得直观。

如果你刚开始接触部署和版本控制,建议你从 Git 开始,熟悉它之后再转而使用更复杂的部署选择,比如 Fabric(http://www.fabfile.org/)。在本章的后面,我们会介绍一些大规模的自动化工具,用于在多个服务器之间部署和管理代码。

14.5.3 使用并行处理

并行处理对脚本自动化来说是一个很棒的工具,让你可以在一个脚本中运行多个并发进程。如果脚本需要多个进程,Python 内置的 multiprocessing 库会成为你自动化的得力工具。如果你有一系列的任务需要并行执行,或者通过并行化可以加速执行任务,多重处理(multiprocessing)是合适的工具。

如何使用 multiprocessing 呢?下面是一个简单的示例:

from multiprocessing import Process, Manager ➊
import requests

ALL_URLS = ['google.com', 'bing.com', 'yahoo.com',
      'twitter.com', 'facebook.com', 'github.com',
      'python.org', 'myreallyneatsiteyoushouldread.com']


def is_up_or_not(url, is_up, lock): ➋
  resp = requests.get('http://www.isup.me/%s' % url) ➌
  if 'is up.' in resp.content: ➍
    is_up.append(url)
  else:
    with lock: ➎
      print 'HOLY CRAP %s is down!!!!!' % url


def get_procs(is_up, lock): ➏
  procs = []
  for url in ALL_URLS:
    procs.append(Process(target=is_up_or_not,
               args=(url, is_up, lock))) ➐
  return procs


def main():
  manager = Manager() ➑
  is_up = manager.list() ➒
  lock = manager.Lock() ➓
  for p in get_procs(is_up, lock):
    p.start()
    p.join()
  print is_up

if __name__ == '__main__':
  main()

❶ 从内置的 multiprocessing 库导入 Process 和 Manager 类,来帮助我们管理进程。

❷ 定义主要 worker 函数 is_up_or_not,培训需要 3 个参数:一个 URL、一个共享列表和一个共享锁。其中的列表和锁是在所有的进程间共享的,让其中的每一个进程能够修改或使用它们。

❸ 使用 requests 检查 isup.me,判定给定的 URL 当前是否在线并且可用。

❹ 测试是否可以在页面中找到文本“is up.”。如果文本存在,这个 URL 就是我们想要的。

❺ 通过 with 代码块调用锁的 acquire 方法。这会得到锁,继续执行下面缩进的代码,然后在代码块的最后释放锁。锁(http://www.laurentluce.com/posts/python-threads-synchronization-locks-rlocks-semaphores-conditions-events-and-queues/)是阻塞的,并且只能在代码中需要阻塞时使用(举个例子,如果你需要确保只有一个进程运行一组特殊的逻辑,比如检查一个共享值是否变化,或是否到达了一个终止点)。

❻ 当生成进程时,传递共享的锁和列表到函数中使用。

❼ 通过传递关键参数创建一个进程对象:目标(即,我应该执行哪个函数)和参数(即,使用什么参数)。这行代码追加所有的进程到一个列表,这样我们可以在一个地方管理它们。

❽ 初始化 Manager 对象,这帮助我们管理共享的对象和进程间的日志。

❾ 创建一个共享列表对象,跟踪每个站点的状态。每一个进程都能改变这个列表。

❿ 创建一个共享的锁对象,如果一个站点中不存在“is up”,停止并且宣布它。如果这些是我们管理的所有站点,我们可能有了一块重要的业务逻辑来处理紧急情况,也因此有了“停止所有程序”的理由。

⓫ 分别开始由函数 get_proc 返回的每一个进程。一旦它们开始执行,join 方法会让 Manager 对象和所有的子进程通信,直到最后一个进程完成。

使用多重处理的时候,你通常会有一个管理者进程和一堆子进程。你可以传递参数给子进程,可以使用共享内存和共享变量。这使你能够确定如何利用和架构 multiprocessing。根据脚本的需要,你或许想要让管理器运行脚本中一系列的逻辑,同时使用子进程运行高延迟或长时间运行的部分代码。

 共享锁对象(https://docs.python.org/2/library/threading.html#lock-objects)提供了同步执行多个进程的能力,同时能保护内部逻辑的特定区域。有效使用它们的一个方式是直接放置锁逻辑到 with(https://docs.python.org/2/library/threading.html#using-locks-conditions-and-semaphores-in-the-with-statement)语句中。

如果不确定脚本是否适合使用多重处理,可以先测试脚本中的一部分代码或者一个子任务,确定你是否能够实现并行编程的目标,或者它是否将逻辑复杂化了。有一些任务使用大规模的自动化和队列来处理会更好,我们会在本章的后面讨论。

14.5.4 使用分布式处理

除了并行处理和多重处理,还有分布式处理,它分发进程到多台机器上(不同于发生在一台机器上的并行处理)。当计算机可以处理时,并行处理更快,但是有些时候你需要更强大的能力。

 分布式处理涉及多个类型的计算问题。有些工具和库可以管理分布在多台计算机上的进程,还有些工具和库可以管理跨越计算机的存储。与这些问题相关的概念包括分布式计算、MapReduce、Hadoop、HDFS、Spark、Pig 和 Hive。

在 2008 年早期,克林顿总统图书馆和国家档案局发布了希拉里·克林顿在 1993 年到 2001 年作为第一夫人的日程表。这份文档包含 17 000 多页的 PDF 图片,为了将其转换为有用的数据集,需要进行光学字符识别,或者使用 OCR 技术。由于正值民主党总统候选人初选阶段,新闻组织想要发布这份数据。为了完成这项工作,《华盛顿邮报》使用了分布式进程服务,将 17 000 多张图片转化为文本。通过分发工作到 100 多台计算机上,他们不到 24 小时就完成了这项工作。

使用类似 Hadoop 的框架的分布式处理包含两个主要的步骤。第一步是映射数据或输入。

这一进程像是一个过滤器。使用映射器说“分离文本文件中所有的单词”或者“分离过去一个小时里推文中包含特定标签的所有用户”。下一步是 reduce(规约)映射后的数据为可用的形式。这类似于在第 9 章使用的聚合函数。如果我们查看所有来自 Spritzer feed 的 Twitter 句柄,可能想要根据不同的地理信息或主题统计每一个句柄的推文数量,或者所有句柄的聚合(即,所有来自这一时区的使用这些单词最多的推文)。规约部分帮助我们处理这些大数据,“规约”它为可阅读和可操作的报告。

正如你可能看到的,不是所有的数据集都需要 map-reduce,而且 MapReduce 背后的理论已经在许多 Python 数据库中可用。无论怎样,如果你有一个非常大的数据集,使用类似 Hadoop 的 MapReduce 工具会节省大量的计算时间。如果你需要一个很棒的教程,建议你阅读 Micheal Noll 写的关于用 Python 编写 Hadoop MapReduce 程序的指南(http://www.michael-noll.com/tutorials/writing-an-hadoop-mapreduce-program-in-python/),它使用一个单词计数程序来探索 Python 和 Hadoop。还有很棒的关于 mrjob(https://pythonhosted.org/mrjob/)的文档,由在 Yelp(http://www.yelp.com)的开发者编写和维护。如果你想要阅读更多关于这个主题的信息,可以查看 Kevin Schmidt 和 Christopher Phillips 的图书 Programming Elastic MapReduce(O'Reilly)。

如果数据集很大,但是分离存储或是实时的(或接近实时),你可能想要了解一下另外一个 Apache 项目——Spark(http://spark.apache.org/)。Spark 因为它的速度、机器学习的使用和处理流的能力获得了流行。如果你的任务处理实时的流数据(来自服务、API,甚至是日志),那么相对于 Hadoop,Spark 会是一个更灵活的选择,它可以处理相同的 MapResuce 计算结构。在你需要使用机器学习或其他需要生成数据并且“喂”给数据集群的数据分析时,Spark 也很有效。PySpark(http://spark.apache.org/docs/latest/api/python/)是 Spark 的 Python API 库,由相同的开发者维护,让你能够在 Spark 进程中编写 Python。

为了开始使用 Spark,建议你阅读 Benjamin Bengfort 的详细的博客文章(https://districtdatalabs.silvrback.com/getting-started-with-spark-in-python),其内容包括如何安装 Spark,同 Jupyter notebook 集成,以及创建第一个项目。你同样可以查看 John Ramey 关于 PySpark 和 Jupyter notebook 集成的文章(http://ramhiser.com/2015/02/01/configuring-ipython-notebook-support-for-pyspark/),在你的 notebook 中进一步探索数据收集和分析的可能性。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文