JJUG CCC 2024 Fall で LT をしました

JJUG CCC 2024 Fall で LT をしました

10月27日に新宿で開催された JJUG CCC 2024 Fall にて、Lightning Talk をしてきました。

弊社の先輩から、 「昨晩からJJUG CCC の懇親会で LT 募集開始しているんだけど、やってみない?」 と声をかけられたのが10月16日。

10月27日まで、あと一週間ちょっとしかない! しかも 「LT した経験もぜひ Blog に書いてほしい」だって?! いつもありがとうございます。

せっかくのチャンスなので勢いで応募しました。 ゆるい LT の場で発表しただけなのですが、自分にとっては新鮮な経験で、 会場には200人くらい(?)いたので緊張しました。

という経験を踏まえ、感じたことなどを書きます。

「Multi-Project Build の魅力」というタイトルで発表を行いました。 LT した内容は以下のとおりです。

練習は大事(当たり前)

経験上、ちょっとした発表なら資料を作りながらイメージするだけで特段練習したりしていませんでした。 弊社の先輩から進められたこともありますが、ほぼ初めてきちんとした公の場で話しますし、発表時間も3分しかなかったので発表練習をたくさん行いました。

終わってみて、「いやぁー練習は大事。」と思いました。

まず練習しないとわからない改善点が多くありました。 実際、「3分ならこれくらいかな」と適当につくった資料で試してみたら8分弱かかるオーバーぶりでした。(それは練習しなくてもわかるやろ) 練習を繰り返すことで表現に改善の余地が見つかり、資料の改善・スクリプトの改善・試行を繰り返しました。

また、緊張などで自分のコンディションは一定ではないし、本番では想定外なことが起きると思います。 練習はそういったときにパフォーマンスを安定させてくれるものだと今回強く感じました。 発表中、頭の中は少しモヤがかかった様に回転が悪い感覚を覚えましたが、練習していたことで頭より先に口が動いてくれました。

Output は学習効果バツグン

こちらも頻繁に言われていることなので当然ですが、やはり Output を経て知識がより自分のものになりました。 今回の LT の前に内容のプログラムを色々試しましたし、正確な表現を Document で調べました。 結果、知識の足りない部分が補完され頭の中に前より定着しました。

自分の学習のためにも、学んだことを仲間に共有する機会を今まで以上につくるのが良さそうです。

実際に経験するということ

実際に経験することって貴重だよねというお話です。

「頭では分かっている」と「身にしみて知っている」の間では厚い壁があり、そこのブレイクスルーのために必要なのが "強い感情を伴う実際の経験" なんだと思いました。 ここに書いているようなことも当たり前だと理解していましたが、以前よりも意識的に感じられるようになっています。 その理解を活かす時も、今までより強いモチベーションで取り組むことができそうです。

今回の経験で、今後勉強会に参加してなにか発表するというハードルが何段階も下がるし、 より難しいことに挑戦できるでしょう。(しらんけど)

シンプルに JJUG CCC の内容が面白かった話

LT と直接関係ありませんが、シンプルに JJUG のメインセッションがすごく面白かったです。 自分の知識体系が広がり、知識人の発表の中でしか得られない養分を得ることができます。 以前より分かることが増えたことでより面白く感じました。

これからも積極的に外部の勉強会に参加しよう! そして頭の中がぐわっと広がるような勉強会を社内でも行いたいです。

話術は大事

学んだとは書きましたが、やはり難しかったです。 自身ではクオリティは低く、手放しで褒められる成果ではなかったと感じています。

対して JJUG のメインセッションで聞いた話は面白くて学びがありました。 そういうことができるエンジニアは "すごい"。

魅力的に伝わり、人に影響を与えられるような話はどんな場面でも有効だと思います。 対外な発表はもちろん、チームのマネジメントしかり、ちょっとした同僚との会話まで。 これは理路整然と説明することとは別ベクトルであり、しかし同程度以上のウェイトで重要、 メガライアー級の威力を持っている能力だと感じました。

面白く (interesting)、そして面白い (funny) 。 そんな技術者にワタシハナリタイ。

稼働中のサービスのデータベースをRDS for MySQL 5.7からAurora MySQL 3に移行した話

背景

開始から9年間稼働中のサービスで利用しているRDS for MySQL 5.7の標準サポートが2024年2月末に終了となるため、RDS for MySQL 8.0へアップグレードすることになりました。
また、RDSと比較するとインスタンスの耐障害性が高く、インスタンスの選択や構成を工夫することでコスト面でメリットがある(約100万円/年のコストが削減できる)ことから、併せてAurora MySQL 3(MySQL 8.0 互換)へ移行することになりました。

Aurora MySQL 3(MySQL 8.0 互換)への移行方法の検討

これらのドキュメントなどを参考に移行方法を検討し、DB クラスターのスナップショットからの復元の方法を採用することにしました。

「RDS for MySQL 8.0へアップグレード」→「RDS for MySQL 8.0からAurora MySQL 3へ移行」の2つの対応をおこないます。

移行スケジュール

契約更新の関係上、Aurora MySQL 3への移行は2024年1月に実施することが決まっていました。
「RDS for MySQL 8.0へアップグレード」と「Aurora MySQL 3への移行」を同時に行うか検討しましたが、実施中に問題が発生した場合の対応(調査や切り戻しなど)が複雑になる可能性を考慮して別々に行うことにしました。
別々に実施することでサービス停止が2回必要になってしまいますが、より確実・安全に実施することを優先しました。

MySQL 8.0へのアップグレードにおける変更点の確認

こちらのドキュメントにSQLの変更がまとめられています。

ローカル環境でMySQL 8.0における変更点を確認し、必要な対応をおこないました。 また、各アプリケーションの動作も確認しました。

予約後の追加(MySQL 8.0 の新しいキーワードおよび予約語

「lead」という単語が予約語に追加されていました。既存のテーブルのカラム名に「lead」を使用していたため、カラム名を変更する対応をおこないました。

暗黙的ソートの変更(ORDER BYの最適化

GROUP BY句、DISTINCT句の暗黙的ソートが廃止になり、ORDER BY句を使う必要が生じました。
こちらについては元々ORDER BY句を使うようにしていたので影響はありませんでした。
お客様の別のサービスでは、この影響による修正にかなり手間取ったそうです。

検証環境でRDS for MySQL 8.0へアップグレード

次は検証環境でアップグレードをおこない、各アプリケーションの動作を確認します。

手順は以下の通りです。
本番環境で計画通りに実施できるようにするため、検証環境での確認は非常に重要だと考えています。

  1. 各アプリケーションの停止
  2. RDS for MySQL 5.7のスナップショットの取得
  3. RDS for MySQL 8.0用のパラメータグループの作成および内容の変更
  4. RDS for MySQL 8.0へアップグレード
  5. 各アプリケーションの起動

RDS for MySQL 8.0へのアップグレードはスムーズにおこなうことができました。

本番環境でRDS for MySQL 8.0へアップグレード

ローカル環境、検証環境で確認ができたので、本番環境でRDS for MySQL 8.0へアップグレードを行います。
予定したメンテナンスの時間内にサービスへの影響もなく、無事にアップグレードを完了させることができました。

検証環境でAurora MySQL 3へ移行

次は検証環境でAurora MySQL 3へ移行します。

手順は以下の通りです。
こちらも本番環境で計画通りに実施できるように意識しながら実施します。

  1. 各アプリケーションの停止
  2. RDS for MySQL 8.0のスナップショットの取得
  3. Aurora MySQL 3のリードレプリカを作成
  4. Aurora MySQL 3のリードレプリカの昇格
  5. Route 53 のDB接続用レコードのエンドポイントをRDS for MySQL 8.0からAurora MySQL 3に変更
  6. 各アプリケーションの起動

この手順でAurora MySQL 3への移行を進めていきます。

「3. Aurora MySQL 3のリードレプリカを作成」を実行すると以下のメッセージが表示されました。

「Cannot upgrade from mysql 8.0.35 to aurora-mysql8.0.mysql_aurora.3.05.1.Specify a current active database version, the latest active minor version for mysql 8.0 is 8.0.33.」

RDS MySQL 8.0へアップグレードしたときにバージョンを当時の最新である「8.0.35」にしました。
ですが、当時のAurora MySQL 3では「8.0.35」へのサポートがされていませんでした。
ちなみに、現在はサポートされています。(Amazon Aurora MySQL 3.06 (MySQL 8.0.34 互換) の一般提供が開始

事前の調査・確認が足りていませんでした。 AWSのドキュメントをしっかり確認すべきでした。

どうやってAurora MySQL 3へ移行するか

Aurora MySQL 3へ移行するためにはRDS for MySQL 8.0のバージョンを「8.0.32」にする必要がありました。
AWSのコンソールではRDS for MySQLのダウングレード(「8.0.35」から「8.0.32」)はできません。
そこでRDS for MySQL 8.0へアップグレードした時に取得したRDS for MySQL 5.7のスナップショットを利用してRDS for MySQL 8.0(8.0.32)へアップグレードすることにしました。
スナップショットから別インスタンスとして復元させるため、本来なら必要がないインスタンスを一時的に作成することになりますが、やむを得ない状況でした。

また、RDS for MySQL 5.7から再実施するため、RDS for MySQL 8.0(8.0.35)の最新データを取得しておき、RDS for MySQL 8.0(8.0.32)へアップグレードした後にインポートする必要があります。
インポートについては差分インポートも考えましたが、手順や確認が複雑になることや本番環境のデータでどれくらい時間が短縮できるかわからないといった懸念点があったため、全量インポートにすることにしました。

以下の手順でAurora MySQL 3へ移行することができました。

  1. 各アプリケーション、バッチを停止
  2. RDS for MySQL 8.0(8.0.35)のdumpを取得(最新データを復元するため)
  3. RDS for MySQL 5.7のスナップショットから別インスタンスとして復元(RDS for MySQL 8.0(8.0.32)へアップグレードするため)
  4. RDS for MySQL 8.0(8.0.32)へアップグレード(Aurora MySQL 3(3.05.1)のサポート対象)
  5. 2.で取得したデータをインポート(RDS for MySQL 8.0(8.0.35)の最新データを復元)
  6. Aurora MySQL 3(3.05.1)へ移行(リードレプリカを作成、昇格)
  7. Route 53 のDB接続用レコードのエンドポイントをRDS for MySQL 8.0からAurora MySQL 3に変更
  8. 各アプリケーション、バッチを起動

本番環境への対応は稼働中のサービスを停止させる必要があり、サービス停止時間を決定するために各作業の所要時間を計測します。
9年間運用してきましたが、本番環境の全データのインポートは実施したことがなく、どれくらい時間がかかるか見当がつきませんでした。
そこで本番環境と同等のインスタンスを検証環境に用意して確認したところ、本番環境の全データのインポートは約40分かかることがわかりました。
事前に検証する作業工数やAWSの利用コストは発生してしまいますが、稼働中のサービスで問題を発生させてしまう方が損害になりうると考え、お客様にもその必要性を理解していただきました。

本番環境でAurora MySQL 3へ移行

検証環境で確認できたので、本番環境でAurora MySQL 3への移行を実施します。
稼働中のサービスなので、サービスの停止時間は極力短くすることを意識します。
「スナップショットから復元」と「RDS MySQL 8.0(8.0.32)へアップグレード」は別インスタンスとして実施できるため、別途事前対応としました。
朝4時から準備・事前対応を開始、4時30分から移行作業を実施し、予定通り7時30分にサービスを開始することができました。

本番環境での実施時間は以下の通りでした。

準備・事前対応

  1. RDS for MySQL 5.7のスナップショットから別インスタンスとして復元(約10分)
  2. RDS for MySQL 8.0(8.0.32)へアップグレード(約15分)

Aurora MySQL 3への移行作業

  1. 各アプリケーション、バッチを停止(約10分)
  2. RDS for MySQL 8.0(8.0.35)のdumpを取得(約15分)
  3. 2.で取得したデータをインポート(約45分)
  4. Aurora MySQL 3(3.05.1)へ移行(約60分)
  5. Route 53 のDB接続用レコードのエンドポイントをRDS for MySQL 8.0からAurora MySQL 3に変更(約5分)
  6. 各アプリケーション、バッチを起動(約10分)

最後に

今回はRDS for MySQL 5.7をRDS for MySQL 8.0にアップグレードし、その後にAurora MySQL 3に移行したお話でした。
いろいろと対応することはありましたが、それぞれしっかり確認しながら進めれば恐れることはないと思います。
ドキュメントの確認不足という反省点はあったので、今後に生かしたいです。

対応コストはかかりますが、本番環境での実施を想定した検証環境での事前の検証や懸念点を解消することは重要だと考えます。
そのため、検証の重要性をお客様に説明することも欠かせません。
今回、検証のコストや環境を用意することへ理解していただいたことに改めて感謝しています。

これからも様々な運用保守対応や追加改修が続いていきますが、しっかりと対応していきたいと思います。

ScalaMatsuri2024に大名スポンサーをしました

ScalaMatsuri2024に大名スポンサーをしました

2016年に初めてスポンサーをさせていただいてから、早いもので8年が経とうとしています。

当時はScalaという言語とそれを取り巻くフレームワークなどに新たな可能性を見出し、Scalaコミュニティの方々から学ばせていただくことも多くありました。

業務導入でのScalaという言語だけでみると経験が浅い中、弊社を頼ってお仕事を発注して頂き、分析プラットホームでのデータ処理から、企業向けサービスのがっつりした機能開発、保守が必要なレガシーコードとの対峙やマイグレーション対応まで、幅広く経験を積んできました。

そのように挑戦的なプロジェクトが進んでいるさなか、数年にわたって働き方を含め社会的影響を及ぼしたコロナ禍が訪れ、ScalaMatsuriだけでなく様々なイベントやカンファレンス界隈がオンラインやハイブリット開催へ切り替えることを余儀なくされました。

そして、ついに今年は完全オフラインでお台場にある「東京国際交流館 プラザ平成」に戻ってきて本格開催しますという発表がありました!

運営メンバーの世代交代もあり、今までのScalaMatsuriを踏襲しつつも新しい試みや変化もあり、どんなカンファレンスになるかを楽しみにして、今年もスポンサーをさせていただきました。

カンファレンス前の準備に練ったこと

さきほども言及したように環境変化が大きく、様々なことが様変わりしました。

私も例にもれず、コロナ禍でリモートワークを余儀なくされました。 以前から、リモートワークを推進したくオンライン・オフラインどっちでもうまくやっていく力を引き出したいという想いがありました。 そこで、コロナ禍が落ち着いた今も、対面で必要な時はオフィスに出社してホワイトボードを使いながらミーティングをすることもあるのですが、環境におかれてこそきづいたり、工夫しようという努力があるのでリモートワークを重点において日々仕事に取り組んでいます。

そこで、気づいたのがオフィスで普段から恩恵を受けていた数々の福利厚生やサービス。 コーヒーやお茶もフリードリンクで用意して頂き、オフィス移転前は大きな冷蔵庫に社員の声で導入されたカルピスなどの飲み物があったりして、うれしかったことを覚えています。(今はWeWorkからドリップ式の本格コーヒーや豆乳など様々なドリンクが提供されています)

自宅でも飲みたいものを飲んではいますが、オフィスと違って同僚からの差し入れや品のローテーションなどの意外性ある出会いが減ってしまうのも事実でした。 私以外にも同じ思いをもってScalaMatsuriに参加している方々は多いんじゃないかなと考えました。

そこで、みなとみらいのオフィスからほど近い場所にある、自店でスリランカから直輸入している紅茶専門店のおいしい紅茶(私も普段愛用しています!)を、みなさんにノベルティとしてお届けできたら、意外性も含めて喜んでいただけるのではないかと思って、お店に相談をしてノベルティ用の専用ティーパックを袋詰していただけることになりました。

どうしても自宅で一人で作業していると、根を詰めてしまうこともあるし少しばかりのリフレッシュとして、お茶を飲んでいる時間に弊社メンバーが過去に書いた技術ナレッジや組織的な取り組みのブロク記事や、他社の方とお話する中で生まれたScala先駆者インタビューという連載記事、弊社が受けたインタビュー記事などを、お茶のお供に読んでいただければと思い、ピックアップして専用の teatime.atware.co.jp というドメインでランディングページを用意することにしました。 (スポンサーをする時のベネフィットも考えて弊社をよりよく知っていただければということも考慮しました!)

当日を迎え

冒頭でカンファレンスの運営のやり方も変わったことがお伝えしましたが、その中のひとつとして、ノベルティ配布方法が事前に運営が袋詰をして全スポンサーの全ノベルティーを一律に参加者全員へ配布するのをやめ、デスクにノベルティを各社が並べ、参加者が各自欲しいものをもらっていくというスタイルになりました。

自分も参加者としてカンファレンスに参加することがあるので気持ちがよくわかるのですが、パッと見だと、紅茶なのかコーヒーなのか、それともウェットティッシュなのかもわからないこともあります。ノベルティをもらいにカンファレンスに来るわけではなく、セッションを聞いたり、参加者と懇親をするのが主目的となるので、どうしても配布ブースはサッと眺めて素通りとなりがちなんですよね。

そこで、気づいていただきやすいように、人の通りがあるようなお店の様にディスプレイして、直感的に感じ取ってもらえるようにお盆とお皿にのせて、粘土で作った「クレイケーキ」も並べてみました。選んでもらえる楽しみも盛り込もうと思って、産地でもミルクティー向き茶葉やストレート向き茶葉やチャイに向いている形状(CTC)など、複数の種類を用意し、特色の違いもわかる資料を置きました。

補充をスポンサー自身で行う必要があったということもあり、受付開始の序盤には自身で補充しながらもらってくださる方の反応を見ていたのですが、海外からの来場者が「Oh!! Sri Lanka tea! Uva〜、Ruhuna〜」と産地名を読み上げながら、どっちにしようかなと悩んでいるのを見かけました。

補充をしている時には、他のスポンサーさんともお話するきっかけにもなりましたので、全参加者に一律にモノを配布する形とこのスタイルも一概にどっちがいいとは言えませんが、今回のような形態は、能動的な行動を促すことになるので、ポジティブな面も多くあるなと思いました。

懇親会タイムでは、ノベルティをもらっていなかった方々が終盤に次々ともらっていってくださり、用意した分はほぼなくなってしまうほどで、弊社からのホスピタリティを考えて作ったモノがまずはお手元に届けることができてよかったです。

ScalaMatsuriでの出会いと感じたこと

今までと同じ会場でしたが、メイン会場とサブ会場の同時並列度は少なく、ほぼメイン会場での発表でした。 セッションを聞いて身になったなと思ったことはありますが、私にとっては久々のリアル懇親会で、スタッフの方は知人の方、また初めてお会いした方々と技術談義や普段の悩みや、最近のScalaや言語事情、組織での課題感をお話でき、すごく有意義な時間を過ごすことができました。

当日、お話してくださった方どうもありがとうございました!楽しかったです。

最後に

初めてお会いした方も「アットウェアさん毎年スポンサーしてますよね」と言ってくださり、存在を認識していただいていることに嬉しく思っています。 コミュニティの発展への寄与、エンジニアングを中心としたシステムづくりのプロとして「システムで人々をしあわせにする」というミッションを果たしていきたいです。

こういう弊社で一緒に働いてくださる方、お仕事の相談をしたいなと思う方、ぜひお気軽にお声がけください!

今年もScalaMatsuriの運営のスタッフの方々お疲れ様でした。カンファレンスを開催していただきありがとうございました。

UX DAYS TOKYO 2024 スポンサーに向けて

UX DAYS TOKYO 2024 スポンサーに向けて

UX DAYS TOKYO 2024が明日、3月15日(金)に開催されます。

アットウェアとしてはUX DAYS TOKYOというカンファレンスに、初めてスポンサーをさせていただくことになりました。
ブログでもUXに言及した記事を公開したことはなく、UXをテーマとした取り組みは少し新鮮に感じる方もいらっしゃるのではないでしょうか。

以前に別のカンファレンスでスポンサーをする時にこんなことをお伝えしたことがありました。

過去にもアットウェアは幾つかのカンファレンスのスポンサーをさせていただいてきました。 弊社メンバーがカンファレンスに参加するときに大事だなと思っているのは、その場を楽しめる空気感です。 これは、セッション内容だけでなく、いろいろな立場の人が気軽に参加できる心遣いやおもてなしの心も大きいのではないかと考えています。

私達自身が参加したいと思えて、そのセッションやカンファレンスの趣旨に同調したいと思えることはとても重要で、このカンファレンスにも同様の想いを感じました。

アットウェアでは創業当初からアジャイルプロセスを導入し試行錯誤しながら、顧客やエンドユーザへ限られた時間とコストを考慮したうえで、よりよい価値を届けることを主眼においてやってきました。

その中で、「強力なフレームワークや言語や開発手法をうまく使いこなして、システムをしっかり作り込めるようになる」ところへのアプローチについては、シビアな非機能要件をクリアするためにそれはそれでとても大事でやったきたことなのですが、エンドユーザがシステムを日々使い続けることに焦点を当て、その体験が最良なモノになるかを模索するために、分析・改善・設計を絶えず行っていくことも大事になると考えています。

その2つのテーマを両軸でやっていくと、オーダーメイドでシステムを開発するうえで、付随する大事な要素が高まりあいます。
UXはアジャイルという考え方に親和性があり、それは目新しいことでもなければ、今までにやってきたことも含まれるかもしれません。

今回スポンサーさせていただくきっかけとして、さきほど述べた、カンファレンスの趣旨に共感したという点以外に、弊社が焦点を当てているテーマと近かったので、シルバースポンサーとしてスポンサーをさせて頂くことになりました。

今年のUX DAYS TOKYOのセッションを見てみると、UIやビジュアルデザイン以外のテーマがほとんどです。

  • AI×デザイン:未来を創造する
    • ユーザー中心設計と技術能力の融合によるAIプロジェクト成功へのバランスの取れたアプローチを学びます。
    • 技術的パフォーマンス、価値、リスクの評価方法についても探ります。
  • ビジュアル・シンキング:アイデアを視覚化して問題を解決しよう
    • ビジュアルシンキングとスケッチを活用してアイデアを視覚的に表現することの価値と考え方を学びます。
    • 普段の業務やコミュニケーションにおける視覚的スキルの重要性とその効果と価値が理解できます。
  • 最もクリエイティブな人と企業の秘密
    • クリエイティブな分野で最も先駆的で独創的な人物のクリエイティブのプロセスを紹介します。
  • 未来を創る:UXキャリアデザイン
    • 自己を見つめ直し正しい方向へ個人のキャリアを伸ばす方法を説明します。
    • ユニークな能力をもつ個人の集合体は強いチームを組成し組織に貢献します。
  • 影響力の高いチームの組成とメトリクス
    • 影響力の高いプロダクトチームの構築について解説します。
    • 多くのチームが重要でないタスクに焦点を当てている現状を振り返り、共通のビジョンと高いビジネス目標に向かう方法を提供します。

紹介文をみると、わくわくしますね。
私たちが、より仕事をうまくやり、価値を創造できる組織になるためのヒントをこのカンファレンスから学べることを期待しています。

世界で活躍されている方を国外からスピーカーとして招くのは大変な準備と意気込みが必要ですよね。
限られた人数で活動されてる主催者の方々におきましては、当日は運営で大変だとは思いますが、陰ながらスポンサーという形で応援いたします。

アットウェアのTechbashを紹介します‼

アットウェアのTechbashを紹介します‼

こんにちは。技術推進ワーキンググループ(以下、技術推進 WG)の西川です。

この記事では私たちが社内で取り組んでいる活動について紹介します。

 

技術推進 WG とは、技術トレンドのキャッチアップや社内の技術力向上を目的に活動しているアットウェアの有志からなる集団です。

読書会や勉強会の開催などの取り組みを通じ、社内の技術的な交流を促進しています。

 

TechBash とは、アットウェア社内向けの LT 大会です。技術推進WGが主体となり、数ヶ月ごとに開催しています。

 

TechBash以前にアットウェアではビアバッシュを行っていました。ビアバッシュとは、ビールを飲みながらワイワイ話すイベントですが、コロナの感染が拡大してから開催をやめてしまいました。対面で行われていた数々のイベントが中止となる中、当時のアットウェアには、社員が気軽に交流する機会が無くなってしまうのではという危機感がありました。

技術推進WGでは、危機感に加えて、社内を技術で盛り上げていきたい思いとカジュアルに技術の話をする場を作りたい思いがありました。そこで、2020年10月からTechBashとしてオンラインで技術交流活動を行うことにしました。

 

TechBashでは、Java 新バージョンの機能紹介といった技術的なものや、ペアプロについて語る開発手法的なものなど、幅広いジャンルの話が行われます。時々、技術的なお悩み相談の場になったりもします。

過去の開催の発表内容を一部紹介します。

2023 年 11 月(テーマ: パフォーマンス)

  • パケット解析プログラムでのパフォーマンスついての悩み事
  • 最短経路問題におけるダイクストラ法を用いた解法紹介
  • パフォーマンス改善入門
  • 水平スケーリング or ボトルネック特定のためのオブザーバビリティ入門
  • k6 で負荷試験入門

2023 年 8 月(テーマ: 書籍紹介)

  • 技術書のおもひで
  • テスト駆動開発(仮)
  • 法務的な本のお話
  • AWS ではじめるインフラ構築入門
  • 技術書経験ほぼゼロの私、技術書に対する印象が変わる?!(仮)
  • 達人プログラマー
  • 関数型プログラミングってなんだろう

 

 長らくオンライン開催で行ってきたTechBashですが、去年の 8 月はオフィスで開催しました。

 

当初はビールを飲みながらLTをして、技術について語り合う場にしたいという感じで始まったTechBashですが、この記事を書いている2024年1月時点で計32回の開催が行われました。

参加者に感想を聞いてみると、「自分の知らない世界を知れて楽しかった」、「発表してみて伝え方やスライドの作り方が鍛えられた」、「自分の好きなことを自由に伝えられてよかった」といった声がありました。

手前味噌ではありますが、様々な方に参加いただき、交流イベントという観点からみると最高のイベントになったと思います。

今後もTechbashがより良いイベントになるように努めていきたいです。

2023年の振り返りと私の新たな目標に向けて

2023年の振り返りと私の新たな目標に向けて

はじめに

こんにちは、アットウェアの北村です。

2024年がスタートし、気持ちを新たに生活されているであろう今日この頃、 みなさまはいかがお過ごしでしょうか? 2023年を振り返り、新年の抱負などを定められたでしょうか?

私自身の2023年は、転機と新しいことに挑戦する1年となりました。 ここでは、昨年の振り返りと今年の抱負を少しばかりさせていただけると幸いです。

これまで

昨年を振り返る前に少しだけ自分についてです。

私は18年に新卒でアットウェアに入社しました。 新人研修を終え、OJTでとあるプロジェクトに配属となりました。 そこでは良い先輩エンジニアの方々に恵まれ、開発・運用・保守など、様々なフェーズの経験を積ませていただきました。

こちらのプロジェクトには 4 〜 5 年という長い期間携わらせて頂いて感謝しかないです。 その一方で、周りの若手社員達がプロジェクトの移動をしているのを見て

自分も新しいプロジェクト・新しい技術に挑戦したい これまで関わることのなかった社員の方と一緒にお仕事したい

と、思うことが多くなっていました。 しかし、その反面で

新しいプロジェクトでもやっていけるのか イチから技術を学びながら、周りから期待されるスピードでタスクをこなせるのか(プロジェクトの進行を妨げないか) 一緒に仕事をする方とソリが合わなかったらどうしよう

等々、ネガティブな気持ちも膨らんでゆき、新たな一歩を踏み出せず二の足を踏んでいるような状況に陥ってました。

このままではいつまで経っても先に進めないと思い、 まずは自力をつけることで、すこしでも不安な気持ちを払拭しようと考え、 『新しい技術にチャレンジする』という目標を持って2023年へと踏み出しました。

2023年 ~転機・新しいことへの挑戦~

気持ちも新たに勉強・仕事の日々を送っていた矢先に、新規プロジェクトの立ち上げのお話があり、自分にやってみませんかとお話をいただく機会がありました。

お話をいただいた当初はどうしても不安な気持ちが大きく、お断りしたいと思いましたが、 プロジェクトの内容として、今まで経験してきた内容とは異なる技術を新たに学べ、これまでと違った内容のシステムを開発する経験が得られるチャンスでもあったので、不安な気持ちと戦う覚悟を持って、新しいプロジェクトに携わらせていただくことにしました。

新しいプロジェクトでは、これまで自分が使用していた技術やフレームワークとは異なるものを新たに学びながら実装するのに苦戦することが多く、なかなか成果が出せずに思い悩むこともありましたが、新しいことに挑戦している楽しさのほうが苦労よりも勝っていたため、楽しさを持って取り組むことができました。

挑戦するモチベーションのキープ

プロジェクトで忙しくなってきた際に、どうしても『新しい技術にチャレンジする』ための時間を確保することが難しかった頃、時間を確保してやらなければいけないという思いが引っかかりつつも、目の前のタスクをこなすことに精一杯で、日々の技術面への学びという意味での積み重ねの頻度が減って、次第にモチベーションも下がっていき、「忙しいからしょうがない...」を言い訳にしてやらない時期がありました。

そこで大学時代の友人に相談すると、細かいスキマ時間を使って勉強するというアドバイスを頂いたので実践してみたところ、参考書を読んでみると細かい章ごとでいい感じに区切って読むことができたり、実装したりすると小さなメソッドごとに分けて進めることができ、自分にとっての勉強法としてマッチしていました。

再び取り組む内容が自分にとって有意義・楽しいと思えるようになってきて、コツコツと日々新しい技術に取り組むことで、学習するのが苦痛にならず、次にどんなことを知りたい・実装してみたいといったモチベーションが継続的に湧き上がってくることにも繋がりました。

2023年をふりかえって

2023年は不安を克服し、挑戦することで良い結果を得られました。 その中で感じたこととして

安定することも大事だが、それによって変化することを恐れてはいけない 挑戦することは大変だけれども、同時に楽しいことでもある

この2つがとても大事な考え方だと感じました。 特に、楽しんで挑戦することは自身のモチベーションを保ち、また新たな挑戦をするためのエネルギーになるので、日々挑戦することを続けていきたいと思います。

2024年の抱負

自分も30歳を超え、今後のキャリアについて考えていかなければいけない時期だと思うので、2024年は新しい技術等を学ぶことを続けつつ、キャリアにつながるようなスキルについて挑戦していきたいです。

AWS Lambda SnapStart を使って Java での AWS Lambda 関数を高速化する

AWS Lambda SnapStart を使って Java での AWS Lambda 関数を高速化する

AWS Lambda SnapStartがどの程度効果があるのか、実際のプロダクションで利用できる性能なのか、気になっていたのでAWS Lambda SnapStart をためしてみました。

AWS Lambda SnapStart は、Java で開発が進められている CRaC を AWS Lambda ランタイムに転用したモノです。
CRaC は、Javaのプロセスイメージをスナップショットとして取得し、再起動時にスナップショットからプロセスを復元することで、Java特有の起動の遅さを解決することを企図したプロジェクトです。

まずはSpring Cloud Function を使って AWS Lambda Function上で動作させる簡単なRest APIを用意します。

このようなパッケージ構成で、パラメータで受け取った値を大文字にして返却するRest APIを作りました。

├── java
│   └── com
│       └── example
│           └── sample
│               ├── SampleApplication.java
│               └── functions
│                   └── Uppercase.java
└── resources
    └── application.yaml

このコードをデプロイし、SnapStartを使わずに、このRest APIをcurlコマンドを使って速度を測ってみました。起動時間などを含めたパフォーマンスを計測するため、 -w オプションを付けています。

curl https://***.lambda-url.ap-northeast-1.on.aws/ -H "Content-Type: text/plain" -d "hello, spring cloud function!" \
  -w " - http_code: %{http_code}, time_total: %{time_total}\n"

上記結果は下記のようになりました。

"HELLO, SPRING CLOUD FUNCTION!" - http_code: 200, time_total: 5.306902

AWS Lambda 関数としてただしく動作していることがわかります。 トータル時間が 5秒 となっているのは、いわゆる Java のコールドスタート問題で、Spring の起動に時間がかかっているためです。 この直後にもういちど同じコマンドを実行すると、以下の様になります。

"HELLO, SPRING CLOUD FUNCTION!" - http_code: 200, time_total: 0.069804

すでに起動しているので、実行時間は 0.07秒 となっており、想定していた通りのレスポンス速度でした。では、次にSnapStartで動作させる設定をしてデプロイ後、実際に測定してみましょう。

AWS Lambda の設定

SnapStart を有効にするのは簡単で、コンソールでは関数の一般設定で、SnapStart の項目を None から PublishedVersions に変更することで有効となります。 AWS CLI では、以下の様なコマンドで有効にできます。

aws lambda update-function-configuration --function-name SpringCloudFunctionSample \
  --snap-start ApplyOn=PublishedVersions

「PublishedVersions」なので、公開されたバージョンに対して実行されることになります。 この設定をして以降は、バージョンを作成する度に、スナップショットが取得されるようになります。 バージョンを発行するには、コンソールの「バージョン」タブで新規に作成するか、AWS CLI では、以下の様なコマンドで実行できます。

aws lambda publish-version --function-name SpringCloudFunctionSample

バージョンを作成すると、スナップショットをとるのに数分を要します。 CloudWatchでログを見ると、INIT START して Spring が起動しているログが確認できる場合があります。 (ときどき出力されないときがありそこは今後調べたい)

INIT_START Runtime Version: java:11.v19    Runtime Version ARN: arn:aws:lambda:ap-northeast-1::runtime:*****
(中略)
:: Spring Boot ::               (v2.7.10)
(中略)

このバージョンに対して AWS Lambda Function URL を作成して、下記 curl コマンドを投げてみます。

curl https://*****.lambda-url.ap-northeast-1.on.aws/ -H "Content-Type: text/plain" -d "hello, spring cloud function!" \
  -w " - http_code: %{http_code}, time_total: %{time_total}\n"

結果は以下の様になりました。

"HELLO, SPRING CLOUD FUNCTION!" - http_code: 200, time_total: 1.452490

Snapstartを使わない時がtime_total: 5.306902 だったので、70% 程度高速化していることがわかります。 なお、CloudWatch のログを確認すると、以下の様に出力されています。

RESTORE_START Runtime Version: java:11.v19    Runtime Version ARN: arn:aws:lambda:ap-northeast-1::runtime:***
RESTORE_REPORT Restore Duration: 315.26 ms

スナップショットから 315.26 ms かけて復元したことが確認できます。 設定をちょっと変えただけで高速化したのスゴイですね!

ランタイムフックの設定

SnapStart によって AWS Lambda の起動が高速化されることが確認できました。 しかし、SnapStart はプロセスのスナップショットをとるという仕組み上、プロセスに状態を保持すると、その状態が使い回されてしまいます。例えば、以下の様な場合に考慮の必要がありそうです。

  • RDSとの接続状態
  • 認証情報
  • 処理で利用する一時データ
  • 一意性が必要なデータ

こうした問題に対処するために、ランタイムフックを利用して、復元時に実行する動作を設定出来るようになっています。 ランタイムフックの実装は、以下のように行います。

CRaCの依存性を build.gradle 追加

ext {
    set('springCloudVersion', "2021.0.6")
    set('awsLambdaCoreVersion', '1.2.2')
    set('awsLambdaEventsVersion', '3.11.1')
    set('cracVersion', '0.1.3') // 追加
}

dependencies {
    implementation 'org.springframework.cloud:spring-cloud-starter-function-webflux'
    implementation 'org.springframework.cloud:spring-cloud-function-adapter-aws'
    compileOnly "com.amazonaws:aws-lambda-java-core:${awsLambdaCoreVersion}"
    compileOnly "com.amazonaws:aws-lambda-java-events:${awsLambdaEventsVersion}"
    implementation "io.github.crac:org-crac:${cracVersion}" // 追加
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

関数クラスに、CRaC の Resource インターフェースを実装し、メソッドをオーバーライドしコンストラクタで関数クラスをコンテキストに登録

public class Uppercase implements Function<String, String>, Resource {

    private static final Logger logger = LoggerFactory.getLogger(Uppercase.class);

    public Uppercase() {
        Core.getGlobalContext().register(this); // CRaC のグローバルコンテキストに登録
    }

    @Override
    public void beforeCheckpoint(Context<? extends Resource> context) throws Exception {
        logger.info("Before checkpoint");
        // チェックポイント作成前の操作をここに書く
    }

    @Override
    public void afterRestore(Context<? extends Resource> context) throws Exception {
        logger.info("After restore");
        // スナップショットからの復元時の操作をここに書く
    }

    @Override
    public String apply(String s) {
        return s.toUpperCase();
    }
}

上記変更を行ってデプロイし、確認用の curl コマンドを投げると以下の様な結果となりました。

"HELLO, SPRING CLOUD FUNCTION!" - http_code: 200, time_total: 1.295677

コンテキストに追加する処理を書いたせいか、実行時間が短くなっていますね。誤差かもしれませんが。

なお、CloudWatchLogs でログを見ると、以下の様なログが出力されています。

2023-04-21 02:47:55.708  INFO 8 --- [           main] com.example.sample.functions.Uppercase   : After restore

ランタイムフックが正しく動作していることがわかります。

同時接続での速度確認

Java で AWS Lambda を実装する場合の問題は、同時接続が発生したときにコールドスタートが多発して速度が遅くなってしまうことでした。 そこで、SnapStart でその状況が改善されるかを確認するために、 Apache Bench を利用して、同時接続が発生した場合のパフォーマンスを測定してみました。

ab -n 100 -c 10

上記コマンドで、リクエスト 100 件を、並行数 10 で行ってくれます。イメージとしては、10ユーザーが同時に10リクエストを要求している感じです。 結果は、以下の通り。

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:       27   71  33.4     68     156
Processing:    23  160 304.9     57    1286
Waiting:       23  156 305.6     52    1285
Total:         53  230 308.2    127    1362

Percentage of the requests served within a certain time (ms)
  50%    127
  66%    171
  75%    183
  80%    211
  90%    916
  95%   1118
  98%   1285
  99%   1362
 100%   1362 (longest request)

トータルでみると、最大が 1362 ミリ秒、最小が 53 ミリ秒。 この最大値が許容できれば、REST API として利用するのもアリかもしれません。

まとめ

SnapStart を利用することで、Java で実装した AWS Lambda が劇的に高速化することがわかりました。 SpringBoot アプリケーションでも問題無く利用できることがスゴイですね!

気をつけなければいけない点として現時点では、AWSのドキュメントに記載があるように以下のような制限があります。

  • ランタイムとして Java11とJava17を利用可能
  • Graviton2 が使えない
  • Amazon EFSが使えない
  • エフェメラルストレージが512MB固定

これらを許容できて、かつ、スナップショットからの復元時間が許容できるものであれば、REST API を作る技術の候補として選択して良いかも知れません。

株式会社ゆめみさんと合同LT大会を開催しました

株式会社ゆめみさんと合同LT大会を開催しました

5月に株式会社ゆめみさんと関連企業の未来シェアと合同LT大会を開催しました。 開催してから少し時間が経ってしまいましたが、楽しく充実した試みになったのでブログに書いてみることにしました。 コロナ禍に入ってから勉強会やイベントはオンライン開催が普通でしたが、今回は久しぶりのオフライン開催でした。

アットウェア x 未来シェア x ゆめみ 合同LT会 in 横浜

当日は、総勢11名の発表者が集まり日々の業務で得たナレッジや趣味で得た経験などを共有しました。 Flutter、React、Android、Dockerやレシートプリンター(Android端末)の開発記など多岐に渡る内容でとても面白かったです。 みなさん5分じゃ話足りないくらい充実した内容でした。 ゆめみさんからは1年目の方がたくさん発表されており、しかもとても堂々とした立ち振る舞いで驚きました。 この積極性は弊社も見習いたい。

発表を受けて弊社にもレシートプリンターを買った方がいました。 レシートプリンターで名刺印刷を実装した話で実際に会場でも使用されていて、 名刺交換してもらった時かっこよくてワクワクしました。 私も欲しいなと思いました。宣伝効果ありですね。

私はReactのコンポーネント設計に関する日頃の悩みをテストファーストという観点から考えてみた時のことを話しました。 社外イベントでLTをするのは初めてだったので良い経験になりました。 その場で参加者の顔を見ながらわいわいした雰囲気を体感して発表できるのはオフラインイベントの醍醐味だなと思いました。

発表資料

LT後には懇親会を行い、話し足りない発表内容について話したり、エディタやテスト、スクラムなど技術談義で盛り上がりました。 Swiftでの単体テストの粒度、E2Eテストをやるか結合テストでカバーするのかといった話やAndroidでのDDDなど、私は普段はやらないモバイル開発の話を聞けて勉強になりました。 フロントエンドという括りでは似たような悩みや考えがあったり、はたまた全く違うような話も聞けて面白かったです。 LT大会も懇親会もみんな技術が好きだとを感じることができる時間でした。

オフラインでのLT大会の雰囲気が良かったので、8月に社内でもオフラインのLT大会をコロナ禍以来久しぶりに開催しました。 オフラインにはオフラインならではの良さがあり、今後も定期的にオフラインイベントもやっていきたいです。 また、社外のエンジニアの方との交流も普段扱わない技術に関して知見を得ることができるし、 何より技術好きな方達との出会いはとても良い刺激になったと思うので交流する場を増やしていきたいです。

JSON vs MessagePack vs Protocol Buffers

JSON vs MessagePack vs Protocol Buffers

実業務で大きなサイズのデータをブラウザと交換する機会があったのですが、その際のデコード処理の負荷が課題となっており、効率的にエンコード・デコードできるデータフォーマットを探していました。候補としてProtocol BuffersとMessagePackが挙がり、詳しくパフォーマンスを知るために今回検証を行いました。この記事ではその調査結果をご紹介します。

主にブラウザでデータを受け取るという観点から デコードが早いかどうか を中心に測定を行いました。

なお、計測に使った環境は次のとおりです。

  • MacBook Pro 14インチ、2021 (Apple M1 Pro) / 32GB
  • Node.js 20.5.0 (V8 11.3.244.8-node.10)
Passmark PerformanceTest 11.0.1000

CPU Mark                      22,049
Integer Math                  46,634 MOps/Sec
Floating Point Math           65,615 MOps/Sec
Prime Numbers                    281 Million Primes/Sec
Sorting                       33,605 Thousand Strings/Sec
Encryption                    12,497 MB/Sec
Compression                  280,803 KB/Sec
CPU Single Thread              3,902 MOps/Sec
Physics                        2,957 Frames/Sec
Extended Instructions (NEON)  11,078 Million Matrices/Sec

Memory Mark                     3,927
Database Operations	            9,486 KOps/Sec
Memory Read Cached             24,395 MB/s
Memory Read Uncached           22,894 MB/s
Memory Write                   24,052 MB/s
Latency                            26 ns
Memory Threaded               118,100 MB/s

MessagePack

MessagePackはJSONと同じスキーマレスなデータ構造です。

MessagePackのためのJavaScriptライブラリとしては、次が人気のようです。

インターネット上でも少し探すとベンチマークが見つかります。この結果を見ると、JSONの方が10倍ほど高速のようです。

バイナリフォーマットと比べてJSONのパフォーマンスがこれほど高いのは意外でした。その理由は@msgpack/msgpackのREADMEのベンチマークで説明されていました。

Run-time performance is not the only reason to use MessagePack, but it's important to choose MessagePack libraries, so a benchmark suite is provided to monitor the performance of this library.

V8's built-in JSON has been improved for years, esp. JSON.parse() is significantly improved in V8/7.6, it is the fastest deserializer as of 2019, as the benchmark result bellow suggests.

(和訳) MessagePackを使う理由は実行時のパフォーマンスだけではありません。それでもどのMessagePackのライブラリを選ぶのかは重要です。そのため、このライブラリのパフォーマンスを観察するためのベンチマークスイートを用意してあります。 V8に組み込まれたJSONライブラリは何年も掛けて改善されており、特にJSON.parse()はV8/7.6で目を見張る改善がなされました。下のベンチマーク結果が示唆するように、2019時点では最も早いデシリアライザです。

ChromeのJavaScript実行エンジンのV8はC++で書かれており、パフォーマンスが高いのは納得できます。

とはいえ、2019年からもう4年が経過しており、多少状況が変わっている可能性はあります。

ベンチマーク

そこで現時点の実際のパフォーマンスを知るために、@msgpack/msgpackのリポジトリ内のベンチマークを実行してみます。

比較しやすいように出力結果は整形してあります。また、比較のために一部のテストケースにJSONを追加しています。

npx node -r ts-node/register benchmark/benchmark-from-msgpack-lite.ts

Benchmark on NodeJS/v20.5.0 (V8/11.3)

operation                                         |   op    |   ms  |  op/s
------------------------------------------------- | ------: | ----: | ------:
(エンコード)
buf = Buffer.from(JSON.stringify(obj));           | 1084100 |  5000 |  216820
buf = require("msgpack-lite").encode(obj);        | 1001900 |  5000 |  200380
buf = require("@msgpack/msgpack").encode(obj);    | 1260600 |  5000 |  252120
buf = /* @msgpack/msgpack */ encoder.encode(obj); | 1311300 |  5000 |  262260
buf = require("msgpackr").pack(obj);              | 2915100 |  5000 |  583020
(デコード)
obj = JSON.parse(buf.toString("utf-8"));          | 1737500 |  5000 |  347500
obj = require("msgpack-lite").decode(buf);        |  575700 |  5000 |  115140
obj = require("@msgpack/msgpack").decode(buf);    | 1536000 |  5000 |  307200
obj = /* @msgpack/msgpack */ decoder.decode(buf); | 1546600 |  5000 |  309320
obj = require("msgpackr").unpack(buf);            | 1424700 |  5000 |  284940

node benchmark/msgpack-benchmark.js

./sample-large.json: (7598 bytes in JSON)

(encode) json             x 82,388 ops/sec ±0.54% (96 runs sampled)
(encode) @msgpack/msgpack x 31,050 ops/sec ±0.16% (100 runs sampled)
(encode) msgpack-lite     x 29,034 ops/sec ±0.76% (96 runs sampled)
(encode) notepack.io      x 28,766 ops/sec ±0.13% (98 runs sampled)
(encode) msgpackr         x 66,822 ops/sec ±0.65% (97 runs sampled)
(decode) json             x 80,895 ops/sec ±0.73% (98 runs sampled)
(decode) @msgpack/msgpack x 32,898 ops/sec ±0.12% (98 runs sampled)
(decode) msgpack-lite     x 15,715 ops/sec ±0.27% (98 runs sampled)
(decode) notepack.io      x 21,699 ops/sec ±0.90% (100 runs sampled)
(decode) msgpackr         x 67,720 ops/sec ±0.21% (99 runs sampled)

結果を見ると、デコーディングに関してはJSONが依然として早いことがわかります。デコーディングにおけるパフォーマンスが低い理由は、JSONと同じくスキーマレスで構造がわからないというのが大きな理由だと考えられます。

ライブラリの中でも msgpackrは早いことがわかります。MeasureThat.netにはmsgpackrの異なるテストケースが載っています。

数値や真理値等を中心としたデータの多次元配列をデコードする MsgPack Numbers Decode というテストケースではJSONと比べて2.6倍程度早いようです。データの読み取りが単純な数値であれば、決まったデータを読み取って変換(ビット演算等)するだけであり、早いのは納得できます。

一方、文字列のデコードを中心とした MsgPack String Decode はJSONに比べて遅いという結果が出ています。MessagePackでは、ヌル終端文字列ではなくPascal文字列を採用しています。つまり、文字列長を最初のバイトに含めるようになっています。これにより、読み取り速度を大幅に向上させられます。しかし、それでも遅いという結果が出ているということは、V8のC++で実装されたJSON.parse()の方がJavaScriptで書かれたmsgpackrよりも早いのだろうと推測しています。

文字列データが支配的でない単純な配列であれば、MessagePackの方が早いのではないかと考えられます。実際にそのようなデータを試してみたところ、JSONよりも1.5倍程度早いという結果が得られました。とはいえ、配列の何番目にデータが入っているという知識を事前に共有しておく必要があり、データ構造の変更に注意を払う必要が出てきます。実用性を考えると好ましいとはいえないでしょう。なお、ここでは Chrome/115.0.5790.114 (V8 11.5.150.16) を計測に利用しました。

エンコードしたデータ

[
  ["hello", 123, true],
  ["world", 456, false],
  ["java", 541, true],
  ["javascript", 231, false],
  ["c", 852, true],
  ["cpp", 142, false],
  ["basic", 431, true],
  ["python", 591, false],
  ["hello", 123, true],
  ["world", 456, false],
  ["java", 541, true],
  ["javascript", 231, false],
  ["c", 852, true],
  ["cpp", 142, false],
  ["basic", 431, true],
  ["python", 591, false],
]
operation              |   op
---------------------- | ------:
JSON Numbers Decode    |   968,421 ops/sec ±0.83% (68 runs sampled)
JSON String Decode     | 1,104,092 ops/sec ±0.54% (69 runs sampled)
JSON Simple Decode     |   923,841 ops/sec ±0.22% (69 runs sampled)
MsgPack Numbers Decode | 1,593,083 ops/sec ±0.17% (69 runs sampled)
MsgPack String Decode  |   994,357 ops/sec ±1.79% (65 runs sampled)
MsgPack Simple Decode  | 1,366,154 ops/sec ±0.13% (69 runs sampled)

MessagePack自体はスキーマレスなデータ形式ですが、亜種のmsgpackrではスキーマを定義するための仕組みもあるようです。msgpackrに掲載されているベンチマークを実行してみました。

operation                                                  |    op    |   ms  |   op/s  |    size   |
---------------------------------------------------------- | -------: | ----: | ------: | --------: |
(エンコード)
msgpackr w/ shared structures: packr.pack(obj);            | 15845200 |  5000 | 3169040 |           |
msgpackr w/ random access structures: packr.pack(obj);     | 16235200 |  5000 | 3247040 |           |
require("msgpackr").pack(obj);                             | 10741900 |  5000 | 2148380 |           |
bundled strings packr.pack(obj);                           |  9101900 |  5000 | 1820380 |           |
buf = Buffer(JSON.stringify(obj));                         |  6359300 |  5000 | 1271860 |           |
(デコード)
msgpackr w/ shared structures: packr.unpack(buf);          | 34135500 |  5000 | 6827100 |        63 |
msgpackr w/ random access structures: packr.unpack(buf);   | 21832500 |  5000 | 4366500 |        58 |
require("msgpackr").unpack(buf);                           |  6387800 |  5000 | 1277560 |       143 |
bundled strings packr.unpack(buf);                         | 15376400 |  5000 | 3075280 |        74 |
obj = JSON.parse(buf);                                     |  7323000 |  5000 | 1464600 |       180 |

require("msgpackr").unpack(buf) とJSONでは、JSONのほうが早いという結果が出ています。一方、スキーマを定義したmsgpackr w/ shared structuresでは、4.7倍という非常に早い結果が出ています。

上記のベンチマーク結果を見ると、JSONのデコードとMessagePackのデコードのパフォーマンスに大きな差がないため、JSONと比べてもおよそ4倍程度の差だと推測できます。これは、後述するスキーマベースのProtocol BuffersがJSONと比べて4倍程度早いこととも一致します。

Protocol Buffers

Protocol Buffersは、スキーマに基づくデータフォーマットです。スキーマはデータ構造の定義のことで、これを事前に定義して送信者と受信者で共有し、エンコードとデコード時に用います。JSONやMessagePackでは、実際にデータを読み取らなければ構造がわかりませんでしたが、Protocol Buffersでは事前に分かっているため、高いパフォーマンスが期待できます。

Protocol BuffersのためのJavaScriptライブラリとしては、protobuf.jsgoogle-protobufが人気のようです。

protobuf.jsのREADMEに載っているベンチマーク結果は、i7-2600KとNode.js 6.9 (2016年)のもので結果が古くなっています。

ベンチマーク

protobuf.jsのリポジトリ内のベンチマークを実行してみます。

ただし、以下の点で変更があります:

  • 静的コードの再生成
    • pbjs --target static data/bench.proto > data/static_pbjs.js
  • google-protobufの更新
    • 3.11.3 -> 3.21.2
> protobufjs@7.2.4 bench
> node bench

benchmarking encoding performance ...

protobuf.js (reflect) x 1,544,621 ops/sec ±0.21% (96 runs sampled)
protobuf.js (static)  x 1,580,495 ops/sec ±0.17% (97 runs sampled)
JSON (string)         x 1,165,063 ops/sec ±0.18% (95 runs sampled)
JSON (buffer)         x   872,308 ops/sec ±0.19% (97 runs sampled)
google-protobuf       x 1,015,041 ops/sec ±0.16% (99 runs sampled)

   protobuf.js (static) was fastest
  protobuf.js (reflect) was  2.3% ops/sec slower (factor 1.0)
          JSON (string) was 26.3% ops/sec slower (factor 1.4)
        google-protobuf was 35.8% ops/sec slower (factor 1.6)
          JSON (buffer) was 44.8% ops/sec slower (factor 1.8)

benchmarking decoding performance ...

protobuf.js (reflect) x 3,936,820 ops/sec ±0.14% (99 runs sampled)
protobuf.js (static)  x 4,269,989 ops/sec ±0.20% (97 runs sampled)
JSON (string)         x   949,356 ops/sec ±0.14% (99 runs sampled)
JSON (buffer)         x   868,264 ops/sec ±0.15% (100 runs sampled)
google-protobuf       x   909,006 ops/sec ±0.18% (95 runs sampled)

   protobuf.js (static) was fastest
  protobuf.js (reflect) was  7.7% ops/sec slower (factor 1.1)
          JSON (string) was 77.8% ops/sec slower (factor 4.5)
        google-protobuf was 78.7% ops/sec slower (factor 4.7)
          JSON (buffer) was 79.7% ops/sec slower (factor 4.9)

benchmarking combined performance ...

protobuf.js (reflect) x 1,057,638 ops/sec ±0.14% (96 runs sampled)
protobuf.js (static)  x 1,106,991 ops/sec ±0.19% (98 runs sampled)
JSON (string)         x   491,279 ops/sec ±0.16% (99 runs sampled)
JSON (buffer)         x   420,535 ops/sec ±0.21% (99 runs sampled)
google-protobuf       x   462,041 ops/sec ±0.31% (95 runs sampled)

   protobuf.js (static) was fastest
  protobuf.js (reflect) was  4.4% ops/sec slower (factor 1.0)
          JSON (string) was 55.6% ops/sec slower (factor 2.3)
        google-protobuf was 58.3% ops/sec slower (factor 2.4)
          JSON (buffer) was 62.0% ops/sec slower (factor 2.6)

公式サイトに掲載されているデータは、Node.js 6.9.1(V8 5.1系)であり、JSON.parse()の改善前のものでした。 今回のNode.js v20によるデコードの結果を見ると、差はやや縮まっているように見えますが、それでも4倍程度はprotobuf.jsのほうが早いことがわかります。

Protocol Buffersがなぜこんなにも早いのかを考察してみます。MessagePackでは文字列のデコードが遅いことが分かっていましたが、Protocol Buffersでも文字列の表現(Pascal文字列)には違いがありません。そのため、(検証は行っていないのですが)Protocol Buffersでも文字列が多いデータのデコードは早くないだろうと予想できます。MessagePackでオブジェクト(Map型=JSONのオブジェクトのような連想配列)を表現したい場合、フィールド名を文字列として表現しなければなりません。一方、Protocol Buffersではスキーマという形でフィールド名が事前に送信側と受信側で共有されており、フィールド名の代わりにフィールドのID(整数値)を使ってエンコードが行われます。Protocol Buffersは文字列のエンコードをしなくてよい分、早いのだろうと思います。他の要因としてデコード処理の効率化の程度の違いやデコード時の型チェックの省略による影響も考えられます。

まとめ

Protocol Buffers(特にprotobuf.js)は非常に早く、 JSONと比べて4倍以上高速 にデコードできることがわかりました。

MessagePackはJSONより遅くなる場合がありました。特に文字列を中心としたデータではパフォーマンスが出ないようです。一方、数値を中心とした単純な配列のようなデータであれば高いパフォーマンスを示しました。また、事前にスキーマを用意しておける亜種のmsgpackrを使えばProtocol Buffersに近い性能を発揮できるようです。

スキーマベースのデータフォーマットが高いパフォーマンスを発揮できる理由は、構造の情報を事前に共有してあることで、プロパティ名・フィールド名(JSONのキーに相当)のような構造の情報を実行時に読み取る必要がないためだろうと思われます。

ただ、桁が変わるほど、つまり10倍、100倍、1000倍といった大きな差があるわけではありませんでした。数KBのデータのデコードにかかる時間は数マイクロ秒程度であり、1000倍のデータ(数MB)がやってきたとしても単純計算で数ミリ秒しか掛かりません。ブラウザ上で更に大きなデータを大量に扱うという場合であれば役立つ可能性はありますが、パフォーマンスだけを考慮するならば、多くのケースでJSONでも十分だと考えられます。

一方、大量のリクエストやデータに応えなければならないサーバ側では、大量のデコード処理を行う必要が出てくるでしょう。サーバ側で使われるCやJavaのようなコンパイル型の言語であればバイナリフォーマットされたデータのデコードにおいてJavaScriptの実装よりも高いパフォーマンスを発揮できると予想されます。デコード処理を効率化できれば、その他のことにCPU時間を利用できるため、パフォーマンスは僅かながら向上するのではないかと期待できます。大規模システムではその小さなパフォーマンスの差が費用に大きな違いを生むかもしれません。

パフォーマンス以外にもスキーマベースのプロトコルには様々なメリットがあることを忘れてはなりません。スキーマによって送受両端でフォーマットの食い違いを予防すること、データフォーマットを安全に更新できること、型安全なプログラミングを実現できること、gRPC等のフレームワークに則った開発ができることなどといった利点があります。そういった他の効果も踏まえて検討をする必要があります。

今回は調べられなかったProtocol Buffersにおける文字列のデコード速度は、いつか測定できればなと考えています。また、今回はライブラリのテストケースをそのまま実行しましたが、条件の異なる様々なテストケースを作成して比較してみたいと考えています。

今回の結果はNode.jsで測定したもので、ブラウザによってはベンチマークの結果が大きく変わります。今回は記載していませんが、Safari(JavaScriptCore)や Firefox(SpiderMonkey)では JSON.parse() のパフォーマンスが異なります(その場合でもフォーマット間のパフォーマンスの差という意味ではあまり変わりません)。

ECSの起動繰り返しが及ぼす料金課金の実態

ECSの起動繰り返しが及ぼす料金課金の実態

クラウド環境が充実してきて、Webサービスのホスティング方法も多様な形になってきました。 AWSで言えば、EC2・Lambda・ECS・EKS・Elastic Beanstalk・Lightsailなどの選択肢があります。

今回はECSで開発環境向けの利用で頻繁にECSの起動終了を繰り返す処理があったことで、意外な所に余波があり、きづいたことをお伝えしようと思います。

料金形態とライフサイクルを意識する

どのサービスを使おうかと検討する際に、クラウド費用の料金と自分たちの運用・用途にあわせて選ぶことになります。

ECSは秒単位の課金がされますので、常に起動していても、任意のタイミングで起動・終了しても1ヶ月でかかるコンピュートリソース料金の換算の仕方はEC2とそれほど変わりありません。

ライフサイクルとしてはコンテナ単位なのかOS単位なのかという違いがあり、コンテナの方が包括範囲が小さいです。

仮に10秒毎に起動終了の処理を繰り返したとしても1ヶ月料金に近い料金がかかるくらいだろうという推測でした。

クラウドで複数サービスを使うということ

クラウドでは複数のサービスを組み合わせて便利に使うことが多く、今回気づいた「意外な所に余波を及ぼしていた」という話もECS単体では発生せず、他サービスと組み合わせて発生する事象となります。

今回の環境はそれなりの規模のリソース量(金額・数量ともに)ということもあり、請求書ダッシュボードを定期的にチェックしています。その際に、他のサービスに比べて絶対的な金額としてはそこまで高くないけど、「このサービスにしては少し費用が高めだなぁと気になりました」項目がありました。それがAWS Configです。

AWS Configはリソースの構成をロギングし、評価、監査、診断ができるサービスです。 このサービスを使うと、生成されたリソース群に対して自分たちのルールに準拠された設定がされているか、などのチェックができます。

料金としては ロギングされた記録1つあたり $0.003 費用が発生します。 1件あたりとしてはそこまで高くなく、仮に1000回記録されても$3です。

ライトユーザーでも気軽に使える料金体系となっていて、利用しないという選択肢の方が少なくなってきているのではないでしょうか。

繰り返し処理の罠

今回陥った罠としてはECSの繰り返し処理でした。 リソースの立ち上げ・終了で発生する課金は、クラウド破産のパタンとして「あるある」な勘所や考慮が必要なポイントなので臭いますね。

ECSのライフサイクル特有の仕様となるのですが、EC2内でサービスを起動する時にはAWSリソースが新たに生成されることがないのですが、ECSは起動・終了の度にセキュリティグループが生成・削除されその度にAWS Configのレコーディングが発生します。

今回のECSの実行するアプリケーションでは、起動時に関連サービスの状態をチェックして「起動する必要がない時は終了する」という処理にしてありました。

この起動・終了を繰り返す処理が非常に短い間隔で行われていたことから、AWS Configのレコーディングログが大量に生成されていました。想定より50〜100倍程度課金が発生してしまっていました。

EC2インスタンスを立ち上げて、待ち受けるのとそれほど変わらない処理に見えても、AWSリソースにアクセスし・操作・トラフィックが流れているという状況では、利用している全てのサービスに気をかける必要がありますね。

運用を始めてすぐのリソース使用状況だと積み重ねがされていないのできづきにくいけど、定期的に費用のチェックをしたりBudgetアラートを仕込んだり項目ごとに適切にしていく設定値を見直していくことで、きづけるようになります。

対策と運用について

コンテナでサービスを起動するというやり方は変えず、ECSは使い続けました。 関連サービスの状態でサービスを起動するという方法をやめました。

というのも、関連サービスの状態が変わるタイミングは手動実行をしていたので、同じタイミングでこのECSアプリケーションも起動・終了をするようにしました。

起動スクリプト修正さえ対応すれば、運用上の手間やフローは今までとそれほど変わらず、Croud Configの料金を想定通り1/10程度に抑えることができました。

まとめ

今回の事例から、あらためて以下のような学びがありました。

  • 空気のようにあるようなサービスにも気を使おう
  • 運用とライフサイクルを結びつけて最適なクラウドサービスや処理方法を検討する
  • 何にどれだけ料金が発生しており妥当かどうかをチェックすることは大事

AWS Lambdaでも「再帰ループ」の検出と停止ができるようになりましたが、意図したイベントループ・繰り返しの場合でも注意が必要です。 考慮漏れはどんな時でも発生し得るので、きづけること・原因を把握できるようになっていきたいです。

参考サイト

新卒1年目からのリモートワーク生活 1年くらい経ってみての感想

はじめに

 はじめまして!

 アットウェアでエンジニアをやっているニシカワと申します。

 アットウェアがリモートワーク制度を導入してから約1年と半年が経過しました。

 横浜に残って働くという選択をしたメンバーがいる中で、過去のリモートワークについて書かれた記事で紹介されたように、全国に移住していくメンバーもいました。

 私も移住を選択した1人です。

 当時の私は新卒1年目。右も左も分からない状況でした。そんな状況でどうして移住を決断したのか、実際に生活してみてどうだったのか、自身のふりかえりも兼ねて記事にしてみたいと思います。

移住のきっかけ

 突然ですが、私は現在、兵庫県の豊岡市という街に住んでいます。

 

 関東圏に住まれている方にはあまり馴染みのない地名かもしれません。コウノトリや城崎温泉が有名な、人口7万人ほどの街です。

 引っ越す前、私はアットウェアがある横浜に住んでいました。

 横浜に住んでいたときは、よく近くの公園で散歩したり近所の商店街で食べ歩いたりと、平凡ながらも楽しく暮らしていました。

 

 しかし、そんな中で、ずっとこのままでも良いのだろうかと思い始めました。たしかに今の生活には満足している、しかし、毎日同じような生活で何か得るものはあるのだろうか、と。

 もともと色々なところに行くことが好きで、学生の頃は青春18きっぷで日本各地を巡っていた身です。一箇所にずっといることがむしろ苦手だったのかもしれません。

 そんなこんなで地方移住しようと思ったのですが、問題は行き先です。それに関しては幸いなことに候補がいくつかに絞られていました。

  • 小田原市

  • 京都の二条付近

  • 豊岡市

 いずれも過去に訪れたことがあり、良さそうな場所だと感じていました。ただ、どうせ行くなら一番遠く、日本海側にしようと思いました。

 それで豊岡市に引っ越したのですが、住んでみると住み心地が良くて、気が付いたら1年くらい経ってしまいました。

業務内容とか1週間の流れとか

 せっかくなのでエンジニアらしく技術的なこともちょこっと書いてみます。

 現在の仕事は、特定の画像データから抽出された情報をまとめたサイトの開発・運用を行っています。技術スタックは、React、Java、AWSあたりを使って開発を進めています。

 

 学生時代に一応プログラミングの経験はあったものの、チーム開発の方法やテストの手法など、入社してから初めて学んだことも沢山あります。

 1週間の流れは、過去のリモートワークについて書かれた記事で紹介されている方達とあまり変わらないです。平日は業務、週末は家でゆっくり過ごしたり外に遊びに行ったりします。出勤の時間がない分、趣味や勉強の時間は取りやすいと感じてます。

 ただ、リモートワークだと徐々に運動をしなくなってしまうので、そこだけ注意しています。

1年くらい経ってみての感想

 移住から1年くらい経ってみて、意外とリモートでも働けるなという感想をもっています。

 開発はクラウドサービスが主なので現地に行かなくても作業できます。作業で止まったときは、Discord(通話アプリ)にチームで常駐状態になっているので、すぐに相談できる環境にあります。どうしても1人だけの環境だと心が荒れていく(個人的な見解です)ので、適度にチームや会社の仲間と話す時間は大切だと実感しました。

 それでも、リモートワークが出社に勝るかと問われれると、一概にそうとは言い切れないと思います。移住してからしばらく経ち、チームの雰囲気にも大体慣れたかなというタイミングで出社の機会があったのですが、普段とはまた違う良い時間となりました。

 出社の際は、同じ画面を見ながら実装することで、リモートワークでは得られない適度な緊張感や一体感に包まれ、チームの仲間との絆を深めることができました。

 仮にこの1年を出社して過ごしていたとしたら、直接の交流から得られる力で、また別の学びがあったと思います。

 リモートワークと出社、どちらか極端に偏るというよりも、チームの状況や雰囲気に合わせて適度に使い分けることが大切だと感じました。

週末の楽しみ

 プライベートなことだと、日本海側の冬を経験し、雪の大変さを実感しました。横浜は雪が降ってもせいぜい数cmですが、豊岡市の雪は足が埋まります。雪用に新しく長靴や上着を買ってなんとか乗り切りました。

 

 買ったものつながりだと、車も買いました。必要なものは徒歩で買える場所にあるのですが、車があると遠出の際に便利です。 

 週末は家でゆっくり過ごしたり外に遊びに行ったりしますが、時間があるときは京都や大阪まで足を伸ばします。

 写真は日本三景の天橋立です。自宅から車で2時間くらいの距離にあり、週末のドライブにもってこいの場所です。

おわりに

 この1年を振り返ってみて、色々とやりたいことができた1年になったと感じています。

 エンジニアとしては将来に繋がる開発のスキルやチームで動く大切さを学び、プライベートでは様々な場所を巡ることができました。

 新卒だからという枠組みに囚われず、自らが得たいものを考えて生きることが大事だと思いました。

 課題への素早い対応や他のメンバーへのサポートなど、まだまだ学ぶことは多いですが、自身の成長に繋がった1年だったと思います。また、学びを深め、いつかリモートワークで海外生活もしてみたいという憧れも芽生えました。

 将来、また横浜に戻り出社を選択するのかは分かりません。しかし、リモートワークであっても出社であっても、エンジニアとして根本的なこと、チームで協力して全力で課題の解決に望むことや、atWareのミッションである「システムで人々をしあわせに」ということは決して変わらないと思います。

 今後も、この1年で学んだことを活かし、一生懸命励みたいです。

VPC Traffic Mirroringを使ってみた話

今回はAWSのVPC Traffic Mirroringについて、某案件で検証を行なったので、紹介/注意点/使い所について書きます。

展開中のノードへの通信をサクッと覗きたいなど特定用途として使えるケースがあると思うので参考になればと思います。


はじめに

  • 今回導入を考えたシステムについて、顧客からの要件としては外部システムから本番環境への通信をテスト環境へ転送し、本番環境と同一のデータでテストを行いたいというものでした。
  • 複数ある外部システムとはWebSocketでそれぞれとコネクションを確立し、システムは一度に最大100MB程のデータpushを受信し続けます。
  • VPC Traffic Mirroringを利用してデータの転送が可能であるかを検証し、使えそうならシステムに組み込みたいという流れです。

VPC Traffic Mirroringの概要

  • 大まかにいうと特定インスタンスのNIC(ENI)に流れてきたネットワーク上のpacketを特定のノードへ転送することが可能です。
  • AWSからの説明そのままですが、ユースケースとして以下のようなものを想定しています。
    • コンテンツ検査
    • 脅威の監視
    • トラブルシューティング
  • 転送先はリージョンまたぎやVPC間も考慮されており、マネージメントコンソールのグルーピングとしてはVPCのページから設定が可能です。
  • 料金
    • Traffic Mirroringを有効にしたENIが起動している間、料金がかかります。
    • 東京リージョンであると0.018USD/hour(2023/2現在)
      • 1ヶ月30日とすると30日×24時間×0.018=12.96USD/month
    • そこまでの値段ではないですが、転送先の仕組みなども用意することも考えたら使う時だけ有効にするのが良いかと。

動作/設定

  • Traffic Mirroringを使う際のリソースは以下の呼称で呼ばれます。以降の説明はこの呼称でしていきます。
    • ソース: 転送元(指定したノード(ENI)への通信を転送)
    • ターゲット: 転送先(EC2/NLB/GLB(他VPC宛など))
    • フィルタ: 転送対象(ポート/プロトコルなど指定)
    • セッション: 上らをまとめたもの
    • 設定例は以下。
      • ミラーフィルタ/ミラーターゲット/ミラーセッションの順に上記リソースを設定します。

ターゲット側の準備

  • 転送されてきたpacketをどう扱うかターゲットに仕組みが必要です。
  • 例1. packet解析ソフトウェアにかけて分析
    • tcpdump
    • Wireshark/tshark
    • AWS公式からは以下のようなツールも紹介している
    • 例えばtcpdumpでpacket captureし、出力されたpcapをS3に置くなど。
  • 例2. packetを処理するようなアプリを自作する
    • ターゲットのNICに対しpacket captureをするようなアプリを自作する。
    • この際、転送されてきたpacketのみ処理するような仮想NICを作るなど工夫がいる(後述)
    • 検証ではGo(gopacket)/Java(pcap4j)でアプリを実装した実績あり。

転送されてくるpacketについて

  • ターゲットに流れてくるpacketはVXLANというL2->L3トンネリングプロトコルの形式で流れてきます。
  • VXLANはUDPで扱います。なので再送/フロー制御は期待できません。また、NLBなどを転送先にする場合には順番が維持できないことがあるとのこと。
  • packetにはVXLANのヘッダ(40byte)が付与されており、その後ろに元のpacketが繋がる形。
  • すなわち、元のpacketを取り出したい場合にはVXLANヘッダ部を取り除く必要がありますが、LinuxであればVXLANタイプの仮想NICを以下のようなip(iproute2)コマンドで作成することで自動的に行うことが可能です。
    • 作成した仮想NICをcaptureすることでVXLANヘッダを除外した元のpacketを取得できます。
    • VNIというVXLAN packetのグループを識別するためのIDと転送時に使用するUDPポートを指定します。(マネージメントコンソールで設定した値)
    • Amazon Linux2で動作確認済み。(kernel versionやdestiributionの細かいところの条件は未確認)
    • NICのMTUについての注意もあるので参考に。
      • 説明の通り、VXLANで転送されたpacketはオリジナルpacketよりHeader分サイズが大きくなります。
      • そのため、ソースNICのMTU < ターゲットNICのMTUという関係になっていないとpacketが切り捨てられる可能性があります。(必要なMTUサイズ設定については上のリンクを参照)

$ sudo ip link add vxlan0 type vxlan id 1 dev eth0 dstport 4789
$ sudo ip link set vxlan0 up


検証とそこから見えた注意点

  • 実際の構成を想定して右図のような仮の環境を用意し、要件に合うか検証してみました。

問題

  • 想定するデータ量を外部システムノードからソースに送信->転送した際、分割されたpacket群の途中から転送されて来ない。。。
    • WebSocketでデータpushするデータを1MB/10MB/100MBと順に上げていってみたところ、10MBぐらいから後半のpacket転送がされていないことが判明しました。
    • ソースに配置したアプリへは正しくデータが送られており、最初はターゲット側のpacket captureアプリ設定なりがおかしいのかと思い試行錯誤したがどうもうまくきません。

原因

  • 「なんでじゃ」と夜も寝られなくなった中、よくよくヘルプを見直すと次のようなものを発見しました。
  • Traffic bandwidth and prioritization
    • Mirrored traffic counts toward instance bandwidth. For example, if you mirror a network interface that has 1 Gbps of inbound traffic and 1 Gbps of outbound traffic, the instance must handle 4 Gbps of traffic (1 Gbps inbound, 1 Gbps mirrored inbound, 1 Gbps outbound, and 1 Gbps mirrored outbound).
      • つまりは、ソースの帯域幅について、想定するトラフィックの2倍〜4倍を見積もっておかないといけない。
      • 今回の要件では上り方向への通信のみ転送したいので本番+テスト環境のインバウンドトラフィック用に2倍必要。
      • ポイントはソース(転送元)の帯域幅が大事ということ。
    • Production traffic has a higher priority than mirrored traffic when there is traffic congestion. As a result, mirrored traffic is dropped when there is congestion.
      • つまりは、ソースの帯域が輻輳した場合、packetがドロップされ転送されない。
  • 問題が起きた流れとしては、以下と考えられます。
    1. 大きいデータをソースに向けてドカっと送る
    2. ソースの帯域で輻輳が起こる
    3. 輻輳のために本番トラフィックが優先される
    4. データの途中から転送が行われなくなる
  • ヘルプの通りCloudWatchを監視してみたところ、データ転送に失敗した場合、輻輳によるpacket dropのメトリクスの値が増えており、上記の制限によりpacketがdropされてしまっていることがわかりました。

対策検討

ソースへの通信の輻輳が起こらないようにデータ流量をコントロールできれば良いのではと思い、以下のようなことを試してみました。

  • ソースのインスタンスタイプを上げて、ネットワーク帯域を強いもの(c5n.largeなり)に上げてみる。
    • 100MBを一斉に送ると、変更前よりも転送された量は多くなったが、後半のpacketがdropされてしまう。
  • ソースで輻輳が起こらないようなインスタンスタイプの関係にしてみる。
    • 外部システム(t2.micro) -> ソース(c5n.large)というようにソースへの通信がゆっくり流れる(?)であろう関係にすると100MBのデータも転送ができる場合が増えた。
    • 当然ながら転送対象のデータだけがネットワーク上に流れているわけでもないため、うまくいったりいかなかったり完璧ではない。
  • AWSへ質問を出してみる。
    • どうにかして輻輳を起こらないようにする方法がないかAWSへも問い合わせてはみましたが、今回用途に合致するような方法は見つからなかった。
    • NLBなどにはデータ流量をコントロールするような機能は公開されていない。
    • また、流量をコントロールする用の別ノードを用意するのは今回用途(テスト環境に流す)に対して、対応が大きすぎる。本番環境に影響が出ては元も子もない。

結果

対策の検討結果より、今回用途に適さないところから「使用しない」という結論に至りました。

  • テスト環境へのデータ転送のためpacket dropしても問題はないが、本番環境と同じデータで動作再現したいことから極力dropは避けたい。(そもそもVXLANがUDPということもある。)
  • インスタンスタイプ(ネットワーク帯域)による制御については、今後増加しうる外部システムが増えるごとにサイジングし続けないといけなくなり、現実的でない。
  • 流入制御する別ノードの必要性など本番環境に影響を与えない形での実現が難しい。

まとめ/使い所

  • 「稼働中ノードへの通信を少し覗き見したい」などのケースにおいてはとても有用なプロダクトかと思います。
    • 通信の監視がアプリ組み込みせずとも後付けで可能。
  • システムに取り込むような本格的な利用となると、検証結果を踏まえて以下のポイントを抑えておくと良いかと思います。
    • 転送するデータ量がどのくらいか
    • packet欠損が起きても問題がないか
    • ソースのネットワーク帯域が輻輳を起こさない環境であるか
  • 制限事項がいくつかあります。特にここは一通り目を通しておくべきです。
    • 検証内容から得た教訓として「困ったら基本に戻ってヘルプを読め」というのを実感させられました。
  • その他参考

以上。

yamoryという脆弱性管理サービスを実案件で活用しました

yamoryという脆弱性管理サービスを実案件で活用しました

前エントリーでは組織として社内へ脆弱性対策への取り組みの一環として、yamoryという脆弱性管理サービスを導入するまでをお伝えしました。 今回はyamoryを実践で実際に使ってみて、各々が個別に最適して工夫した所や所感をご紹介したいと思います。

最初はImmediate(即時に影響を受ける可能性)を無くすところから

1つ目の適用プロジェクトの事例です。

スタートアップ系の案件となります。ビジネスモデルを立証や確立を目指していくところから始めるので、コストも限られていて機能実装のバランス感覚が非常に重要になってきます。

プロジェクトが始まってから数年経過していますが、現在もユーザを獲得したり市場の要望に応えていくフェーズの真っ只中で、たくさんのモジュールや個別対応などシステムも大きくなってきています。

その中には初期頃に作ったモジュールも含まれており、特段理由がなければライブラリを最新バージョンにはアップグレードせず、当時の最新版を利用しているモノもありました。

社内にyamoryが導入されたということで、試しにyamoryを使ってスキャンしてみたところ、幾つかキャッチできていなかった危険な脆弱性が見つかり、取り急ぎ対応しました。

やはり、逐一開発チームだけで脆弱性情報をキャッチしていくには時間の都合上無理があるとは感じていたので、yamoryがあると非常に助かるということで、チーム内で相談して本格導入が決まりました。

yamoryを導入すれば脆弱性情報が公開されて即時に対処できるようになるので、対応基準とフローを検討することにしました。

対応方針

  • 危険な脆弱性は迅速に対応して0を維持する
  • 週間レポートで脆弱性が発生したら普段使っているITS(課題管理システム)でチケット化して対応する
  • MinorやDelayedについては把握はしておき、いつ対処するかは状況によりけりということにする
  • 判断できる基準を設けてワークフローを策定し作業をルーチン化する

ということにしました。

ざっくり言うと、赤タグ(Immediate)は逐次対応して即時リリースしていくという方針です。基本的には遅くとも1週間ごとに対応が回っていきます。

yamoryで自動スキャン・作業をワークフロー化することにより、着手予定の実装・運用系タスクやスプリント目標に影響せず、リソースも集中してリズムよく取り組めています。

以下のワークフローが、今回決めて取り入れたバックエンドのJava/Springフレームワークモジュール向けのもので、この他にもフロントエンド向けのワークフローも作りました。

yamory対処ワークフロー

今回立てたワークフローと方針で暫く試してみると、想定していた運用ができ、うまく回っていきました。

手始めにプログラムモジュールに対して脆弱性のスキャンを適用しましたが、Dockerコンテナで運用しているシステムもあります。yamoryにはコンテナの脆弱性スキャン機能も用意されてされているということで、どうするかを検討しています。 コンテナイメージの共有スコープは極力狭めたいという考えがあり、コンテナのスキャンについてはyamoryで行うか、それともコンテナをホストしているクラウドベンダーが提供しているSaaS機能を使うかが焦点になっています。 簡単でしたが、1つ目の脆弱性管理の実践の紹介でした。

CIに簡単に組み込めて安心感を得ることができました

次に、2つ目の適用プロジェクトの事例です。

新規事業のスクラッチからの案件で、スピード感を高めてフィードバックループのサイクルを早めていくことはもちろんこと、機能開発もどんどん行っています。

まず、チームには脆弱性対応へのアイディアとしてyamory活用の提案を出し、採用を即決し、存在する全てのリポジトリのCI Hookにyamoryを追加しました。

設定後は、だいたい月曜日にメールで脆弱性検知の通知が届くので、通知に「気づいた人が対応する」という運用で始めてみました。

暫く運用してみると、yamoryを採用したいと言った人が率先して対応していく流れになり、気づけばいつも特定の人(採用を推進した人)ばかりが対応しているという状況が生まれてしまいました。

個人依存にはしたくないなと思っていたところ、定期的に立てているプロジェクト全体目標の中に「様々なことで個人依存を減らし自動化をすすめる」というモノがあり、チームで対応策を考えてみました。

検討した結果、「検出したらチケット管理システムに脆弱性検知チケットを起票し、チームリーダーが担当者を割り振る」という案が出て、それを実行してみることに決めました。

これで、誰かが率先して対応するという形ではなくなりましたが、誰もが脆弱性対応に貢献できるようになりました。

続いて、yamoryを導入して気づいたことや所感をお伝えしたいと思います。

お悩み発生

yamoryを導入してからは「あぁ、これアップグレードをしないと...」と気にかけなくても済むという安心感を得ることができ、開発リソースも少なく済むという時間を得られた反面、導入した副作用のような悩みも発生しました。

それは何かというと、サービスの課金体系とプロジェクトのモジュール管理体系との兼ね合いです。

本案件ではイベントドリブンでデータを処理するバリエーションが多く、Serverless Functionのモジュールをたくさん用意しています。バリエーションが多い分、コードリポジトリをたくさん作っていたのです。

yamoryは契約毎に「合計スキャンアセット数の上限」が決められており、超えてしまうと追加でパック購入する必要が出てきてしまうそうで、もしかしたら「他プロジェクトや予算を圧迫してしまっているのではないか」という懸念に気づきました。

リポジトリの分け方は、開発スタイルやアーキテクチャ設計や運用設計にも影響してきます。yamoryで契約している数を超えないように、「節約のために本来しなくてもいいモジュールをまとめたり、リポジトリの数を節約しようかな」という意識がでてきます。

他にも、お金とリソースの配慮面でステークホルダーが増えて別視点で配慮する必要が増えました。

幸いなことに、まだ全社のプロジェクトを合わせても上限数には達していないということなので、リポジトリ数(スキャンアセット数)の精査や対応はしていませんが、yamory導入プロジェクトが増えてきたスキャンアセット数割当やプロジェクト毎に利用量に応じたコスト計算や利用料徴収などをしていくことになるのかなという将来をイメージしました。

さらにデータパターンなども増えてくる可能性もあるので、もしかしたら私達のプロジェクトはyamoryの料金形態と相性が悪いかもしれないのかなと。

料金によってSaaSやクラウドサービスを選択したりアーキテクチャを設計するように、yamoryもSaaSと考えれば、料金形態と案件特性との相性で取捨選択をしていき、設計や運用のし易さを加味して、トレードオフすることになりそうです。

ちょっとしたツラミ

もう一点気になったことが、依存ライブラリが内部で使っているライブラリに脆弱性が発見された時の事象です。緊急性が高くないMinorな脆弱性だとyamoryのトリアージで「今は対応しない」としてマークし、検知情報を消し込むのですが、暫く経つと同じ脆弱性がスキャンすることで検知されてしまい、「またこのライブラリが...」となって、警告に対して億劫になってしまいました。

感想をまとめると

悩みは発生したものの基本的にはyamoryを導入してよかったです。 想定していた課題感が別に出たのも興味深かったです。

その他には以下のようなことを感じました。

  • 安心感を含め心理的な影響は多大だなと実感した
  • 脆弱性検知ツールに頼るということは違うプロジェクトでも活用できそう
  • 導入の敷居の壁は料金次第で技術要素としては問題なくフィットする
  • 脆弱性検知ツールの仕様有無に関わらずセキュリティ情報はベストエフォートでキャッチするし情報交換するということはしたい
    • 安心できるから何もしないということにはならなかった
    • 世の情報を全部把握するということを課さなければ負荷に感じない
    • もしかしたら情報収集は一種のライフワークかもしれない

まとめ

今回は2つのプロジェクトで実践した結果のご紹介をしました。 CIに組み込みやすいということで、導入しようと実践したプロジェクトではすんなりと設定・運用までもっていくことができたようです。新たな気づきもありました。

いくら脆弱性対応をしても何かが便利になるというわけではありませんが、安全にシステム運用してユーザさんにも安心してサービスを使い続けて頂くには必要なことですので、これからも目に見えない持続的な価値提供をできように取り組みを拡げていきたいと思います。

心を合わせてともに働く前にやるといいかもしれないワークショップ資料を公開します

心を合わせてともに働く前にやるといいかもしれないワークショップ資料を公開します

突然ですが...

  • チームで仕事をすることってよくありますか?

  • チームで仕事をする際、人間関係に起因しそうな問題で、ストレスを感じることってありませんか?

  • もっともっと効果的なチームになりたいですか?

上記のような問いにあてはまる方は、ぜひ読んでみていただければなと思います。

かくいう私達も上記の問いにはあてはまりますし、なんとかしたいなぁと思っています。そして、私たちは人間の力、そしてチームの力を信じています(信じたい、信じられるシチュエーションを増やしたい。の方がより適切かもしれません)

異なる背景を持ち、違う考え方をするもの同士が「共通の目標を達成するのだ!」

と話し合い、その過程でおきるであろう化学変化と、その結果に価値があると信じています。

効果的な化学変化を生み出すために必要なことはいくつかありそうですが、チームメンバーがお互いのことを知り、安心して意見を言い出せる関係もその一つだと思っています。

このような世界を作ることに貢献できることを期待して下記のようなワークショップをデザインしてみました

  • 参加者が「これからともに働く上で知りたい/表明しておきたい」価値観を洗い出す

  • 上記で洗い出された価値観について、各々が自身の考え(価値観)を表明し、お互いにそれを理解する

  • 上記で表明し理解した、お互いの価値観を尊重する約束事を作成してみる

そして、このワークショップの名前を「心を合わせてともに働くときにやったほうがいいかもしれないワークショップ」と名付けてみました。

具体的にどんなワークショップか、ワークショップ資料をダウンロードしてのぞいてみませんか?もし気に入っていただけたら、ファシリテーターズガイドも用意しているので、すぐにお試しいただけるかなと思います。

資料は以下からダウンロードできます。

ご参考までに、我々が想定しているユースケースの一部を共有してみます。

  • チームが発足したとき

    • チームビルディングの一環として

  • 現在のチームの効果性をあげたいとき

    • チームメンバのことをもっと理解する試みの一環として

  • その他(もしかしたら、下記のケースでも使えるかもしれません)

    • 学校で、新しいクラスになったとき

    • チームスポーツで、チームとして纏まりたいとき

    • 結婚前提のお付き合いを始めるとき

おまけに、弊社内でこのワークショップを実施した際の意見のいくつかを共有してみます。

  • 下記は参加者6名からのフィードバックの5段階評価をグラフ化したものです

  • これは良いものだと思いますね。共有すること・発信することは大事だと思います
  • 時間が足りなくてマニフェストは作成できませんでしたが、対話で価値観のすりあわせができました
  • 新しくチームを作る時はやれたらいいな、と思いました

このワークショップが、よりよいチームになることへのキッカケになれば幸いです。

板垣 哲二、栗山 弘子、梶平 昌邦

リモートワーク制度_とある社員の1日

リモートワーク制度_とある社員の1日

新型コロナウィルスの感染拡大によりわたしたちの生活や働き方は大きく変わり、この経験は、今後の働き方を考えるきっかけになりました。

そして、わたしたちアットウェアSIカンパニー(※1)では、このコロナ禍の経験を活かし、選択的全国世帯でのリモートワーク制度を導入することにしました。

この制度は、各自が自らの意思・責任で、勤務場所(オフィス/自宅)・居住地を選択し、自分らしく働ける働き方を実現するための制度です。もちろん、 一切出社しなくていい制度ではなく、組織活動に必要な場合はオフィスへ出勤することもあります 。

~期待する効果~

  • 1人ひとりが自分らしく働く

    • 自分がパフォーマンスを発揮できる方法を選択できる

    • 幸せ・笑顔につながる

    • 自分の時間計測できる

    • 通勤のストレスから開放される

    • お互いの思いやりがUPする

  • 多様性のある働き方ができる

    • ライフステージに合わせて柔軟に働ける

    • 家族との時間を確保しやすくなる

  • 場所によらず素敵な仲間と仕事ができる

    • 全国採用が可能になる

    • 自己都合で引っ越す場合にも仕事を継続できる

この制度を利用して、居住地を変更した社員のインタビュー と 社員の日常 を2回にわけてご紹介いたします。

※1アットウェアでは、2021年12月よりカンパニー制を導入しています

とある社員の1日

今回は社員数名の日々の過ごし方ををご紹介させていただきます。

◆近隣在住者のケース

  • 勤務形態:基本リモート

  • 出社頻度:週1回

  • 出社する主な理由:運動

  • 居住地:横浜市内、会社まで電車&徒歩で30分

  • 2020年1月中途入社(業界歴20年)

  • 趣味:釣り、ゲーム、猫

基本の週予定(主な作業のみ)

※WG(ワーキンググループ):採用・評価・ブランディングなどの組織活動をグループで行っています

基本の1日

リモートでも出勤する日でも、1日の流れは変わりません

◆遠隔地在住者のケース1

  • 勤務形態:基本リモート

  • 出社頻度:月1

  • 出社する主な理由:プロジェクト定例

  • 居住地:中部地方、会社まで2~3時間

  • 2021年5月中途入社(業界歴6年)

  • 趣味:ちょっとヨガ

出勤がある週の予定(主な作業)

基本の1日

出勤する日の1日

◆遠隔地在住者のケース2

  • 勤務形態:基本リモート

  • 出社頻度:半年に一回

  • 出社する主な理由:GMDay

  • 居住地: 関西 会社まで 5~6時間

  • 2021年5月中途入社(業界歴3年)

  • 趣味:サーフィン・写真・キャンプ

※ GMday:半年毎に開催するアットウェア全社のイベント

大体の週予定(主な作業)

基本の1日

22年新卒研修を終えて

22年新卒研修を終えて

初めに

こんにちは。22年新卒の岡本と申します!
22年新卒3名の研修が終わりを迎え、プロジェクトに参加していく時期となりました。
今回研修を終えてみて研修がどんなものだったのか、自分がどのように成長できたかを紹介していこうと思います。

 

今年度の研修の流れ

まずは今年度の研修の流れを紹介していこうと思います!研修は新卒メンバー3名と、研修サポーターの方々とのチームで行いました。研修の最初に研修サポーターの方々から研修の全体像や守ってほしいルール等、ガイドラインの説明がありました。そして、研修を続ける期間やどう進めていくかはほとんど自分達で決めることができました。とても自由だと思いませんか?しかし、そういった自由に伴う責任として、自分達はどういう姿になることを目標にして、それに向かってどうハイペースで進んでいくかという内容を決める必要がありました。研修で何をするか、どういうふうに進めていくのか、いつまでにどうなっていたいのかを自分達で強くイメージして計画を立てることができたので成長の速度が自分の想像よりとても早かったと感じます。

 

今年度の研修の内容

研修の内容は、ソフトスキルとハードスキルという2つの側面がありました。皆さんはソフトスキルとハードスキルという言葉を聞いたことがありますか?私はありませんでした。ハードスキルというのは専門的知識、すなわちプログラミングのスキルやツールの使い方などを指します。一方ソフトスキルというのは、もっと汎用的なスキルです。例えば主体性やコミュニケーションスキル、仕事をする上での心構えなどを身につけることです。

まず最初に、ソフトスキル研修を行いました。活動の一つとしてアットウェアの歴史や現在取り組んでいることなどについて調べました。自分達で社員の方々にアポイントをとって調べていき、自分達から行動して結果を得るための主体性や、さまざまな制度や現在の活動内容、組織構造、それらができた経緯などの組織で活動していくために必要な知識を身につけました。

同時に、7つの習慣という本を読み、社会人として自立して生きていくために重要な価値観や、チームでシナジーを生んで大きな成果を出すための考え方を学びました。この本に書いてあることはどれも自分の考え方を根本から変えてくれてくれるようなものばかりでした。社会通念に縛られていた自分が新しい考え方を身につけるまで3ヶ月もかかりましたが、仕事上だけでなく、人生を通して役に立つ考え方を身につけられたと思います。この本の内容を理解するために行った取り組みで特に印象に残っているのは、ミッションステートメントという人生の目標を立てるために行った「ミッションステートメント合宿」です。1泊2日の合宿を通して自分がどういう人間に成長していきたいのか、そのために何をする必要があるのかを深く考え人生の目標をたてました。今まで日々を流されて過ごしてきた自分にとって、日々を向上心を持って過ごしていくための軸ができたのがとても大きな成長だったと思います!

 

その後のハードスキル研修では、自分達でほぼ全てのカリキュラムを決めました。新卒メンバー3名で何をするのかを真剣に話し合い、実践に近い形でのプロダクト作りに挑戦しました。アットウェアで多く取り扱っているアジャイル開発に倣い、毎週プロダクトオーナー役の研修サポーターの方と今週どのような価値を生み出すことを目標にするのかを決めます。そしてどうやればその機能を実装できるのか、何を勉強する必要があるのかを細かく考え一週間分の計画を立てるのですが、知識のない状態で計画をたててその通りに実行するのはとても難しく、アジャイル開発の難しさを実感しました。私は今までwebアプリを作った経験がなく実業務への不安が大きかったのですが、研修サポーターの方々にフィードバックをもらいながら実践に近い形で開発をしていくことで自分に足りていない能力や経験が身について実業務に入るのが楽しみになりました。また、新卒メンバーでのチーム開発という形だったのですが、事前にソフトスキル研修があったおかげでチームメイトとのコミュニケーションや関係を大切にし、自分だけでなくお互いの成長を考えあえる研修にできたと思っています。

 

最後に

このブログでは、アットウェアの研修がどんなものだったかを振り返ると共に、自分がどのような成長ができたかを書いてきました。

まとめると、研修を通して自分はこのような成長ができたと感じています。

  • 自分から行動する主体性が身についた
  • 自立して生きていくために重要な価値観を学んだ
  • チームでシナジーを生んで大きな成果を出すための考え方を学んだ
  • 日々を向上心を持って過ごしていくための人生の目標を立てた
  • 実践に近い形のハードスキル研修で、技術的な能力や経験が身についた

アットウェアでの研修では開発に必要な技術だけでなく、自分のさまざまな価値観を変えて社会で生きていく上での能力やマインドセットを楽しく身につけられます。このブログを見てアットウェアに興味を持ってもらえたら幸いです!
私はこれから自分で配属希望を出したプロジェクトで活動をしていきますが、最後に研修後の活動への意気込みを書いて終わりにしたいと思います。
実業務はハードスキルの側面が強く、技術を身につけることにとらわれてしまいそうですが、ソフトスキル的な成長との両方を考えて人として成長していきたいと考えています。その一歩目として、プロジェクトで活動をしていく上でただ流されて活動するのではなく、自分にとっての価値、お客さんにとっての価値が何なのかを真剣に考えて取り組んでいきたいと思います。

yamoryという脆弱性管理サービスを社内に導入しました

yamoryという脆弱性管理サービスを社内に導入しました

アットウェアではシステム開発・運用業務をしていく中で、様々なツールやサービスを導入しています。 ここ数年かけてセキュリティ周りへのアプローチとして、脆弱性管理サービス「yamory」を新たに導入しましたので、どういう視点と取り組みで組織に浸透させていったかを紹介したいと思います。

本記事では2年かけてやった社内への導入編として紹介し、次の記事では実際にプロジェクトで適用した実践編をお届けします。

システム開発をやっていく中で持っていた課題感

システム開発をやっていると、設計手法・実装フレームワーク・マネージメントなど様々な分野でナレッジを活かしてゴールに向かっていくわけですが、ゴールというのは納品を指すのではなく、ファーストリリースも通過して、永続的に価値を発揮し続けられるシステムとチームを形成していくことにあります。

その中で運用という面で避けて通れないのが、セキュリティ対策です。 クラウドパタンのベストプラクティスや最新のライブラリを適用したとしても、時間の経過と共に脆弱性が発見されることは避けて通れません。

システムの多くはMavenやGradleなどで依存関係のライブラリを管理しており、記憶で覚えきれなくなるほどの数になります。

そういう中で、ライブラリのバージョンは機能追加により不定期でアップデートすることもあれば、重大な脆弱性が発見されたタイミングで上げることがあります。

重大な脆弱性が見つかったライブラリ以外についても、「影響度が少ないだろう」とバージョンアップを放置しておくと以下の2つの観点で問題になることが多いので、小まめにアップデートをしていくという方針を取っているプロジェクトチームが多いです。

  • セキュリティホールが重なっているライブラリが依存関係を拡大させビックバンアップデートとなってしまう
  • バージョンが古いライブラリは最新のバージョン(バージョン2つ飛ばしなど)にアップグレードできないことがある
    • リファクタリングの粋を超えどんどん手がつけにくくなる
    • アップデート作業にかける専用予算などを確保して工数の問題が発生しがち

次に、プロジェクト横断に関連する状況をご説明します。

弊社では利用している主要なフレームワークはありますが、プロジェクトチームによって最適なモノを選んでいるため、専任者として全プロジェクトの利用ライブラリを把握してアップデート計画を立て、対応していくという体制をとっていくのはコミュニケーションコストを含め現実的ではありません。 そうなると個別最適となり、各チームで(もしくは中の誰かが)公開されているCVEやIT情報記事をRSSで購読したり、SNSでキャッチした情報でチームごとに対応しています。チームごととはいっても、少しでも効率化や情報共有をしてお互いに助け合っていこうということで、技術・セキュリティを扱う社内チャットへ展開しナレッジ共有を図っていこうという取り組みを長年行ってきました。

しかしながら、全ての脆弱性を自発的(プル方式)に調べていると、作業の重複や抜け漏れが発生する可能性がありますし、人的リソースの使い方がベストエフォートな対応となり最適なリソース配分や時間の使い方ではない状態でした。

最近ではAmazon InspectorやGitHub Dependabotが出てきて、検知する仕組みを利用し、社内横断でナレッジを溜めたり、取り組みがしたいと考えていたところでした。

yamoryとの出会いと紹介

そういった課題感を持っている状況でyamoryというサービスが世に登場して、yamoryのプロダクトオーナーが弊社に以下のような問い合わせをしてくださいました。

「新規事業としてサイバーセキュリティソリューション「yamory」を立ち上げました。 サービスの品質向上に向けて、様々な企業様からお話をお伺いしたく考えております。 「yamory」のサービスについて電話・web会議・面談等でご意見をお伺いできますでしょうか。

これはいい機会だと思い、Webミーティングを開いてお話を聞かせていただくと、以下の機能があることがわかりました。

  • SaaSでサービスを提供しているがソースコードを預ける必要がない
    • 預ける情報は依存関係を示すpom.xmlなどのメタ情報だけでよい
    • ソースコードの管理を最小スコープのまま維持できる
  • 使っているライブラリの脆弱性をリアルタイム(日次やCIと連動)で検出できる
  • 攻撃方法や脆弱性の種類などレポート形式で表示
  • 危険性を段階わけして一覧化・対応するかどうかのステータス管理(トリアージ)ができる
  • 社内の複数チームで利用できる組織機能があり横断した脆弱性状況も把握できる

私達の課題感を解消してくれるツールになりえると感じ、またサービスが開始されて間もないということで、フィードバック&トライアルに参加させていただくことになりました。

会話の中では「こういう事ができたらいいな」という事を開発者とプロダクトオーナーの方と直接会話でディスカッションしながらニーズを伝えることができ、また自分たちのこともより明確に理解できて、いい場となりました。

社内への導入に向けて

何はともあれ実際に使ってみようということで、イメージしていた通りの検知の仕組みで、可視化とハンドリングのサイクルを回していけることがトライアル期間の利用の中でわかりました。

CIへの組み込みにあたっては特別なagentをインストールする必要がなく、「APIのエンドポイントにAPIキーをcurlコマンドで送信すればよい」というシンプルな仕組みで、導入の敷居がとても低かったです。

弊社が主に使っている言語サポートとしては、JVM上で動作するJavaやScalaを始めとする(mavenやgradleやsbt)とJava Script(npm)に対応しており実用に足る状態でした。ただ、トライアル時点ではPythonのpip対応の要望はあるがまだリリースできていないとのことでしたが、対応していく方向性ではあるということでしたので、カバー範囲として充分でした。

いくつかの商用サービスを開発しているプロジェクトチームに評価を協力してもらって、社内の幾つかのリポジトリにも適用してみました。

社内でのファーストインプレッション

全社的に最初の評価をして出たフィードバックは意外な反応でした。

それは「サービスのポテンシャルは高いものの、自分たちのチームがこのサービスを活かし切れる状況ではない」という意見が複数のチームからでたことです。

例えば、SIの案件としてプロジェクトチームが今までセキュリティ対策に対して取っていたアプローチや、顧客と共にマイルストーンを決めて保守開発をしているやり方、プロジェクトによってはファーストリリース前という段階というケースもありました。脆弱性対策は大事だということはわかっているが、シードステージで予算の比重のかけ方のバランスどりに影響するといった点です。

これは私達のフィッティングの問題で、話をよくよく聞いてみると「とはいったものの、ぜひ使ってみたい」という意見がほとんどでした。

いきなり全振りで今までのやり方を考慮せず切り替えるのではなく、ホップ・ステップ・ジャンプ(ふつうのことにしていく)が必要だなと感じて、いつでも辞めれる・強制はしない・関心を高める、といった、推進活動をベースにして導入戦略を立てていくことにしました。

初年度の導入指針

初年度はまずホップをしたいということで、以下の導入コンセプトを立てて行き渡らせることに注力しました。

自分たちが認識していない脆弱性や未来に発生しうる脆弱性にも対応できるように、
アットウェアとして「システム開発をする時にはこれくらいのことはやっているよ」
というレベルの底上げをしていきたい。

社内で年一回行っている全社セキュリティオリエンテーションでも、ひとつのテーマとして話題に触れ、あるべき論を押し付けないということも心がけて、以下のような導入指針をきめて普及を進めました。

  • チーム毎にどのアプリケーションをスキャン対象にするかなどはお任せします
  • すぐ絶対に脆弱性0にする必要はなく誰かに報告を義務付けるということはしません
  • 使いたいという人があればいつでも招待します

契約を結ぶ

トライアル期間の終了に際し、社内からの理解も得てこの取組をさらに推進していくことを決めて、それなりの金額で年間契約を結びました。(専任者を設けるよりは全然安い金額ですが)

契約に至るまでにyamoryの中の方と交流させていただいた中での印象も導入の意志決定に影響したので、幾つか紹介します。

  • 開発者やプロダクトオーナーと直接やりとりでプロダクトの方向性がイメージができた
  • マイルストーンとその意義を聞いた時にパワーをかけ方・優先度の付け方に共感した(将来性)
  • 「社内へ普及しSIという業態で適用する」という弊社の課題感を共有した時のディスカッションで会話のコンテキストレベルが合った
  • 社内への勉強会やデモなど協力を惜しまない姿勢
  • 不安に感じた点について問い合わせたところ真摯な対応で説明いただけた
  • ユーザの意見を大事にしつつプロダクトのビジョンと方向性がしっかりしていた

1年経って普及はできたのか?

できませんでした。

と書いてしまうと誤解を生んでしまうかもしれませんが、yamoryという言葉をちらほらと会話の中で聞くようになったり、社員が四半期ごとに立てている個人目標の中に「yamoryを導入する」と書いてくださる方がでてきました。

非機能要件にあたる脆弱性管理を他の要件と共にバランスよくやっていきたいという意識が導入する前より顕著に高くなってきており、取り組みが作用してくる機運が高くなってきたというのを感じました。

半年後にヒアリングを行った結果、各プロジェクト事情を聞かせてくれました。

わかったことは、「本格導入はまだまだ道半ば」ということです。

そこで、1年目の契約が終わるタイミングくらいにyamoryの開発者とプロダクトオーナーと営業さんにご相談して、社内勉強会を開催していただくことにしました。

勉強会の後半部分で実際にPoCコードが存在する脆弱性を再現してみましょうということで、デモをしていただきました。この勉強会には多数の方が参加して事後アンケートでも非常に反応がよかったです。

「こういうこと大事だよね」という意見や「また勉強会をやって欲しい」という意見をもらいました。

1年目はホップの年と位置づけたので、次の年は更にステップアップしていくにはどうしたらいいかを考えました。

2年目の契約に向けて

今までは私が中心になって推進して私が最終的に判断の意志決定をしていました。 これからさらに飛躍するために、個人ではなく組織としての取り組みに発展したくて、 その輪を拡げてみようということを意識しました。

その時に、yamoryの契約に向けて営業さん・プロダクトオーナーとディスカッションしている時に伝えたのは「社内で一人も継続して使いたいという人がいなければ契約を更新しません」という意志決定の基準です。

つまり、自分のチームや全社で契約金額のコストをペイできるかどうかはさておき、

「もし、どこかのプロジェクトの案件で引き続きプロジェクト予算を使ってでも活用していきたいのであれば継続方向で調整をしていきますが、使い続けたいという声がなければ一旦契約は満了する方向にします。」

ということを全社展開したところ、使ってもらっていたプロジェクトメンバーからの反応は「継続できるなら利用したい」という声がいくつも届きました。

この瞬間に、今まで「各プロジェクトに使ってもらっていた」という状態から「自分の意志で使っている」にステップアップできたのです。

これで、2年目の契約に向けての機運もあがり、後押しをもらいながら期日ギリギリになってしまいましたが、yamoryの初めての契約更新ができました。

2年目でついに実運用で活用が確立

yamoryはサービスとして成長し、ホストスキャンの機能も加わりさらに便利になりました。 Docker対応やライセンス管理機能なども発表され実用性がどんどんあがってきました。

そんな中、CIへの組み込みやITSでのチケット管理フローまで確立できたチームがついに現れました。それに加えて、新規に立ち上がったプロジェクトでも導入されました。

log4j2の脆弱性が世の中を賑わせたりして、脆弱性という話題が賑わった年でした。 yamoryの活用事例のインタビューが他社で発表されたりして、HPに掲載されている導入企業数も増えたようで、弊社取引先も導入していたりして、世の中の需要の実感を感じました。

社内でも実用的な活用ができはじめて、取り組みが実になってきました。

そして3年目の今

こうやって、やったことや感じたことをアウトプットしようという段階まできました。

「世に同様のツールが充実してきてどれを選べばいいのか」という悩みの種も増えましたが、根本的な課題へのアプローチや意識を忘れず、この取り組みを通して文化形成の礎もできた気がします。

どんないいものでも、運用段階に持っていきDevOpsとして融合していくまでが大事で、小さな積み重ねが糧になっていきます。これからもよいサービスやツールがあれば実体験を通して評価し、導入を検討して、よりよいシステム開発ができる組織になっていければと思います。

リモートワーク制度_社員インタビュー

リモートワーク制度_社員インタビュー

新型コロナウィルスの感染拡大によりわたしたちの生活や働き方は大きく変わり、この経験は、今後の働き方を考えるきっかけになりました。

そして、わたしたちアットウェアSIカンパニー(※1)では、このコロナ禍の経験を活かし、選択的全国居住でのリモートワーク制度を導入することにしました。

この制度は、各自が自らの意思・責任で、勤務場所(オフィス/自宅)・居住地を選択し、自分らしく働ける働き方を実現するための制度です。もちろん、 一切出社しなくていい制度ではなく、組織活動に必要な場合はオフィスへ出勤することもあります 。

~期待する効果~

  • 1人ひとりが自分らしく働ける

    • 自分がパフォーマンスを発揮できる方法を選択できる

    • 幸せ・笑顔につながる

    • 自分の時間が確保できる

    • 通勤のストレスから開放される

    • お互いの思いやりがUPする

  • 多様性のある働き方ができる

    • ライフステージに合わせ柔軟に働ける

    • 家族との時間を確保しやすくなる

  • 場所によらず素敵な仲間と仕事ができる

    • 全国採用が可能になる

    • 自己都合で引っ越す場合にも仕事を継続できる

この制度を利用し居住地を変更した社員のインタビュー と 社員の日常を2回にわけてご紹介いたします。

※1アットウェアでは、2021年12月よりカンパニー制を導入しています

社員インタビュー

・名前:吉井

・入社年月:2021年4月入社(新卒)

・趣味:ランニング,旅行,映画鑑賞,FPS

◆どこでどんな働き方をしていますか?

今は、地元の静岡で働いています。働き方としては、基本フルリモートで、毎月1回は横浜本社へ出張し、お客さま含め、顔を合わせて打ち合わせを行っています。

たまに、お客さまのオフィス(都内)で打ち合わせを行うこともあります。

リモート作業といっても、1人でもくもくと作業するのではなく、音声チャットツールを使ってプロジェクトメンバーと会話しあったり、ペアプロしながら進めています。

◆全国居住が制度化される前と後で、働き方や生活で変化した点はありますか?

そうですね、僕の場合は、制度導入前後で、フルリモートは変わっていませんが、気軽に出社する。ということはできなくなりましたね。

コロナ禍になってからの入社だったので、入社してからずっと、「基本フルリモート」でした。ただ、入社当時は、会社に近い横浜市内に住んでいたので、ふらっとオフィスに出勤するようなこともありましたが、地元に戻ってからは、地元のネットワークを活用して、「新しいことに挑戦しよう!」と取り組んでいます。

◆横浜と地元でネットワークの違いはありますか?

地元の場合は、もともと、学生の間に構築できていたネットワークで、横浜では、コロナ禍の特殊な状況だったということもあって、ネットワークの構築には至らなかったですね。

「知らない土地でオンラインで」というのは、難しかったです。オンラインは気軽さもあるのですが、メンバーの名前が覚えづらかったり、会話のフックを見つけ難かったです。

◆なぜ、地元に戻ることを決断したんですか?

もともとこんなに早く地元に帰ることは考えていなかったんです。たまたま住んでいたシェアハウスが閉まることになったのがきっかけです。

1年近く住んでみて、横浜という土地の良さはわかってきたんですが、コロナ禍の生活は、都会だと人との接触数が多かったり、外出がしにくかったり、本来の都会の良さを体感し難かったんですよね。あと、色々なところに住んでみたいという願望があったことや、将来のために軍資金を貯めたいという気持ち、賃貸契約に縛られたくないという想いから、横浜市内での転居ではなく、実家に戻ることを選びました。

◆会社が離れた場所にあることで、不安を感じることはないですか?

ないか、あるか。でいうと、あります。相手の人となりを知る・自分を知ってもらうという関係性の構築に不安を感じています。ただ、飲み会や親睦会は好きなので、参加できるチャンスがあれば、積極的に参加したり、自分からも周囲の人を誘ったりと、不安を改善できるように意識しています。

◆会社の本社機能が近くになくて、困ったことはありますか?

9ヶ月ほど過ごしてみましたが、困ったということはあまりないです。あえて言うなら、健康診断のために出勤するのは大変なので、自分で医療機関を探して健康診断を予約する必要があるということですね。今までは、会社が横浜近辺の提携医療機関を予約してくれていました。全国居住によって、自分でやらなければいけないことが、ごく稀にありますが、地元に帰るということを自分で決断したので、困りごとだとは感じていません。

◆今の働き方で、しみじみと感じる良さ。を教えてください。

会社がシェアオフィスにあるということで、縛られずに働きやすい。とは思っていたのですが、アットウェアでは、社員が制度を作っていくことができるので、有志メンバーで制度改訂に取り組んだんです。その結果、全国居住を会社公認。とすることができたので、今は、縛られていないだけではなく、自分が思い描いていた”多拠点生活”の実現にも近づけていると感じています。

◆更なる改善ポイントをしいてあげるとすると?

僕たちの仕事は、機密情報を扱うので、どこでもふらっと気軽に業務を行うことはできません。例えば、人の目があるようなパブリックな場所で業務を行うことには、まだまだ課題があると感じています。(満員電車で顧客名を出して会話はしない。ことと同じ観点)

より柔軟に働くためには、インフラ整備なのか、各自のセキュリティに対する意識なのか、さまざまな対策がもっと必要だと思うんです。

他にも、チームで業務を進める上で、ほぼあったことがない人と一緒に取り組むことの大変さは感じているので、GMDay(半期に1度のリアル全社イベント)などを活かして、お互いの人となりを知った状態で、一緒に取り組めるとよいと思っています。

Scrum Interaction 2022 のスポンサーになりました

Scrum Interaction 2022 のスポンサーになりました

こんにちは。アットウェアでアジャイルコーチやスクラムマスターとして活動している梶平です。

アットウェアは、2022年9月22日(木)にオンラインで開催される Scrum Interaction 2022 にスポンサーとして協賛します。

個人的な話になりますが、前回の Scrum Interaction 2019 では、ジェフサザーランドさんと、野中郁次郎さんが同じ場所にいらっしゃるという奇跡的な場で、私自身とても興奮したことを鮮明に覚えています。

更に組織変革の事例を多く知ることができたり、参加者同士のグループディスカッションもとても楽しく、学び多き時間を過ごせました。

興奮。楽しさ。学び。

それだけではなく、場から発せられているエネルギーのようなものが自分の中に入っていくような感覚もあり、自身の日々の活動について応援されているような、ありがたい気持ちにもなれました。

今回もアジャイルの力に助けてもらいつつ、自身・チーム・組織の変革に取り組まれている事例や、その中で感じる悩み・モヤモヤを聞き、そして参加者の方々と話し合えることがとても楽しみです。

株式会社アットウェア 21年度新卒採用者 インタビュー動画その1

株式会社アットウェア 21年度新卒採用者 インタビュー動画その1

21年度新卒採用インタビュー その1

第1段は多拠点エンジニアを目指している吉井さんです。以下のようなことを聞いています。

  • 自己紹介

  • アットウェアを選んだ理由

  • アットウェアに入っての感想

  • 入社した時の研修

  • 仕事に慣れていく過程

  • 現在の仕事の進め方

  • 挑戦したいこと

  • どんな人にアットウェアを勧めるか?

株式会社アットウェア 採用チャンネルはこちら