TECH PLAY

株式会社エニグモ

株式会社エニグモ の技術ブログ

247

この記事は Enigmo Advent Calendar 2022 の 19 日目の記事です。 こんにちは、Webエンジニアの平井です。普段はSELLチームに所属していて BUYMA における出品者側の機能開発を担当しています。 今回は、最近リリースしたカタログシステムをサーバレス アーキテクチャ で開発したので利用した技術や学びについて書きたいと思います。 目次 目次 サーバレスアーキテクチャ メリット デメリット カタログシステムとは システム設計 技術スタック サーバレスフレームワーク API カタログデータ新規作成、更新処理 メリット デメリット 学び 良かった点 悪かった点 サーバレス アーキテクチャ そもそもサーバレス アーキテクチャ とは何でしょうか。人によって解釈は異なるかと思いますが、私はイベント駆動型のプログラム実行環境を利用してアプリケーションを開発する アーキテクチャ だと理解しています。システムを開発していく上でサーバーを意識する必要が無いという特徴があります。ざっくりメリットとデメリットは以下が挙げられます。 メリット サーバーを構築する手間が省けて、開発者がアプリケーションの開発に専念できる。 リソースの利用料金はコードを実行した時間に対して課金される。アイドル時間は課金されない。 デメリット 利用できる言語が限られている。 実行時間制限 Lambdaだと最大15分 カタログシステムとは 次に今回開発したカタログシステムについて説明します。カタログシステムは BUYMA のカタログ出品機能のためのシステムです。 カタログ出品機能は、出品者に対して BUYMA 側で用意したカタログを提供することで、出品者の出品作業の効率化、高品質な画像の提供を目的としています。 カタログ出品の大まかな流れは以下になります。 撮影チームが商品を撮影、画像を クラウド にアップロード オペレーションチームが色名、型番の確認、サイズの計測を実施 1,2の情報をカタログシステムの API 経由でデータ保存 4で保存したデータを API で BUYMA 側に提供 BUYMA 上のカタログ出品画面から出品者が適当なカタログを選択して、出品 以上の流れの3,4の部分(カタログデータの新規作成/更新、提供)をカタログシステムが担当していて、弊社の クラウド サービス利用実績より AWS 上に構築しました。 システム設計 詳細は省略していますが、以下が アーキテクチャ 図になります。 カタログデータ新規作成/更新は Google App Scriptから API 経由で実行され、図の上部が該当部分です。 カタログデータ提供も API 経由で実現しています。 技術スタック 次にカタログシステムの開発に利用した技術、主に AWS のサービスについて紹介します。 サーバレス フレームワーク まず、サーバレス フレームワーク については SAM を利用しました。 サーバレス フレームワーク とはサーバレスアプリケーションを構築する上でInfrastructure as Codeを実現するためのものです。今回利用したSAMの特徴は以下になります。 サーバレスアプリケーション構築用の オープンソース フレームワーク YAML ファイルでリソース管理 CloudFormation構文を拡張してサーバレスアプリケーションの構築が簡単になっている サーバレス フレームワーク にはSAMを含めて代表的な3つのサービスがあり、それぞれのメリット・デメリットは以下だと考えています。 SAM メリット CloudFormationを抽象化したものなので, CloudFormationを知っていたら書きやすい。 デメリット 構文が若干冗長 serverless メリット AWS , GCP , Azureで利用できる。 デメリット serverless独自の構文を覚える必要がある。 AWS CDK デメリット ブログラミング言語で設定を記載できるが、可読性が yaml に比べると低い ローカルでのテスト実行には、SAMを使う必要がある。 やり方 今回、開発チームにCloudFormationの経験があるエンジニアが居た点、マルチ クラウド に対応する必要がない点、ローカル環境での実行が簡単な点より SAM を選択しました。 API API は一般的な API Gateway とLambdaの構成です。工夫した点としては API Gateway とSwaggerの yaml ファイルを連携して API 定義するようにしました。 以下のようにSwaggerで定義した yaml ファイルのパスを指定することで連携できます。Swaggerで API 定義するようにしたことで API を追加するためには API 定義 yaml ファイルを更新する必要があるため、 API 追加によるドキュメントの更新漏れを防ぐことができます。 Resources : Api : Type : AWS::Serverless::Api Properties : DefinitionBody : 'Fn::Transform' : Name : 'AWS::Include' Parameters : Location : api.yaml カタログデータ新規作成、更新処理 カタログデータの新規作成、更新処理部分には AWS Step Functions を利用し、Lambdaをワークフロー的に実行しています。 AWS Step Functionsはワークフロー管理サービスで json でワークフローを定義します。 AWS Step Functionsを導入してみて感じたメリット、デメリットは以下になります。 メリット Step Functionsの GUI がリッチである。 ワークフローの全体像、各タスクの進行状況、ログ、成功状況がわかりやすい。 Lambdaを分割することで各Lambdaの凝集度が高まり、メンテナンス性があがる。 各Lambdaのリトライ設定が簡単。 デメリット 途中のLambdaで失敗した際のデータ整合性を考慮する必要がある。 個人的には GUI がリッチな点が特に好きで、データ作成、更新処理に何か不具合がある際は基本的にこの GUI から デバッグ を開始するため、 デバッグ が効率的になるようにタスク成功時の出力内容や失敗時の例外メッセージの内容を工夫して実装しました。 以下が処理詳細画面で、左のアイコンをクリックすることで各タスクのInput, Outputも確認できます。 学び 最後に開発して得た学びについて書きたいと思います。まず、サーバレス アーキテクチャ で開発して体感した良かった点、悪かった点は以下になります。 良かった点 開発者だけで構築できるリソースが多く、管理が不要なので開発体験が良かった。 AWS を利用した過去の ユースケース が多く、参考にする情報に困らなかった。 公式ドキュメント Serverless Land 悪かった点 コードの共 通化 が難しい Lambda Layer を使えば可能そう。 今回の場合各Lambdaに共通するモデル定義は共 通化 したかった。 また、今回Lambdaは Python で開発しましたが開発初期は普段利用している Ruby との言語的違いが原因で開発に時間がかかりました。 Lambdaの内 58%がPythonを利用 しているという情報を知り、メインの潮流に乗ったほうが良いと判断して Python を選択しましたが、 特に Python を利用して良かった点が無かったのでスケジュールがかなりタイトな場合は普段慣れている言語を使ってもよいと思いました。 以上になります。 明日の記事の担当はエンジニアの池田さんです。お楽しみに 株式会社 エニグモ すべての求人一覧 hrmos.co
こんにちは、UIUXデザイナーの和田です。 この記事は Enigmo Advent Calendar 2022 の18日目の記事です! 弊社では、 BUYMA のサービスやアプリ・WebサイトのUIUXをよりよくしていくことを目的に、 「より深くユーザーを理解して」「ユーザーにとって価値のある体験」を届けていくために、UXリサーチに基づいた改善に力を入れています。 今回は、 BUYMA の顧客理解のために進めているUXリサーチの取り組みについてご紹介します。 【1】ユーザーセグメント分類|User Segmentation BUYMA の会員について、RFMの指標をベースに「 利用頻度軸 (Recency&Frequency)」「 価格志向軸 (Monetary)」「 年代軸 」 からユーザーセグメントの分類を進めています。 【各セグメントのボリューム】を把握して、 主要なセグメントにおけるユーザーの購買傾向や利用傾向 について、 視覚的に捉えられるようにLookerのツール整備をデータアナリストとUIUXデザイナーが協働で実施しています。 利用頻度軸(Recency&Frequency) 全体の購買傾向から適切な 閾値 を検討して、「利用頻度」と「直近の利用傾向」からセグメントの分類を進めています。 価格志向軸(Monetary) ユーザーにおける純粋な生涯累計購入金額で分類するのではなく、「どのくらいの価格帯のアイテムを中心に購入しているか?」「どんな価格帯のアイテムに興味関心が高いか?」という観点で、F0ユーザーやF1-2といった利用歴の浅いユーザーについても価格(購買行動)に関する志向を把握できるように分類を進めています。 年代軸 年代については、生活スタイルや行動特性の異なりを考慮して分類しています。 上記の3つの軸を考慮して、【社内で主要なセグメントのユーザーモデルについて共通理解できるようにすること】を目標にユーザーセグメントの調査・分類を進めています。 また、これらの 定量 的なユーザーセグメントの分類をもとに、 【2】や【3】の定性調査を進めることで、各セグメントのよりリアルな価値観・行動特性、UXに関する課題を把握して、具体的な改善を進められるようにしています。 【2】ユーザーアンケート|User questionnaire 弊社では、主に Google フォームを用いてユーザーアンケートを運用しています。 主に以下のような手順で、【1】のユーザーセグメント分類をベースに、UXについて深堀り調査したいセグメントに絞ってアンケートを実施しています。 アンケートは、メールやLINEによる配信や、Webサイト上にアンケート募集バナーを出すなど、対象のユーザーセグメントに合ったタイプで実施するように心がけています。 アンケートの計画・実施手順 アンケートのリサーチ目的・検証内容の整理 配信対象者の選定 アンケート設問の設計、 Google フォームの作成 アンケートの配信・公開 インセンティブ (謝礼)の付与 アンケート結果まとめ・共有・ふりかえり 【3】のユーザーインタビューを前提に、 設問の中でインタビューに協力いただける協力者を募るかたちでアンケートを実施することもあります。 会員向けのユーザーアンケートでは、会員データと紐付けて分析できるようにしているため、 ユーザーセグメントやユーザーの購買傾向・利用傾向を踏まえて、ユーザーインタビューにご協力いただきたい方を選定させていただくようにしています。 また、細かく検証したいUXについての設問をアンケートに用意することで、 アンケート回答内容から「あらゆる価値観や行動特性を持つユーザー」に対してインタビューが実施できるように工夫しています。 【3】ユーザーインタビュー|User Interview ユーザーインタビューは【2】のユーザーアンケートから、UXについてより深堀りして調査したい場合に実施しています。 近年のインタビューは、すべてオンライン(Zoom)を用いたインタビューとさせていただいており、さまざまな地域からご参加いただいています。 インタビューは約60分間で実施しており、 ユーザーの価値観や行動特性(日頃の行動や嗜好など)から インサイト を深堀りしていく 【 A. ユーザー モデリング 型の設問 】と、 過去の体験やこれから行いたい事柄を実際の画面を用いてシミュレーションいただきつつ、 その様子を観察・フローに沿ってUX(そのタイミングにおける思考やペイン・ゲインなど)について深堀りしていく 【 B. UX検証型の設問 】の2つから構成しています。 インタビューの主な計画・実施手順について、ご紹介します。 インタビューの計画・実施手順 インタビューの目的・ ヒアリ ングポイントの整理 インタビュー候補者選定 *1 インタビューシナリオの作成 インタビュー打診・調整、スケジュール作成 個別インタビューシートの作成 ユーザーインタビューの実施 インセンティブ (謝礼)の付与 インタビュー結果まとめ・共有・ふりかえり ユーザーインタビューの前に、ユーザーそれぞれの「個別インタビューシート」を用意するようにしています。 「プロフィール」や「購買傾向」、「利用傾向(お気に入りや登録年など)」、「購買や問い合わせの履歴」、「アンケートの回答」などを細かくまとめたシートとなっており、 基本的なインタビューシナリオに基づいた ヒアリ ングの中で、インタビュー対象者それぞれに合った ヒアリ ングをできるように工夫しています。 また、「インタビューの記録」についても同一シート内に収めることで、ユーザー単位で俯瞰できるようにして「傾向の把握」や「振り返りしやすいかたち」にしています。 弊社では、定期的にユーザーインタビューを実施させていただいております。 今後も、ユーザーインタビューを通じて 定量 的な数値からは読み取ることが難しいさまざまなペインや気付きを得ていきたいと考えています。 さいごに 弊社では、UXリサーチから導いたUXにおける課題(AS-IS)から、施策・企画(TO-BE)を検討して、日々サービスとUIUXの改善に取り組んでいます。 仮説通りの効果が得られているのか確認してよりよいかたちにしていくために、ABテストの活用や効果検証を実施して細かいアップデートや方向修正もおこなっています。 UXリサーチを通じて「より深くユーザーを理解して」「ユーザーにとって価値のある体験」を届けられるよう、 BUYMA のサービス・UIUXの改善にご期待いただけますと幸いです。 明日の記事の担当は サーバーサイドエンジニア の 平井 さんです! お楽しみに。 株式会社 エニグモ すべての求人一覧 hrmos.co *1 : 【2】ユーザーアンケートにて、インタビュー協力者を同時に募るようにしています
こんにちは、データサイエンティストの堀部です。 この記事は Enigmo Advent Calendar 2022 の16日目の記事です。 普段の業務では情報検索(検索/レコメンド)、不正検知、ユーザー属性の推定などを BUYMA にプロダクトとして組み込むことを行っています。その中でも モデリング 以前のタスク設計や探索的データ分析( EDA : Explanatory Data Analysis)、データのクレンジング・前処理、特徴量エンジニアリングなどを主に SQL (BigQuery)で行う部分に多くの時間を割いています。 1 今回は、違和感のある予測結果から気づいた傾向を元にデータの前処理を追加したことでモデルの精度改善につながった一例を紹介いたします。 概要 気づいた経緯 検出方法 結果 まとめ おまけ 概要 データから 機械的 な(ボットのような)アクセスを除外したことで、 機械学習 モデルの精度が改善しました。 そもそも気づいた経緯や検出方法、除外した結果について紹介いたします。 気づいた経緯 商品のブランドのitem2vecを閲覧履歴から生成した際に、 BUYMA 内で人気のブランドと直近1年で1件も購入されていないマイナーなブランドの類似度が非常に高く出ているパターンが複数見受けられました。違和感を感じ、学習データでマイナーなブランドに対してアクションを行なっているユーザーのlogを閲覧数が多い順に見たところ、一定間隔で別の商品詳細に遷移するというのを繰り返しているlogが見受けられ、人間ではないアクセスの可能性が高いと判断しました。 ちなみに、item2vecなどのベクトルはarray型でBigQueryに格納し、コサイン類似度などを SQL で計算できる様にしていますがとても便利です。 create temp function cos_sim(vec1 array<float64>, vec2 array<float64>) returns float64 as ( ( select sum (elem1 * elem2) / sqrt ( sum (elem1 * elem1))/ sqrt ( sum (elem2 * elem2)) from unnest(vec1) elem1 with offset pos1 inner join unnest(vec2) elem2 with offset pos2 on pos1 = pos2 ) ); 検出方法 「1度でも1分以内に次の商品詳細への遷移を100回以上繰り返しているユーザー」という条件で検出しました。 2 こちらを SQL でセッショナイズを行うことで実装しました。 3 セッショナイズのイメージ サンプルクエリ with item_action_view_detail as ( select ial.user_id, ial.time, ial.time - lag(ial.time) over ( partition by ial.id order by ial.time ) as interval_action from item_action_log as ial where ial.action = " view_detail " ), session_head as ( select id, time, case when lag(time) over ( partition by user_id order by time ) is null then 1 when time - lag(time) over ( partition by user_id order by time ) > interval 60 second then 1 else 0 end as session_head_flg from item_action_view_detail ), session as ( select user_id, time, concat ( user_id, " - " , sum (session_head_flg) over ( partition by user_id order by time rows between unbounded preceding and current row ) ) as session_id, from session_head ), session_summary as ( select session_id, user_id, count ( 1 ) as cnt_view, from session group by 1 , 2 ) select distinct user_id from session_summary where cnt_view >= 100 結果 ランキング学習を行っているモデルに対し、検出したユーザーIDを除外する前と除外した後のデータそれぞれ学習させたモデルでのテストデータでの精度を比較したところMAP(Mean Average Precision)が約2%改善しました。商品のブランドのitem2vecも除外後のデータで生成し直したところ、直感に合うようなブランド同士が類似度が高く出るようになりました。 機械学習 での推論結果をBigQueryに格納しているため、MAPなどの評価指標も SQL で計算できるようにしています。 (下記、average_precisionの平均をとったものがMAPになります) create temp function precision (y_true array<int64>, y_pred array<int64>, n int64) returns float64 as ( ( select sum ( case when elem1 = elem2 then 1 else 0 end ) / n from unnest(y_true) elem1 with offset pos1, unnest(y_pred) elem2 with offset pos2 where pos2 < n ) ); create temp function average_precision(y_true array<int64>, y_pred array<int64>, n int64) returns float64 as ( ( select sum ( precision (y_true, y_pred, m+ 1 )) / array_length(y_true) from unnest(generate_array( 0 , n -1 )) as m where y_pred[safe_offset(m)] in unnest(y_true) ) ); まとめ やったことは単純ですが、データの前処理の大切さを体感できた事例だったので紹介させていただきました。 Garbage In, Garbage Outを胸に刻みましょう。 おまけ 最近話題のchatGPTに BUYMA について歌詞を書いてもらいました 手にしたいものを 思い浮かべたら BUYMAに行くよ みんなの想いが集まる 世界中の商品が たくさん見つかるよ お求めやすい価格で 今日も新しいものが届くよ ハイブランドの服や靴 おしゃれなバッグやアクセサリー 雑貨や家電まで BUYMAで探してみよう 会員登録すれば さらにお得な特典が たくさんあるよ お気に入りを見つけて 買い物の楽しみを増やそう BUYMAで楽しい買い物 手にしたいものを 思い浮かべたら BUYMAに行くよ みんなの想いが集まる 今すぐBUYMAで 買い物しよう! 宣伝上手ですね。 話題のAIに弊社のサービスを認知されていて少し嬉しかったです。 明日の記事の担当は人事の右川さんです。お楽しみに。 株式会社 エニグモ すべての求人一覧 hrmos.co データクレンジング〜特徴量生成部分で dbt の活用を検討中です ↩ 実際の SQL ではユーザーエージェント( UA )でのボット除外を行ったデータに対して処理しています ↩ SQL でのセッショナイズは、 10年戦えるデータ分析入門 や ビッグデータ分析・活用のためのSQLレシピ に詳しく記載されています ↩
こんにちは、エンジニアの竹田です。 この記事は、 Enigmo Advent Calendar 2022 の15日目の記事です。 さっそくですが、エンジニアのみなさまは一流のエンジニアとはどんなエンジニア像をお持ちでしょうか。 自分は「障害を未然に防ぎ、継続的に安定運用可能なシステムを構築できるエンジニア」を一流のエンジニアだと考えています。 ひとえに障害と言っても、仕様と異なる動作をしない、リソース不足等によるシステム停止が発生しない、などいろいろと定義はあるかなと思います。 今回のエントリでは前者の「仕様と異なる動作をしない」という点について、業務を通じて見識を深められる場面がありましたのでご紹介したいと思います。 検索システムのリプレイス 今期は、とある検索システムのリプレイスに注力していました。 エニグモ では検索システムに Apache Solrを利用しており、今回リプレイスするシステムについても構成としては過去に こちらのブログ で紹介したものと近い構成となります。 自分は検索システムへのデータ投入、および検索リク エス トを行って結果を整形する箇所(主に Rails )の改修を担当しています。 リプレイスに当たり、 Rails からSolrへの直接リク エス トではなく、中間媒体として検索 API を経由する形式に変更しました。 このため、まずは既存コードやログを調査してリク エス ト方法や動作仕様をまとめ、いざコード改修に移りました。 コード改修 調査した仕様を元に一旦コード改修を完了し、ある程度動作するものができました。 その後、既存のテストコードを元に新コードのテストコードに移植を進める中で、細かな動きを実装できていないことに気付きました。 (画像はイメージです) 型が数値なのか文字列なのか nil 許容するのか 調査しきれていなかったリク エス ト方法や利用箇所がある 中には、えっ、そんな動きするの、みたいなものまで... コードやログを目視しただけでは分からなかったことが次々とでてきました。 テストコードの重要性の再認識 テストコードを動作させることで、より詳細な動作を知ることができました。 後から考えると、もっとしっかりとコードチェックをしていれば把握できていた点もあると思いますが、やはり作業しているのが人ですので、どうしても見落としは避けられないと思います。 テストコードがなければ デグレ を引き起こしていた可能性があり、「仕様と異なる動作をしない」点を満足できない状態にしてしまうところでした。 普段コードを書く際、テストコードも意識して書いてはいたものの、作成に当たってはコード カバレッジ 、モックの使用、境界値や複雑なパターンの網羅をどこまで厳密にするか等、、考慮することが多いです。 それなりに時間を要しますし、テストコード自体の視認性に納得がいかなかったりと、正直あまりテストコードを書くことは好きではありませんでした。 ですが、今回、多くの点をテストコードに助けられました。 テストコードの意義などを検索すると様々な方の記事がヒットするためその辺りの言及はしませんが、理屈としては理解できるもののなかなか溜飲を下げられないものだと思っています。 その点においても、実際にテストコードに助けられたという体験は非常に貴重なものでした。 最後に 過去にテストコードを地道に作成いただいた担当の方に感謝をしつつ、今後の誰かの助けになるということを意識して、テストコードを書くことを心掛けていこうと思います。 テストコードを全てパスした状態でのリリースは、精神的な安心感にも繋がりますね。 明日の記事担当は、データサイエンティストの堀部さんです。お楽しみに! 株式会社 エニグモ すべての求人一覧 hrmos.co
こんにちは、サーバーサイドエンジニア の 橋本 です。 この記事は Enigmo Advent Calendar 2022 の 14 日目の記事です。 はじめに エンジニアとして仕事をしているとコードを読むことが多いと思います。例えば、仕様調査、CSからのお問合せ対応、レビュー対応などがあると思います。 今年を振り返るとコードを書く以上に読むことが多く、コードをより正確かつ速く読むにはどうすればいいかを考えることが多くありました。 ということで、この記事では私個人がコードを読む時に意識していることを紹介していこうと思います。 いきなりコードは読まない 1つ目はいきなりコードは読まないことです。業務で使われているコードの量は1つの機能でもとても多いです。いきなり読み始めるととても時間がかかったり、迷子になってしまうかもしれません。なのでまずはシステム全体を把握してインプットとアウトプットが何なのかの理解を進めます。把握の仕方は、システム仕様書を読んだり、担当した方と MTG して処理の大まかな流れを教えてもらっています。 全体の把握と同時並行で、実際に動かしてみることが多いです。実際に動かすと理解が進みます。 読む目的を意識する 2つ目は読む目的を意識することです。コードを読む目的は様々だと思います。表は一例です。 コードを読むケース 知りたいこと レビュー対応 バグが無いか、仕様を満たしているか、設計的に問題ないかを確認する。 CSからのお問合せ対応 バグが発生している原因を知る。 目的が曖昧な状態でコードを読み始めると、本来は読む必要が無いコードも読むことになり時間が足りなくなるケースがあると思います。業務は期限が決まっていることが多いので、効率的に進めるためにも目的を意識することは大事だと考えています。 適度にメモを取る 3つ目は適度にメモを取ることです。業務で使われているコードは量が多く、一度に読んで全てを把握するのは大変です。なので私はメモを取りながら読み進めることが多いです。メモの取り方ですが、 ソースコード 上に直接書いたり、別途テキストファイルに書いたり、slackのスレッドに書いたりなどして流れを整理しています。まだ慣れていない プログラミング言語 の場合は読むのに時間がかかると思うので、メモはかなり有効だと感じています。 おわりに 今年は色々な機能のコードを読むことが多く、 BUYMA の仕様について詳しくなりました。それだけでなくコーディングの技術についても学ぶことが多かったので、コードを読むというのはとても大事だなと改めて感じました。多分来年も読むことが多いので頑張りたいと思います。 明日の記事の担当はエンジニアの竹田さんです。お楽しみに。 株式会社 エニグモ すべての求人一覧 hrmos.co
この記事は Enigmo Advent Calendar 2022 の13日目の記事となります。 お疲れさまです。インフラチームの山口です。 弊社では一部イン フラリ ソースのモニタリングにDatadogを利用しています。 その中で、今回はDatadogの利用開始当初に GUI で作成されたモニターをTerraformerとTerraformを使用して構成管理した際の事例について報告します。 同様の技術スタックを使用したインポートや構成管理における具体的なテンプレート等の事例には事欠かないと思いますので、作業計画を中心に説明します。 要は、TerraformerやTerraformの使い方は様々良い資料があると思うため、今回固有の対応をした点を注力して説明します。 本稿の構成を以下に記載します。まず、対象とするモニターの状態などの前提を説明します。次に、作業の流れを概説し、Terraformの ディレクト リ構成等を少し説明します。そして最後にまとめます。 1. 前提 まず作業の目的と対象とするモニターについて説明します。 目的 GUI で人間が手で作成したモニターをTerraformで構成管理する。 対象とするモニター 構成管理の対象とするモニターの概要を以下に記載します。 あるプロジェクトでのイン フラリ ソースの監視のために手で作成されたモニター309件を対象とします。 複数種類のイン フラリ ソースの監視のためのモニター群ですが、当該プロジェクトであることを示すタグのみが付与された泥団子状態です。対象のモニターを、サーバロールごとのタグを付与した上で、ロールごとにmodule化し取り扱いをしやすくすることを目的とします。 モニター件数 特徴 309件 ・インポート対象を識別できる特定のタグが付与されている(例: project: xxx といったタグのみ) ・モニターは Rails のWebサーバや、バッチサーバ、DBサーバといったイン フラリ ソースの監視目的 2. 作業の概要 作業の概要について説明します。今回の対応は大きく2段階に分かれます。 まず、STEP1としてインポート対象のモニターをTerrformerで一旦1つのtfファイルにインポートし、その後人手でサーバのロールを表すタグをモニターに付与しapplyすることで、泥団子状態を改善させます。 次に、STEP2として、サーバのロールごとに再度Terraformerでインポートし、tfファイルを リファクタリング しapplyを行います。 以降で各STEPの内容とポイントを説明します。 STEP1: 事前準備 STEP1では泥団子状態を脱することを最優先とします。 そのため、一旦Terraformerでインポートした後に、人間が大雑把にモニターにタグを付与しapplyします。その際のポイントとしては、モニターによっては「どのようなタグを付与するべきか」悩むケースもあると思いますが、Terraformで管理可能になることで泥団子状態より悪くはならないため速度優先で「エイヤ」でタグを付与しapplyしてしまいます。 実際にタグの付与は私が作業したのですが、作業当時の記録を見ると10分で25%進んだと記録があり、1時間もかからずに思いの他早く済んでいたようです。 一旦既存のモニターをTerraformerで一括で1つのtfファイルにインポートする tfファイルのモニターの内容を精査し、各モニターの用途(サーバロール)が判別可能なようなタグを人手で付与しapplyする 図1 STEP2: サーバロール単位でのインポートと リファクタリング 以下をサーバロール数分繰り返します。 端的には、Terraformerでインポートしたtfファイルの内容を人間が読みやすいように修正し、かつ意図しないリソース再作成なども発生しないようにtfstateも修正した上でapplyします。 特定のサーバロールのモニターをterrformerでインポート tfファイルを リファクタリング してapplyする 図2 3. インポート後の ディレクト リ構成や修正内容 インポート後の ディレクト リ構成やTerraformerが自動生成した内容からの修正ポイントを説明します。 本記事は、技術的な説明を主とする記事ではないため概要のみを簡単に記載します。 ディレクト リ構成 ディレクト リ構成を以下図に記載します。 複数環境に対応可能なようmodule側に主なリソースを切り出して、そのmoduleを環境ごとに呼び出しモニターを作成する構成としています。 また、 terraform workspace 等は使わずに愚直に環境・サーバロール単位でtfstateを分ける構成としています。 リモートバックエンドも使わずに、原始的にtfstateを リポジトリ にコミットします。 これは、複数人で 人海戦術 的な方針で分担して作業する際にリモートバックエンドを操作するためのキーの設定やミスする可能性のある箇所を極力減らすことを念頭においたというのがもっともらしい言い訳ですが、実際は横着をしたためです。 図3 tf、tfstateの リファクタリング Terraformerでインポートした際に リファクタリング を行った観点を以下で箇条書します。 リソース名を人間が判読可能なものにする resource "datadog_monitor" "tfer--monitor_1234567" といった自動生成されたリソース名を人間が判別しやすいものに修正します。 1のリソース名の修正に伴いtfstateも修正する これは、モニターの場合は状態を持たないリソースのため特に再作成でも大きな問題は無いですが、 リファクタリング 時の修正差分等を terraform plan で確認したいために tfstateも修正し極力再作成を回避します。 ヒアドキュメントを使う Terraformerでインポートしたモニターは message が1行で可読性が良くないためヒアドキュメントを使うよう修正します。 まとめられるリソースはfor_eachでまとめる for_eachでまとめられるリソースは for_eachで複数作成します。その際の2との兼ね合いは状況を見て判断します(場合によっては再作成もやむなしとする)。 4. まとめ(所感) 最後に所感とまとめを記載して終わります。 所感 利用開始直後でも最低限の初期設計は重要 その時はその時のベストを尽くしてるはずなので昔を悪し様に思わない気持ちが重要(今もそのうち昔になるので) ただし過去の経緯や判断に過度に忖度をする必要性はない(でないとずっと辛いままのため) こういった、過去のしがらみ踏まえた改善活動ができるのは事業会社ならでは まとめ ある作業を、「すべて人間 or すべて スクリプト で対応する」といった形に拘ってしまうと辛いことがあるため最も早く目的を達成できそうな方法を選ぶことが重要。それは会社の人的リソースの状況にもよると想像されるため、適度な塩梅は自分たちで考えていくしか無い(身も蓋もないまとめ)。 明日の記事の担当はエンジニアの橋本さんです。お楽しみに。 株式会社 エニグモ すべての求人一覧 hrmos.co
こんにちは、新卒エンジニアの川本です。 BUYMA のサーバーサイドを中心に開発しています。 この記事は Enigmo Advent Calendar 2022 の12日目の記事です。 データ モデリング について学習中で、DB設計の入門書を読んで論理設計について第1~5正規化といった内容を学習しましたが、いざ個人開発でデータ モデリング しようとしたらどうしたらいいのかよくわからず、手を動かすことはできませんでした。 そんな状況の時にイミュータ ブルデー タ モデリング という モデリング 手法について知ったことをきっかけけに、データ モデリング がイメージしやすくなりました。 この記事ではイミュータ ブルデー タ モデリング を実践してみて感じたことを紹介できればと思います。 目次 データと情報の違い イミュータブルデータモデリングとは イミュータブルデータモデリングの手順 普段Railsで開発していて感じたこと イミュータブルデータモデリングとの向き合い方 最後に データと情報の違い データと情報には以下の違いがあります。 データ 客観的な事実を記録したもので、文脈や解釈がない RDB に記録される 情報 文脈や解釈の与えられたデータ SQL で抽出する この違いから正確な情報が必要ならデータが正確に記録されていなければならないことがわかると思います。 イミュータ ブルデー タ モデリング とは イミュータ ブルデー タ モデリング とは、データを失わずに RDB に正確に記録できるように、更新と削除がなるべく起きないようにデータ モデリング することです。 更新と削除が起きるということは、データが変更された、失われたということです。 つまり、正確なデータをすべて RDB に記録できていないことになり、必要な情報を抽出できない可能性が出てくるということです。 イミュータ ブルデー タ モデリング の手順 ここでは、イミュータ ブルデー タ モデリング を実践したことで、正規化について理解が深まった瞬間があったので例を交えて紹介できればと思います。 詳しい手順が知りたい方は以下の記事がすごくわかりやすいです。 scrapbox.io エンティティはイベントとリソースにに分類される 分類の判断には、エンティティが日時属性を持つかどうかで判断できます。 日時属性を持つエンティティはイベントエンティティに分類されます。 エンティティに対して、「~する」という動詞をつけてみると識別しやすいです。 例えば「会員する」という日本語は不自然ですけど、「注文する」という日本語は自然です。 ここから注文はイベントエンティティで会員はリソースエンティティであることがわかります。 今回はこのイベントエンティティについて少し深ぼって説明していきます。 イベントエンティティには日時属性を1つだけ持つようにする イベントは1つの日時属性を持ちます。 例えば、注文エンティティなら注文日時を持ちます。 ここで以下のような設計の注文テーブルがあったとします。 上記の注文テーブルは、注文日時の他に請求日時、入金日時、更新日時を持ってしまっています。 これはこの注文テーブルの中に、以下の異なるイベントが混在していることを示しています。 請求 入金 これらは別のイベントエンティティである請求エンティティ、入金エンティティとして分解することができます。 そうすると以下のように設計することができます。 こうすることで、請求や入金が発生しても注文テーブルをUPDATEする必要なく、それぞれのテーブルへのデータのINSERTのみでデータを記録することができます。 ここまでの流れは実はOne Fact in One Place(1つの事実は1つの場所に)という正規化の行為そのものとなっています。 第1~5正規化を意識しながら初学者が正しく正規化するのは難しいと思いますが、ここまで紹介した手順だとまだイメージがつきやすいのではないでしょうか。 普段 Rails で開発していて感じたこと Rails で普段開発をしていると更新日時をもたないことは違和感があるかもしれません。 Rails でscaffoldすると更新日時カラム(updated_at)が自動で入ると思います。 order(注文)リソースをscaffoldする。 $ rails g scaffold order amount:integer 自動的に作成日時(created_at), 更新日時(updated_at)が入る。 # == Schema Information # # Table name: orders # # id :bigint not null, primary key # amount :integer not null # created_at :datetime not null # updated_at :datetime not null # class Order < ApplicationRecord end これは Rails がWEBシステムで必要なのは、最新のデータだけであるという制約を設けていて、UPDATEが起こること前提の設計になっているからだと思われます。 この強い制約を設けることでUPDATEやDELETEを許容する代わりに、たいていのことはデータベースと1対1となったModelの CRUD で表現できるというシンプルさを手に入れることができます。 Modelに書くことができず、Serviceクラスが肥大化したりするのはデータ モデリング の設計が悪い可能性が高いそうです。 このあたりは以下の Podcast で詳しく説明されているので、聞いてみてください。 anchor.fm イミュータ ブルデー タ モデリング との向き合い方 イミュータ ブルデー タ モデリング で考えると、イベントをエンティティとして捉えることからエンティティの数も増え、INSERTのみで記録することからデータ量も増えます。 そうすると、論理設計の段階では問題なかったかもしれませんが、いざ物理設計する際に実装を考慮するとパフォーマンスの問題に直面することもあるかと思います。 イミュータ ブルデー タ モデリング はデータ モデリング における正解ではなく、一種の論理設計をする際の制約として捉えるといいと思います。 考え方としては以下のような順番かと思います。 イミュータ ブルデー タ モデリング で論理設計する。 物理設計の段階で実装を考慮するとパフォーマンス的に厳しい箇所が見つかる。 問題となる箇所に対してUPDATEを許容する。 最後に イミュータ ブルデー タ モデリング はデータ モデリング における正解ではなく、一種の考え方です。 私のように初学者でデータ モデリング に対して苦手意識がある人は一度イミュータ ブルデー タ モデリング について調べて実践してみるといいかもしれません。 興味がある人は、 WEB+DB PRESS Vol.130のデータ モデリング 特集を面白いので読んでみてください。 gihyo.jp こちらの楽々ERDレッスンという書籍も実践的な内容が多くおすすめです。 www.shoeisha.co.jp 明日の記事の担当は インフラエンジニア の 山口 さんです。お楽しみに! 株式会社 エニグモ すべての求人一覧 hrmos.co
こんにちは、22新卒で入社したエンジニアのhashinoです。 この記事は Enigmo Advent Calendar 2022 の9日目の記事です。 背景 皆さん、普段コンテナを利用していますか? エニグモ では、 Kubernetesを活用 していて、開発環境でもDockerを活用しています。 しかし、最近はWebAssemblyがコンテナを完全に置き換えるかもしれないという噂も耳にします。 既に Kubernetes では、kubelet API 互換の Krustlet が注目を集めています。kubeletは、ご存知の通りOCI準拠のコンテナを実行しますが、Krustletは、 WebAssembly System Interface ランタイムのWebAssemblyを実行するものです。 Kubernetes 上でPodの代わりにWebAssemblyを動作させることが可能になっています。 また、 Fermyon では、WebAssemblyマイクロサービスを構築するためのDeveloper ToolであるSpinを開発しております。 このような背景から、コンテナの代わりにWebAssemblyが利用される未来も想像ができるようになってきたところです。 そして、先々月末に大きなニュースが発表されました。 それが、DockerのWebAssemblyコンテナです。 https://www.docker.com/blog/docker-wasm-technical-preview/ この記事を読んだところ、Docker API を使ってWASM Runtimeでの実行が可能になるということです。 さらには、WASM Imageなる概念もあり、これにより既存のDocker Imageと似たようなエコシステムやパイプラインの活用が期待できるということです。 DockerとWASMはどのように統合されたのか 多くの読者の方が気になっている点ですが、プレビューに書いてあった内容を簡単に私なりにまとめました。 OCIアーティファクト とcontainerd-shimを活用している。 OCI準拠のWebAssemblyランタイムである WasmEdge を採用し、そのために containerd-wasm-shim を作成した。containerd-wasm-shimは、OCI アーティファクト からWASMモジュールを抽出し、WasmEdge Runtimeを使用して実行する。 containerd-shimを使用できるようにするために、 --runtime=io.containerd.wasmedge.v1 フラグによって、WASM Runtimeを宣言できるようにした。 実際に私の MacBook のDocker DesktopでWASMコンテナを作成して実行してみました。 今回は、 公式のサンプル を参考に進めました。 [デモ]実際にDocker DesktopでWASMを実行してみる 今回は、Go言語を使ってサンプルを作ります。 WASMへの コンパイル が容易なtinygoをインストールします。 brew tap tinygo-org/tools brew install tinygo そして、 Hello World するだけのGoのプログラムを用意します。 本記事では、このコードをWASMバイナリに コンパイル して、それをOCIイメージとして利用可能であることを検証します。 package main func main() { println("hello world") } では、まずWASMバイナリに コンパイル しましょう。 tinygo build -o wasm.wasm -target wasm ./main.go このコマンドで、 wasm.wasm というバイナリが出来上がります。 ここから、WASMコンテナ関連の部分に入っていきます。 先ほど作成したWASMバイナリをOCI互換のイメージにしていきます。 以下のように少し無理矢理ですが、Dockerfileを使って実現できます。 FROM scratch COPY ./wasm.wasm /wasm.wasm ENTRYPOINT [ "wasm.wasm" ] ここで利用している scratch というコンテナイメージは、Dockerコンテナを実現する上で最小限のもののみので構成された非常に軽量なコンテナイメージです。 今回は、Dockerイメージのエコシステムを活用するためにscratchの中にWASMモジュールを入れるように構成しています。 docker buildx build --platform wasi/wasm32 -t sample-wasm-container . これでOCI互換のWASMイメージを作成できるはずなのですが、 ------ > exporting to image: ------ ERROR: failed to solve: operating system is not supported このようなエラーに遭遇しました。(かなり詰まりました汗) Docker DesktopのContainerdのイメージストア機能はデフォルトではOFFのようなので、ONにする必要があります。 以下のリンクの手順通りに進めることで解決しました。 https://docs.docker.com/desktop/containerd/ もう一度以下のコマンドを実行すると成功します。 docker buildx build --platform wasi/wasm32 -t sample-wasm-container . では、出来上がったイメージを見てみましょう。 ➜ docker image ls REPOSITORY TAG IMAGE ID CREATED SIZE sample-wasm-container 0.1 1711f20d1ef5 4 minutes ago 128kB ➜ docker image inspect sample-wasm-container | grep -A 3 "Architecture" "Architecture": "wasm32", "Os": "wasi", "Size": 127948, "VirtualSize": 127948, wasm32 というArchitectureのイメージができていることが確認できます。 では、ここからこのイメージをDocker Hubに登録していきます。 docker image tag sample-wasm-container mikiko/sample-wasm-container:1.0 docker image push hashino/sample-wasm-container:1.0 ところが、以下のようなエラーが出ました。 server message: insufficient_scope: authorization failed 以下のコマンドで再度dockerにログインすることで解決できました。 docker login Docker HubのWebUIからもDockerイメージが保存されていることが確認できます。 では、実際にDocker Hubに保存したWASMイメージを実行してみましょう。 docker container run --rm --name= \ --runtime=io.containerd.wasmedge.v1 \ --platform=wasi/wasm32 \ mikiko/hello-wasm-container:0.1 hello world うまく実行することができました! まとめ 本記事では、先々月に発表されたDocker WASMコンテナを実際に実行してみるところまで進めました。 Dockerが公開したWASMコンテナを検証してみました。 これまで通りのコンテナ レジストリ を活用したビルドやデプロイに関するエコシステムを活かして、WASMを導入できることが分かりました。 ぜひ、皆さんもご検証ください!! 参考文献 https://www.publickey1.jp/blog/22/docker_desktopwebassemblywebassembly.html https://github.com/opencontainers/artifacts https://www.docker.com/blog/docker-wasm-technical-preview/ https://docs.docker.com/desktop/wasm/ https://nigelpoulton.com/webassembly-the-future-of-cloud-computing/ https://github.com/tinygo-org/tinygo https://tinygo.org/docs/guides/webassembly/ 株式会社 エニグモ すべての求人一覧 hrmos.co
斧を研ぎましょう こんにちは、エンジニアの後藤です。 BUYMA のWebアプリを作る仕事をしています。 この記事は Enigmo Advent Calendar 2022 の8日目の記事です。 この記事のゴール この記事のきっかけ どのように実現するか 新たに見つけた課題 最後に 本当に最後に この記事のゴール この記事では、 Visual Studio Code でコードを書きつつ、サクサク rspec を実行したり Java プロジェクトをビルドしたり、 lint も実行したり、ということができるようになる、というのをゴールとしています。 エディタのカスタマイズを 愛する人 、エディタとコンソールを行ったり来たりしながら開発を進めている人におすすめの記事となります。 対象のエディタは Visual Studio Code です。 この記事のきっかけ この記事を書くきっかけになったのは私が、エディタを emacs から Visual Studio Code へ乗り換えたことに起因します。 emacs で rails アプリケーションを書いていたときは、 rspec -mode という emacs 拡張をインストールすることで、 rspec ファイルとテスト対象のファイルを行き来する カーソルのある行の rspec を実行 カーソルのあるファイルの rspec を実行 といったことがキーボードから行えました。 Visual Studio Code を使い始めてから、 Rails Go to Spec という プラグイン を見つけて、 rspec とテスト対象のファイルを行き来する はできるようになったのですが、カーソルのある行の rspec を実行するという事ができませんでした。そのため、 プラグイン でも書くか(エディタのカスタマイズは大好物です)、と思っていた所に良い方法をみつけたのでこの記事を書きました。 どのように実現するか 結論から言うと、 Visual Studio Code の標準機能のみで実現できました。その方法は、プロジェクトの tasks.json にタスクを追加することと、キーボードショートカットの割当です。 Visual Studio Code には、プロジェクトの ディレクト リ内にある、 .vscode/tasks.json ファイルにタスクを記述しておくことで、 Tasks: Run Task からプロジェクトに関連したタスクを実行できる、という機能です。 この機能と、 Tasks: Rerun Last Task へキーボードショートカットに割り当てることで、実現します。 では、早速 rails プロジェクトを対象に rspec を実行する場合を見ていきましょう。以下のような .vscode/tasks.json を作成します。 { // See https://go.microsoft.com/fwlink/?LinkId=733558 // for the documentation about the tasks.json format " version ": " 2.0.0 ", " tasks ": [ { " label ": " rspec file ", " type ": " shell ", " command ": " rspec -fd ${relativeFile} ", " group ": " test ", " problemMatcher ": [ { " owner ": " ruby ", " fileLocation ": [ " relative ", " ${workspaceFolder} " ] , " pattern ": { " regexp ": " ^rspec \\ s+(.*):( \\ d+) \\ s+# \\ s+(.*)$ ", " file ": 1 , " line ": 2 , " message ": 3 } } ] } , { " label ": " rspec here ", " type ": " shell ", " command ": " rspec -fd ${relativeFile}:${lineNumber} ", " group ": " test ", " problemMatcher ": [ { " owner ": " ruby ", " fileLocation ": [ " relative ", " ${workspaceFolder} " ] , " pattern ": { " regexp ": " ^rspec \\ s+(.*):( \\ d+) \\ s+# \\ s+(.*)$ ", " file ": 1 , " line ": 2 , " message ": 3 } } ] } ] } 作成したタスクは、以下になります。 タスク名 説明 rspec file カーソルのある rspec ファイルのテストをすべて実行する rspec here カーソルのある行の rspec のテストを実行する これで準備は整いました。 それでは、開発の流れを見ていきます。 rspec ファイルを編集していて、特定のテストを実行します。 Tasks: Run Task -> rspec here を選び、カーソルのある行の rspec のみが実行されます。 また、編集中のファイル全体の rspec を実行する場合は Tasks: Run Task -> rspec file を選択することで実行できます。 加えて、 Tasks: Rerun Last Task にキーボードショートカットを割り当てておくことで(私の場合はCommand + Shift + T)で、 rspec の作成する Tasks: Run Task -> rspec here` を実行 テストが失敗するのを確認 ソースを実装 キーボードショートカットから、 Tasks: Rerun Last Task を実行 Tasks: Run Task -> rspec here が実行される テストが成功するのを確認する Tasks: Run Task -> rspec file を実行 同じファイル内の他のテストが壊れていないことを確認 という開発ができるようになりました。 ちなみに、今回は rspec に特化したタスクを記述しましたが、 JavaScript を書いているときは、lint タスクを書く、 Java プロジェクトの場合は、ビルドタスクや JUnit タスクを書いておくことで、すべての言語で同じように開発が進められます。 めでたしめでたし。 新たに見つけた課題 と思っていたのですが、新しい課題を見つけました。 rspec here で、特定のテストを実行後、ソースファイルを編集した後に、カーソルと rspec ファイルのテスト対象行に持っていかないと、同じテストが実行できません。これは、地味に面倒くさい。できれば、 Tasks: Rerun Last Task Command のようなコマンドで、最後に実行したタスクのコマンドをそのまま実行する事ができれば、解決しそうですが、どうやらそのような機能は無いようです。 これは、機能追加の依頼をするか プラグイン を書かないと解決できなさそうです。 これは、来年の アドベントカレンダー の時にでも解決したいと思います。 最後に みなさん、斧を研いでいるでしょうか? 斧を研ぐと言っても、本当に斧を研ぐということではなく「きこりのジレンマ」のお話です。「きこりのジレンマ」というのは簡単に説明を書くと、 あるところに、忙しく木をきっているきこりがいました。彼の木を切るペースが日に日に落ちていきます。それを眺めていた人が、斧の切れが悪くなっているのでは?と感じ、斧を研いではどうか、と提案するのですが、きこりは忙しくて斧を研いでいる暇はないと答えた というお話です。 では、エンジニアにとっての斧は何でしょうか?いろいろあると思うのですが、エディタは斧の一つではないかと思います。 年1回、 アドベントカレンダー の時だけなどと言っていないで、日々斧を研ぎましょう。 Tasks: Rerun Last Task Command は他のみんなも欲しいのでは、という事を信じて、 Visual Studio Code のプロポーザルを書いてみたいと思います。近い将来。 本当に最後に 明日の記事の担当はエンジニアの橋野さんです。お楽しみに。 BUYMA を作っている、株式会社 エニグモ では、斧を研いで仕事を進めるエンジニアを求めています。ご興味のある方は以下の求人を御覧ください。 株式会社 エニグモ すべての求人一覧 hrmos.co
こんにちは、サービスエンジニアリング本部の寺田です。 軽く自己紹介になりますが、私は SIer で SE を2年間経験したのち、現職の エニグモ には 2020/7 よりジョインしております。 普段は主に Ruby on Rails を用いた BUYMA のサーバーサイド開発をやっています。 最近興味ある事は アルゴリズム で、週末には Atcoder にちょくちょく挑戦したりしています。 ちなみに、この記事は Enigmo Advent Calendar 2022 の7 日目の記事になります! 12 月はこのように弊社のエンジニアが記事を執筆しますので、ぜひお楽しみに! 組み込みメソッドをなぜ覚える必要があるのか? 私が嫌いなものそれは暗記です...なるべく覚えるものは少なく済ませたい、そんな思いが私にとって常にあるのです。そんな私にとってプログラミングを勉強したての頃に思ったことはこれでした。 「ぶっちゃけ for と if が使えれば何でもできるんじゃないのか?」 そうなんです。たいていのプログラムは for と if を使えば表せるのです。ではなぜ膨大な量の組み込みメソッドを覚える必要があるのか?? 一つ理由となるのは、それは読みやすい(=可読性が高い)からですよね。 ただ、組み込みメソッドを使ったプログラムが誰にとっても読みやすいかと言ったら、そうでもないですよね? # 配列の合計を計算する ## inject を利用した場合 puts [ 2 , 3 , 4 , 5 ].inject { |result, item| result + item } ## for ループを利用した場合 sum = 0 [ 2 , 3 , 4 , 5 ].each do |v| sum += v end puts sum 配列の要素の合計を計算するのに、 inject というメソッドを使ってます。これは知ってる人は簡単に読めるかもしれませんが、直感的には for ループを使用したプログラムの方が読みやすい気がします。 では、組み込みメソッドを絶対使った方が良いケースとはどんな場合でしょうか? それは、 「 for や if を使って簡単に書けるプログラムより圧倒的に早い場合」 これは絶対に組み込みメソッドを使ったプログラムの方がいいですよね? ruby には優れた アルゴリズム を使用して書かれたメソッドがあらかじめ存在しています。今回の記事では4つのメソッドと、これらに使用されている アルゴリズム について紹介していこうと思います! array#sort 問題 1~100000 までの数字がランダムに並び替えられた配列を、 昇順に並び替えてください。 for と if を使ったプログラム len = array.length len.times do |i| (len - 1 - i).times do |j| if array[j] > array[j + 1 ] array[j], array[j + 1 ] = array[j + 1 ], array[j] end end end for と if だけを使って簡単にプログラムを作成した場合、こんな感じでしょうか? ここで用いられている アルゴリズム は バブルソート というものです。 バブルソート の アルゴリズム を図解すると... 隣り合った数値同士を比較し、大小関係が合っていない場合は値を交換する。というのが基本の考え方になります。 1番目の要素と2番目の要素の大小関係を比較 2番目の要素と3番目の要素の大小関係を比較 ... 最後から一つ前と最後の要素の大小関係を比較 とすることで、一番最後の要素の値が確定します。 これを要素の数だけ繰り返すというものになります。 なので、ループの回数は要素の個数を n とすると、 n(n-1)/2 回で、計算量は となります。 オーダー記法 ここでオーダー記法(例に出てきた という書き方)を軽く押さえておきましょう。 オーダー記法はコンピューターによる計算がどれくらいの時間がかかるかを示したものです。 各計算量オーダーに対して、実際にどれくらいの計算回数になるのか表で見てみましょう。 10 3 33 100 100 7 664 10000 1000 10 9966 1000000 10000 13 132877 100000000 1000000 20 19931569 1000000000000 計算量はオーダーによってかなり異なることがわかります。 に比べて はかなり高速ですし、 よりは の方がとても高速です。 また、この差は数が大きくなればなるほど広がっていきます。 Ruby の組み込み関数を使用 ここで本題に戻りましょう。 Ruby の組み込みメソッドを使用して、この問題を解くならば、 Array#sort が使えます。 array.sort Array#sort で使われている アルゴリズム は クイックソート というものです。 手順としては以下の流れでソートを行います。 基準となる数値を決める 基準より小さい or 以上のグループに配列の要素を振り分けていく 要素が1つ以上あるグループにおいて、各グループ内で新たに基準を決める グループ内で基準より小さい or 以上のグループに配列の要素を振り分けていく この繰り返しを、それぞれのグループの要素が1つずつになるまで繰り返していき、最後に全てを結合することでソートを実現していきます。 計算量ですが、平均で になります。 最良のケースでは一度のループで各グループの要 素数 が、前回のループの半分の数になっていきます。 証明は省きますが、このように段々と 1/2 になっていき、最終的にn 個 => 1 個に要素が減っていくまでにかかる計算量は となると覚えておくと良いでしょう。 さらに、毎回のループで配列の長さである n 回の比較を行うため、 が計算量となります。 実際にプログラムを実行して計算量を比較してみたのが以下の実行結果です。 n = 100000 の場合、for ループによる バブルソート より、 Array.sort が 1000 倍も早いです。 Enumerable#bsearch 問題 1000000000 個の要素があるソート済みの配列の中から、 特定の数以上の値が初めて現れるインデックス番号を求めてください。 for と if を使ったプログラム array.each_with_index do |v, i| if (v >= 99999999 ) puts i break end end 非常にシンプルに考えるとこうでしょうか? このような アルゴリズム は 全探索 と呼ばれるものです。 配列の全要素に対して一つ一つ比較して答えを求めるものになります。 配列の長さだけループが走るので、長さ n の配列に対して計算量は です。 Ruby の組み込み関数を使用 では Ruby の組み込み変数、 Enumerable#bsearch を使った場合はどのような アルゴリズム になるでしょうか? array.bsearch { |x| x >= 99999999 } こちらで使用されている アルゴリズム は 二分探索 というものです。 配列の中から 2 という数字を探す場合を考えてみましょう。 こちらの アルゴリズム では以下の手順で答えを求めます。 左端と右端の値の中心の値を基準に、探したい数が基準より小さい or 以上かを求める 基準より小さい場合 => 探したい値は左半分にあるとわかる 基準以上の場合 => 探したい値は右半分にあるとわかる 要素が一つになるまで繰り返す こちらもループを繰り返すたびに、要素の数は 1/2 => 1/4 => 1/8 ... とどんどん半分になっていきます。 なので、要素が1つになるまでに必要なループのオーダーは になります。 これは全探索の よりかなり高速です。実際にプログラムを実行した結果を見てみましょう。 ものすごい違いですね。二分探索は全探索より 1000000 倍も早いという結果となりました。 Integer#pow 問題 を計算してください。 とても大きな数で累乗の計算をしてくださいというケースですね。 for と if を使ったプログラム ans = 1 ( 100000000 ).times do ans = ans * 3 end puts ans 累乗は言い換えれば底を指数の回数だけ掛け合わせるということです。 これを素直に実装すれば上記のようになるでしょうか。 指数の回数だけループして掛け算を行いますので、指数を n とすると計算量は になります。 Ruby の組み込み関数を使用 Ruby の組み込み関数には Integer#pow というものがあります。これは Integer#** と アルゴリズム は同じです。 3 .pow( 100000000 ) こちらは アルゴリズム として 繰り返し二乗法 が使われています。 例として を考えてみましょう。 愚直に計算するとループの回数は指数の数である 8 回です。 しかし は変換してみると、以下のようになることがわかります。 このように考えれば、ループの回数は4回で済みます。 この手順を一般化して考えると、以下のようになります。 求めたい値を、指数を 1/2 にした値を掛け合わせた式で表す 指数が 1 になるまで繰り返す 指数はループを経ることに 1/2 => 1/4 => 1/8 ... と半分になっていきます。指数が n ならば、1 になるまでに発生するループの回数は で非常に高速です。 実際にプログラムを動かして比較してみました。 非常に高速です。愚直な計算方法より 1000000 倍も早いことがわかります。 Integer#gcd 問題 463836510 と 692647128 の最大公約数を求めてください for と if を使ったプログラム ans = 0 ( 1 ...[a, b].max).each do |d| ans = d if (a % d == 0 && b % d == 0 ) end puts ans 最大公約数とは、二つの値を割り切れる最大の整数のことです。 この定義をそのまま実装するならば、上記のようなプログラムになるかと思います。 こちらは全探索の アルゴリズム となっていて、与えられた数が n とすると計算量は となります。 Ruby の組み込み関数を使用 最大公約数を求めるメソッドとして、 Integer#gcd が用意されています。 a.gcd(b) こちらは ユークリッドの互除法 と呼ばれる アルゴリズム が使用されています。 ユークリッドの互除法 というのは以下の定義を指します。 2つの 自然数 a, b について、a / b = q、a % b = r とすると、 「a, b の最大公約数」は「b と r の最大公約数」に等しい。 式で表すと以下のようになります。 ここで は a と b の最大公約数を表します。 これを繰り返すことによって、少ないループの回数で最大公約数を求めることができます。 例えば、629 と 481 の最大公約数を求めてみましょう。 最後のステップでは、148 を 37 で割った際のあまりは 0 になっています。 これは 148 と 37 では 37 が最大公約数になっていることを意味します。 ゆえに、 = = 37 と最大公約数が求まります。 そして、この アルゴリズム の計算量はざっくりと になります。 、 として、 より以下のことが言えます。 すなわち、 が成り立ちます。 2回のループを経ることで、確実に値が 1/2 以下になるわけですね。 先ほどから何度も出てきたパターンですが、値が 1/2 に減少していく アルゴリズム は計算量が となります。 実際に実行速度を比べてみましょう。 計算速度は 10000000 倍に速くなっています。 まとめ Ruby には良い アルゴリズム を使った組み込みメソッドが用意されている アルゴリズム の紹介として、 クイックソート 二分探索 繰り返し二乗法 ユークリッドの互除法 を紹介した。 良い アルゴリズム を使うことでプログラムは何万倍にも高速になることがある タイトル詐欺になってしまいますが、大事なことは Ruby のメソッドを覚えることではなく、どういう アルゴリズム があり、自分が直面した問題を解決するためにどの アルゴリズム を使うべきかを判断できるようになることだと思います。 Web エンジニアの裾野が広がってコンピューターサイエンスを学んだことのないエンジニアの方もいらっしゃるかと思います。この機会にぜひ興味を持ってもらえると嬉しいかなと思います! 明日の記事の担当は サービスエンジニアリング本部 の 後藤 さんです。お楽しみに! 株式会社 エニグモ すべての求人一覧 hrmos.co
こんにちは、2022年に新卒入社したエンジニアの川本と橋野です! この記事は Enigmo Advent Calendar 2022 の6日目の記事です。 エニグモ では社内の若手を中心にjunior workshopという名で勉強会を行っております。 経験の浅いメンバーの技術力アップを主目的としておりますが、興味のある方はどなたでも参加できる会となっています。(ベテランの方大歓迎です!) 勉強会の形式と、半年ほど勉強会をやってみて感じた、よかった点、今後やってみたいことなどを紹介できればと思います! よかった点 よかった点1:知見の共有 1つの技術書を読むのにも、1人で読むより、勉強会であれば様々な知見を持ったメンバーが集まっているので吸収できることが多いです。 技術書の内容を業務で実践したことがある人からは、具体的なエピソードを聞くことができますし、抽象的な概念の勉強をしている時は特に理解の助けになります。 よかった点2:社内交流が増える 勉強会は誰でも参加OKとしているので、様々なメンバーと交流できるいい機会となっています。 普段一緒に仕事をしないメンバーのことを知れたり、他部署の業務内容を知れたりと、コミュニケーション活性化や、会社理解の向上に繋がっていると思います。 以下のような形でSlackで勉強会当日にリマインドをしており、誰でも飛び入りでzoomのURLから参加可能となっており、参加の敷居はなるべく下げるようにしています。↓ エンジニア採用をやっている人事の方も参加してくれています! よかった点3:社内文化の形成 エニグモ には技術的関心が高いエンジニアが多いので、社内では下記のような技術力向上に向けての取り組みがされています。 Hacker's Delight エンジニアが個人的に学習していることや、業務で実践したことなどを発表するLT会です。週に1回開催しています! 開発合宿 コロナ以前は開発合宿も行われておりました!そろそろ再開できそう。。。? tech.enigmo.co.jp Ruby Kaigi 2022年は現地の 三重県 でオンフライン参加された方もいます! tech.enigmo.co.jp Kaigi on Rails 2022年は Gold Sponsors として参加しました! tech.enigmo.co.jp 若手勉強会もこうした社内文化の1つとして エニグモ に根付き、エンジニア組織全体のコミュニケーション活性化、技術力の向上に繋がると考えています。 勉強会の形式 輪講 という形式で、週替わりで担当者が勉強した内容をまとめてきて発表し、みんなが質問して議論していくというやり方でやっています。 22新卒が中心に開催している勉強会は、5月から開催しています。 そして、12月現在、2テーマ目に突入しています。 1テーマ目と2テーマ目の間には、振り返りを設けて、進め方を少し改善をしました。 初期から大切にしていることと、改善したことを紹介します。 初期から大切にしていること 勉強会を開催するにあたって、やりたいこと/やりたくないことなど開始前に話し合いました。 参加者が参加負担にならないようにし、勉強会を継続して開催したい。 受け身になりすぎないようにしたい。 この2つの意見を受けて、 みんなが予習必要ではない方式にする。 担当者は必ずしもまとめ記事を作ってくる必要はなく、最低限ファシリテートできるようにしておく。 開催出来なさそうであればその週はスキップをする。 以上のことを決め、無事に1テーマ目を終えることができました。 改善したこと 初期から大切にしていることに加え、改善した点があります。 以前は、勉強会の時間内に決めたところまでを読み終わらなかった場合、時間を延長してまでやっていました。 しかし、今は時間のキリのいいところで終わり、終わらなかった分は翌週にまわしています。 これは、1テーマ目の勉強会での反省にあった、「進度が早く、理解があまり出来ないまま進んでしまった。」という意見があったためです。 このため、現在のやり方では、みんなで疑問点を解消しつつ、意見交換をし、私たちのペースで進め、理解を確実にしていくことを大事にしています。 今後やりたいこと これまでの勉強会は技術書を読んできて、内容を議論するといった形式でしたが、もう少し手を動かしたいという意見もあります。 なので今後はライブコーディングをしながら下記のような方法も取り入れてみたいと考えています! AtCoder やLeetCodeの問題を解く。 SQL の問題を解く。 リファクタリング をみんなで考えて議論しながらやっていく。 まとめ 最近の勉強会は、担当者ごとに発表のやり方の個性がでていて、飽きず面白いです。 また、勉強会は個人にとっても会社にとってもメリットが多いと感じました。 これからも勉強会をさらに盛り上げれるように工夫していきたいと思います。 テックブログでも若手勉強会でやった内容をどんどん発信していければいいなと思っております! 明日の記事の担当は 私(川本)のメンターをしていただいているエンジニアの寺田さんです。 アルゴリズム についての記事です。お楽しみに! 株式会社 エニグモ すべての求人一覧 hrmos.co
この記事は Enigmo Advent Calendar 2022 の 5日目の記事です。 こんにちは。フロントエンドエンジニアのWooです。 エニグモ へ入社して3年目、主に BUYMA の購入者側のページをReactで構築しています。 BUYMA ではReactのグロー バルス テート管理のために主にReduxを使用していますが、今回は新しい取組としてRecoilを導入し、開発を行なってみましたので、その経験を共有しようと思います。 まず、軽くRecoilについて理解し、Recoilを導入するようになった理由、Recoilで開発する時に良かった点や困ったこと、他にリリースする際に失敗した話、最後にはこれからRecoilのより良い開発経験のための整理などをこの記事でお話ししたいと思います。 Recoilを軽く理解する RecoilはReactプロジェクトのための数多いグロー バルス テート管理ライブラリの中の一つで Facebook が2020年5月に出したライブラリです。なので、Reactを作った Facebook が出したRecoilは他のライブラリ(Redux, Mobx)とは違い、React専用ながらReactに最適化されたと言えるライブラリです。 Recoilを導入するようになった理由 2022年2月、 BUYMA では スマホ ウェブの検索絞り込み画面の使用性を高める企画が始まりました。 従来の画面はかなり前に作られたものだったので、画面の機能改善ではなく、新しい検索絞り込み画面を開発する方向に進められました。 私は新しい検索絞り込み画面のステートをどう構成すれば開発しやすくなるのかを悩みながらステート設計方法などを探していました。 そんな中、私はRecoilに接するようになりました。 新しく作る検索絞り込み画面は機能は多いながらも操作性は単純で軽い画面になる必要がありました。 Recoilはユーザーの絞り込み条件により、変更される数多いステートを柔軟に拡張・分解しながら開発ができそうと思いました。 さらにReduxに比べコードの量も多く減らすこともでき、少人数でもスピード感ある開発ができそうと思いましたので、検索絞り込み画面開発に適合だと判断、導入を進めるようになりました。 Recoilで開発した時の良かった点 まず、RecoilはReactのSuspenseと一緒に動作するようにデザインされていました。 コンポーネント をSuspenseで囲むと非同期処理などでまだ保留中の下位 コンポーネント をキャッチし、代替するUIをレンダーしてくれました。 これにより、データを取得している間のローダー表示を全体的に統一することができました。 その他、ステートを使う時にどんなエラーが生じるかの定義が簡単でした。それはErrorBoundaryでキャッチする仕組みでした。 ErrorBoundaryはエラーをキャッチし、エラーを記録し、クラッシュした コンポーネント ツリーの代わりにフォールバック用のUIを表示するReact コンポーネント でした。 グロー バルス テートの設定と定義が非常に簡単で、ステートの使用はRecoilが提供するHooksを利用、ステートをget/setすることだけでした。React Hooksの文法と似ていることで、初めてRecoilを書くエンジニアでもすぐになれる利点がありました。 また、グロー バルス テートを使用するためのボイラープレートの量が非常に少なく、全体的にラーニングカーブが低いというメリットがありました。 そして、ステートの変更や定義が頻繁に行われても既存コードとの影響度が低いため、開発要件によるステートの変更でも柔軟に対応が可能でした。 propsを渡さなくても良い特徴では コンポーネント の リファクタリング や分割などが容易でした。 API の非同期の処理ではユニークなインプットがある時のみ実行されるようにキャッシュされる処理があり、ユーザーの同じアクションを防ぐなどの実装を考慮しなくてもよい便利さがありました。 Recoilで開発をする時に困った経験 ユーザの絞り込み条件変更によるReactの処理では、Suspenseを利用しました。 Suspenseは API の非同期処理を待機中の下位 コンポーネント の代わりにローダーをレンダーしてくれましたが、実際に動作を確認すると絞り込み条件変更の度に表示される真っ白のローダー画面が与える印象は求めている操作性の軽い画面とは違うように感じられました。 非同期データを使う最小限の コンポーネント をSuspenseで囲む コンポーネント 構造が設計可能であれば、全画面ローダーを表示する必要はないかもしれません。 しかし、検索絞り込み画面はヘッダー以外のところが非同期データによってレンダーされる コンポーネント のため、前述の方法の設計ができませんでした。 そうして考えた方法は、単なるスピナー表示ではなく、スピナーを絞り込み項目と一緒に見せる方法でした。 スピナーに絞り込み項目も含めSuspenseに渡すことになったので、このローダー コンポーネント は肥大化されましたが、パフォーマンスに大きな影響はありませんでした。各 コンポーネント ごとにステートを使っているおかげで、 リファクタリング はJSX部分の簡単な修正で済みました。 Recoilで開発したコードをリリースする際に失敗した話 BUYMA のReactコードは、babelを通してES5コードに変形した後、もう一度uglifyを行う過程を経ることになります。 このES5に変形する過程ではnode_modulesを含みません。 問題はnode_modulesにあるRecoilライブラリを OOO _app.jsの結合ファイルに含めてuglifyしようとした時に起きました。 uglifyはES6コードを解析できず、圧縮に失敗していました。 Recoilライブラリは主にES6で書かれていたのが原因でした。 リリースの過程でしか確認できないファイル圧縮の失敗は予想できなかったのです。 結局、他の代案を探さなければなりませんでした。 RecoilライブラリをES5に変形する方法など考えてみましたが、おすすめしない方法だとネット上では勧告していました。 近年 BUYMA は IE をサポートしなくなりましたので、結合のファイルをES5に変更する過程をなくす方法もありました。しかし、その方法は影響範囲が多く、少人数で解決できないと考えられました。 そんな中、 BUYMA はReactライブラリを CDN ロードする方式で運用されていることが思い出しました。 近いところの一番簡単な方法が見つからず、遠いところの難しい方法だけを考えていました。 結局、Recoilの CDN を利用してuglify問題を解決する方法を採用することになりました。 Recoilのより良い開発経験のための整理 最近はまた別の画面でRecoilを使って開発をしました。 2回目の開発経験では、 命名 部分の理解度を高めるとRecoilを知らないエンジニアでもコードが理解しやすいかもという考えを持ちながらコードを作成しました。 selectorは以下のように関数の名前を 命名 しました。 意味的に派生したステートの名前を 命名 しようとしました。 コンポーネント では、上記の派生したステートの名前を簡単に理解できるようにコードを作成しました。 Recoilのフォルダとファイルの構造はステートの単位を意味するatomsと派生のステートを修正して新しい結果を作るselectorsに分離して使用することが便利でした。 /api /atoms /components /containers /hooks /selectors Recoilの開発の際にはReduxの開発の際と同様、意図しないステートの更新などを確認する必要があるので、開発ツールとして DebugObserver は必須だと思います。 ReduxのDevToolほど強力なツールではないと思いますが、シンプルな更新ログの形でいつも Chrome のDevToolsを開いて開発する私には見やすくてわかりやすかったので、不便ではありませんでした。 終わりに Recoilに対する小さな経験を話すことができて嬉しいです。 今度機会があればRecoilの多様なユーティリティ機能の使用経験を整理してみたいと思いました。 開発ツールの不在などReduxよりパワフルではないと思いますが、Reactフレンドリーな書き方や簡単な非同期処理など、開発しやすいRecoilライブラリの長所と魅力をこの記事で少しでも伝えられましたらと思います。 関連記事 Recoil: https://recoiljs.org/docs/introduction/installation グロー バルス テータス管理ライブラリ Recoil : https://abangpa1ace.tistory.com/212 株式会社 エニグモ すべての求人一覧 hrmos.co
こんにちは、エンジニアの岡本です。 BUYMA のWebアプリを作る仕事をしています。 この記事は Enigmo Advent Calendar 2022 の2日目の記事です。 弊社は10/22、23に開催された Kaigi on Rails にゴールドスポンサーとして参加し、更にオンラインブースを提供しました。 当日の雰囲気を知りたい方およびこれからテックカンファレンスのスポンサーをしたりブースを提供しようと思っている企業の方に参考にしていただけたら幸いです。 参加するまでの準備 上長の同意を得る 会社の 知名度 に寄与し、普段使っている OSS である Ruby および Ruby on Rails への貢献をする意味でも参加してみるのはどうかということで相談し同意を得ました。 予算の確保・稟議・スポンサー応募 スポンサー費用申請のため、人生で初めて稟議書を書きました。無事承認されて安堵しました。 そのあとは公式サイトからスポンサー応募を行いました。 ここまででも、スポンサーされている企業の担当者の方の苦労が手に取るように分かりました。地道なプロセスの上にテックイベントは成り立っているのです。感謝。 ブースの提供内容を考える 具体的に何をすれば良いか分からず、過去の参加記を調べた上で「社内の開発組織やエンジニアのパーソナリティを知ってもらう機会にしよう」ということにしました。 社内のエンジニアと人事担当者の協力を得て、ブースに参加していただき、それぞれテーマと時間割を決めました。 当日利用したタイムテーブル は Google docs で即興で作りました。 当日の雰囲気と反省 当日の発表は YouTube で公開されています。(以下はプレイリストになっています) www.youtube.com 一方のブース。なかなか参加している側としては見知らぬ人のところへ行くのは勇気がいることなので、序盤はブースに来ていただくのも大変でした。ブースに来てもらう工夫として Twitter /spatial.chatでの告知をしたり、ブースで話していることのテーマを画面に書いていました。 spatial.chatを使ってブース運営している様子 わかったこと 大きな Rails アプリケーションをどう運用しているかに関心がある人は一定数存在し、話題として需要がある 休憩時間にブースにくる人が増える。発表時間に来訪する人は少ない。発表の合間の休憩時間が20~30分くらいあることが何回かあるのでそこで 接触 を図る 競プロや Ruby ライブラリのHowToなどライブコーディング的なことをやっていたり、DB マイグレーション のスライドを用意して発表してる会社もあり、人が集まっていた ブースを出すならオフラインイベントで出せたらより楽しいのだろうなと感じました(筆者の主観に基づく) つぎやること オフラインでのスポンサー参加の検討(RubyKaigi、Kaigi on Rails など) エンジニアならではの企画を用意する(ライブコーディングの様子を公開する) ノベルティ の配布 発表の合間の休憩時間が20~30分くらいあることが何回かあるのでそこで 接触 を図る (必ずやるとは言っていない) 来年のKoR 2023年のKaigi on Rails はオフラインでも開催が検討されているそうです。2020年の開始以降、初めてのオフラインでの開催ということで盛り上がることを期待しています。 2日間ありがとうございました!クロージングで告知しましたが、2023はTokyoでハイブリッド開催を目指しています🎉 このアカウントをフォローして続報をお待ちください。 またお会いできるのを楽しみにしています〜!! #kaigionrails — Kaigi on Rails (@kaigionrails) October 22, 2022 株式会社 エニグモ すべての求人一覧 hrmos.co
こんにちは、インフラエンジニア の 加藤( @kuromitsu_ka )です。 先日、自社のメディアサービス( STYLE HAUS )のElastiCache for RedisのEOL対応(2.x→6.xへアップグレード)を実施しました。 環境の説明と今回やったことの概要 STYLE HAUSの環境は、 AWS に構築している本番環境とステージング環境、開発者のPC端末に構築しているテスト環境があります。 検証の段階で、PC端末に構築しているテスト環境(普段はlocalのRedisを使用している)から、ElastiCacheに接続して、バージョンアップの動作確認するため、今回、接続用の環境を構築しました。 ※ こちらの記事も参考になると思います。 aws.amazon.com ざっくりやること ElastiCacheと通信可能なサブネットにEC2 インスタンス を作成 EC2 インスタンス にてSSM Agentを起動( Amazon Linux2だとデフォルトでインストールされている) PC端末でSession Managerを実行 インフラの図 インフラ構成とIAM EC2 サブネット:ElastiCacheへ通信できるサブネットに作成 AMI: Amazon Linux2を利用 Amazon Linux2では、SSM Agentがデフォルトでインストール済み 参考: https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/systems-manager-setting-up.html インスタンス タイプ:t2.micro EC2の インスタンス プロファイル 参考: https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/session-manager-getting-started-instance-profile.html 参考: https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/getting-started-restrict-access-quickstart.html 実際に インスタンス プロファイルに付与したポリシー { " Version ": " 2012-10-17 ", " Statement ": [ { " Effect ": " Allow ", " Action ": [ " ssm:GetDocument ", " ssm:DescribeDocument ", " ssm:StartSession ", " ssm:TerminateSession " ] , " Resource ": " * " } , { " Effect ": " Allow ", " Action ": [ " ssmmessages:CreateControlChannel ", " ssmmessages:CreateDataChannel ", " ssmmessages:OpenControlChannel ", " ssmmessages:OpenDataChannel " ] , " Resource ": " * " } , { " Effect ": " Allow ", " Action ": [ " ec2messages:AcknowledgeMessage ", " ec2messages:DeleteMessage ", " ec2messages:FailMessage ", " ec2messages:GetEndpoint ", " ec2messages:GetMessages ", " ec2messages:SendReply " ] , " Resource ": " * " } ] } 開発端末のIAMユーザー 参考: https://aws.amazon.com/jp/about-aws/whats-new/2022/05/aws-systems-manager-support-port-forwarding-remote-hosts-using-session-manager/ 実際にIAMユーザーに付与したポリシー { " PolicyVersion ": { " Document ": { " Version ": " 2012-10-17 ", " Statement ": [ { " Sid ": " 0 ", " Effect ": " Allow ", " Action ": " ssm:StartSession ", " Resource ": [ " arn:aws:ec2:ap-northeast-1:xxx:instance/<EC2インスタンスのID> ", " arn:aws:ssm:ap-northeast-1::document/AWS-StartPortForwardingSessionToRemoteHost " ] } ] } , " VersionId ": " v2 ", " IsDefaultVersion ": true , " CreateDate ": " 2022-09-28T06:55:24+00:00 " } } 作業者端末の手順 作業者のPC端末には、Session Manager プラグイン のインストールと、上記のIAMユーザーの設定が必要でした。 Session Manager プラグイン のインストール手順 参考( Mac 用の手順): https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/session-manager-working-with-install-plugin.html#install-plugin-macos 参考( Linux 用の手順): https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/session-manager-working-with-install-plugin.html#install-plugin-linux セッション確立のコマンド --targetは、今回、SSM agentを起動させているEC2のid --parameters '{"host": で指定するElastiCacheのエンドポイントを、必要な接続先に変換する。 localPortNumber は、端末や 仮想マシン の空いているポートを使う。 セッション開始!! $ aws ssm start - session \ -- target < EC2 インスタンスの ID >" \ -- document - name AWS - StartPortForwardingSessionToRemoteHost \ -- parameters '{"host":["<ElastiCacheのエンドポイント>"], "portNumber":["6379"], "localPortNumber":["16379"]}' \ -- profile < PC 端末に設定した IAM ユーザー> Starting session with SessionId : < IAM ユーザー>_connection_by_SSM-052ccf2de6652c027 Port 16379 opened for sessionId < IAM ユーザー>_connection_by_SSM-052ccf2de6652c027. Waiting for connections ... Connection accepted for session telnet 動作確認 aws ssm start-sessionのlocalPortNumberで指定した、 localhost のポートがElastiCacheと繋がっている。 $ (sleep 1 | echo quit)|telnet localhost 16379 Trying ::1... telnet: connect to address ::1: Connection refused Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. +OK Connection closed by foreign host. 感想 今回の接続環境の作成方法を知らなかった時は、Nginxで多段プ ロキシー を用意する案も考えていましたが、今回の構成は、短時間且つ簡単に構築できてよかったです。本来の目的だった、EOL対応も、問題なく、完了できてよかったです。😢 株式会社 エニグモ すべての求人一覧 hrmos.co
はじめに RubyKaigiが2019年以来の現地開催となり、2022年は 三重県 津市で行われました。 今年は現地と配信のハイブリッド開催であり、弊社から2名が現地参加、4名がオンラインで参加しました。 rubykaigi.org 過去の参加記 tech.enigmo.co.jp 本ブログには2017年の記録しか残ってないのですが、2019年まで毎年現地参加し、スポンサーをしている年もあります。 では、現地参加したメンバーとオンライン参加したメンバーそれぞれが感じたことを紹介します。 現地参加編 エンジニアの橋野です。新卒エンジニアとして4月からenigmoに入社しています。 詳しくは こちらの入社エントリ をご覧ください。 オフラインでおこなわれるカンファレンスは、初参加でしたのでとても楽しみにしていました。 初の現地開催参加という目線でレポートしていきたいと思います。 印象に残ったセッション Ruby Committers vs The World 数々の名言が残ったセッション。コミッターの方が自由に議論していてワクワクしました。 Ruby コミッターの方々が身近に感じられてとても楽しかったです。 Why is building the Ruby environment hard? 共感できることの多い発表でした。"ソフトウェアは何もしないと壊れる"しっかり胸に刻んでおきます。 The Better RuboCop World to enjoy Ruby RuboCopに苦しめられないための提案がとてもいい案だと思いました。楽しくRuboCopを使っていきたい...! スライドの挿絵がMidjourneyを使っていて、檻に閉じ込められた ruby が忘れられません。 感想 津駅に降り立ったのは人生初で、お昼ご飯や夕飯、スポンサー企業の方々からいただいた食べ物を通して三重に来たんだな〜〜!と主に食べ物で実感ができました。笑 また、会場には無料 Wi-Fi があり、コメントやメモがとても捗りました。駅からも少し距離があったのですが、 シャトル バスを出してくださったのでとても便利でした。スポンサー企業の皆様、ありがとうございます。 宿泊したホテルでは、同行者のstevenさんがエンジニアらしい数字?の404号室を引き当てていました! 最終日には、転職ドラフトのブースで404チャレンジというガチャガチャをしました。わたしはターミナルのピンバッチが当たったのですが、stevenさんはなんと404のピンバッチを見事当てていました。 会場には各地から集まった参加者がたくさんいて、こんなにも Ruby を好きな人たちがいるんだということを感じることができました。ここにいる人たちはほとんど Ruby を書いているということに感動しました。 また、休憩時間には普段なかなか交流ができない同世代のエンジニアとお話しができ、とても有意義に過ごすことができました。 普段あまり触れることのない技術の話も聞けて楽しかったです。 RubyKaigi運営のみなさん、スポンサー企業の方々、 Rubyist のみなさん、本当に素晴らしいカンファレンスに参加させていただきありがとうございました! オンライン参加編 新卒2年目の岡本です。主に BUYMA の出品者向け機能を開発しています。 Ruby の存在を知って5年ほど経ちますが、RubyKaigiに参加するのは今回が初めてです。 印象に残った発表 3日間、各セッションいずれも楽しませていただきました。個人的に印象に残っているのが以下です。 Ruby meets WebAssembly 1 Building a Lightweight IR and Backend for YJIT 2 ruby /debug - The best investment for your productivity 3 String Meets Encoding 4 Wasm対応について、 Webブラウザ で Ruby が動くことに感動しました。 irb がブラウザで動いている… irb-wasm.vercel.app デモの紹介は明快で、聴衆を引きつけた上で内部の実装の解説をされていて素晴らしいと思いました。 Ruby をWebAssemblyに変換する上で大きく3つの障壁 5 があり、それをAsyncifyという非同期処理を実現する アルゴリズム によって問題を解決しているとのことでした。 また Cookpad さんが提供されている Cookpad Code Puzzle for RubyKaigi 2022 にもWasmが取り入れられているようです。私はこれを書いている時点でfunc20まで解けていないのですが…解けると楽しいです。 ruby-puzzles-2022.cookpad.tech String Meets Encoding の発表について、業務で CP932 を扱ったりテキストを エンコード する場面によく出くわすので発表を楽しみにしていました。stackprofやperf、lldbを用いて Ruby でのstring encoding処理で ボトルネック になっている箇所を探索していく課程を垣間見れて大変勉強になりました。最終的にPRも作成されています。 6 YJITや ruby /debugは使ったことがなかったのですが、セッションを聞いて面白いと思ったのでアプリケーションに導入してみたいと思っています。 参加した感想 1. Ruby の開発の第一線に立つエンジニアの話を聞くのは刺激になる Ruby だけでなく普段使っている各種gemの作者・コミッターの方の発表をオンタイムで聴くとワクワクしました。またkateiさんのような才能あふれる方を見ると自分も頑張らないといけないと思いました。 2.オンラインだと落ち着いてメモがとりやすい 自宅からの参加ということで、外部キーボードとモニターに接続した状態で発表を視聴していました。2画面以上の環境で発表を聞きながら検索をしたり GitHub のissue/PRを閲覧できたので情報の摂取効率は高かったと感じています。(個人の感想) 3.ハイブリッド開催は大変 配信トラブルにより2日目の発表が一部聞けなかったのですが、スタッフの皆様の多大なご尽力のおかげで各セッションを楽しむことができました。この場をお借りしてお礼を申し上げます。 4.コンピュータ何もわからん Alan WuさんのYJITに関するセッションにおいて、バックエンド/フロントエンドという話題が上がりましたが、WebアプリケーションではなくCPU アーキテクチャ におけるそれでした。CPUの基本動作において、フェッチからデコードがフロントエンド、命令実行がバックエンドと言うらしいです。知らんかった… 最後に 2023年のRubyKaigiは長野県 松本市 で開催される予定です。2020年に現地開催されるはずだった松(Matz)本の地で Rubyist の皆さんとお会いできることを楽しみにしています!信州そばいっぱい食べましょう! お知らせ 弊社 エニグモ は2022年10月21日、22日に開催されるKaigi on Rails 2022にゴールドスポンサーとして参加します! 当日はオンラインブースを設置します。EM・テッ クリード などが参加予定です。 海外ファッションEC「 BUYMA 」の開発事情について・当日の発表についてなど、ざっくばらんにお話しできればと思います。 kaigionrails.org 採用情報はこちら hrmos.co https://speakerdeck.com/kateinoigakukun/ruby-meets-webassembly ↩ https://github.com/ruby/ruby/pull/5826 ↩ https://github.com/ruby/debug ↩ https://speakerdeck.com/ima1zumi/string-meets-encoding ↩ setjmp/longjmpに依存しているCRubyの例外機構・Fiberのcontext switch・保守的 GC ↩ https://github.com/ruby/ruby/pull/6351 ↩
こんにちは、テッ クリード の Steven です。 この記事で開発部門におけるメンタリングの体制を紹介して、学んだことを説明できればと思います。 メンタリングの目的 メンタリングはエンジニアが仕事を通して提供する価値が上がるようにサポートすることだと思います。 技術力を伸ばすのも重要ですが、仕事が全体的にもっと効率よく進むように仕事のやり方を改善するのがポイントです。 調査のやり方、コミュニケーションの取り方、時間管理、振り返り方、作業のタスク分けとスケジュールなど仕事を進める中で必要となるスキルを伸ばすことを目的としています。 メンタリングは ティー チングとも違っていて、どうすればいいのかをただ教えるのではなく、あくまでメン ティー をサポートして、自分一人で成長できるようにすることです。 何をすればいいのかを指示するのではなく、問題をどうすれば解決できるのか解決策を助言するか、判断しやすくなるようにアクションを提案することに留めます。 もちろん成長要素のない問題が発生した場合、正解が一つしかない場合、わざわざ考えさせる意味がないので、その時に限って答えを教えます。 手取り足取り、全てを細かく説明するのが優しいと感じられることがありますが、それだと、相手が自分で考えることなく、言われたことをそのまま実行するだけなので、成長には繋がりにくいと思います。 メンターがいなくなって、新しい問題が発生したら、解決するには多分苦労するでしょう。 メンタリングはその状況を避けるためにあって、優しさより成長を優先すべきだと思います。 当然ですが、メンタリングは社員全員にではなく、新卒やジュニア限定としています。 それも当人の技術力、仕事の捌き方によって決まるもので、基準値を超えれば、メンタリングを終わりとします。 メンタリングの体制 開発部門でメンタリングを受けるメン ティー にメンターが一人付きます。 そのメンターは日々の作業の手助け、成長のためのサポート、作業のレビュー、週次振り返りを担当します。 メン ティー のために時間が取れるように、メンターは基本的に一人のメン ティー だけを担当します。 メン ティー は 1on1 という対面月次振り返りも受けます。 対面相手はリーダー層のエンジニアになります。 それとは別でメンターのメンタリングのための会議も毎月実施しています。 メンターとメンタリングの経験があるエンジニアが集まる MTG です。 メン ティー の週次振り返り 毎週メン ティー とメンターで振り返り MTG を実施して、一週間の間にメン ティー が行った作業と、発生した問題を分析して、改善案を出します。 YWT の形で行っていて、やったこと(Y)、わかったこと(W)、次やること(T)を事前にメン ティー に記事にまとめていただいてから、メンターと二人で話し合います。 YWT の記事でまとめるのは作業内容も含まれますが、それよりも仕事の進め方を改善するために取ったアクション(Y)、作業をする中でやり方についてわかった重要なこと(W)、次の振り返りまで仕事の進め方を改善するために取る予定のアクション(T)というのが内容となります。 技術についてわかったことは自然と増えて、メンタリングをそんなに必要とするものでもないので、それで時間を浪費しすぎないように気をつけています。 その記事を確認した上でメンターはメン ティー とディスカッションをして、時間の使い方がよくないとか、調査方法が非効率だとか、メン ティー が抱えている問題を掘り出して、改善アクションを提案します。 メンターはできるだけ、表面的な問題ではなく、根底にある問題を暴き出すように努めます。 改善アクションが決まれば、口頭で終わらせるのではなく、アクションをしっかりと振り返り記事に記録して、次の振り返りで実施されたかどうか、フォローアップを行います。 アクションがわかりやすくまとめられて、実施される前提でメンターが振る舞えば、メン ティー もやる気が出て、アクションが取りやすくなるかと思います。 YWT の例 以下は振り返りに慣れたエンジニアが実際に書いた YWT です。 入社したてのメン ティー でこんな風に状況を分析して情報をまとめるのが難しいと思いますが、目指すべき振り返りの形だと思います。 レビュー入力欄改善と検索UIはプロジェクトの名前です。 Y(Yattakoto) レビュー入力欄改善はキリのいいところで一旦打ち切った 検索UIでは figma や画面仕様を見ながら詳細設計した W(Wakattakoto) プロジェクトに アサイ ンされたばかりだが画面仕様書の作成を通して実装できるぐらいには仕様を把握することができた 検索UIのチケット1枚あたりの作業量は膨大ではないのですぐ終わってモチベーションが保ちやすい。レビュー入力欄改善のタスクはチケット1つで結構な作業量なのでチケットを細分化する必要があると感じた。 コンポーネント 作成のタスクに入ったが、 css の適用はしないのででき上がるviewは不完全なものになるのでタスクはどうやったら完了なのかが曖昧なのがわかった T(Tsugiyarukoto) ペアプロ を通してタスクの完了ラインについて把握する メン ティー の 1on1 毎月メン ティー とリーダー層のエンジニアの間で 1on1 という対面振り返り MTG も実施しています。 1ヶ月において、行った作業と成長したところ、まだ抱えている問題を確認します。 目的は週次振り返りと同じで、仕事のやり方に対する問題の掘り出しと、改善アクションの提案です。 メンターと違う方が見ることで、メンターが見逃した問題を発見することもできれば、メンターに相談しにくい話も聞けます。 それに加えて、人事考課で設定した半期の目標の進捗も確認して、進捗が悪ければ、アクションプランを提案します。 カウンセリングという ストレスチェック も行って、作業量が多すぎるとか、最近成果が出せてないとか、ストレス要素の排除に努めます。 メンターのメンタリング メンタリングは制度だけではなく、メンターのスキルでもあるので、そのスキルが磨かれるようにメンターのメンタリングも行っています。 初めてメンターになる方の場合、最初のうちはメン ティー の週次振り返りに経験者も同伴します。 最初の会はその経験者が仕切ってメンタリングのやり方を見せますが、それ以降はメンターに任せて、サポートに徹します。 それとは別で、毎月現役メンターとメンタリングの経験者が MTG で集まります。 メンターによるメン ティー の話を通して、次にメンターが取るべきアクションをディスカッションします。 メンターのやり方に問題があるとわかれば、何に気をつけるべきか、どんな風に問題を解決すべきかと伝えて、アクションを取っていただきます。 軌道修正の意味合いが強くて、あくまで問題があれば指摘をして、それ以外はメンターに判断を任せます。 メンターも月次 1on1 を受けることがあるので、必要に応じてその場面でもメンタリングに対する助言をします。 学んだこと 当然かもしれませんが、メンタリングにおいても明確な目標を持った方がいいです。 メン ティー の課題を分析した上で目標を設定して、達成のためにアクションを取っていただいて、改善の経過を計測するのが重要です。 日々発生する細かい問題をスポットで解決するだけではメンタリングの本当の効果は得られず、メン ティー の成長に時間がかかってしまいます。 日々の作業の中で発生する表面的な問題を通して、メン ティー がかかえている根本的な課題を掘り出すのもポイントです。 特定の機能の ソースコード の場所がわからなくて、ずっと悩んでいて作業が進まなかったというのが問題であれば、課題は ソースコード の場所を覚えてないのではなく、調査方法に問題があるか、すべきだった相談をしなかったというところにあります。 そこからメン ティー とのディスカッションを通してより細かい原因を割り出して(迷惑をかけたくなかったので、相談をしなかったとか)、改善アクションを決めるのが適切だと思います。 ここで ソースコード の場所を教えるだけだと、問題は一時的に解決しますが、おそらく違う形でまた発生するので、根本的な解決にはならないです。 どの時点でメンタリングが不要なのかと基準を設けるのもいいでしょう。 試験とまで行かなくても、誰でも確認できる、共 通化 された基準があると、メンターとしてもメン ティー としてもやりやすくて、やる気も出ると思います。 最後に、メンタリングの目的とやり方はメンターの間でブレることがあるので、認識合わせをしっかりと行った方が安全です。 特にメンタリングの経験が少ない方だと、メンタリングと ティー チングの違いを把握しきれないことがあるので、時間を取ってゆっくりと説明した方がいいと思います。 メンタリングで行うことを明文化して、流用できるガイドを用意できると、ベストかもしれません。 終わりに エニグモ はもともと 中途採用 のみでしたので、メンタリング制度はありませんでしたが、新卒を積極的に採用することとなって、メンタリングの必要が現れて、どうやっていくか色々考える必要がありました。 メンタリングを通して、メンターがメン ティー の代わりに仕事をしてしまうとか、表面的な問題しか解決できずメン ティー のレベルが上がらないままでいるとか、望んでいたのとは違う結果になってしまうこともあるので、やり方に気をつけるべきです。 メンタリング制度を導入することで新卒の育成だけではなく、開発部門で振り返り文化が根付いて、メンタリングを受けてないメンバーの仕事のやり方もより早く改善するようになったと思います。 エニグモ に入った時にまだなかった文化ですが、未開拓地だった場所に色々道路と橋が建てられて、成長の場としてはよりいいところになったと思います。 株式会社 エニグモ すべての求人一覧 hrmos.co
こんにちは、インフラエンジニア の 加藤( @kuromitsu_ka )です。 今回は、Sambaのアクセス制御を DNS 名で実施したので必要だった設定を記載します。 エニグモ 社では、令和の今もオンプレミスでSambaを利用した古き良きログの集約サーバが稼働しています。この度、オンプレミスのログサーバと同じ構成のものを AWS に構築することになりました。その際、Sambaのアクセス制御で少し工夫した部分があったので、ログを残します。 エニグモ 社のログ集約サーバの仕組み ログサーバからアプリサーバごとに ディレクト リを作成して、Sambaインストール済みのサーバをログサーバからマウントすることでログを集約しています。インフラチームでない開発者は、基本的にサーバへ SSH できないので、ログサーバだけアクセスを許可することで、ログを確認できるようにしています。 Sambaのアクセス制御を DNS 名で設定する動機 オンプレミスのSambaのアクセス制御は、公開 ディレクト リごとにIPセグメントやログサーバのIPを指定してアクセス許可設定しています。オンプレミスのサーバでは、プライベートIPが固定でしたが、 AWS では、サーバが再作成されても大丈夫なように、 DNS 名でアクセス制御することにしました。 オンプレミスでのSambaアクセス許可設定 hosts allow = ログサーバのIPや、本番環境のIPセグメント AWS では、SGでアクセス制御をしてもよかったのですが、運用上が面倒なのでSambaの設定でアクセス制御することとなりました。 AWS での理想のSambaアクセス許可設定 hosts allow = ログサーバのホスト名 Sambaサーバの DNS 名でのアクセス制御に必要だった設定 ログサーバからマウントされるアプリやDBのサーバ(Sambaサーバ側)ではレコード引きを許可する設定と、 ホワイトリスト 設定が必要で、ログサーバ(Sambaクライアント側)では、ログサーバの逆引きレコードが必要でした。 必要だった設定(Sambaサーバ側) ホスト名のIPをレコード引きを許可する設定が必要でした。 ホスト名検索の許可 dns proxy = yes hostname lookups = yes ホワイトリスト 設定 hosts allow = ログサーバのドメイン名 必要な設定(Sambaクライアント側) Sambaのアクセスには、PTRレコードが必要でした。 CloudFormationでログサーバ作成と同時に逆引きレコードも設定できるようにしました。 RecordSetPtr : Type : AWS::Route53::RecordSet Properties : HostedZoneId : ${PTRレコードホストゾーン} Type : PTR Name : !Sub - ${FourthOctet}.${ThirdOctet}.${SecondOctet}.${FirstOctet}.in-addr.arpa - FirstOctet : !Select [ 0 , !Split [ "." , !GetAtt Instance.PrivateIp ]] SecondOctet : !Select [ 1 , !Split [ "." , !GetAtt Instance.PrivateIp ]] ThirdOctet : !Select [ 2 , !Split [ "." , !GetAtt Instance.PrivateIp ]] FourthOctet : !Select [ 3 , !Split [ "." , !GetAtt Instance.PrivateIp ]] ResourceRecords : - !Sub - ${良きホスト名} TTL : 300 デバッグ ログ Sambaサーバの DNS 名でのアクセス制御に、逆引きレコードが必要となった際のログです。 PTRレコードがない状態でのアクセス Sambaクライアント側からだと弾かれてしまいます。 [root@SambaClient ~]# mount.cifs //${Sambaサーバ}/test test -o vers=3.0,password=,dir_mode=0755 -vvv mount.cifs kernel mount options: ip=10.195.101.57,unc=\\10.195.101.57\syslog,vers=3.0,dir_mode=0755,user=root,pass=******** mount error(13): Permission denied Refer to the mount.cifs(8) manual page (e.g. man mount.cifs) Sambaサーバ側のログ IPベースで制御していそうでした。「matchname failed on 10.195.100.9」 ※この際、SambaクライアントのIPは 10.195.100.9 Denied connection from 10.195.100.9 (10.195.100.9) [2022/04/11 16:44:43.212303, 0] ../../source3/smbd/server.c:1788(main) smbd version 4.10.16 started. Copyright Andrew Tridgell and the Samba Team 1992-2019 [2022/04/11 16:44:43.266814, 0] ../../lib/util/become_daemon.c:136(daemon_ready) daemon_ready: daemon 'smbd' finished starting up and ready to serve connections [2022/04/11 16:44:45.916505, 0] ../../lib/util/access.c:365(allow_access) Denied connection from ip-10-195-100-9.ap-northeast-1.compute.internal (10.195.100.9) [2022/04/11 16:45:17.430789, 0] ../../lib/util/access.c:365(allow_access) Denied connection from ip-10-195-100-9.ap-northeast-1.compute.internal (10.195.100.9) 逆引きレコードのホスト名で、弾かれていることが判明しました。 # nslookup 10.195.100.9 9.100.195.10.in-addr.arpa name = ip-10-195-100-9.ap-northeast-1.compute.internal. Authoritative answers can be found from: 動作確認 DNS 名で許可しているサーバからのみ、Sambaマウントできることを確認します。 許可しているログサーバの DNS 名は、 logserver です。 Sambaサーバの許可設定 [root@SambaServer ~]# cat /etc/samba/smb.conf [global] : dns proxy = yes hostname lookups = yes : include = /etc/samba/smb.d/test.conf [root@SambaServer ~]# [root@SambaServer ~]# [root@SambaServer ~]# cat /etc/samba/smb.d/test.conf [test] : hosts allow = 127. logserver 逆引きを設定していおらず、アクセス許可もされていない他のクライアントからだと、Sambaマウントできない。 [root@NotAllowedSambaClient ~]# hostname -I 10.195.100.9 [root@NotAllowedSambaClient ~]# [root@NotAllowedSambaClient ~]# [root@NotAllowedSambaClient ~]# nslookup 10.195.100.9 9.100.195.10.in-addr.arpa name = ip-10-195-100-9.ap-northeast-1.compute.internal. Authoritative answers can be found from: [root@NotAllowedSambaClient ~]# [root@NotAllowedSambaClient ~]# [root@NotAllowedSambaClient ~]# mount.cifs //${Sambaサーバ}/test test -o vers=3.0,password=,dir_mode=0755 -vvv mount.cifs kernel mount options: ip=${Sambaサーバ}/,unc=\\${Sambaサーバ}/\test,vers=3.0,dir_mode=0755,user=root,pass=******** mount error(13): Permission denied Refer to the mount.cifs(8) manual page (e.g. man mount.cifs) 逆引きレコード設定済みのアクセス許可のあるログサーバ( logserver )からだと、Sambaマウントできる。 [root@logserver ~]# hostname -I 10.195.116.243 [root@logserver ~]# [root@logserver ~]# [root@logserver ~]# nslookup 10.195.116.243 243.116.195.10.in-addr.arpa name = logserver.honyarara.com. Authoritative answers can be found from: [root@logserver ~]# [root@logserver ~]# [root@logserver ~]# mount.cifs //${Sambaサーバ}/test test -o vers=3.0,password=,dir_mode=0755 -vvv mount.cifs kernel mount options: ip=${Sambaサーバ},unc=\\${Sambaサーバ}\test,vers=3.0,dir_mode=0755,user=root,pass=******** [root@logserver ~]# [root@logserver ~]# [root@logserver ~]# df -h ファイルシス サイズ 使用 残り 使用% マウント位置 : //10.195.101.57/test 50G 19G 32G 38% /root/test 感想 今回は、古のシステムを触ったので供養ブログとなりましたが。 事例がパッと見つからない課題は、毎回取り組むのが楽しいです。 困った時は、ドキュメントを読むのが大事ですね。 株式会社 エニグモ すべての求人一覧 hrmos.co
こんにちは! 株式会社 エニグモ に22年新卒入社しました橋野です。 サービスエンジニアリング本部で BUYMA のサービス開発を担当しています。 今回の記事では、 エニグモ への入社理由についてお話ししようと思います。 目次 わたしとは? コロナ禍のエンジニア就活 内定承諾を決めた3つの理由 エニグモのサービス 世界を変える新しい流れを エニグモで働く人 おわりに わたしとは? まずは簡単に私について自己紹介できればと思います。 学生時代は ハッカソン が好きで、たくさん ハッカソン に出場したり、また私自身もプログラミングの団体に所属しており ハッカソン を主催したりしたこともありました。 ハッカソン にたくさん出場するようになったきっかけは、人数合わせで初めて出た ハッカソン で悔しい思いをしたので、なんとかリベンジをしたいと思ったからです。たくさん出るうちに楽しくなっていき、どんどんのめりこみました。 テックイベントに参加するのも好きで、コロナ禍の前はよく学校終わりに勉強会やLT会などにも積極的に参加していました。 エニグモ でも勉強会がほぼ毎週開催されているので、参加しています。 実は、元々小さい頃から機械が好きで、小学生の頃からロボットをいつか作ってみたいなと思っていました。大学3年生のときに、 マイコン を購入し、おもちゃを趣味でつくったこともあります。そういうところも、 ハッカソン やプログラミングに興味を持つきっかけになったかもしれないです。 コロナ禍のエンジニア就活 大学3年生にあがったくらいで就活を意識し始めました。 新卒エージェントサービスを使ったり、 Wantedly や逆求人イベント等のエンジニア向けのサービスを使ったりしてたくさんの企業を見ました。 勤務拠点が東京の会社を希望していたので、オンラインメインの就活は関西に住んでいた私にとって長距離の移動が少なく活動しやすい環境だったと思います。 ただ、自宅から面接を受けていたので、面接中は家族に協力してもらったりと気を遣わすこともあり、家族は大変だと思います。 また、友人にESを添削してもらったり、就活の相談に乗ってもらったりしました。 家族や友人の協力があってこその就職活動だったと思います。 エンジニア就活で色々と焦りや不安を抱えることはあったのですが、妥協せずに最後の最後まで就活をしました! 内定承諾を決めた3つの理由 選考を受けるまで、 BUYMA で1回買い物をした程度で エニグモ が BUYMA を運営していることは知りませんでした。 エニグモ との出会いは就活をしている時に、たまたま エニグモ で働いているエンジニアをフォローしており、 中途採用 募集のツイートを見かけました。 また、今までのツイートから エニグモ のリアルを事前に知ることができ安心感がありました! 選考のスピードは他社と比べて圧倒的に早く、そこもプラスの点でした。 私が最終的に、 エニグモ へ内定承諾を決めた理由は下記の3つとなります。 エニグモ のサービス ECサービスが好きなので、サービス開発からユーザーの売り買いに携われたらいいなとぼんやり考えていました。 ネットショッピングは見ているだけで楽しく、ワクワクするところやサービス自体がユーザーに商品を買わせようと工夫しているところが面白いです。 わたしはより快適に買い物ができたり、新しい出会いがうまれる機会を提供できるサービスの開発をできるようになりたいと就活のサービス選びの軸として1つ持っておりました そんな時に、見かけた BUYMA の開発ができる求人に迷わずにここだ!と思い応募しました。 Twitter で見かけた求人は 中途採用 のものだったのですが、中途しかなくてもとりあえず応募しようという覚悟でした。 そんな思いとは裏腹に エニグモ は新卒も通年採用をやっていたので、どの時期に選考を受けても歓迎してくれました。 世界を変える新しい流れを わたしは、大学生3年生の頃に「新しい価値」を提供できるようになりたいと思いました。学生の頃は学生なりに取り組んでいましたが、社会人になっても会社を通してもっと大きなことに挑戦したいと考えていました。 エニグモ には、「世界を変える新しい流れを」というミッションをかかげており、 そのミッションに共感し、 エニグモ で新しい価値を提供していきたいと思っています。 「世界を買える」と「世界を変える」をかけているらしく、おもしろいですよね。 エニグモ で働く人 エニグモ で働いている人は、やさしい人が多いです! 面接や面談でも私自身に興味を持ってくださり、知ってくれようとしたことが印象的でした。また、自分を着飾るのではなく、正直に話したときに受け止めてくださったことが嬉しかったです。 入社後も部署関係なく交流ができたり、登山が好きな人がいたり、楽しい人が多いです。 (登山は、誘っていただきましたが運動不足ということもあり少しハードルが高くてまだ参加できていませんが...) ファッションECというだけあって、スタイルハウス編集部や BUYMA のMDの方々はとてもおしゃれな方が多いなと思いました。(エンジニアはおしゃれやファションに興味がそこまである人ばかりではないので安心してください。) おわりに 現在は OJT を受けながら BUYMA の開発をしています。自分自身早く現場に入って開発をしたいと思っていたので、楽しく、刺激のある毎日を送っています。 まだまだメンターのサポートありきで、開発しているので早くチームの力になれるようにたくさん吸収していこうと思います。 登山好きな人は多いのですが、 ボルダリング が好きな人は少ないのでぜひ ボルダリング に興味がある方もお待ちしています!笑 エニグモ に興味ある方は、下記募集チェックお願いします。 新卒採用も通年採用で募集しております。 株式会社 エニグモ すべての求人一覧 https://hrmos.co/pages/enigmo/jobs
はじめまして! 2022年4月に エニグモ へ新卒入社した川本です。早いもので入社して2か月がたちました。 この記事では、コロナ渦での就活についてや、なぜエンジニアを目指したのか、そしてなぜ エニグモ に入社を決めたのかについて書いていこうと思います。 新卒でエンジニアを目指している方、 エニグモ に興味を持っている方へ、少しでも参考になれば幸いです。 目次 自己紹介/エンジニアを目指したきっかけ 就職活動について コロナ禍での就活で大変だったことや気を付けたこと エニグモの採用(説明会・面接・面談)への印象 エニグモに入社した理由 入社して2ヶ月たち感じること 今後の抱負 最後に 自己紹介/エンジニアを目指したきっかけ 2021年12月から インターン として エニグモ で働いており、2022年4月に新卒入社しました。 サービスエンジニアリング本部に所属し、海外通販サイト『 BUYMA 』のWebアプリケーション開発に携わっています。 大学時代はア マチュア キックボクサーとして活動していたのですが、骨折して動けない期間に暇になり、家の中でもできる何か新しいことを始めようと思い、はじめて自分でパソコンを買いました。 それまでは、実はマイパソコンすら持っておらず、大学のパソコンルームでレポートなどを書いていました... 最初はこれから研究室の配属もあるし、パソコンスキルを身につけようかといった考えで購入しました。 大学の 数値計算 の講義で、 Fortran という プログラミング言語 に触れたことや、大学院に新設されたAIのコースを知って、プログラミングやITに少し興味を持ったことをきっかけに、ドットインストールなどのオンライン学習サービスでプログラミングの勉強をするようになりました。 とはいっても、私は大学で 海洋学 を専攻していてITとは無縁な所にいたので、この時はまだエンジニアになろうとは全く考えていませんでした。 その後も個人で学習は継続して、大学3年の夏に初めてWEB系企業の インターン で開催していた ハッカソン に参加しました。この ハッカソン はランダムに組まれた3人チームで行い、自社の API を使ってWEBアプリケーションを作るといった内容でした。 初めての ハッカソン の参加でしたが、チームメンバーにも恵まれて最優秀賞をいただくことができました。 この時初めて自分達で考えたア イデア をサービスにして、そのサービスを使ってもらいフィードバックをもらうという経験をしたのですが、この体験にとてもやりがいを感じることができ、エンジニアとして仕事がしたいと思うようになりました。 就職活動について コロナ禍での就活で大変だったことや気を付けたこと この記事を読んでいただいている、就活生の皆さんにとっては既にリモート就活が一般的かもしれませんが、私の感じたリモート就活のメリット、デメリット、気をつけたほうがいいことを紹介できればと思います。 メリット 企業に足を運ぶ必要がないため、一日に複数社の選考を受けることができます。 交通費の節約になる。特に地方の学生は、IT系などの東京に集中している企業は受けやすくなったと思います。 大学と就活の両立がしやすい。大学にいながら研究の合間に面接を受けることができるのはとても助かりました。 デメリット 会社や面接官の雰囲気がわかりにくい。 自分の意見が相手に伝わっているかどうかわかりにくい。 気をつけたこと デメリットに挙げた通り、リモートだと会社や面接官の雰囲気がわかりにくいことがあると思います。 最初のカジュアル面談や一次面接はリモートでいろんな企業を受けることに非常にメリットを感じましたが、選考が進めばどこかのタイミングで対面での面接の機会を設けることをおすすめします。 実際にオフィスを見学したり、働いている社員の方々を見ることで感じることも多いと思います。 私は内定承諾する際は、内定先の企業に実際に訪れるようにしていました。その中で エニグモ の雰囲気が一番自分にあっていると感じて内定承諾しました。 エニグモ の採用(説明会・面接・面談)への印象 就活を始めた初期に エニグモ の求人をたまたま見つけて、そこで初めて BUYMA を運営している企業なのだと知りました。 BUYMA のことは以前から知っていて、使ったこともあったので、まずはお話を聞いてみようといった感覚で応募しました。 エントリー後は、人事面談、一次面接、二次面接、最終面接といった選考フローで進んでいきました。 エニグモ の採用で驚いたことは、一次面接からエンジニア部門の部長やマネージャーの方に面接していただけることです。 他社では一次面接は人事、二次面接では現場のエンジニアといったケースが多かったため、珍しいなと感じました。 内定後も新卒で エニグモ に入社したエンジニアの方との座談会の機会を設けていただきました。同年代の方にざっくばらんに質問することができて、自分の中で最終確認することができました。 エニグモ に入社した理由 私が エニグモ へ入社を決めた理由は、大きく三つあります。 一つ目は、CtoCのサービスを扱っていることです。私は大学で 海洋学 を専攻していたため一次産業が身近で、生産者と消費者を繋ぐプラットフォームについて興味がありました。 BUYMA はファッションをメインに扱っていて一次産業とは異なりますが、ユーザーとユーザーを繋ぐCtoCという面でシステム的に近いプラットフォームであったため、 BUYMA の開発をしてみたいと思いました。 二つ目は、自分の興味や、やりたいことを尊重してくれるところです。私は学生時代はデータ基盤の開発しかほぼやったことがなく、アプリケーションの開発はあまりやったことがありませんでしたが、アプリケーションの開発がやりたいと伝えたところ柔軟に受け入れてくださいました。 三つ目は、 エニグモ の社員の人たちの雰囲気がいいなと思ったからです。選考を通して、決まった質問をする感じではなく丁寧に私のことを考えて質問してくださっている印象があり、一緒に働きたいと思える方が多かったです。 入社して2ヶ月たち感じること 入社前から抱いていたイメージと大きく違うことはありませんでした。 ただ、想像していた以上に BUYMA は大きなシステムだなと思いました。 当たり前かもしれませんが、これまで私が ハッカソン や個人で開発していたシステムとは ソースコード の量が全然違い、理解するのが大変です。 しかし、大きなシステムである分知らないことがたくさんあるため、毎日新しい学びがあり成長を実感できるため楽しく開発ができています。 今後の抱負 まずは目の前の業務をしっかりと一人でこなせるようになりたいです。 今はまだ経験が浅いので、いろんな分野を経験して、自分の興味がどこにあるのかを見つけて、その分野に強みを持てるようになっていきたいです。 また言われた通りに開発するだけでなく、しっかりと自分の意見を持ちサービスをより良くするためにどうするべきか考えて実装できるエンジニアになりたいと思っています。 最後に 今はエンジニアが人気職業になって世の中に様々な情報があふれているため、エンジニアを目指す就活生にとっては、何が正しいのか中々判断がつきにくいと思います。 私も非情報系学部の学生だったためその一人でした。 そんな私が就活を通して大切だと感じたのは、 ハッカソン や インターン に参加して同じ学生のエンジニア仲間を作ったり、現役のエンジニアと交流することです。 周りの同じエンジニア志望の学生が何をしているのか、現役のエンジニアはどのようにしてエンジニアになったのかを知ることで、自ずと自分に今何が足りなくて、これから何をすればいいのかわかってくると思います。 またそういった仲間がいると技術の話や就活の話を共有できるため、楽しく学習を継続することができてモチベーションも保てると思います。 最後までお読みいただきありがとうございます。 株式会社 エニグモ すべての求人一覧 hrmos.co
こんにちは、インフラエンジニア の 加藤( @kuromitsu_ka )です。 今回は、 Amazon Aurora のポイントインタ イムリ カバリ(特定時点へのリストア)を触ったので、記事を残します。 概要 Auroraのバックアップ保持期間内であれば、特定の時点のデータで、DB クラスタ を作成できる機能があり、これが便利でした。 DB クラスタ の作成にかかる時間と、DB作成時にどこまで正確にデータを復元できるか確認したので、そのまとめを記載します。 ※手順の方は、ドキュメントに記載あるので割愛します。 ざっくりよかったこと バックアップ保持期間であれば、秒単位で指定した時点でDB クラスタ を作成できる。 運用中のDBを切り戻すのでなくDBを新規作成するため、現行DBに手を加えなくて良い。 ちょっと細かいところ。 Auroraは、 フルバック アップと合わせて、 トランザクション データも保存しています。 一番早くて、最新時間の5分前の時間で、DB クラスタ を作成できる模様でした。 ※切り戻せる時間の範囲については、 describe-db-clusters  から確認できます。 参考になる公式ドキュメント 特定の時点への DB clusterの復元 Aurora DB クラスターのバックアップと復元の概要 検証したこと ざっくり2つ確認しました。 DB クラスタ 再作成にかかる時間の計測 切り戻し時点の前後の トランザクション データの正確性の確認 (検証1)DB クラスタ 再作成にかかる時間の計測 Aurora クラスタ のステータスが、作成中から使用可能になるまでの時間を確認しました。 モニタリング用に、Aurora クラスタ のステータス確認 スクリプト も作成しました。 $ cat check.sh #!/bin/bash while true do echo $( date + " %Y%m%d %H:%M:%S "; aws rds describe-db-clusters --db-cluster-identifier $1 | jq -r " .DBClusters[].Status " ) sleep 1 done 結果としては、以下のようになりました。 積んでいるデータが大きいと、そこそこ時間はかかりそうなものの、まぁ大丈夫かと。 データ 所用時間 インスタンス タイプ データのサイズ 開発環境データ 15分程度 db.t3.small(vCPU:2,メモリ:2GiB) 30GB 本番環境データ 27分程度 db.r6g.4xlarge(vCPU:16,メモリ:128) 160GB おまけの計測 Auroraのリストアも、 フルバック からリストア後、差分適用してるのかな?と思い。 開発環境にて、 フルバック アップ取得時間を軸に、ざっくり2パターンで検証しました。 結果として、特に大差はなかったです。 Auroraの フルバック アップ取得から、1時間経過した時点のデータでDB作成した場合 →約13分30秒 Auroraの フルバック アップ取得より、1時間前(23時間経過した)の時点のデータでDB作成した場合 →約14分00秒 (検証2)切り戻し時点の前後の トランザクション データの正確性の確認 切り戻したい時間帯に発生していた トランザクション のデータは、ちゃんと復元できるのか確認しました。 検証の結果 リストアでデータが正確に復元できないのは、リストアで指定する時間の前後1秒間にコミットされていない トランザクション だけでした。 具体的な検証方法 スクリプト でINSERT,UPDATEを流して、 トランザクション を発生させました。 スクリプト 実行中の時間を指定して、DB クラスタ を作成して起動後のデータを確認しました。 検証ログ データの追加時間・更新時間がわかるように、こんな感じのテーブルを作成して トランザクション を発生させました。 +------------+-------------+------+-----+-------------------+-----------------------------+ | Field | Type | Null | Key | Default | Extra | +------------+-------------+------+-----+-------------------+-----------------------------+ | id | int(11) | NO | PRI | NULL | | | comment | varchar(20) | YES | | NULL | | | created_at | timestamp | NO | | CURRENT_TIMESTAMP | | | updated_at | timestamp | NO | | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP | +------------+-------------+------+-----+-------------------+-----------------------------+ スクリプト のINSERT,UPDATE部分 外部のサーバから、任意の数の トランザクション を発生させる スクリプト です。 ※DELETEも流していた時の名残もありますが、こちらはスルーでお願いします。 for i in $(seq ${NUMBER_OF_QUERIES_INSERT_and_UPDATE}) mysql -h $RDS -u${user} -p${password} -e "INSERT INTO ${TABLE_NAME} (id, comment) VALUES (${i},\"insert${i}\");" mysql -h $RDS -u${user} -p${password} -e "UPDATE ${TABLE_NAME} set comment=\"update${i}\" where id=${i};" # if [ ${i} -lt ${NUMBER_OF_QUERIES_DELETE} ] || [ ${i} -eq ${NUMBER_OF_QUERIES_DELETE} ]; then # mysql -h $RDS -u${user} -p${password} -e "DELETE FROM ${TABLE_NAME} WHERE id = ${i};" # fi done echo $(date "+%H:%M:%S") Script END >> ${STATUS_FILE} スクリプト の出力するステータスファイルから開始終了時間を確認 # cat /tmp/status.txt 2022-01-31 11:58:21 Script START 2022-01-31 21:52:14 Script END DB クラスタ ー作成 スクリプト 終了間際の、2021/01/31 21:52:00に切り戻します。 リストア後のテーブル 2021/01/31 21:51:59秒までのデータは、問題なく切り戻せていました。 mysql> select * from bm_messages.AWSNEXT_1215 ORDER BY id desc limit 5; +--------+--------------+---------------------+---------------------+ | id | comment | created_at | updated_at | +--------+--------------+---------------------+---------------------+ | 379369 | insert379369 | 2022-01-31 21:51:59 | 2022-01-31 21:51:59 | | 379368 | update379368 | 2022-01-31 21:51:59 | 2022-01-31 21:51:59 | | 379367 | update379367 | 2022-01-31 21:51:59 | 2022-01-31 21:51:59 | | 379366 | update379366 | 2022-01-31 21:51:59 | 2022-01-31 21:51:59 | | 379365 | update379365 | 2022-01-31 21:51:59 | 2022-01-31 21:51:59 | +--------+--------------+---------------------+---------------------+ 5 rows in set (0.01 sec) 感想 DBを切り戻すんじゃなくて、別途作成してくれるところがいいなぁって思いました! 株式会社 エニグモ すべての求人一覧 hrmos.co