Help us understand the problem. What is going on with this article?

AWS LambdaでPythonをSchedule実行させる

More than 3 years have passed since last update.

はじめに

2015/10のAmazon re:Invent 2015で、Lambdaに関して幾つかの機能追加が発表されました。
個人的に大きいのは以下の3つです。

  • Lambda functionをPythonで記述できる
  • Lambda functionをSchedule実行させる事ができる
  • Lambda functionの最大実行時間が5分に拡張された (従来は1分)

AWS LambdaをData Pipelineを使ってSchedule Drivenで起動させる記事を以前書いたのですが、Schedule実行の機能はLambdaの標準機能としてサポートされました。この記事ではLambda functionをPythonを使って記述し、Schedule実行させる手順をチラ裏しておきます。

制限事項

今回発表/追加されたLambda + Python + Scheduleの実行環境ですが、気を付けて置くべき制限があります。大きいのは以下の項目です。

  • Lambda functionの処理は5分以内に終了させないとErrorになる(なので時間がかかる処理には使えない)
  • Schedule実行の最短周期は5分 (なので1分に1回Lambda functionを実行する、とかはできない)
  • PythonはVer 2.7のみ対応 (3.xは現時点で対応されていない)
  • PythonでPython2.7の標準library以外をimportして使用するには、library毎zip圧縮してUploadする必要がある(手順は後述)

Case1:5分毎にPythonのPrintで出力をしてみる

一番最初のCase studyとして、単にPrintするだけのPython Scriptを、5分毎のSchedule実行させる、という一番ベタなケースです。Schedule実行の結果が正しく出力されているかLogを見てみます。

AWS ConsoleのLambdaから、Create a Lambda functionを選択します。

Step1 雛形(blueprint=青写真)の選択

Lambda functionの雛形が沢山ありますがlambda-canaryを検索して選びます。Lambda function上で、Python scriptをSchedule実行させる雛形です。

select_blueprint.png

Step2 Event sourceの設定

今回はSchedule実行なので、Event sourceにはScheduled Eventを選択します(defaultで選ばれていると思います)。
NameDescriptionは適当な説明文を入れればOKです。
Schedule expressionはdefaultでrate(5 minutes)になっているはずなのでそのままで良いです。

Configure_event_sources.png

Step3 Python scriptの設定

Python scriptと、IAM roleの設定を行います。

Pythonのcodeは以下を使います。ひたすらprintするだけのCodeです。

import json, datetime, commands

def lambda_handler(event, context):
    print commands.getoutput('cat /proc/cpuinfo | grep -e "processor" -e "model name"')
    print commands.getoutput('cat /proc/meminfo | grep MemTotal')
    print commands.getoutput('cat /proc/meminfo | grep MemFree')
    print datetime.datetime.now().strftime('%Y/%m/%d %H:%M')  
    print '-------------------------------'

    print event
    print event['account']
    print context.__dict__
    print context.memory_limit_in_mb

Python script以外は、以下の設定が必要です。他はDefaultのママで良いです。

  • NameはLambda functionの名前です。(他のLambda functionと被らなければ)適当な文字列で良いです。
  • RoleはLambda functionに付与するIAM roleです。今回は他のAWS Resourceにアクセスしないので、lambda_basic_executionを選択すれば良いです(lambda_basic_executionと言うIAM roleが無い場合には、この名前のroleを作成する事になります)。

Configure_function.png

Step4 設定確認

最終確認です。Enable nowを選択すると、この設定でSchedule実行がEnableされます。Enable nowを選択しCreate functionを押せば完成です。

Review.png

Step5 Print出力された結果を確認

Lambda functionの出力結果は、CloudWatch logsに保存されます。
AWS ConsoleのCloudWatchのLogsから、Lambda_Testを選択します。すると、5分毎に実行Logが追加され、printした内容がLogに残っていると思います。

CloudWatchLogs.png

Python scriptの補足

  • Python2.7に標準で入って居るLibraryは、import json, datetime, commandsの様に書けばOKです
  • mainというmethodは無く、lambda_handlerというMethodがEntry pointとして(event, contextという引数で)呼ばれます。 Entry pointの関数はConfigurationHandlerで指定を変える事が可能です event_hander.png
  • Entry pointの引数であるevent, contextの中身は、何をEvent sourceとするかで違ってきています。printでevent, contextの中身を吐き出しているので、チェックしてみてください。

Case2:Schedule実行の周期を5分毎から10分毎に変えてみる

Step1 古いSchedule実行設定の削除

AWS ConsoleのLambdaから、先ほど作ったLambda_TestのfunctionのEvent sourcesのタブに行きます。
rate(5 minutes)で設定したSchedule実行をxで一旦削除し、Add event sourceを選択します
EditEventSource.png

Step2 10分毎のSchedule実行の設定

Add event sourceのDialogで、Event sources typeScheduled Eventを選択し、以下の様にDialogを埋めます。

  • NameDescriptionは適当な説明文を入れる
  • schedule expressioncronを選択し、cron(0/10 * * * ? *)と書く

ここで注意なのは、Lambdaのcronの文法が、いわゆるLinux一般のcronの文法と微妙に違う点です。
この記事を参考にcron(0/10 * * * ? *)と書いてください。

EditEventSource2.png

Enable nowを選択すると、この設定でSchedule実行がされます。10分毎に実行LogがCloudWatch logsにあるか確認して見て下さい。

Case3:標準ではないLibraryを入れてみる

numpypandasrequestsと言った、Python2.7標準では無いlibraryをLambda + Pythonで使いたい場合は、Script fileそのものと合わせてLibraryも一緒にzipしてuploadして上げる必要があります。詳細は、AWS公式サイトのCreating a Deployment Package (Python)を参照して下さい。

Step1 Python scriptをfileとして保存

以下のPython scriptをLocalに保存します (ここではLambdaTest.pyと言うfile名で保存する想定で進めます)。
Python Scriptの中身は、requestslibraryを使ってgoogle.co.jpをHTTP GETして、Status CodeとResponse BodyをPrintするものです。

LambdaTest.py
import requests, datetime

def lambda_handler(event, context):
  target_URL = 'https://www.google.co.jp'

  r = requests.get(target_URL)
  print datetime.datetime.now().strftime('%Y/%m/%d %H:%M') 
  print '-------------------------------'
  print r.status_code
  print '-------------------------------'
  print r.text

requestsと言う、Python2.7標準に無いlibraryが必要なので、このCodeをこのままLambdaに登録するとErrorになります。そのため、requestsのlibrary fileを同じフォルダに置き、zip圧縮して、zipをLambdaに登録します。

Step2 Libraryを含んだzip fileを作成

pip install-t /PathTo/LambdaTest.py optionで実行すると、指定したフォルダにlibrary fileを配置してくれます。例えば、LambdaTest.pyが/home/hogeに有るとしたら、pip install -t /home/hogeと実行すればOKです。

以下みたいなファイル構成になるはずです。これら(フォルダが2個、ファイルが1個)をzip圧縮して、適当な名前を付けます(LambdaLibraryZip.zipとしたとします)

folder.png

Step3 Entry Pointの関数名を変更

Lambda functionのCodeをzipでUploadする場合、Entry Pointの関数名(Pythonのmain関数)が*.pyのファイル名 + . + Scriptの中のEntry Pointの関数となります。今回の例で言うと、LambdaTest.lambda_handlerと設定する必要があります。ConfigurationタブのHandlerLambdaTest.lambda_handlerと設定します

HanderName.png

Step4 zip fileをUploadして実行

Codeタブから、Upload a .ZIP fileで、先ほど作成したLambdaLibraryZip.zipをUploadして、Save and testをクリックして、Python Scriptが正しく実行されているか確認してみてください。

uploadzip.png

最後に

LambdaのPython対応、Schedule実行対応は、Python Loveな私的にはとても良いNewsです。Amazonの掲げる2 tier Architecture、もしくはサーバレスアーキテクチャへの大きな布石になると思います(そしてAmazonにどんどんLockinされていく...)。

ただ、まだLambda + Python + Schedule実行でも置き換えられない領域が幾つかあると思います。

短い周期での実行が必要なケース

Lambdaの最短実行周期は5分です。これで多くのニーズはカバーされると思いますが、『1分毎にStatus Checkや死活監視したい』などの要件もやはりあります。Server-lessで短い周期のSchedule実行を行うAWS serviceを自分は知らないです(知っていたら教えてください)。

Amazonが出してきた提案は、EC2 t2.nano Instanceなのでは、と思っています。現行のt2.microよりも更に安いInstanceを用意してヤッから、これ使ってチラシの裏にでも書いてな、って事です。

処理に時間かかかるケース

Lambdaの最大処理時間は今回5分に拡張されました(従来は1分でした)。1分だった時は、S3のLogをLocalに持って来て、中身をParseして、Errorが見つかったらAlarmを発動しつつ結果をRDSに書き込んでおくと言った処理をLambda functionでする時に、Log sizeが数100MBを超えるとTimeoutするようなケースがありましたが、今回の5分への拡張で多くのニーズはカバーされると思います。が、『大量のDataのDailyのETL Batch処理』などの処理の時間が必要な要件もやはりあります。

自分の知る限り、この手の演算やData転送で処理に時間が掛かる要件には、

が良いんじゃないかなぁ、と思っています。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away