KAKEHASHI Tech Blog

カケハシのEngineer Teamによるブログです。

AWS Glue Crawlerを利用した分析用テーブルの構築

こちらの記事は カケハシ Advent Calendar 2023 の3日目の記事になります。

こんにちは、カケハシで Musubi AI在庫管理 の開発をしているMLエンジニアの藤本です。

Musubi AI在庫管理 ではS3に出力している内容に関する分析用テーブルの管理にAWS Glue Crawlerを利用しています。

今回は、分析用テーブルを管理する際のAWS Glue Crawlerの使い方と注意点について紹介できればと思います。

Musubi AI在庫管理でのAWS Glue Crawlerの利用方法

Musubi AI在庫管理(以下、AI在庫)では適切な在庫管理を行う為、以下の予測を出しています。

  • 来局予測
  • 発注点予測
  • 需要予測に基づいた発注のおすすめリスト

AI在庫管理の予測機能は他のバックエンド機能に対して疎結合な構成となっており、予測された値はS3上に出力された後にSQSを介してバックエンド側に連携され、バックエンド側では当日予測された結果のみを持っています。

予測結果の連携フロー

過去の予測結果はS3上にあって分析するには扱いづらい状態になっているため、Glueデータカタログで管理しており、定期的なメタデータの更新にAWS Glue Crawlerを導入しています。

AWS Glue Crawlerはテーブル定義の自動作成、更新や、パーティションが増えたときのメタデータの更新を行ってくれますが、誤判定で意図しない変更があると困るのでテーブル定義は別途明示的に行い、AWS Glue Crawlerによる更新は行っていません。 日々の予測が蓄積されていくにつれパーティションが増えていくので、そのメタデータ更新のためにAWS Glue Crawlerを利用しています。

カケハシでは分析基盤としてDatabricksを導入していますので、データカタログに登録された予測結果はDatabricksに連携して、Databricks上でNotebookやクエリ上から参照して評価や分析を行う事ができるようになっています。

S3にある予測結果のデータ連携フロー

AWS CDKによるAWS Glue Crawlerの構成

AWS Glue CrawlerはTerraformやAWS CDKなどのIaCツールで構成する事ができます。AI在庫管理の需要予測システムではAWS CDKを使ってインフラを構成しているため、AWS CDKでGlue Crawlerを構成する例をご紹介したいと思います。

CDKは各種のAWSリソースがPythonやTypeScriptにおけるオブジェクトとなっていて、コード補完がとてもよく効くので、機械学習エンジニアにとってもインフラ構成がやりやすいIaCツールになります。

注意点としては、クロール対象のS3が想定通りの階層になっていないとパーティション更新に失敗したり他のところまで更新されてしまうといった現象が起こります。

後は設定したスケジュールに則ってCrawlerが動作し、日々の予測結果をデータカタログ上に更新するようになります。

import { aws_iam as iam, aws_s3 as s3, aws_glue as glue } from 'aws-cdk-lib';

// 対象のS3
const bucket = new s3.Bucket(this, 's3bucket', {
  bucketName: 'test-bucket',
});

// role定義
const crawlerRole = new iam.Role(this, 'iamrole-gluecrawler', {
  assumedBy: new iam.ServicePrincipal('glue.amazonaws.com'),
  managedPolicies: [iam.ManagedPolicy.fromAwsManagedPolicyName('service-role/AWSGlueServiceRole')],
});

bucket.grantRead(crawlerRole);
bucket.grantPut(crawlerRole);

// crawlerプロパティ定義
const crawlerProps: glue.CfnCrawlerProps = {
  role: crawlerRole.roleArn,
  targets: {
    // クローラー対象を指定、Glue Data Catalogを指定している
    catalogTargets: [
      {
        databaseName: 'testdatabase',
        tables: ['testtable'],
      },
    ],
  },
  name: 'gluecrawler-name',
  // 変更されたテーブルスキーマを検出した時の動作設定 https://docs.aws.amazon.com/ja_jp/glue/latest/dg/crawler-configuration.html#crawler-configure-changes-api
  schemaChangePolicy: {
    // 変更を無視してテーブルを更新しない設定
    updateBehavior: 'LOG',
    deleteBehavior: 'LOG',
  },
  schedule: {
    // スケジュールを設定することでクローラーを定期実行できる
    scheduleExpression: 'cron(30 23 * * ? *)',
  },

  // 全てのパーティションに対して更新をかける設定 https://docs.aws.amazon.com/ja_jp/glue/latest/dg/crawler-configuration.html#crawler-configure-changes-api
  configuration:
    '{"Version": 1.0 ,"CrawlerOutput": {"Partitions": { "AddOrUpdateBehavior": "InheritFromTable" }}}',
};

// crawler作成、CfnCrawlerについてはL1 constructsのみの提供となっている https://docs.aws.amazon.com/ja_jp/cdk/v2/guide/constructs.html#constructs_lib
new glue.CfnCrawler(this, `testcrawler`, crawlerProps);

運用上の注意点

上記で紹介したCrawlerの設定はテーブルの更新を既存のデータを含め行うような設定になっていますが、データが多くなってくるとコストが膨らんできます。増分クロールでの運用が可能であればそちらの設定で実装した方が良いかと思います。

また、S3で保存しているファイル形式がcsvの場合、連携先のテーブルについてカラムの追加や変更があった時には旧テーブルのマイグレーションが必要になります。とくに、カラムの追加や削除時にはマイグレーションを行わないとカラムずれが発生し、Aのカラムを指定したらBのカラムの内容が取れてしまうような現象が起こり、分析に影響が出てしまいます。

最後に

今回は分析用テーブルの構築をAWS Glue Crawlerで行うやり方についてご紹介しました。CrawlerではS3の他にも複数のデータソースから情報を統合して分析しやすい環境を構築できますので、分析が難しい場所にデータがある・複数データソースがある等の課題を感じられている方に今回の記事が参考になれば幸いです。