Photoruction工事中!

Photoructionの開発ブログです!

AWS Lambdaで効率よく本番・検証環境をわける!

こんにちは!株式会社フォトラクションでWEB開発をしている下川原です。

Photoruction Advent Calendar 2022の4日目の記事になります。

はじめに

どんな人がこの記事を読むと幸せになるか。

  • AWS Lambdaで開発を進めてる人(言語問わず)
  • AWS Lambdaのソースをコピーして検証環境・本番環境を作っちゃってる人

AWS Lambdaを環境ごとに分ける!

1. 下準備

まずは、検証用、本番用にする直前のLambda関数ができていることが重要!

2.バージョンを作成する(AWS CLIで行う場合)

aws lambda publish-version --function-name myTestsFunctions --description "とりあえず動くようにした"

(説明)
aws lambda publish-version バージョンを作成するコマンド

オプション

--function-name 関数を指定

--description バージョン説明を記載(わかりやすい説明が良い)

コマンドを実行後の内容を控えておく。(Versionが大事)

{
  "FunctionName": "myTestsFunctions",
  "FunctionArn": "arn:aws:lambda:ap-northeast-1:******:function:myTestsFunctions:1",
  "Version": "1",
  ...
}

2.バージョンを作成する(AWSコンソールで行う場合)

lambda関数の画面からバージョン

[新しいバージョンを発行]

押すと、バージョン説明を入力してその時点のソースコードでバージョンができる

バージョン説明は、わかりやすくすると良い。

3.エイリアスを作成する(AWS CLIで行う場合)

aws lambda create-alias --function-name myTestsFunctions --name staging --function-version 1 --description "検証用"

・説明
aws lambda create-alias エイリアスを新たに作るコマンド

オプション

--function-name 関数を指定
--name エイリアスの名前(staging , production, develop用途に応じてどうぞ)
--function-version エイリアスに設定するバージョンを設定
--description バージョン説明を記載(わかりやすい説明が良い)

3. エイリアスを作成する(AWSコンソールで行う場合)

4.再度ソースコードの修正を行いたい場合

ソースコードの修正を終えて

手順2を再度行うことで、新しいバージョンを発行する。

そのあと、エイリアスを更新する

エイリアスを更新(AWS CLIで行う場合)

aws lambda update-alias --function-name myTestsFunctions --name staging --function-version 2

・説明
aws lambda update-alias エイリアスを更新するコマンド

オプション

--function-name 関数を指定
--name エイリアスの名前(staging , production, develop用途に応じてどうぞ)
--function-version エイリアスに設定するバージョンを設定
--description バージョン説明を記載(わかりやすい説明が良い)

エイリアスを更新(AWS コンソールで行う場合)

エイリアスの設定画面 > 一般設定 > 編集

新たなバージョンを選択して保存をする

さいごに

Lambda関数を本番用、ステージング用、開発用と別けるのではなく、

バージョン管理とエイリアスをしっかり設定することで、

即座に反映したい環境へ、反映ができるので活用していただきたい。

参考

https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/configuration-versions.html

https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/configuration-aliases.html#configuration-aliases-config

株式会社フォトラクションでは一緒に働く仲間を募集しています

テストケース作成等で、同一セル内に連番を振る方法

QAエンジニアの山本です。

Excel/スプレッドシートの同一セル内に、連番を振る方法を共有します。

Excel/スプレッドシートに同一セル内に連番を振る機能はないのですが、テストケースを作成時は、一つのセル内に連番を振りたいです。 私は最初、手入力で連番を振っていたのですが、これが地味に手間がかかります。 調べてみた所、Visual Studio Code(以下:VS Code)の拡張機能を使用すれば、簡単に連番を振れる事が分かりました。

VS Code拡張機能を使用して連番を振るメリットとして、私は下記の2つを実感しています。

  1. 連番を振る時間を約半分に短縮出来る
  2. (番号の打ち間違えを気にする必要がないので)連番を振る時のストレスがほとんどない

手順の詳細は下記の通りです。

  1. 公式ページから、VS Codeをインストールする
  2. VS Codeを開く
  3. サイドバーの「Extensions」/「拡張機能」を開く
  4. Japanese Language Pack for Visual Studio Code」と「vscode-input-sequence」をインストールする

    ※「Japanese Language Pack for Visual Studio Code」はVS CodeのUIを日本語に変換する拡張機能です

    ※「vscode-input-sequence」は連番を振るための拡張機能です

  5. VS Codeを再起動して拡張機能を有効化する

  6. VS Codeで新規ファイルを開く
  7. Excel/スプレッドシートのセル内の値をVS Codeのファイルにコピー&ペーストする
  8. ctrl+alt+下矢印キー/command+option+下矢印キーをクリックしてマルチカーソルにする
  9. ctrl+alt+0/command+option+0をクリックしてインプットパネルを開く
  10. インプットパネルに連番の一番最初の数字を入力してenterをクリックする
  11. 右矢印キーをクリックして入力を確定する

    ※必要に応じて「.」「,」などを追加する

  12. 値をExcel/スプレッドシートのセルにコピー&ペーストする

完成!

まとめ

この記事では、テストケース作成等で、同一セル内に連番を振る方法を共有しました。

この記事が、少しでも皆様のお役に立てれば幸いです。

株式会社フォトラクションでは一緒に働く仲間を募集しています

社内イベント「めざせフォトラクションマスター」開催

はじめに


Photoruction Advent Calendar 2022の2日目です!

こんにちは、株式会社フォトラクションCTOの中村でございます。

突然ではありますが、職場がフルリモートのエンジニア及び特にマネージャーの皆様!

フルリモートの状況で開発効率は上げられておりますか??

なかなか難しいですよね?

うん、うん、わかります、わかります。

これから「フルリモート環境における開発組織チームビルディング」をテーマに、

弊社での取り組みを時々共有させていただきますので、皆様の何かの気付きに少しでもなれれば幸いです。

完全出社制からフルリモートへ


弊社も多くの企業同様コロナ以前は完全出社制でしたが、コロナ直後から全社的にフルリモートへ移行しました。 現在も一部業種を除いて基本フルリモート制になっております。最近はビジネスやコーポレート系の部署のメンバーは週何度が出社する人が増えてきましたが、エンジニアに関してはほぼ出社することはありません。 またフルリモート制を採用したこともあり、関東圏以外のメンバーも増えてきいる状況です。

フルリモートを続けるには・・・


世間ではリモートワークの制度見直しや、出社回帰が騒がれだし、外資のIT大手もそちらの方向に向かってますし、某イーロンさんの日々の発言からもその状況はますます加速しそうですよね。

リモートワーク自体のメリットデメリットはいろいろなメディアで取り上げられているので特に言及はしないのですが、リモートのメリットを享受し続けるには組織として成果を出し、その環境でも問題ないことを証明し続けないといけないことは明白な感じです。

成果を上げていける開発組織はと考えたときに、色々あるとは思いますが、まぁまずは良いチームであることかなと。

信頼関係を築く


良いチームとはと問うと、様々な意見が出てくるとは思いますが、突き詰めると信頼関係の構築された環境であることかと思います。

我々はそうなっているのか?

雰囲気が特段悪いわけでもないですし、開発に関しても致命的な問題は起きてはいないのですが、まだメンバー同士に多少距離感あることは否めず、この辺りが縮まってもっとお互い理解できてくると、もっとよい開発組織になるのになぁと。

私が今年3月入社なので知らなかったのですが、会社に一度も来たことがないし、他の社員とオフラインであったことがない人がとても多いという事実が各メンバーと話す中で知りました。

リモートのみで信頼関係を築くのは効率悪いですよね。

自分の役割はメンバーそれぞれが深くコミュニケーションを取れる場をつくり、お互いを知る機会を作ることであると認識しました。リモートでの施策はシャッフルランチ、LT会、勉強会などいつくか行っているので、新たには実際会って話せるものがいいなとコロナ後初めてのエンジニア向けのオフラインイベントを12/2に開催することにしました。やっぱ一度会ったことあるのと無いのでは大違いだと思うのです。場所は半数以上のメンバーがオフィスにきたことがこともあり、オフィスに決めました。

折角オフラインで会うのだし、有用なイベントにするには


オフラインイベントを行うことは決めたので、次はテーマやコンテンツをどうするか。

最初はコンテンツはアプリ開発コンテストや新規事業案の提案、技術的負債の解消など、場所はちょっとした避暑地で1泊2日位で計画を進めていました。

ただ、メンバー同士も会ったことが人が多い状況で、いきなり泊まりやチームワークを要する凝ったコンテンツは上手く行かないのではないかと感じました。

そんな中、開発組織ももっとプロダクトに寄り添いユーザに必要な機能を企画開発していきたいというメンバーの声を多く聞くようになり、それをどのように実現してかも課題の一つだったのですが、入社が間もなかったり、ある程度在籍しても特定の領域のみ開発しているメンバーは、我々が提供するサービス:建設生産支援クラウド「フォトラクション」が現場ではどのように利用されているをあまりイメージできていないということに気づきました。ユーザーに必要な機能の企画開発にはプロダクト理解が必須です。開発組織全体でのプロダクト理解を深めることで、他部署とのより良い連携、質の良いユーザヒアリングなどに繋がり、最終的にはフォトラクションのサービスの質を上げることができると思います。

「めざせフォトラクションマスター」の開催へ


そこで、建設生産支援クラウド「フォトラクション」をリアルな現場の作業を想定したワークショップを通じ、プロダクト理解を深め、全員がフォトラクションマスターになれるようことをテーマとしたコンテンツに決めました。業務に詳しいメンバーと共に現場のユーザが実際に行っている作業をベースに課題を作っております。初めての試みなので、いろいろ問題は起きると思いますが、今回のイベントを通じて一人でもプロダクト理解が深まり、メンバーそれぞれがより仲良くなれるきっかけになれば思っております。

さいごに


こちら最後まで読んでいただきありがとうございます。

この投稿が出る日に実際イベントが開催されるのですが、より具体的な内容や、良かった点や反省点など別途レポートいたしますので、またよかったら読んでいただけると幸いです

株式会社フォトラクションでは一緒に働く仲間を募集しています

チームでドラッカー風エクササイズをやってみた

こんにちは!株式会社フォトラクションでプロダクトマネージャーをしています南風原はえばる)です。

Photoruction Advent Calendar 2022の1日目の記事になります。

きっかけ

この記事を読んでくれているみなさんは、ドラッカー風エクササイズをご存知でしょうか?

私がこの言葉と出会ったのは社内で週1で開催している輪読会の中です。

また、社外のエンジニアイベントに参加した際、実際にチームで取り組んだ方の話を聞いてぜひうちのチームでもやってみたいと思いました。

というのも、9月からチームが再結成し新メンバーも加入してきたタイミングだったため、メンバー同士の理解を深めていきたかったのと、お互いに期待していることのすり合わせを行うことでよりチームとして結束してプロダクト開発を進めていきたいという気持ちもありました。

ドラッカー風エクササイズとは

  • 書籍「アジャイルサムライ」で紹介された、チームメンバー同士でお互いの考えを交換し合う手法です。
  • 4つの質問にそれぞれ答え、チームメンバーに共有することで、お互いの考えや価値観、期待のすり合わせを行います。

    【4つの質問】

    1. 自分は何が得意なのか?
    2. 自分はどういう風に仕事をするか?
    3. 自分が大切に思う価値はなにか?
    4. チームメンバーは自分にどんな成果を期待してると思うか?

どうやったのか?

今回は、「お互いを知る」ことと「お互いの期待を知る」ことを第一目的としたかったので、本家の4つ質問を少しアレンジして以下の質問に答えていく形をとりました。

【4つの質問】

  1. 自分の得意なこと?
    • 業務における得意分野、性格的な特性。他人と比較せず、自分が得意だと思うことでOK
  2. 仕事をする上で大切にしている価値観
    • 仕事のスタイル、こんなことでモチベ上がる、これは避けてるなど
  3. チームメンバーから期待されていると思うこと
  4. メンバーに対して期待すること

進め方としては、最初に質問1~3を各自記入しそれぞれ共有してもらってメンバー同士の理解を深める時間をとりました。

最後に質問4を記入してメンバーに期待していることと、自分が期待されていると思っていたところのすり合わせや感想を言い合う時間をとりました。

ツールはMiroを用いて行いました↓

まとめ

実際やってみての感想としてメンバーからは以下のような声をいただきました。

  • 普段、業務をする中で仕事に対する価値観や大切にしていることを考える機会がないのでこの時間で考えるきっかけになって良かった
  • 他のメンバーの大切にしている価値観とかを知ることができて新しい発見になった
  • メンバーから期待されていることが知れて良かった …etc

普段、業務に追われて中々こういったチームビルディングを目的としたワークショップを開催できずにいたのですが今回ノリでやってみよ〜と提案し、実際に開催することができよかったです。

(ノリに乗ってくれたチームメンバーには感謝!!)

実際に開催してみて、個人としてもメンバーの得意なこと考えていることや価値観、期待していることなどを知ることができたのでとても有意義な時間でした。

一度の開催で終わらせずに定期的に開催していこうと思います。

株式会社フォトラクションでは一緒に働く仲間を募集しています

光学文字認識(OCR)をフロントエンドで実装してみました

こんにちは。webチームのジョンです。

今回実装するのはクライアントサイドで走るOCRになります。

始める前にご注意を!

そのため、ライブラリーのパフォーマンスはクライアントのパソコンのスペック次第になります。 クライアント側のスペックがそこそこ必要なため、商用利用は非推奨です。

自分のサイトにまともなOCR機能を実装したい場合はバックエンドで走らせるか(今回使うライブラリーもバックエンドで走らせます)、他のサービス(Amazon TextractやGoogle Vision Apiなど)を使用するかをご検討してください。

光学文字認識 (OCR) とは

光学文字認識 (OCR) は簡単に説明しますとテキストの画像を機械で読み取り可能なテキスト形式に変換するプロセスです。

光学文字認識OCRは決して新しい技術ではありません。現代のスマホにも既にある機能です。iOS15からライブテキストという機能があり、iPhoneで取った写真のテキストを自動的に読み込まれます。スマホのアプリストアからも「ドキュメントスキャナー」などを検索すれば、いろんなOCRアプリが出てきます。

技術スタック

OCRブラウザーのクライアントサイドに走らせるため、Javascriptの知識は必須になります。

パッケージマネージャを使う場合はNodeJsの知識、少しでも必要になります。

さて、今回使うライブラリーはTesseract.jsというライブラリーになります。このライブラリーはTesseract OCRからJavascriptにポートされたライブラリーとなります。Tesseractは元々ヒューレット・パッカード(HP)が開発して2005年にオープンソースされたOCRエンジンです。2006年から2018年まではGoogleがメンテしていました。

インストール方法

インストール方法は2つあります。おすすめはパッケージマネージャを使ってインストールする方法です。でももしパッケージマネジャを使えないもしくはそもそも使っていない既存案件にインストールしたい場合はCDN URLからライブラリーを使えます。

CDN

<script src='https://cdnjs.cloudflare.com/ajax/libs/tesseract.js/3.0.3/tesseract.min.js'></script>

スクリプトタグを埋め込んだ後にTesseractというグローバル変数がアクセスできるようになります。

Tesseract.jsのGithubページでインストール方法のところにバージョン1とバージョン2のインストール方法しか書かれていないため、別のCDNを使いました。他のバージョンを使いたい場合はこちらから参照してください。

パッケージマネジャ

# For v3
npm install tesseract.js
yarn add tesseract.js

# For v2
npm install tesseract.js@2
yarn add tesseract.js@2

パッケージマネジャからインストールする場合はバージョン3がNodeJsバージョン14以上は必要になります。

使用方法

Tesseract.jsのGithubページではTesseract基本の使い方は2つ記載されています。Tesseract.recognize()ファンクションの使い方とウェブワーカーの使い方です。

import Tesseract from 'tesseract.js';

Tesseract.recognize(
    'https://tesseract.projectnaptha.com/img/eng_bw.png',
  'eng',
  { logger: m => console.log(m) }
).then(({ data: { text } }) => {
  console.log(text);
})
import { createWorker } from 'tesseract.js';

const worker = createWorker({
  logger: m => console.log(m)
});

(async () => {
  await worker.load();
  await worker.loadLanguage('eng');
  await worker.initialize('eng');
  const { data: { text } } = await worker.recognize('https://tesseract.projectnaptha.com/img/eng_bw.png');
  console.log(text);
  await worker.terminate();
})();

Tesseract.recognize()ファンクションの裏ではワーカーと同じ使い方になっているためどっちを使っても変わりがありません。

Tesseract.js

const createWorker = require('./createWorker');

const recognize = async (image, langs, options) => {
  const worker = createWorker(options);
  await worker.load();
  await worker.loadLanguage(langs);
  await worker.initialize(langs);
  return worker.recognize(image)
    .finally(async () => {
      await worker.terminate();
    });
};

file型のインプットから読み込みの例

<!DOCTYPE html>
<html lang="en">
<body>
    <input type="file" name="my_file" id="my-file">
    <script src="js/from_input.js"></script>
</body>
</html>
import Tesseract from 'tesseract.js';

const readImage = (imageUrl) => {
    Tesseract.recognize(imageUrl, 'jpn', { logger: m => console.log(m) }).then(({ data: { text } }) => {
        console.log(text);
    });
};

(() => {
    const fileInput = document.getElementById('my-file');

    fileInput.addEventListener('change', (e) => {
        const file = e.target.files[0];

        // fileインプットから選択した画像のデータURL発行
        let fileReader = new FileReader();
        fileReader.readAsDataURL(file);
        fileReader.onload = function () {
            readImage(fileReader.result); // 画像のデータURL
        }
    })
})();

日本語縦書きについて

パッケージマネジャを使っている場合は、デフォルトでサポートしている言語を簡単に確認することができます。下記のファイルにご参照して下さい。

node_modules/tesseract.js/src/constants/languages.js

TesseractOCRでは日本語縦書き用のjpn_vertという言語オプションはあります。でも上記のlanguages.jsファイルを確認しますとjpn_vertはありませんがjpn_vertをそのまま使えそうです。

Tesseract.recognize(
    'https://画像/URL/です.png',
  'jpn_vert',
  { logger: m => console.log(m) }
).then(({ data: { text } }) => {
  console.log(text);
})

IndexedDBを確認しますと、ちゃんと.traineddataがダウンロードされているようです。

自分でOCRを学習させたい場合

この記事のスコープ外になりますが、Tesseract.jsにも自分で学習させた.traineddataファイルを使えそうです。こちらにご参照ください。

実際に使ってみましょう!

上記file型のインプットから読み込みの例に書いている通りをCodepenに反映しました。

サンプル画像として簡単にGoogle文章画像をイメージ検索して下記のを取りました。自分が使えたい画像で試してもいいです。

test_image.png

Codepenを開いてConsoleを開いてください

上記のテスト画像を読み込みますと、下記のような結果を得られます。

アウトプットを見ますとほとんど合っていますが、間違っているところは3か所あります。

最後に

TesseractJsはそのまま使用することはできますが、場合によって予想している結果を得られない時もあります。もし、機械学習の経験があるなら、実際に使うデータによってTesseractを学習させた方が一番いいとは思います。

株式会社フォトラクションでは一緒に働く仲間を募集しています

Amazon Athena 使ってみました

こんにちは、PhotoructionでWebエンジニアをしている田村です。

先日ログ検索機能の実装を担当しAWSのプロダクトである Amazon Athena について調査したのでどのようなサービスか簡単に説明したいと思います!

Amazon Athena とは

標準的なSQLAmazon S3に格納したデータを分析することを簡単に行えるサービスです。

AthenaにS3バケットをデータベースとして定義し、テーブルに対してクエリを実行することができます。

前提

実際は、S3バケット作成・ログファイルをS3に転送・IAMロール定義など準備が必要ですが、今回ここでは詳細に説明しませんので別途調べてみてください。

ちなみにIAMユーザーのポリシーは最低限こんな感じでとりあえずAthenaによる検索はできると思います。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "athena:*"
            ],
            "Resource": [
                "*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "glue:GetDatabase",
                "glue:GetDatabases",
                "glue:GetTable",
                "glue:GetTables",
                "glue:GetPartition",
                "glue:GetPartitions",
                "glue:BatchGetPartition"
            ],
            "Resource": [
                "*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:GetBucketLocation",
                "s3:GetObject",
                "s3:ListBucket",
                "s3:ListBucketMultipartUploads",
                "s3:ListMultipartUploadParts",
                "s3:AbortMultipartUpload"
            ],
            "Resource": [
                "arn:aws:s3:::sample-bucket/*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:ListBucket",
                "s3:GetBucketLocation",
                "s3:ListAllMyBuckets"
            ],
            "Resource": [
                "*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "lakeformation:GetDataAccess"
            ],
            "Resource": [
                "*"
            ]
        }
    ]
}

S3にログファイルを格納

下記のようなディレクトリ構成でログファイルを格納します。

sample-bucket/sample-logs 以下の2022 10 30 31 などは年・月・日を表しています。(詳細は後述)

sample-bucket
└── sample-logs
    └── 2022
        └── 10
            ├── 30
            │   ├── 20221030-1.log
            │   └── 20221030-2.log
            └── 31
                ├── 20221031-1.log
                └── 20221031-2.log

各ログファイルはJSON形式のレコードが1行ずつ蓄積していく形です。

{"log_date":"2022-10-30","item1":"value11","item2":"value21","item3":"value31"}
{"log_date":"2022-10-30","item1":"value12","item2":"value22","item3":"value32"}
{"log_date":"2022-10-30","item1":"value13","item2":"value23","item3":"value33"}

(…以下略)

Athenaでテーブル作成

下記のような定義のテーブルを作成します。

これは”sample_dbs3://sample-bucket/sample-logs/マッピングした samples という名前のテーブルを作成する”というような内容となります。 カラム定義はlog_dateitem3ですがこれはログファイルのレコードとなるJSONの項目と一致します。

CREATE EXTERNAL TABLE sample_db.samples (
    `log_date` STRING,
    `item1` STRING,
    `item2` STRING,
    `item3` STRING
)
PARTITIONED BY (year INT, month INT, day INT)
ROW FORMAT SERDE 'org.apache.hive.hcatalog.data.JsonSerDe'
LOCATION 's3://sample-bucket/sample-logs/'
TBLPROPERTIES (
    'projection.enabled' = 'true',
    'projection.year.type' = 'integer',
    'projection.year.range' = '2000,2200',
    'projection.year.digits' = '4',
    'projection.month.type' = 'integer',
    'projection.month.range' = '1,12',
    'projection.month.digits' = '2',
    'projection.day.type' = 'integer',
    'projection.day.range' = '1,31',
    'projection.day.digits' = '2',
    'storage.location.template' = 's3://sample-bucket/sample-logs/${year}/${month}/${day}'
);

PARTITIONED BY TBLPROPERTIES などが気になりますね。 これらはデータのパーティション分割のための定義となります。

Athenaの機能”データのパーティション分割

クエリによってスキャンされるデータの量を制限できるようになるため、パフォーマンスが向上し、コストが削減されます。

実はAthenaはスキャンしたデータ量によって料金がかかってきます。(スキャンされたデータ 1 TB あたり 5.00USD) 上記サンプルログはパッと見た感じでそれほど気になりませんが、Photoructionの操作ログを記録するとなると恐ろしく大量のレコード数になることが予想されます。

そのため、あらかじめ任意のキーでデータをパーティションに分割し、クエリで「この条件でスキャン対象を絞って検索結果を返してね」という記述をしてスキャン量を抑えることができます。

テーブル上の実際のレコード

SELECT * FROM sample_db.samples を実行するとこのような結果が得られます。

テーブル作成時のカラムには指定していなかったyear month day が一緒に返ってきました。

# log_date item1 item2 item3 year month day
1 2022-10-30 00:00:00 value11 value21 value31 2022 10 30
2 2022-10-30 00:00:00 value12 value22 value32 2022 10 30
3 2022-10-30 00:00:00 value13 value23 value33 2022 10 30
4 2022-10-30 00:00:00 value14 value24 value34 2022 10 30
5 2022-10-31 00:00:00 value11 value21 value31 2022 10 31
6 2022-10-31 00:00:00 value12 value22 value32 2022 10 31
7 2022-10-31 00:00:00 value13 value23 value33 2022 10 31
8 2022-10-31 00:00:00 value14 value24 value34 2022 10 31

つまり”PARTITIONED BY” “TBLPROPERTIES” とは

TBLPROPERTIESディレクトリとyear month dayマッピング(と併せて型や範囲も)定義していることになります。 sample-bucket/sample-logs/2022/10/30/xxxxxx.log の場合は、データとしてyear=2022 month=10 day=30 となります。

またPARTITIONED BY によって year month dayパーティション分割するということになります。

というわけでSQLSELECT * FROM sample_db.samples WHERE year = 2022 AND month = 10 day = 30 のようにすると、実際にはsample-bucket/sample-logs/2022/10/30/ 以下のファイルのみスキャン対象とし、それ以外のディレクトリはスキャンしないため、その分スキャン量を抑えられる(=サービスの利用料金を抑えることができる)ということになります。

実装サンプル

それでは実際にAWSSDKPHP版)を使用してAthenaを検索してみます。

前提:composerでaws/aws-sdk-php3.x系 を利用

// ①クエリ
$query = 'SELECT * FROM sample_db.samples WHERE year = 2022 AND month = 10 AND day = 30';

// ②Athenaクライアント
$athenaClient = new Aws\Athena\AthenaClient([
    'region' => 'ap-northeast-1',
    'version' => 'latest',
    'credentials' => [
        'key' => 'SAMPLE_AWS_ACCESS_KEY_ID',
        'secret' => 'SAMPLE_AWS_SECRET_ACCESS_KEY',
    ],
]);

// ③クエリ実行
$startQueryResponse = $athenaClient->startQueryExecution([
    'QueryString' => $query,
    'ResultConfiguration' => [
        'OutputLocation' => 's3://sample-bucket/sample-results'
    ]
]);

// ④QueryExecutionId取得
$queryExecutionId = $startQueryResponse->get('QueryExecutionId');

for ($times=0; $times < 20; $times++) {
    // ⑤QueryExecutionIdを元に実行ステータスを取得
    $responseExecution = $athenaClient->getQueryExecution([
        'QueryExecutionId' => $queryExecutionId
    ]);
    $status = $responseExecution->get('QueryExecution')['Status']['State'];

    // ⑥ステータスが「QUEUED」(受付済み)、「RUNNING」(実行中)だったら1秒待って繰り返す
    if (in_array($status, ['QUEUED', 'RUNNING'])) {
        sleep(1);
        continue;
    }

    // ⑦ステータスが「SUCCEEDED」(成功)だったら結果を取得してみる
    if ($status === 'SUCCEEDED') {
        // ⑧QueryExecutionIdを元に結果セットを取得
        $responseResults = $athenaClient->getQueryResults([
            'QueryExecutionId' => $queryExecutionId
        ]);
        $resultSet = $responseResults->get('ResultSet');

        // meta情報
        $meta = $resultSet['ResultSetMetadata']['ColumnInfo'];

        // 検索結果
        $rows = $resultSet['Rows'];
    }

    break;
}

AthenaをSDKを使用して検索する場合、非同期処理で行われるので、実行後に状態を監視して完了するのを待ってから結果を得る必要があります。 よって、

  1. SDKクライアントの初期化(②)
  2. クエリ実行し、結果取得用キー取得(③④)
  3. 結果取得用キーを使ってステータスをチェック(⑤)
    1. 「実行中」なら少し待って再度ステータスチェック(⑥)
    2. 「成功」なら結果取得用キーを使用して検索結果を取得する(⑦⑧)

というような流れになります。

また、③のOutputLocationでログファイルを格納しているディレクトリとは別のS3ディレクトリを指定していますが、Athenaはクエリを実行して成功すると自動で結果セットのCSVをこのディレクトリに出力します。 ですので、例えば検索結果をフロントエンドで確認しつつクエリ結果CSVをダウンロードする機能なども容易に実装することが可能です。

最後に

いかがでしょうか?

今回ご紹介した機能はAthenaのごく一部の機能となり、実際には非常に多くの機能があります。 当然ですが実際にはAthena以外の箇所でログの出力方法・出力先、S3に転送するタイミングや手段などしっかり設計する必要があります。

いろいろと便利なサービスやツールを組み合わせて実装する機会はこれからも多々あるかと思います。 それらをうまく利用して作業時間の短縮やコストの削減を図り、本来時間をかけたい部分に注力してより良いプロダクトを作っていきたいと思います💪

エンジニアカンファレンスのスポンサードについて

Androidエンジニアの久木田です。

僕は本職でAndroidエンジニアをしながら、エンジニア採用に関する業務や今回の主題であるエンジニアカンファレンスのスポンサードの窓口などもやっています。

スポンサードしたいと思っているカンファレンス

正直、無限にスポンサードしてエンジニアみんなが知っているようになれば最高ですが、予算という制約があり、投資対効果という点を重視してスポンサードするカンファレンスを選んでいる状況です。

ですので、Photoructionで採用している技術が主題になっているカンファレンスにスポンサードする方針を取っています。

具体的にどういう技術かというと

についてです。

これらに関するカンファレンスで、投資対効果が妥当だと判断したものには積極的にスポンサードしていきたいと思っています。

これまでにスポンサードしたカンファレンス

時系列順にこれまでスポンサードしたカンファレンスを上げると

です。

「あれ?あのカンファレンスなくね?」っていうのがあると思いますが、いくつか僕のミスで申し込みが出来なかったものがあります。。。

来年はリベンジします🔥

なぜスポンサードするのか

多くの企業と同じく究極も目的はエンジニア採用です。

なのでスポンサードをすることでエンジニアのみなさんにフォトラクションの名前やロゴについて認識してもらい、あわよくば事業内容も知ってもらえると嬉しいなと思っています。

まだまだ始めたばかりなので成果は全くないですが、これから数年続けることで採用にもいい結果が返ってくるようになってほしいです。もちろんそのために入りたいと思える魅力ある開発部隊にしていきたいと思います。

目指したい姿

エンジニアならみんなPhotoruction知ってるよねという状態になればいいなと思っています。

そのためにも、今できてないあれやこれやをできるように色々やっていきたいと思っています。

とりあえず、今はノベルティグッズすら用意できてないのでそこからですね。

あと、他社のスポンサードの告知記事だとよく「弊社からは〇〇が登壇します」というのがあるので、そういうのも出来るように社内から登壇者が出てくるようにしたいなと思っています。

登壇に関しては、意欲のあるひとがいればスポンサーセッションを申し込むこともできるので興味のある人は是非お声掛けください。カジュアルにお話しだけでも!

最後に

これからもいろんなカンファレンスに(予算が許す限り)スポンサードしていきたいと思っています。

もし、上記の技術に関するカンファレンスを主催されている方で、スポンサードして欲しいとかあれば、お声掛けいただけると検討いたしますのでお気軽にお声掛けください。(スポンサード募集の情報とか意外と見つけづらいので)

株式会社フォトラクションでは一緒に働く仲間を募集しています

corporate.photoruction.com www.wantedly.com