こんにちは。Ltech運営チームの河西です。今回は、2021年7月13日(火)に開催した「Ltech#18 AIで住まい探しをスムーズに!【おとり物件予測&3D間取り】」についてレポートします。 lifull.connpass.com Ltechとは Ltech(エルテック)とは、LIFULLがお送りする、技術欲をFULLにするイベントです。特定の技術に偏らず、様々な技術の話を展開していく予定です。 AIで住まい探しをスムーズに Ltech#18のテーマは、住まい探しをより便利にするためのAIを使った取り組みです。LIFULLでは2018年よりAI戦略室を立ち上げ、「創造と革進で喜びを届ける」をビジョンに掲げ、様々な取り組みを行ってきました。今回はその中でも 物件間取り図の3D化 おとり広告予測モデルの開発 といった内容の取り組みを語ってもらいました! それではさっそく発表レポートに行きたいと思います。 3D間取りを支える技術 最初は3D間取りを支える技術の発表です。 3D間取りを支える技術 from LIFULL Co., Ltd. www.slideshare.net 3D間取り図とは、LIFULL HOME'Sにおける2次元の間取り図をディープラーニング技術の活用により、画像認識・ポリゴン化して3Dモデルとして可視化し、より実際の物件に近い形で見ることができるサービスです。 これにより、従来1件あたり数万円の作成コストがかかっていた3Dモデルを安価・大量に生成ができるようになるようになりました。 ※3D間取りはこちらから実際に体験できます! https://www.homes.co.jp/3dmadori 次にそんな3D間取り図サービスを支えている技術を見ていきます。 3D間取りを支える技術は非常に広範囲に渡っています。特に、LIFULLでの全社アプリケーション実行基盤である「KEEL」を活用することにより、AIに特化したエンジニアでもシステム構築の負荷が軽減され、サービスの早期リリースが実現できたとのことです! ※KEELは過去CreatorsBlogでも紹介しています。 www.lifull.blog 次に間取り図画像の認識や、工夫しているポイントについてです。 間取り画像の認識については、3つの層に分け出力を行い、3Dモデル化しているそうです。3Dモデルとして可視化する際にも工夫している点として、 3Dモデル内の移動を簡単にするために、ポリゴン化したデータに移動点を作成して、移動データを付与 2次元間取り図内に浴室やトイレといったアイコンがない場合でも、独自のルールで設置し、可視化 などといった点についても話してもらいました。 最後に今後の展望については360度カメラを使ったフォトグラメトリの活用・家具配置シュミレートなども実現していきたいと語ってもらいました。 3D間取り図の開発には2~3年を要し、データの収集に苦労したり、機械学習モデルを何度も変更したりと、このような素晴らしいサービス誕生の裏には絶え間ない努力があるのだと感じました! LIFULL HOME'Sのおとり広告予測モデルの開発 続いておとり広告予測モデルの開発の発表です。 LIFULL HOME'Sのおとり広告予測モデルの開発 from LIFULL Co., Ltd. www.slideshare.net おとり広告とは、LIFULL HOME'S上で「成約済み物件の広告の消し忘れ」や「呼び込みのための架空物件の広告」など実際には契約ができない物件広告が存在している状態です。おとり広告があることにより、ユーザーは安心して住まい探しができないといった問題があります。LIFULL HOME'Sでは、 専属の情報審査チームによる能動調査 不動産管理会社とデータ連携 掲載110番 といった形でおとり広告をなくす取り組みを行っていますが、今回は「専属の情報審査チームによる能動調査」にAIを取り込み、募集終了物件の特徴を学習させて、募集終了確率を予測するAIを開発しました。 次に実際の能動調査の流れやAI学習から調査対象予測までの流れを見ていきます。 従来の専属の情報審査チームによる能動調査では審査チームが一定のルールに基づいて、調査対象物件リストを調査しています。そのため ルールでは選定できない物件がある ルールの複雑化への対応が難解 などの問題がありました。 AIを用いた機械学習フローの導入では、一定ルールに基づいた物件リストデータを用いますが、今度はAI学習用データに偏りが生じ、結果的に募集終了確率の精度が悪化してしまう問題が発生しました。そこで、精度を向上させるために、一定ルールではなく、無作為にデータを抽出することで、偏りをなくし、学習モデルの精度を向上させる取り組みを行ったそうです。 また、このようなモデル開発を効率的に行うための工夫として、BigQueryを用いたデータ加工、AutoML Tablesでの学習自動化、一連の流れをAirflowでスケジューリングし、機械学習フローを全自動化する効率化も合わせて行ったとのことでした! 最後に、おとり物件をゼロにすることが最終的な目標と語ってもらい、ユーザーがより安心して住まい探しができる未来の実現に向けて、素晴らしい取り組みだと感じました! まとめ 今回はAIを用いて住まい探しをよりスムーズにするための取り組みをお二方に発表してもらいました。今回発表されたもの以外にもAI戦略室では様々な施策を計画中とのことで、今後どのようなサービスが出てくるのか非常に楽しみです! 最後に Ltechでは、LIFULLエンジニアが中心となって皆様の技術欲を満たすよう実例を交えた勉強会を開催しています。今後も Ltech を積極的に開催していきますので、ぜひ気になった方は、connpass で LIFULL のメンバー登録をよろしくお願いします! lifull.connpass.com
こんにちは! KEEL チームの花塚です。 最近一番驚いたことは、OPA Gatekeeperの「OPA」を「オーパ」と発音するらしいということです。 さて今回は、OPA GatekeeperやConftestなどを用いてKubernetesのセキュリティ面を強化した話です。 以前からチームメンバー全員がセキュリティに気を配っているものの、今まで対策していることが妥当なのか、考慮漏れはないだろうかということを定期的に確認する機会がありませんでした。 闇雲に対策せず一度自分たちの対策を見直し、継続的にセキュリティを向上していける仕組み作りの過程をお伝えできればと思います。 目次 目次 解決したかった課題 OPA Gatekeeperとは Pod Security Policyの廃止 Kubernetesへの脅威 本番環境に導入するまで GatekeeperとConftestで使用するRegoを同期させる ConstraintとConstraintTemplateをクラスタへ適用する GatekeeperとConftestのテスト CIの形骸化を防ぐ おわりに 解決したかった課題 改めてセキュリティ対策を進める上で解決したい課題がありました。 それは「マニフェストの監査が自動化できていない」ことです。 KEELはマルチテナント構成をとっており、各サービスのマニフェストを一つのクラスタにデプロイします。 人力で各サービスのマニフェストのチェックすることは、不適切な設定・悪意のある設定の見落としなどが発生する可能性がありましたし、そのようなマニフェストをデプロイできない仕組みが必要でした。 結論としてOPA GatekeeperとConftestを採用しており、この後に詳しく紹介します。 OPA Gatekeeperとは 解決したい課題でも触れたように、結論としてはOPA Gatekeeperを採用しました。ここでは簡単にOPA Gatekeeperについて紹介します。 OPA Gatekeeper(以降、Gatekeeper)は、KubernetesのAdmission Controllerとして動作し、アンチパターンなマニフェストのデプロイの禁止などを可能にするカスタムコントローラーです。 github.com 以下の例では、 Constraint と ConstraintTemplate のCustom Resourceをデプロイすることで hostPID: true であるPodのデプロイを禁止することができます。 package deny_host_pid violation[msg] { input.review.object.spec.hostPID msg := sprintf( " Sharing the host pid is not allowed: %v " , [input.review.object.metadata.name]) } 上記の例でも分かる通り、Gatekeeperは、内部でポリシーエンジンである Open Policy Agent を使用しているためポリシーの記述にRegoを使用します。 強い権限を用いているマニフェストのデプロイを禁止するなど、セキュリティ面でも活用できますが、Istioの VirtualService や Gateway の衝突を防ぐなど、さまざまなユースケースを実現することができます。 余談ですが、Regoを使うことで汎用的にポリシーを記述することができる一方、「学習コストが高そう」 、「少し苦手」という方がいるかもしれません。 最近ではRegoの学習への課題を解決するために、ポリシーをyamlで記述できるKubernetes NativeなKyvernoが開発されています。 github.com Pod Security Policyの廃止 Kubernetesクラスタのセキュリティ面を強化していく意思決定をした際、まず最初に解決策として候補に上がったのが Pod Security Policy です。 PodSecurityPolicy を使うことで、Privileged containerのデプロイなど、セキュリティ的に好ましくない行動を制限することができます。 しかし PodSecurityPolicy は、Kubernetes v1.21から非推奨となり、v1.25からは廃止となることが発表されました。 github.com 先ほど紹介したようにGatekeeperは、さまざまなポリシーを記述することができます。 PodSecurityPolicy でできることは、多くのことがGatekeeperでも実現可能です。 実際にGatekeeperのlibraryでは、 PodSecurityPolicy をRegoで記述した サンプルコード が置かれています。 KEELでは、以前からGatekeeperを使っていることや廃止されることを考慮して、 PodSecurityPolicy の代わりとなるものをRegoで記述する意思決定を行いました。 また、Gatekeeperと似たような用途として使える Conftest というツールがあります。 Gatekeeperは実際にクラスタ内でリソースが違反していないかを動的にチェックしますが、一方Conftestは、Kubernetesのマニフェスト(マニフェスト以外にも対応しています)が違反していないかを静的にチェックします。 ConftestをCIに組み込むことで、デプロイ前にマニフェストがポリシーに違反してないかを確かめることが可能です。 ConftestもGatekeeperと同様にポリシーをRegoで記述するため、Gatekeeperとセットで採用しています。 ちなみに PodSecurityPolicy は廃止されるようですが、今後は PodSecurity admission が PodSecurityPolicy の代替となるようです。 Kubernetesへの脅威 Kubernetesに限らずセキュリティ対策を行う場合は、まずは「脅威を知る」ということが重要になります。 最初はKubernetesのセキュリティの全体感を、以下のような記事を読んで把握することをおすすめします。 クラウドネイティブセキュリティの概要 | Kubernetes Matrix - Enterprise | MITRE ATT&CK® Threat matrix for Kubernetes NIST SP 800-190 今回Kubernetesのセキュリティ対策を考える上で参考にしたのが、Kubernetesを対象とした以下の脅威モデリングのレポートです。 github.com このレポートは2020年1月に作成されているので少しだけ古いですが、一般的なKuberentesクラスタを対象とした主なAttack Vectorを把握することが可能です。 またAttack Treeもレポートに含まれており、ある攻撃を達成するための大まかな道筋を把握することもできます。 例えば以下の「Malicious Codeの実行」に関するAttack Treeでは、Privileged containerを利用したステップなどが必要であるということが分かります。 引用: https://github.com/cncf/financial-user-group/blob/master/projects/k8s-threat-model/AttackTrees/MaliciousCodeExecution.md このように攻撃の目的を達成する道筋を把握することで、「Privileged containerのデプロイを禁止する」など具体的な対策を考案することができます。 AWSやGCPなどのクラウド上でKubernetesを運用している場合は、「使用している権限(IAM Userなど)でどこまで悪用できるのか」を考慮するなど、自分たちの環境と照らし合わせて対策を考えることが大切です。 このように簡単に脅威を洗い出すだけでも、対策への妥当性を説明できることやコストに見合った対策を優先して取り組めると思います。 本番環境に導入するまで さて、ここからはセキュリティ対策を本番環境へ導入するまでの過程について書いていきたいと思います。 GatekeeperとConftestで使用するRegoを同期させる ConftestとGatekeeperで同じ内容のポリシーを記述する場合でも、以下の理由からRegoを併用することができません。 少しだけ文法に差異がある Gatekeeperでは ConstraintTemplate に直接Regoが埋め込まれる GatekeeperとConftestのRegoが別々で管理されるということは、どちらか一方を変更した場合、もう一方のRegoも変更しなければなりません。それは不便ですよね。 そこでKEELチームでは、GatekeeperとConftestのRegoを併用するためにkonstraintを導入しました。 github.com ここでは詳しく説明しませんが、konstraintの library を使用することで、GatekeeperとConftestのRegoの差異を吸収してくれます。 以下がkonstraint用に書き換えたポリシーです。 core や pod ライブラリをimportしています。 package deny_host_pid import data.lib.core import data.lib.pods policyID := " P1000 " violation[msg] { pod_has_hostpid msg := core.format_with_id(sprintf( " %s/%s: Sharing the host pid is not allowed " , [core.kind, core.name]), policyID) } pod_has_hostpid { pods.pod.spec.hostPID } ポリシーを記述した後に、以下のコマンドを実行すれば Constraint と ConstraintTemplate が生成されます。 $ konstraint create <policy_dir>. 現在はkonstraintとGithub Actionsを併用することでRegoのファイルを更新しただけで、自動で Constraint , ConstraintTemplate のファイルを生成・更新するようにしています。 ConstraintとConstraintTemplateをクラスタへ適用する Constraint と ConstraintTemplate を何も考えずにクラスタに適用してしまうと、意図していないリソースまでも影響を受ける可能性があります。 enforcementAction: dryrun を使用し、一定期間様子を見ながら適用することをおすすめします。 また、Gatekeeperではデフォルトでメトリクスを公開しているため、違反している Constraint 数も知ることが可能です。どの Constraint が違反しているかは、今のところメトリクスからは判別できないようです。 github.com Gatekeeper v3.4.0からは、 enforcementAction に warn が追加されたそうなので、本番環境での Constraint の使い分けがいろいろとできそうです。 GatekeeperとConftestのテスト 本番に適用することを考えると、記述したRegoのテストについても考慮しなければなりません。 セキュリティに関する機能のテストはとても重要です。いつの間にか攻撃し放題になっていたら嫌ですよね。 まずは記述したRegoのテストについてですが、先ほど説明したようにkonstraintを使用することで、RegoをConftestとGatekeeperで同期させています。 そのため片方のRegoが正しく動くということを証明できれば、もう一方のRegoも同様に正しく動くということが言えそうです。 Conftestの場合、cliで verify コマンドを使用すると、xxx_test.regoというファイルのテストケースを実行してくれます。 $ cat policy/privileged-container/src_test.rego package privileged_container test_privileged_true { input := { "securityContext" : { "privileged" : true }} container_is_privileged(input) } test_privileged_false { input := { "securityContext" : { "privileged" : false }} not container_is_privileged(input) } $ conftest verify 2 tests, 2 passed, 0 warnings, 0 failures またKEELでは、e2eテストを定期的に実施しています。 www.lifull.blog 以下のようにGatekeeperのテストケースを書いておけば、意図しないデプロイが防がれているかを定期的に確認することができます。 Describe( "Gatekeeper" , func () { Context( "when try to deploy deployments" , func () { f := framework.NewFramework(basename, framework.Options{ClientQPS: - 1 }, nil ) f.SkipNamespaceCreation = false BeforeEach( func () { gatekeeperTester.cs = f.ClientSet gatekeeperTester.namespace = f.Namespace.Name }) It( "should be successful to deploy a normal deployment" , func () { gatekeeperTester.createNormalDeployment() }) It( "should be failed to deploy a violated deployment" , func () { gatekeeperTester.createViolatedDeployment() }) }) }) CIの形骸化を防ぐ CIにおけるセキュリティ等のベストプラクティス(今回だとConftestのポリシー)を提供する場合に考慮すべきことは、「CIの形骸化」です。 Linterなどを導入してみたはいいが、結局無視している状態になることは少なくないと思います。 KEELではCIを形骸化させないために、CIのテストに失敗したら 必ず 対応する方針にしています。 これは言い方を変えると、「必ず対応すべきポリシーやテスト のみ を提供する」ということになります。 「できれば対策をしたほうがいい」ようなものは提供せず、あくまでガードレールのような開発する上で必ず対策しておきたいものを提供しています。 また、各種Linterの出力をrunbookに変換できる runbook-translator というソフトウェアも開発しています。 各Linterの出力を、reviewdogの errorformat を用いてParseして変換することにより、開発者に何をしてほしいのかを具体的に指示します。 github actions comment errrorformatを使うことで、Linterの特定のエラーコードは無視するなども可能です。 おわりに いかがでしたでしょうか。Kubernetesにおけるセキュリティ対策を、考案から本番環境に導入するまでの流れを紹介しました。 今回の取り組みは、脅威を洗い出して対策を考案したこともあり、間違いなくクラスタのセキュリティを向上させたと思います。 また対策に必要な工程の一部を自動化させたことで、今後も継続してセキュリティ対策に取り組めると思います。 まだまだセキュリティ関連でもやることがありますので、これからも取り組みを発信していきます。 それではまた次回のブログで!
こんにちは。テクノロジー本部の稲垣です。 LIFULLでは、提供するサービスによって、様々なDBが稼働しています。 異なるDBエンジン間でのデータ移行が必要となるプロジェクトが立ち上がることとなり、AWSが提供しているAWS Database Migration Service(AWS DMS)による検証を行う機会がありました。 www.lifull.blog AWS Database Migration Service(AWS DMS)がリリースされて間もないころに、一度検証目的で使ったことがありましたが、今回使ってみて、色々と分かったことがあったので、紹介します。 AWS Database Migration Service(AWS DMS)とは エンドポイント レプリケーションインスタンス(Replication Instance) データベース移行タスク(Replication task) DMSを使用した2つのデータ移行パターン 移行用の環境を別途作り、動作確認した上で移行 サービス運用しながらデータ移行 継続的なレプリケーション(CDC)を使用する際の注意点 ソースDB側の更新量に合わせた、レプリケーションインスタンスのサイジング データベース移行タスクの設定について テーブル作成モードと再開・再起動 CDCのTransactional Apply ModeとBatch Apply Mode DMSの検証 DMSのログ 実際に使用する前に確認しておくこと おわりに AWS Database Migration Service(AWS DMS)とは docs.aws.amazon.com AWS Database Migration Service (AWS DMS)は、リレーショナル データベース、データ ウェアハウス、 NoSQL データベース、その他の種類のデータストアなど、さまざまなデータベースを格納できます。AWS DMS を使用して、オンプレミスのインスタンス間 (AWS クラウドセットアップを使用)、またはクラウドセットアップとオンプレミスセットアップの組み合わせの間で、AWS クラウドにデータを移行できます。 https://docs.aws.amazon.com/ja_jp/dms/latest/userguide/Welcome.html より一部抜粋 Oracle,MySQL,PostgreSQL,MariaDB,Microsoft SQL Server,Db2,Amazon DynamoDB,Amazon S3など、様々なデータベースに対応しています。 また、RDS-RDS間でも利用することができます。 AWS Database Migration Service(以下 DMS)は、「レプリケーションインスタンス」を作成して、ソースおよびターゲットの「エンドポイント」を指定します。 そして、「データベース移行タスク」を作成して、移行処理を実行させるといった流れです。 AWS DMSレプリケーションプロセス https://docs.aws.amazon.com/ja_jp/dms/latest/userguide/CHAP_GettingStarted.html より抜粋 上記の説明で出てきた、以下の3つについて説明します。 エンドポイント データベース移行タスク レプリケーションインスタンス エンドポイント データベースの接続情報の定義 ソースDB(Source Database)とターゲットDB(Target Database)それぞれに存在する レプリケーションインスタンス(Replication Instance) ソースDB、ターゲットDBとの接続を確立し、ソースDBで発生した変更内容をキャッシュする データベース移行タスクが実行されるインスタンス データベース移行タスク(Replication task) ソースDBとターゲットDBの間でデータ移行を実際に行う場所 移行タスクのタイプが「フルロードのみ」、「フルロード+継続的なレプリケーション(CDC)」、「継続的なレプリケーション(CDC)のみ」によって、タスクの動作が異なります。 フルロードのみ:ソースDBから既存のデータをフルロードし、レプリケーションインスタンスにキャッシュし、ターゲットDBに適用 フルロード+継続的なレプリケーション(CDC):フルロードが終わった後に、ソースDBで変更があった内容を定期的に読み込み、レプリケーションインスタンスにキャッシュし、変更データをターゲットDBに反映させる 継続的なレプリケーション(CDC)のみ:フルロードは行わずに、ソースDBで変更があった内容を定期的に読み込み、レプリケーションインスタンスにキャッシュし、変更データをターゲットDBに反映させる 今回は、 フルロードのみ および 、フルロード+継続的なレプリケーション(CDC) での検証を行いました。 DMSを使用した2つのデータ移行パターン 実際にDMSを使用して、データ移行を行う場合、以下の2つのデータ移行パターンを想定しました。 移行用の環境を別途作り、動作確認した上で移行 サービス運用しながらデータ移行 移行用の環境を別途作り、動作確認した上で移行 【データ移行の流れ】 既存の本番環境と並行して、新しいDBに読み書きするアプリケーションを開発 データ移行用のターゲットDBを作成 データ移行タスクを設定 データ移行タスクをフルロード実行(新しいDBにソースDBのデータが反映される) 新しいDBを参照して、動作確認 アプリケーションを本番環境にリリースする際は、一時的にサービスを止める データ移行タスクを停止し、フルロード実行 新しいアプリケーションをリリース(以降は新しいDBに対して読み書き) 【メリット】 事前に動作確認を行っているため、本番環境での不具合を事前に発見できる テストをして問題があった場合も、環境を再構築すれば切り戻しできる 【デメリット】 環境構築に時間がかかる 同じ機能のソースプログラムを複数管理しなければならない サービス運用しながらデータ移行 【データ移行の流れ】 データ移行用のターゲットDBを作成 データ移行タスクを設定 ソースDBの変更内容をターゲットDBへ定期的に反映 アプリケーションのDB参照先を段階的にソースDBからターゲットDBに変更 移行テーブル対象が増える際は、データ移行タスクを一時的に止めて、テーブルマッピングに追加→データ移行タスクを再開 【メリット】 リリースを止めずにデータ移行ができる 最小限の構成でデータ移行ができる 【デメリット】 データ移行後に問題が発生した場合の切り戻しが困難 本番環境に影響が出てしまった場合、事業へのマイナスインパクトがある 安全性を重視するのであれば「移行用の環境を別途作り、動作確認した上で移行」、多少安全性を犠牲にしても、工数を優先するのであれば「サービス運用しながらデータ移行」といった選択になります。 今回は、移行ケースとして、「サービス運用しながらデータ移行」を想定し、Data Migration Serviceの設定を行いました。 DMSの設定については、web上で紹介しているページがありますが、実際にやってみると、分かりにくい箇所がいくつかあったため、紹介します。 継続的なレプリケーション(CDC)を使用する際の注意点 ソースDB側の更新量に合わせた、レプリケーションインスタンスのサイジング 今回の移行ケースでは、ソースDBに更新が発生する状態で、ターゲットDBにデータ移行を行います。 よって、フルロード+継続的なレプリケーション(CDC)を採用するため、以下の流れでデータを反映していきます。 ソースDBで変更が発生 ↓ レプリケーションインスタンスで変更内容をキャッシュ ↓ ターゲットDBに反映するためのSQLを生成 ↓ ターゲットDBに対して生成したSQLを実行し、変更を反映 ソースDBでのトランザクション処理順に、ターゲットDBに反映するための内容をレプリケーションインスタンス内でまとめて、ターゲットDBへ反映する処理を繰り返しています。 つまり、ソースDB側の更新量が多くなると、その分レプリケーションインスタンス内での処理にかかる負荷が増えていき、レプリケーション遅延を引き起こしやすくなります。 データベース移行タスクの設定について データベース移行タスクについて、少し前で触れました。 データベース移行タスクを設定する際は、主に以下の2つです。 タスク設定 テーブルマッピング タスク設定、テーブルマッピングともに、AWSコンソール上で直接設定する方法と、json形式で設定する方法があります。 テーブルマッピングについては、テーブル数が多いケースでは、json形式で設定したほうが楽です。 タスク設定については、検証時に設定した内容について触れます。 テーブル作成モードと再開・再起動 タスクを設定して、テーブルマッピングで設定したテーブルに対して、どういったモードで再開するかを設定できます。 テーブルマッピングの変更などで、定期的にタスクを停止および再開する際に使用します。 テーブル作成モードには、以下の3つがあります。 何もしない:タスクを停止したときの状態のまま ターゲット上のテーブルを削除:ターゲットDBのテーブル自体を削除 TRUNCATE:ターゲットDBのテーブルは残したままで、テーブルのデータのみ削除 そして、タスクを再開すると、新規にテーブルマッピングが追加されたテーブルについて、 テーブル作成モードが適用されます。 一時的にテーブルマッピングから外したテーブルを、再度追加した際に、テーブル作成モードを「何もしない」以外にしてしまうと、ターゲットDB側の該当テーブルのデータが消えてしまうので、注意が必要です。 CDCのTransactional Apply ModeとBatch Apply Mode DMSタスクはデフォルトでは、 Transactional Apply Mode です。 ソースDBでトランザクションがコミットされた順にターゲットDBへ適用されます。 一方で、ターゲットDBへの書き込み量を減らしたり、まとめて書くことで効率的に動作させることで、高パフォーマンスが期待できる Batch Apply Mode が存在します。 タスク設定のBatchApplyEnabledをTrueに設定することで、有効化できます。 Batch Apply Modeの場合、以下のようにまとめて変更を行うため、ソースDBでトランザクションがコミットされた順で、必ずしも反映されない可能性があります。 一定期間にソースDBに行われた変更をレプリケーションインスタンス上にキャッシュ ↓ 同一テーブルに対する複数のクエリはDMS側でまとめられる ↓ 最終的な変更をまとめてターゲットへ書き込む 今回の要件では、「サービス運用しながらデータ移行」することが前提であり、ソースDB内のテーブル間で依存関係があるテーブルが複数存在していたため、Batch Apply Modeの適用は見送りました。 DMSの検証 タスク設定に「検証の有効化」というチェックボックスがあります。 「検証の有効化」チェックボックス チェックボックスの下の説明には、以下のように書かれています。 全データのロードを実行した後すぐにAWS DMSでソースとターゲットのデータを比較する場合は、この設定を選択します。 検証することで、データが正確に移行されたことを確認できますが、完了するまでに通常より時間がかかります。 ソースDBとターゲットDBで、同じDBエンジンでデータベースの文字コードが異なる場合、DBエンジンが異なる場合など、ソースDB側に特殊文字などが入っていることが原因で、ターゲットDBに移行できないデータが存在するケースがあります。 その場合、ソースDBとターゲットDBで差分が生じてしまうのですが、DMSの検証を有効化することで、AWSコンソール上で差分が発生しているテーブルと原因となっているデータなどを検出してくれます。 データ移行で漏れが発生してしまうと、大きな問題になる可能性もあるので、データを確実に移行したいケースでは有効化するのがオススメです。 テーブルマッピングに設定したテーブル全てが、DMSの検証対象です。 しかし、以下の点に該当する場合は、有効な検証結果が得られない、大幅なレプリケーション遅延が発生するなど、サービスに影響が出てしまう可能性があります。 ソースDB側で大量の更新が定期的に発生するテーブルが存在する ソースDB側に膨大なレコード数、およびカラム長が長いなど、データ量が多いテーブルが存在する DMSの検証処理自体は、レプリケーションインスタンスで行われますが、ソースDBの変更をターゲットDBに反映するレプリケーション処理も、同じくレプリケーションインスタンスで行われています。 よって、DMSの検証処理、レプリケーション処理どちらかの負荷が大きくなると、もう片方の処理にも影響を与えてしまう可能性があります。 例えば、「サービス運用しながらデータ移行」するケースで、ターゲットDB側も既にアプリケーションで利用されている場合は、DMSの検証を有効化することで、レプリケーション処理自体が遅延してしまうというリスクを抱えてしまうことになるので、設定にあたっては検討が必要です。 DMSのログ DMSのログとしては、以下があります。 DMSタスクログ ClouwdWatch Logsに出力される DMSタスク例外情報 ターゲットDB内にテーブルawsdms_apply_exceptionsが作成され、エラーが発生したテーブルやエラー情報が格納される DMSの検証情報に関するログ ターゲットDB内にテーブルawsdms_validation_failures_v1が作成され、エラーが発生したテーブルやエラー情報が格納される awsdms_apply_exceptionsについては、カラムSTATEMENTに、ターゲット側でエラーが発生したときに実行されたステートメントが記録されます。 awsdms_validation_failures_v1については、カラムDETAILSに、DMS検証時に指定されたキーと一致しないすべてのソース/ターゲット列値のJSON形式の文字列(エラーとなったデータ)が記録されます。 実際に使用する前に確認しておくこと 色々と説明しましたが、DMSを本番稼働しているサービスに使用する場合、以下の点について、確認しておいたほうがよさそうです。 データ移行パターン(サービス運用しながら・移行用の環境を別途作る・開発を一定期間止める) サービス運用しながらデータ移行する場合は、データ移行するソースDBで更新頻度が高いものがないか 移行するテーブル間で依存関係があるものがあるか(依存関係がない場合は、Batch Apply Modeモードの適用も検討) DMSタスクの数(複数稼働させる場合は、対応するレプリケーションインスタンスも用意するか) DMSの検証有効化有無(DMSの検証を無効化する場合は、ソースDBとターゲットDBの差分チェック方法の検討) おわりに 実際にData Migration Service(DMS)を使ってみて、分かりにくかった点について紹介しました。 オンプレミスで動いているDBをAWSへの移行を検討している、もしくはAWS内で別のDBエンジンへの移行などで、Data Migration Service(DMS)の利用を検討している方にとって、少しでもこの記事がお役に立てたら幸いです。
こんにちは。Ltech運営チームの井坪です。 今回は、2021年6月8日(火)に開催した『Ltech#17 実録!LIFULLアジャイル導入までの挫折と取り組み』についてレポートします。 lifull.connpass.com Ltechとは Ltech(エルテック)とは、LIFULLがお送りする、技術欲をFULLにするイベントです。特定の技術に偏らず、様々な技術の話を展開していく予定です。 LIFULLアジャイル導入までの挫折と取り組み Ltech#17のテーマは『アジャイル』です。日本でも多くの企業でアジャイル開発が導入されてきていますが、導入したけどうまく使われていないといったことも耳にされることが多いかと思います。特に大企業では既存の業務の進め方が存在し、アジャイルな開発がやりにくい場合も多いようです。LIFULLでの導入事例を踏まえて、導入時の課題や推進していく条件、体制作り・運営の苦労や工夫について語っていただきました。 大企業でアジャイル開発を推進できる条件とその心構え 大企業でアジャイル開発を推進できる条件とその心構え from LIFULL Co., Ltd. www.slideshare.net 最初の発表は『LIFULLで経験したアジャイル開発の導入における課題』とその経験から学んだ『アジャイル推進していくための条件』について発表していただきました。 LIFULLでは2013年頃、開発スピード向上のためにスクラムが導入されるようになりましたが、開発体制や当時のリリースフローの影響もあり運営が難しく下火になっていました。 その後、2018年頃から中途入社メンバー中心に各部署や各プロジェクトでスクラムが採用されるようになり普及し始め、今ではアジャイル勉強会の開催やスクラムサークルの活動が行われるようになりました。 アジャイル導入・運営から学んだ「推進してくための条件」は以下のようです。 ※発表者個人の見解になります。 * 型に囚われない * 考えるきっかけを作る * 土壌を作る 開発チームにはスクラムの経験者と未経験者がいる場合もあり、最初から完全なスクラムの型を目指す必要があるのか。 最初から完全な型通りに進めようとすると難しく上手くいかないこともあったりします。 どこに課題があるか気付いてもらうところから始め、チーム内で解決策を話し合い考えてもらい、世の中で起きている変化や課題に対してどう対応していくのかを話し合うことでチーム全員が納得して進められるようになっていきます。 スクラムを利用したアジャイルオフショア開発のとりくみ スクラムを利用したアジャイルオフショア開発のとりくみ from LIFULL Co., Ltd. www.slideshare.net 次は、LIFULLにはベトナムのホーチミンに開発子会社である『LIFULL Tech Vietnam(LFTV)』があり、LFTVとの開発においてスクラムを利用したオフショア開発のために取り組みについて発表していただきました。 リモートワーク全体の問題としてチーム間のコミュニケーションが不足するうえ、開発チームは日本とベトナムに分かれているので、デイリースクラムで雑談する機会を設けてコミュニケーションを図ったり、 ベトナムチーム側の問題を検知しづらいため雑談を兼ねた定期的な相談できる場を設けているそうです。 最後に 今回はLIFULLでアジャイル開発を導入・推進されている お2人に発表していただきました。LIFULLの事例や個人の意見ではありますが、今後アジャイル開発を導入しようとしている方々やアジャイル開発で困っている方々のご参考になれば幸いです。 Ltechでは、LIFULLエンジニアが中心となって皆様の技術欲を満たすよう実例を交えた勉強会を開催しています。 今後もLtechを積極的に開催していきますので、 ぜひ気になった方は、connpassでLIFULLのメンバー登録をよろしくお願いします! lifull.connpass.com
プロダクトエンジニアリング部の関川です。 最近リモートワークを行う上で欠かせないツールがリアルタイムコミュニケーションツール。 ZoomやDiscordなどの製品はそれぞれの方法でリアルタイムコミュニケーションを可能にしてきましたが 民主化された技術の一つとして、WebRTCという技術があります。 この記事はWebRTCに調べる機会があったので、基本的なWebRTCについてとその仕組みについて備忘録のような形でまとめました。 インフラ初心者でもわかりやすいように心がけて書きました。 触りやこんな技術なんだということをお伝えできれば幸いです。 WebRTCってなに? WebRTCのRTCは Real Time Communicationの略で、文字通りwebにおけるリアルタイムコミュニケーションを実現する技術です。 ブラウザ間での映像、音声などのデータを相互にやり取りのできるように作られており、2012年頃にGoogleによってオープンソース化されました。 専用のアプリケーションを必要とせず、ウェアラブルデバイスとの通信に用いられたりと幅広い利用がされています。 強みとしては、レイテンシーの少なさと多くのブラウザが標準対応を行っていることで、特にChromeやSafariに新たに機能追加など行うことなく利用できる点は 導入へのハードを大きく下げ、誰でも簡単にリアルタイムコミュニケーションができることへの貢献になりました。 さて、このWebRTCを支える基礎技術についての説明をします。 WebRTCを支えるネットワーク技術(基礎) P2P通信とは? P2P通信はPeer to Peerの略です。Peerとは英語で対等、同等の意味を持つ単語で文字通り、対等同士の通信ということになります。 よく比較されるのが、サーバークライアント型の通信です。サーバーに問い合わせて、情報もらう形式などサーバーから送られる情報とクライアントから送られる情報とでは かなりの差があるのに対して、 P2P型は対等な立場で情報を共有するという特徴 を持っています。 大きな差としてはサーバークライアント型と比べて負荷分散がされている点と回線が非常に軽いです。 ネットワークの型 テレビ会議システムはリアルタイム通信を行う上で負荷分散と回線の軽さが非常に重要なため 、この技術が用いられていると推測できます。 ただし、勘違いしていけないのは「WebRTCは一様にP2P通信を行っているわけではない」という点です。それに関しては後述するTURNについてのお話で触れます。 UDP UDPとはユーザ データグラム プロトコルの略で、これは名前での理解はなかなか難しいですね笑 ちなみにプロトコルとは各々が統一性のない好き勝手な情報を伝えないように取り決めた約束事のことです。 では何の約束事かというと、UDPはデータを送るための形式の定義です。 UDPの話をするときに必ず出てくるといっても過言ではないのがTCP(トランスミッション コントロール プロトコル)です。 この2つはよく比較されますが、その違いを端的に言うと、データをどれだけ確実に送りたいかです。 情報の欠落などの不具合を避けるためTCPはコネクションを作成し、送られてきたデータの順番に間違いや欠落がないかを確認して、正しく送られてきたかを常に確認します。 一方UDPはコネクションの手順などを省き、受ける側がデータを受け取ったかを確認する作業も省略します。 これだけ聞くとTCPの方が優れているように思えますが、リアルタイム性を求める場合はUDPの方が早いことは確かです。 通常のコミュニケーションでも一言一言に対して、「今の聞こえた?」「聞こえたよ」と確認することはないため、WebRTCとの相性はよいのです。 WebRTCは音声や映像はただ伝えるだけという特徴を生かしてUDPに対して独自の再送制御を作って、リアルタイムコミュニケーションを実現しています。 WebRTCの基本構成 どのようにWebRTCがつながるのか続いて説明します。 ここではP2P通信を前提として話を進めていきます。 WebRTCの構成はこのような構成になります。 構成要素 P2P通信するといっても 「P2P通信ってことはサーバーレスなんでしょ?なんでサーバーが必要なの?」と上の図を見て感じた方もいるのではないでしょうか? 確かに P2P通信はサーバーを必要としませんが、それは相手について知っていたらの話 です。 いざ ブラウザ同士でP2P通信するぞとなっても、相手はネットのどこかにいる名前も住所もしゃべる言語も知らない相手 です。 特定することは難しいでしょう。 そのため必要なのがシグナリングサーバーです。 シグナリングサーバー シグナリングサーバーとは 通信するために必要な情報を相手に伝えるためのサーバー です。 各ブラウザはシグナリングサーバーを経由してプロトコルの交換や通信経路の探索など行うための情報を共有します。 その時に用いられるのがSDP (Session Description Protocol)です。 SDPとは、通信を行う際、お互いが どのような映像・音声のコーデックを使えるかなど通信における取り決めをやりとりするためのプロトコル で 様々な情報を含んでいますがまず重要なのが以下の二つです。 セッションを構成するメディア そのメディアを受信するために必要な情報(アドレス、ポート、形式など) これらの情報をシグナリングサーバー経由で互いに送りあうことで、P2P通信のための準備を整えていきます。 P2P通信確立の流れとしては ① SDPをブラウザAが作成して、それをシグナリングサーバーに送信し、ブラウザBに送る。これをoffer SDPといいます。 ② もう片方のブラウザが受け取り、その中で自分も使えそうななどを探し、通信できるものを返す。これをanswer SDPといいます。 SDPのやり取り これで双方がどうのように通信するのかは確立できます。 ただし、これだけではまだP2P通信は確立できないのです。 通信の壁、NAT 確できない理由をNATの説明とともに行います。 NATとはネットワークアドレス変換のことを意味し、一般家庭などではブロードバンドルーターやWiFiルーターがその役割を果たしています。 1つのグローバルIPアドレスを、複数のPCやデバイスで共有することができるようにする仕組みです。 また複数のPC/デバイスが同時に通信できるように、ポートマッピングによるポート変換も行っています。 このNATを超える作業がP2P通信を行う上で非常に重要になります。 ブラウザは基本知りうる情報はNAT内部のこと つまり ローカルネットワークのIPアドレス 自分のUDPポート ですがローカルネットワークのIPアドレスを相手に伝えたところで通信できるはずがありません。 たとえば、マンションの部屋番号がわかっていても、住所がわからないのでは相手に物を送ることはできません。 そのため、ネットワークの外から見た情報(グローバルIP、NATによって割り当てられたUDPポート)を得る必要があるのです。 STUNサーバー グローバルIPアドレスがわからなければ誰かに教わる必要があります。そのために必要なのがSTUNサーバーです。 STUNとはSession Traversal Utilities for NATsの略です。 これは通称"NAT越え"を行う際に用いられる手段で、ネットワークの外から見た自分の情報を教えてくれるサーバーです。 よく鏡のような役割と例えられます。(自分を写してくれる的な意味で) STUN このようにして得られた情報を元にICE Candidateを作成して互いにやり取りします。 先ほどのP2P通信確立の流れの続きとして ③ STUNサーバーから得られた情報をシグナリングサーバー経由に送り、相手の SDP で受信したリストから候補となる IP/ポートのペアを取得し、そこに STUN リクエストを送信する。 ④ 相手のブラウザから応答が返ってきた場合、発信元のブラウザはチェックが成功したと見なして、その IP/ポートのペアを有効な接続候補として認定する。 この接続候補をICE Candidateといいます。 ICEとはInteractive Connectivity Establishmentの略 で、 ブラウザを取り巻く環境は人それぞれ違うため、互いにP2Pの通信のできそうなIPやポートをかき集めて、相手と共有し、接続確認を行うためのプロトコルです。 基本的にはこのICE Candidateで通信可能経路を見つけることができれば晴れてP2P通信が可能な状態になります。 ただし、この際UDPホールパンチングを行うため、それが可能な環境でなくてはP2P通信を確立できません。 ここまでのP2P通信前提のWebRTCは、STUNによりNATを超えることができなかった場合には、基本的に通信は困難なものになります。 TURNサーバー STUNでも超えられないNATを超えるために必要なのがTURNサーバーです。TURNはTraversal Using Relay around NATの略称で パブリックIPアドレス上に TURN サーバーを置き、 UDP 通信を行うブラウザ同士は直接的には TURN サーバーにデータを送信し、 TURN サーバーは受け取ったデータをそのままもう一方へとリレーする、という仕組みです。 P2P通信ができないと判断した場合に補助的に用いる場合もありますが TURNでデータをやり取りする場合は基本的にはP2P通信ではなくなります 。 TURNサーバー まとめ 上記の内容は基本的にはWebRTCの初めの一歩なものです。皆様の役に立てば幸いです。 個人的には将来的にはVRデバイスなども用いた開発ができると面白いことができるだろうなと感じました。 この技術を勉強することは通信やインフラの知識をつけるという観点でもおすすめの技術なので、試しに触ってみてください。 またそこから安定性などを求めたりすると数多くのプロトコルやハードウェアや回線などの戦いができる初心者でも楽しめて、なおかつやりこみ要素の高い技術です。 LIFULLでは一緒に働く仲間を募集しています。よろしければこちらも合わせてご覧ください。 hrmos.co hrmos.co
こんにちは。Ltech運営チームの山下です。今回は、2021年5月13日(木)に開催した『Ltech#16 LIFULL HOME'S におけるエンジニア×マーケティングテクノロジー』についてレポートします。 lifull.connpass.com Ltechとは Ltech(エルテック)とは、LIFULLがお送りする、技術欲をFULLにするイベントです。特定の技術に偏らず、様々な技術の話を展開していく予定です。 エンジニア×マーケティングテクノロジー 今回の Ltech のテーマは「 LIFULL HOME'Sにおけるエンジニア×マーケティング 」です! LIFULLにはマーケティングスキルとエンジニアスキルの両方を兼ね備えた「 マーケティングテクノロジーエンジニア 」と呼ばれるハイブリットなエンジニア職があります。 あまり馴染みの無い職種ですが、今回は なぜマーケティングテクノロジーエンジニアが必要なのか 実際にどのような業務を行なったのか と言った内容で語っていただきました。 それでは発表レポートに行きます! エンジニア × マーケティングテクノロジーが必要な理由 エンジニア × マーケティングテクノロジー が必要な理由 from LIFULL Co., Ltd. www.slideshare.net 最初は、「エンジニア × マーケティングテクノロジー」のスキルを掛け合わせた、「マーケティングテクノロジーエンジニア」についての紹介と、「マーケティングテクノロジーエンジニア」が必要な理由です。 プロダクトを運用する上では効果測定を含めた分析が必要不可欠ですが、マーケター・アナリスト〜エンジニア間のコミュニケーションコストが割高になったり、要件調整・設計段階でエンジニア観点が欠落しているため、システムの品質低下につながりがちですね。 分析用のタグが乱立することで、仕様が煩雑化し、調査するにはソースコードを読むと言った経験はWebエンジニアであれば多数の方が経験されていると思います。 エンジニアにマーケティングスキルを持たせることで、要件・設計段階から参画することにより、 サービスのPDCA高速化 、 システムのQCD向上 が期待できます。 マーケティングテクノロジーエンジニアは「マーケター」「データアナリスト」「Webアプリケーションエンジニア」のハイブリット型のエンジニアで、「各担当者のブリッジを行うのではなく、 各領域の習熟度を高めるプロフェッショナルである 」というのはとても印象に残りました! 広範囲のスキルセットを必要とするため、ハードルは高いですが、今後需要が加速することが想定されますね。 LIFULLではLINEを中心としたオムニチャネル戦略をとっています。次のセッションで実際にどのようなことをやったのか触れていきます! 実践マーケティングテクノロジーエンジニア 実践 マーケティングテクノロジーエンジニア from LIFULL Co., Ltd. www.slideshare.net 続きまして、LINEによる物件情報の通知配信時間を改善したお話についてです。 施策当初、LINEの通知配信時間を物件詳細画面の閲覧される時間帯を参考に設計していたところ、「 物件詳細画面を閲覧する時間とLINEを確認する時間は同じなのか? 」「 より効率の良い時間があるのではないか? 」と言った仮説を元に動き出した案件になります。 当初のシステム構成上、外部システムを経由してWebhookしていたため、限られた情報しか取得できなかったそうです。 そこで、LIFULL独自のアプリケーションである「EOS(Elastic Omnichannel Service)」へ移行することで、外部サービスを経由せずWebhookすることが可能になり、全てのLINE利用者の行動をデータ化し集計することに成功しました。 結果、データサンプル数が増え、より細かいユーザーの行動データを集計することに成功し、様々な分析を行えるようになりました。 現行のデータ数に満足せず、より正確なユーザーの行動を集計するためシステム構成を変更することは、マーケティングテクノロジーエンジニアがいるからこそできるアクションだと思いました! まとめ マーケティングテクノロジーエンジニア(CRMエンジニア / データエンジニア)は世の中にまだ浸透していないですが、これから需要が高くなっていき、企業 / プロダクトに必要不可欠な存在になっていくことが想定されます。 今回は「エンジニア×マーケティングテクノロジー」についてのセッションでしたが、今後「エンジニア×何かしらのスキル」をかけ合わせたハイブリットなエンジニアが増えていくだろうと思いました。 最後に Ltechでは、LIFULLエンジニアが中心となって皆様の技術欲を満たすよう実例を交えた勉強会を開催しています。今後も Ltech を積極的に開催していきますので、ぜひ気になった方は、connpass で LIFULL のメンバー登録をよろしくお願いします! lifull.connpass.com
こんにちは。LIFULLのプロダクトエンジニアリング部の野澤です。エンジニアリングマネージャーをやっています。 LIFULLでは組織構造として部の下に「ユニット」があり、その下に「グループ」がぶら下がっています。 今期からは私はユニット長を拝命し、間接マネジメントを行うようになりました。 マネジメント業務の中でも1on1は部下のモチベーション維持やキャリア形成、戦略理解を促進させるために重要な手法です。 グループ長時代も1on1はやっておりましたが、間接マネジメントをやるにあたり、メンバーからは相談がしにくくなってしまったようで、「特に話したいことはありません」となってしまうことが増えていきました。 そこで改めて1on1を有意義にするためにはどうしたらいいか考えてみました。この記事ではそのための取り組みを紹介できればと思います。 LIFULLでの1on1 1on1は今やいろんな業界や会社で取り入れられていると思います。 LIFULLでは「3つのしごと」について1on1で対話をすることが推奨されています。 「3つのしごと」とは「仕事」、「志事」、「私事」です。 仕事 「仕事」はもっとも分かりやすい1on1のテーマでもあります。 普段行っている仕事で困っていることや感じたことなどをざっくばらんに意見交換します。 なかには技術的にうまく行かなかったことの相談に乗ることもあります。 また、仕事を通して得られた学びや気づき、成長したことなどについても話してもらうことが多いです。 他にも指示した戦略や戦術、目標に対しての質問に答えたり、どうやったらもっとチームがスムーズにコミュニケーションできるようになるかなどといったことについても話します。 業務をスムーズに進められるようにすることや、メンバーの成長を促進するのもマネジメントの役割なので 1on1のなかで課題発見や課題解決をしたり、成長の確認や次の成長のためのアドバイスを行うようにしています。 志事 次に「志事」です。志事は主にキャリアやスキルアップについての話題です。 LIFULLでは「内発的動機づけ」を非常に重要視します。 なぜなら、自分自身がやりたいと思って取り組むのとそうでないのとでは、パフォーマンスに雲泥の差が出るからです。 また、LIFULLでは 「利他主義」 を社是として掲げ、「常に革進することで、より多くの人々が心からの『安心』と『喜び』を得られる社会の仕組みを創るを経営理念としています。 なので当人が「心からやりたい」と思い、熱中できるような仕事でなければ、社会をあっと言わせるような革進を生み出すことは難しいですし、「指示されたことだけをやっている」ような仕事では、ついつい目の前の作業だけに意識がいってしまい、「人々の心からの『安心』や『喜び』」からかけ離れてしまいます。 なので、時々目線を上げるためにも「本当にやりたいことができていますか」、「理念に対しての仕事ができていますか」という問いかけを行います。 こういった話のなかで、「挑戦したいと思っていることがある」、「違う仕事をやってみたいと思うようになった」のような会話が生まれます。その後、具体的な部署異動や職種変更を検討していきます。 LIFULLでは「キャリア選択制度」があり、半年に一回、自身のキャリアを見直し、配属を希望する部署を申請することができます。必ずしも部署異動が実現される訳ではないですが、日々の1on1を通じてその人のやりがいや将来目指しているものを把握し、より会社の戦略・戦術にフィットするような部署を検討します。 また、そうしたキャリアを実現する上でどういうスキルが必要か、どうやって伸ばしていくことができるかといったことも話し合います。オススメの本やイベントを紹介したり、他部署のメンバーを紹介することもあります。 私事 いわゆる雑談でプライベートな話です。 一緒に働くメンバーと気持ちよく仕事をする上で欠かせないのが、「その人となりを知ること」です。週末どんなことをしたかとか、プライベートで悩んでいること、面白い発見、その他なんでも話します。思いついたことをカジュアルに安心して話せる機会です。 こうした私事についての話を通して、相互理解を深め、信頼関係を構築します。特に新しいメンバーのオンボーディングの際や新しく部署を新設した際はとても大事な会話になると思います。 コロナ禍になり、普段取れるコミュニケーションも限定的になってしまったこともあり、週に30分はこうした1on1をすることにしています。 何に困ったのか 冒頭で「間接マネジメントをやるにあたり、メンバーからの相談もしにくくなってしまったようで」と書いた件です。 1on1では最初に「話したいこと、相談したいこと、困っていることはありますか」と質問することにしています。1on1は基本的にメンバーのための時間で、メンバーが話したいことを優先したいからです。 ですが、ユニット長になってからは「特にありません」となることが多く、一方的に私が質問するような会になってしまったのです。 直接現場のメンバーと話すとなると、彼らにとって私は現場で一緒に働いているわけではないし、彼らはグループ長とも1on1をやっているので、ユニット長にどこまで話していいか、何を話していいか分からなくなってしまったようです。 どう解決したのか ということで、私は以下の2つを実施しました。 1on1の目的を文書化する 1on1の使い方を文書化する 1on1の目的を文書化する ユニット長としてメンバーの仕事、志事、私事の状況を理解することには意味があり目的があります。目的を明確にすることで、「話してもいい」という共通理解を作ることにしました。 例えば 「仕事」…ユニット長として、みんなが仕事で最大のパフォーマンスを発揮できるように、困っていることを確認し、解決したい。 「志事」…ユニット長として、みんなが満足いくような成長をすることで会社の理念の実現に近づけるように、みんなが心からやりたいと思っている仕事ができているかを確認し、個人のキャリアに合った仕事の可能性を検討できるようにしたい。 「私事」…ユニット長として、一緒に働くメンバーとして、お互いに好きなこと、嫌いなこと、嬉しかったこと、困っていることを理解することで、信頼関係を深めたい。 のような感じです。 こうすることでメンバーからは何のために、何を話すべきなのかが明確になります。これを社内ブログで投稿し、誰でも見れるようにしてみました。 1on1の使い方を文書化する 上記だけでも足りるかな、と思ったのですが1on1の活用事例も合わせて掲載してみました。 相談相手 / 壁打ち相手 仕事で〇〇しようと思っているんですがどう思いますか? 仕事で〇〇に困っているんですがどう思いますか? ◯◯さんに困っています 会社や部の方針 このあいだ総会で言っていた戦略について疑問を持ったので教えてください 追加されたり変更された会社のルールや制度について、それらの目的や意図を教えてください キャリアについて この間とある本を読んで(とある人と話して、またはとあるイベントに参加して)、自分はもっと◯◯みたいな仕事がしたいと気づいたのですが、どうやったらそういった仕事の機会をもらうことができるでしょうか? どうやったらその仕事ができるようなスキルを身につけることができるでしょうか? 上司へのFB この間、野澤さんは◯◯みたいな発言をしていましたが、言い方が適切ではなかったと思います もっと他の部署の組織長みたいに具体的なビジョンを示して欲しいです もっと公平な評価をして欲しいです 今の目標設定に納得がいっていません もっとメンバーの仕事を見て欲しいです 仕事が多すぎます。もっと優先順位をつけて選択と集中をして欲しいです 上司へのプライベート(?)な質問 野澤さんは休日は何やってるんですか? 好きな食べものはなんですか? 野澤さんのキャリアビジョンについて教えてください 野澤さんが20代のときのことを教えてください ◯◯のニュース見ました?野澤さんはどう思いますか? みたいな感じです。 この「上司にとっての1on1の目的」と「活用事例」はいわば、1on1のコンテキストを豊かにするものだと思っています。1on1に対する期待を上司とメンバーとの間ですり合わせる作業です。ルール化すると重たいですが、コンテキストをリッチにしておけば、個々人が自由に考えて話すべきことを考えやすくなります。(この辺は 『NO RULES(ノー・ルールズ) 世界一「自由」な会社、NETFLIX』 を参考にしてみました) どうなったのか 実際に話題のバリエーションが広がりました。 上記のブログを投稿した後の1on1では「ユニット長の貴重な時間を私の雑談に費やすのはもったいない」と思っている方がいたことも分かりましたし、「細かな業務や技術的な相談で煩わせたくない」と考えていたメンバーがいたことも分かりました。 特に「1on1の使い方」がメンバーには刺さったらしく、「こういう質問もしていいんだ」という感じたそうです。雑談もバリエーションが広がり、「野澤さんが20代のときのインターネット黎明期ちょっと後のときってウェブの可能性をどう思ってたんですか?」みたいな話も出るようになりました。 1on1は基本的にメンバーのための時間です。メンバーがうまく1on1を活用してもらえるよう意識付けを行っています。こんな感じで日々、エンジニアリングマネージャーとしてのマネジメントを試行錯誤しています。 LIFULLの1on1に関しては、 弊社CTOの記事 も合わせてご覧ください。 LIFULLでは一緒に働く仲間を募集しています。よろしければこちらも合わせてご覧ください。 hrmos.co hrmos.co
こんにちは。Ltech運営チームの市来です。 今回は、2021年3月31日(水)に開催した『Ltech#15 未来の体験をつくるLIFULL Labの取り組み ~ LIFULLのR&D部門とは ~』についてレポートします。 lifull.connpass.com Ltechとは Ltech(エルテック)とは、LIFULLがお送りする、技術欲をFULLにするイベントです。特定の技術に偏らず、様々な技術の話を展開しています。 未来の体験をつくるLIFULL Labの取り組み ~ LIFULLのR&D部門とは ~ Ltech#15のテーマは、LIFULLのR&D部門である『LIFULL Lab』の取り組みについてです! LIFULL Labでは、社会における既成概念、人々の固定概念を壊し、「あらゆるLIFEを、FULLに。」する研究・企画・開発を行い、世界を変えるような未来の体験をつくる取り組みを行っています。 今回はLIFULLのR&D部門である LIFULL Labの方々にこれまでの事例やいま取り組んでいる内容について語っていただきます! それでは各発表のレポートです。 「ありえるかもしれない未来」をR&DするLIFULL Lab 「ありえるかもしれない未来」をR&Dする LIFULL Lab from LIFULL Co., Ltd. www.slideshare.net 最初の発表は、「Well-beingな暮らし」の実現を目指し、社会課題解決に向けたResearch&Designを行うLIFULL Labの活動方針や研究領域や取り組みなどについてご紹介です。 LIFULL Labでは、外部パートナーとオープンイノベーションで「体験できる」状態まで実装するということで R&Dの「D」意味としては「Development」はなく「 Design 」であるというのが印象的でした。 また、現在進行中のプロジェクトとして紹介された下記プロジェクトはどれもワクワクするものばかりでした。 現在絶賛R&D中のWell-being Cityについても近々公開できるかも!?ということで、とても楽しみです! VR空間上で「したい暮らし」を見つける体験のプロトタイプ『 空飛ぶホームズくん 』 ユーザのTwitterの投稿を解析し、自分に足りていない感情に出会える場所を推薦するサービス『 LIFE WILL 』 絶賛R&D中の「Well-beingになれる街」のあり方とその指標を探索するプロジェクト 食による社会課題解決と持続可能な社会を目指すプロジェクト『 Earth Cuisine 』 上記の「空飛ぶホームズくん」と「LIFE WILL」については、この後のセッションで深堀していきます! Well-beingを測る「LIFE WILL」開発の舞台裏 Well-beingを測る「LIFE WILL」開発の舞台裏 from LIFULL Co., Ltd. www.slideshare.net 続いて、ユーザのTwitterの投稿を解析し、自分に足りていない感情に出会える場所を推薦するサービス『LIFE WILL』についてのお話です。 Twitterの直近200件の投稿から感情分析し、ポジティブな感情だけではなくネガティブな感情にも触れることでよりWell-beingになるという考え方(感情の多様性=Emodiversity)で、 分析した結果、よりWell-beingになるための場所や街、物件情報を全国1800の市町村からレコメンドしてくれるサービスとなってます。 「ラッセンの円環モデル」を参考にLIFULL独自の感情モデルを作ったり、分析結果がネガティブな印象になりすぎないように感情のオノマトペ化やキャラクター化を行ったり、どのように作り上げていったのかを知ることができとても面白い内容でした。 今後の課題としては、現在ユーザの感情分析はTwitterのみで、街の感情分析はアメブロ・はてなブログのみなので、その他のテキストデータも分析に使えないか探索していくとのことでした。 分析するテキストデータが増えることにより、さらにユーザや街の感情が精緻化されそうなので楽しみです。 ちなみに私のTwitterアカウントで試したところ、一番強い感情は「ツンツン」で一番弱い感情は「モヤモヤ」と結果が出てきて、自分では把握していない感情を知ることができました! みなさんも是非おためしください。 lab.lifull.com ニオイセンサで探索する街の新たな指標 ニオイセンサで思索する街の新たな指標 from LIFULL Co., Ltd. www.slideshare.net 続いて、街のニオイも居住先を決める際の新たな指標になるのではないかという仮説を思索しているお話です。 街には特有のニオイがあり、プルースト効果によって懐かしいと感じるのではないかという仮説をもとに、ニオイセンサを用いて街のニオイを検証している内容となります。 ニオイセンサのメーカーに、街のニオイのサンプルとして街の空気を入れた袋を段ボールに入れてメーカーに送った話は面白かったです(笑) センサメーカーからは、「街によってニオイの主成分が変わることが分かり、街のニオイの判別できる可能性がある」という回答をもらったとのことで、細谷さんにて実際に計測し可視化するためのアプリを開発したり、自転車にセンサをつけて街中を走ったりなど、技術力・実行力共に高くカッコいいと思いながら聞き入ってました。 課題としては、現状ニオイの基準点を整備できていなかったり、気象条件によって左右されないようにしたり、サンプルがまだ足りないなど、まだまだ仮設の段階とのことでした。 ニオイの感じ方は人それぞれ違うと思いますが、数値化されることで科学的に同じニオイかどうかわかるのはとても興味深い内容でした。 このニオイのR&Dが進んでいくと、街のニオイが住まい探しを行う上で新たな検索軸になりそうですね! 「空飛ぶホームズくん」を実現するVR技術 「空飛ぶホームズくん」を実現するVR技術 from LIFULL Co., Ltd. www.slideshare.net 最後に、VR空間上で新たな住まい探しを体験する「空飛ぶホームズくん」についてのお話です。 「空飛ぶホームズくん」はVR空間上に再現された街を飛び回りながら物件探しを行うことができます。 VRに初めて触れるユーザでもVR酔いしないような操作や移動速度などを試行錯誤したり、操作で迷わないようにかなりシンプルな操作となるように設計したりなど、ユーザに寄り添ったものになっているなぁと感じました。 VR上に再現しているミラーワールドにはゼンリン3DマップやGoogleMapが使用されていますが、つい先日公開された「PLATEAU」を用いることができるかについても調査しているとのことでした。 VRで物件探しができるようになることで、遠く離れた場所の物件でも手軽に見れるようになるので、もっと広めていきたいですね! アフタートーク 各セッションが終わった後、登壇者全員でざっくばらんにアフタートークをしました! LIFULL Labで扱うテーマはどのように決めているのかについてや街のニオイの収集を手伝いたいなど、参加していただいた方々とゆる~く雑談を行いました。 PLATEAUなどのオープンデータも続々と出ているとのことで、VR界隈が広く普及して身近なものになっていければなと感じました。 最後に Ltech では、LIFULLエンジニアが中心となって皆様の技術欲を満たすよう実例を交えた勉強会を開催しています。 今後もLtechを積極的に開催していきますので、 ぜひ気になった方は、connpassでLIFULLのメンバー登録をよろしくお願いします! lifull.connpass.com
テクノロジー本部の鈴木( @szk3 )です。ソリューションアーキテクト・クラウドアーキテクトとして業務にあたっており、最近はWebRTC周りに興味関心があります。 自分が所属するチームでは「アーキテクト相談」 という 技術相談の取り組み を行っています。 今回は、その技術相談で取り入れている 「ナレッジマネメント」および、知識経営の提唱者である野中郁次郎先生が提唱した「SECIモデル」 について紹介します。 背景 相談手法 ナレッジマネジメントとは? SECIモデルとは? アーキテクト相談の対応範囲 プロセスをスムーズに回せるような環境・運用整備 表面化・連結化における、形式化(ナレッジ化) 運用への向き合い方 回答に時間がかかりませんか? 他の技術相談窓口と競合しませんか? ナレッジの効果測定はどうやっていますか? 情報鮮度への対応はどうしてますか? まとめ 背景 LIFULLでは、多種多様なプロダクト開発を行っておりますが、それらの設計や開発工程においてグループ内だけでは判断しづらい内容がでてくることがあります。 そういった悩みは、個人・組織において以下のような問題を引き起こしかねません。 個人レベル 悩みの解決の糸口が見つからず、開発工程を圧迫する ルールや規約があることを知らず、手戻りにつながった そもそも、誰に聞いていいかわからない 組織レベル 別のグループも同じ悩みを抱えているが、その悩みが共有できてない 相談内容と回答の中から、汎用的なものはストックしておきたい そういった課題に対し、汎用的な技術相談窓口として機能しつつ、それらのやりとりを一過性のものにしない相談の仕組みが「アーキテクト相談」です。 「アーキテクト相談」の目的は "システム・アーキテクチャの初期設計・手戻り工数削減" です。 この目的を達成するために "解決策を一緒に整理し、使えるナレッジとして再利用できるようにする" という一連の流れをサポートしています。 相談手法 「ナレッジマネメント」を説明する前に、相談手法について整理します。 他の方法(例えば対面での口頭、電話)もありますが、ここではテレワークを前提とした現時点で実際に使っている相談手法を列挙しています。 手法 メリット デメリット チャット (Slack / Chatwork ) ・個別相談でも気兼ねなく聞ける ・ほぼリアルタイムで相談にのってくれる ・ やりとりの流れを追うのに時間がかかるケースがある ・大人数の部屋だと相談しにくい人が、少なからずいる オンライン会議 (Zoom / Meet ) ・話したほうが早いケースがある ・熱量が伝わりやすい ・相談内容を他の人にシェアしづらい(議事録残らない可能性) ・時間的な制約がある チケット駆動 (JIRA) ・議論が混ざりにくい ・シェアしやすい ・テンプレ化しやすい ・情報をリンクさせやすい ・チケットを書くのが大変(文章の整合性、伝える情報の粒度) ・解決までに速度がワンテンポ送れる ドキュメントを読む (公式Web, Confluence、Github(README)、Google Drive等の資料) ・自己解決できる ・シェアしやすい ・目的の情報を探すのが、困難な場合がある ・情報鮮度が信用出来ないケースがある ※ドキュメントを読むは、正確には"相談"ではありませんが、解決したい課題があるという意味では同じレイヤーに存在する手法だと考えます。 お察しの通り、 どれか一つで解決するのはなく全ての手法を使っています し、運用ルールしだいでデメリットを解消するようなことも可能です。 また、相談者のコンテキストに合わせて、複数組み合わせることもあります。 どれが良いというのはなくて、 相談相手が「選択できる」状態を作っておき、特性にあわせた手法を選べるのが重要 と考えています。 また、上記には含めていませんが、Google グループ の「会話」はスレッド的に使えます。オープンにディスカッションできて検索もできるので、お手軽に情報管理するのにおすすめです。 ナレッジマネジメントとは? 「アーキテクト相談」では、相談と回答から再利用可能な情報を抽出しドキュメンテーションしています。 その一連の流れを、 ナレッジマネジメントのフレームワーク「SECIモデル」を用いて運用しています。 「ナレッジマネジメント」とは、 企業が保持している情報・知識と、個人が持っているノウハウや経験などの知的資産を共有して、創造的な仕事につなげることを目指す経営管理手法 *1 です。 ナレッジマネジメント - Wikipedia この管理手法を、技術相談の過程で生み出される情報資産の管理に適用しています。 「ナレッジマネジメント」に関しては、北陸先端科学技術大学院大学 知識科学研究科 梅本研究室の資料が大変参考になります。 www.jaist.ac.jp SECIモデルとは? 「SECIモデル」とは、ナレッジマネジメントのフレームワークであり 個人の暗黙知を組織的な形式知に変換し、その形式知を個人が体験することで暗黙知に変えていくプロセス になります。 そのプロセスにおける、知識変換の流れを4つのステージで表現しています。 それぞれのステージを簡単に説明すると、 共同化 では、個別の暗黙知を共有し組織の暗黙知として扱えるようにします。 表出化 では、組織の暗黙知を明示的な言語や図を通じて形式化します。 連結化 では、形式化された情報を組合わせて新しい形式を生み出したり体系化します。 内面化 では、整理された情報を使って個人が行動・体験して新しい暗黙知にしていきます。 このプロセスを継続的に回し続けることで、 組織的に使える情報資産を作り、個人と組織に貢献していくことが可能になります。 アーキテクト相談の対応範囲 「SECIモデル」はやや難しそうにも見えますが、チームとして具体的にやっていることがイメージできると、意外とシンプルであることがわかります。 宛先のない技術相談の窓口として機能し、課題の顕在化を推進する( 共同化 ) 課題を整理し、ソリューションを一緒に考え、ナレッジ化する( 表出化 ) ナレッジを体系化する( 連結化 ) 新しいナレッジの認知を促し、個人が利用できる状態を創出する( 内面化 の環境整備) ここから分かる通り、「アーキテクト相談」の責務は単純に相談内容に回答するだけに留まりません。 「SECIモデル」の共同化から内面化までの全てのプロセスに関与します。 では、具体的に何をしているか説明します。 プロセスをスムーズに回せるような環境・運用整備 「SECIモデル」の実践において、相談者や回答者側のルールを整備や、相談窓口の多様化(チャット / オンライン会議 / チケット駆動)など、日々改善サイクルを回しています。 たとえば、 ナレッジの一覧をどのようにすれば見つけやすくなるのか? ナレッジのフォーマットはわかりづらくないか? ナレッジ担当の負荷は分散されているか? 相談者は質問しづらくないか? 効果測定をどのように行うか? など、考慮ポイントは多岐に渡ります。 そのため、週次の定例MTGにて相談内容と運用改善についてディスカッションし、TRYし続けています。 表面化・連結化における、形式化(ナレッジ化) 技術相談への回答後、そのやりとりからナレッジを抽出しますが、ひとつの相談から複数のナレッジが得られることもあります。 それらのナレッジ候補について、チーム内でナレッジ化の必要是非についてレビューを行います。無駄に全てをストックすることはしませんし、再利用しにくい知識はここでフィルタされます。 ナレッジ化が合意された知識はドキュメンテーションされますが、その成果物であるナレッジもチームによるレビューが行われます。これによりナレッジの質を高めています。 また、ナレッジを検索しやすいように整えたり、そのナレッジ同士の関連を更新していく作業も対応範囲のひとつです。 運用への向き合い方 技術相談および「ナレッジマネジメント」の運用過程において、課題や懸念点も生まれてきます。 ここでは、運用における課題や懸念点について、チームがどのように考え、向き合っているかを紹介します。 回答に時間がかかりませんか? 技術相談(特にチケット駆動)でのやりとりは、全てにおいて決して早いレスポンスが返せているとは思っていません。 提供された資料の読み込みと、回答期待値のすり合わせに時間がかかるケースなどは一定数存在します。 ただし、これらは回答精度をあげるために必要な時間であったりもするので、 ある程度は許容しています。 許容はしつつも、それらを可能な限り短くしようとする改善活動は行い続けています。 たとえば、あまりにも回答に時間がかかりそうなチケットは、チケットを分割することで回答者側のアサインを増やす工夫をしています。 仕組みに縛られすぎず、 目的を見据えたうえで柔軟に対応しています。 他の技術相談窓口と競合しませんか? LIFULLではスペシャリティのあるチームが多数ありますので、そういったチームでは相談窓口を開いています。 しかし、それらと 競合するとは考えていません。 相談者の質問ドメインが明確であれば、それぞれのスペシャリストなチームが対応するのが、最も適切で自然だと考えているからです。 たとえば、社内のアプリケーション実行基盤チームはSlackで問いかければ数分で答えが返ってきます。その体験は代替できないものであり、専門的な相談に対しては直接聞いてもらったほうが明らかに全員の幸福度は高いと考えています。 逆に、ドメインを定義しにくい相談や、クラウド活用、アプリケーションの設計に関する相談については、「アーキテクト相談」が窓口になるケースが多いです。 ナレッジの効果測定はどうやっていますか? これはまだ試行錯誤中ですが、その中でもいくつか取り組んできた例を紹介します。 まず前提として、アーキテクト相談では ナレッジをConfluenceに保存しています。 Confluenceとはチーム開発におけるドキュメントのコラボレーションツールです。 非常に多機能で、JIRA(課題管理ツール)と連携するとドキュメントを統合的に管理することができます。 www.atlassian.com 効果測定として、当初はナレッジへの「いいね」の数などが指標の候補になりました。 しかし、もっとわかりやすく直感的なフィードバックをいただけるように、以下のようなアンケートページをConfluence上に作成しました。 ConfluenceではHTML(+css+javascript)を記述することができるので、HTMLマクロでアンケートを作成しています。 ボタンを押すと、そのページのコメントに評価内容を投稿する仕組みになっており、各ナレッジからこのマクロを含むページをインクルードすることで、アンケートを一元管理しつつ、より詳細なフィードバックが得られる仕組みを実現しています。 また、直近では、Google Analyticsを使い、効果測定のための指標を作れないか検証を始めたりもします。 ここらへんは、まだまだ発展途上です。 情報鮮度への対応はどうしてますか? Confluenceのラベル機能を利用して、見直す可能性があるナレッジを可視化しています。 具体的には、ナレッジに「要ナレッジメンテ」のラベルを付与し、コンテンツレポートテーブルマクロで一覧化しています。 これらを定期的に見直す仕掛けをつくることで、鮮度を保っていきたいと考えています。 まとめ 以上、 「アーキテクト相談」という技術相談を通じたナレッジマネジメントの実践 について紹介しました。 技術相談については、100社あれば100社のスタイルがあると思います。 それぞれのベストプラクティスを探す旅に正解や終わりはありません。 「アーキテクト相談」への 相談件数は前期比で2.8倍になり相談していただけるUUも増加傾向にあります が、まだまだやれることがたくさんあると感じており、今後も改善しつづけ発信していきたいと思います。 我々は、「SECIモデル」を用い "知識の管理"、"知識の経営" を実践していくことで 「経営をリードするエンジニア」を体現していきたい と考えています。 新しい季節は人の流れが変化し、技術的な相談事が増える時期でもあります。 そういった機会をチャンスと捉え、「SECIモデル」で社内で使える知識に変えていきたいですね。 弊社の取り組みが、これから技術相談のフローを整備しようとしている方の参考になれば幸いです。 *1 : Wikiより抜粋
品質改善推進ユニット 品質統括グループの岡です。 社内の開発が円滑に効率よく進められるような仕組みづくりや、システムやプロセスの品質向上のための活動をしています。 昨年より始めた取り組みを紹介いたします。 きっかけ LIFULLでは、常に新しいことに挑戦し、スピード感を持って日々開発を進めていける土壌があります。 一方で、組織も大きくなり運営するサービスも増加してきたこともあり、開発チーム、各プロジェクト、システムの状況を把握することが難しくなってきました。 そんな状況の中で、情報をもっと早くキャッチアップできていたら予防できたはずの障害が発生し、課題が明らかになりました。 「システムや開発プロセスの品質が見えていなくて、打つべき対策を打てていない可能性が…」 「そういえば、運営するシステムに関する情報が品質改善の組織としてきちんと把握できていない…」 品質改善推進Uが行ってきたこれまでの開発PJ支援は、主には開発担当者からの相談を受けてからでしたので、どうしても後手になってしまったり、問題が起こるまで手を打てずにいました。 目指すのは開発チームのパートナー そこで、必要な対策が事前に打てるように能動的にこちらから働きかけていくことはできないか、ということになりました。 やりたいことは、「○○ができてません」といった品質に関する指摘をしていく…ということではありません。 私たちは、開発チームに寄り添って、コミュニケーションすることを大切にしていきたいと考えています。 共に品質に関する状態を確認し、今後の計画を見つめ直すことで、後回しになりがちなシステムの技術的負債の解消に関わる改善施策などが中長期的計画にしっかり組み込まれるようになる、そんな改善サイクルを構築していくことを目指すことにしました。 はじめに、理解するところから まずはLIFULLで運営するプロダクトについて、アセスメント(情報収集、調査、分析、評価)を行う必要がありました。 プロダクトオーナーの協力を得て集まった定性的情報、各種ツールを利用して取得した定量的データなど様々な情報をコンバートしてデータベース化し、TableauというBIツールを利用して情報集約と可視化を行いました。 それらのデータを元に、品質に関して専門に動ける品質改善推進の組織が、開発チームの協力を得ながら追加の情報収集と調査を共に行い、理解を深めながら今後の計画を検討することにしました。 アプローチしたいプロダクトは… とはいえ、プロダクトの数は90近くあったため、収集済みのプロダクト情報から1回目のアセスメントによりアプローチを開始するプロダクトを絞り込み、初回の対象プロジェクトとして、以下の3つの項目に注目して約4分の1のプロダクトを抽出しました。 事業規模(売上や会員数など) 個人情報の保持件数 セキュリティに関する対策状況(定期的な診断状況、監視運用体制など) 現在、初回の対象プロダクトとなった開発チームに対し、アプローチを開始し、詳細のヒヤリングや追加調査などに着手し始めたところです。 ひと段落したら、例えば運用状況(開発形態や外部サービス連携有無など)やシステム経過年数など、別の観点でのアセスメントにより抽出したプロダクトへのアプローチを検討する予定です。 開始してみて いくつかの開発チームと取り組みを開始したところですが、どの担当者も快くざっくばらんに応じてくれ、非常に協力的で助かっています。 意図を理解しようとしてくれているのを感じますし、開発者としての問題意識の高さを感じます。 この活動を通して、 「複数の課題があり何を優先して対応すべきか迷っている」 「対策していたが、今回再確認したら別の要因でうまくいっていなかったところが見つかった」 「体制変更により業務フローも変更のため、早急な移行計画が必要」 など、課題の整理や気づきを得られたり、さらに深掘りした調査の実施に繋がったり、協力体制を築くきっかけになったりしています。 より効率の良い品質向上への改善提案、計画、支援につなげていく流れを作りたいと考えています。 まとめ 今回の取り組みは私たちにとっては新しい試みであり、完成形はまだ見えていません。 生み出されたサービスの品質維持・向上と、さらにスケールさせていくための後押しとなるような、意義ある活動にしていけるようこれからも試行錯誤していければと思います。 お読みいただきありがとうございました。
はじまして、プロダクトエンジニアリング部の関川です。 最近はテレワークの影響で、めっきり外に出ることが少なくなり、会議もzoomなどを用いたものがほとんどです。 巷ではVR空間で会議するなどを一部の企業が取り入れているようでwithコロナの新しい風を感じます。 そんなオンラインVRが導入されるのはまだ先の話の方が多そうですが、まず自作で体験してみるのはどうしょうか? そのための技術の選定や簡単なPUNを用いたプロジェクトの作成方法をまとめたので試してみてください。 また今回は導入ですが、次回の記事でoculusを用いたオンラインVRを作成していきます。 オンラインVRを作成する場合に上がるBaaS技術 VRを作成するといえばいろいろな開発環境想像される方は多いですが、 今回のターゲット開発環境は Unity です。 開発環境 Unity2019.4.15f1 VRオンラインサービスを作るとなると ・サーバーはどう用意する? ・費用は? などを考える必要があり、一気にハードルが上がるイメージですが そんなときに利用したいのがネットワークエンジンライブラリ。 ライブラリの導入は爆速でネットワーク問題を解決してくれます。 Unityに対応したネットワークエンジンは複数あり、その概要と個人的見解などを紹介します。 結論から書くとタイトルにある通り、PUN2はいいです。 PUN(Photon) Photon Unity Networking Photonは世界No.1の独立系リアルタイムネットワークエンジンです。そのUnity用パッケージをPUNと呼びます。 フレームワークとしてPUNとPUN2があり、今からやるならPUN2を推奨します。 photonはマルチプレイヤーでのゲームを可能にし、あらゆるプラットフォームのゲームに対応しています。(PC、スマホ、家庭ゲームなど) また機能として、ユーザー数に応じた自動スケーリング、ランダムマッチなどを可能にするマッチメイキングAPIなど開発を支援するものが盛りだくさん。 個人的にはアセンブリが整理されていてテスト書きやすそうという部分が大きいです。 MUN Monobit Unity Networking マルチプレイを簡単に実装できるUnity専用の無料アセットです。 日本の開発ということもあり、法人へのサポート体制がかなりしっかりしていそうです。利用料もPUN2と変わらず、過去に 違い と言われてたUDP通信非対応はMUN2では対応されたため、いよいよPUN2との差がほんとにすくない印象なのですが 個人単位でのドキュメントとかがあまり見られないので、学習面を考えると日本語、英語合わせて文献豊富なPUN推しです。 UNet Unity5.x系の最大の産物。 Unity公式のネットワークエンジン。 この項目で伝えたいことは UNet は非推奨となり、今後 Unity から削除される予定です。新しいシステムが開発中です。 ただこれはよく使われていたBaaSなので、 PUNもMUNもこれをベースに作られています 。 故にUNetの記事は調べると今でもかなり出てきますし、たまにPUNと偽って出てくる時があるので注意です。 チュートリアルとかも手厚いのでネットワークエンジンの基礎を学びたい方はここをあえてやるのもいいのかもしれないです。 Mirror UNetからの移行をするユーザーのためのOSSのネットワークフレームワークです。 これ単体ではPUNなどと違い、インターネット経由の通信はできず、LAN内環境で動かすことができます(逆にPUNはPhoton server経由がマスト)。 そのため、 インターネット環境を必要としないのは魅力的ですが、サーバーも別容易となるとオンラインVRを爆速で作るには学習コストが高いですね。 個人的には文献もさほど多いとは言えないのとUNetから入らないと「Mirrorワカラナイ」になりそうなのでここでもPUN推し。 結論:PUN2を使う PUN2とMUNはほんとに近い物で、選ぶときは少し迷いましたが、やはり困ったときの文献の量は非常に大きいので、今回はPUN2を用います。 そのためPUN2についてもう少し掘り下げて行きます。 PUN2とは 仕組み PUN2は極力開発者の負担を減らすため、構造すら 公式チュートリアル で「気にする必要がない」と明言しているくらい開発者は意識せずとも作成できます。 そのため、ここで理解しておかないといけないのはPhotonのマスターサーバーとロビーとルームの概念です。 マスターサーバーはPhotonに対するすべての通信を管理している立場であり、複数のゲームサーバーが存在しています。 その先にゲーム単位など個々のロビーが存在しています。 さらにそのロビーの先にプレイヤー同士が集うルームがあるイメージです。 Photonはこの概念が重要なの覚えておくとよいです。 利用料 PUN2自体は無料ですが、Photon Cloud自体は料金表が存在します。 利用料は従量課金性で、指標としてCCU(Concurrent Users:同時接続ユーザー数)と転送量が出てきます。 利用プランとして 20CCUまでは無料枠として使うことができるので、開発などの段階やお試しが可能です。 詳しい料金に関してとPUN plusに関しては今回のスコープから外しますので、 こちら を参考にしてください。 PUN2でオンラインの空間を作る VR開発を行う上だとどのデバイスに対応しようとかはあるのですが 今回はまずオンラインゲームを作る大まかな部分を手順を解説していきます。 まずは登録・ルームサーバーを立てる ここら辺は大体のPUN2に関しての 他の記事 で書かれているので割愛しますが大まかな流れだけ共有します。 ボイスチャットを用いるので二つのアプリケーションidを作成してください。 1. Photonの公式サイトに入り、右上の会員登録を済ます。 2. マイダッシュボードへ行き、新しいアプリケーションを作成しアプリケーションIDをコピーする。 3. Photon Voiceのアプリケーションを作成して、アプリケーションIDをコピーする。 プロジェクト作成する unityを立ち上げプロジェクトは3Dで作成します。 プロジェクトにasset storeからPUN2とPhoto Voice 2をインストールして、 各IDを入力してください。 サーバーとの接続はこれ一行 PhotonControllerという名の空オブジェクトを作成おいて、 scriptsファイルにC#コードを追加 Photonのネームスペースを追加して一行。 PhotonNetwork.ConnectUsingSettings(); これをシーン開始の"start"の中に仕込めば完了。 ルーム作成とジョインのコールバック定義 次にマスターサーバーへ接続完了した後のコールコールバックを定義します。 動きとしては、 1.マスターサーバーに入って、ルームがあれば入る 2.なければ作成してルームに入る という流れ。 コールバックが爆速に早くなったのがPUN2のPUNとの違いだそうです。 public class MatchMaker : MonoBehaviourPunCallbacks { // アバター public GameObject PhotonObject; void start (){ PhotonNetwork.ConnectUsingSettings(); } // マスターサーバーに接続したとき public override void OnConnectedToMaster() { // ルームがないならルームを作り,あとならそのままルームに入る PhotonNetwork.JoinOrCreateRoom( "room" , new RoomOptions(),TypedLobby.Default); } // ルームに入ったとき public override void OnJoinedRoom() { // アバター(オブジェクト)を作成する PhotonNetwork.Instantiate(PhotonObject, Vector3.zero, Quaternion.identity, 0 ); } } photonサーバー設定を行う photon server setttingsを探し以下のように設定を行います。App IDを設定していればJPサーバーに設定を変更するだけでよいです。 Photon VoiceのAppIDも忘れずに入力しましょう。 状態共有するには?(オンラインゲーム化) アバターとして扱うゲームオブジェクトは prefab化 しておきます。 また共有したい情報によりますが、アバターなど人型の場合,add componetから "Photon view"と "Photon TransormView"と"PhotoAnimatorView"を追加します。 さらに"Audio Source"と"Photon Voice Speaker"をボイスチャット用に着けます。 実行する オブジェクトにスクリプトを結び付けなどを行い、 アプリケーションをビルドして最低二つのアプリでログインし、同一空間にアバターが二つあり、声が届いていれば成功です。 まとめ 爆速でのオンラインツールを開発可能にするのがPUN2の強みです。 ぜひ一度やってみてはいかがでしょうか? 今回はオンラインVRを作成する前段階としてオンラインゲームを作成しましたが 次回はoculusのデバイスを用いて、オンラインVR作成する手順を解説したいと思います。
KEELチーム の相原です。 最近開発している コマンド1発でKubernetes上にProduction Readyな環境を手に入れる コードジェネレータの話です。 Kubernetesの利用を広める上での課題 Kubernetes Manifestの難しさ 既存の解決策 設定量の増大 コードジェネレータで解決する 捨てやすさ 抽象度 変更への追従しやすさ Open Application ModelとKubeVela keelctl を開発してきてみて Kubernetesの利用を広める上での課題 KEELチームが開発しているアプリケーション実行基盤は巨大なMulti Tenancy Kubernetesクラスタをベースとしていて、各アプリケーション開発者はKubernetes Manifestといくつかの設定を記述するだけでProduction Readyな環境ですぐにアプリケーションを稼働させることができます。 これは車輪の再発明の防止や開発速度・運用品質の向上などの大きなメリットをもたらし、LIFULL HOME'Sの大部分と新規開発のアプリケーションの多くがこの上で稼働するようになりました。 こうして我々のプロジェクトは一定の成果を得ることに成功しましたが、社内で利用を広めていくにあたっていくつかの問題点が出てきました。 Kubernetes Manifestの難しさ 一つ目はKubernetes Manifestの難しさです。 topologySpreadConstraints や podAntiAffinity を利用したPodの適切な分散 PodのTerminating時にEndpoint ControllerによってPodのIPがロードバランシング対象から外れるのを待つための preStop フック(あるいはそれ相当のアプリケーションによるSIGTERMハンドリング) 安全なPod Evictionのための PodDisruptionBudget の設定 Recommended Labels の付与 適切なSecurityContextの設定 Kubernetes Manifestを書くにあたっては、このような広く知られているベストプラクティスがいくつかあり、アプリケーション開発者にこうした設定を要求するには無理があります。 LIFULLではIstioを利用している ため更に設定量は増えますし、Service Topologyのようなバージョンアップによって増えた新しい機能も取り入れて欲しいといった思いもあります。 既存の解決策 一般にこういった課題を解決するためにはHelmや、現在ではKustomizeなどが用いられてきました。 これらのソフトウェアを利用することでベストプラクティスをテンプレート的に用意して、利用者は必要最低限のパッチを当てるだけでよいというようなものです。 ただしHelmはChartの作成者によって自由度が大きく変わるため、特定のミドルウェアであればともかく大勢が満足するようなウェブアプリケーションのテンプレートをHelm Chartとして提供することは難しいです。 Kustomizeは割とこの問題の解決だけを考えれば理想的な選択肢で、 Remote Build を用いればベストプラクティス部分をうまく共通化できるでしょう。 モノレポにしていればRemote Buildも必要ありません。 実際に我々もKustomizeは出た当初くらいから長く使ってきています。 LIFULLではモノレポではなく権限分離の考えからアプリケーションごとにリポジトリを分けているため、当時はまだなかったRemote Buildが必要となりKustomizeのWrapperを自前で書くなどしてこの問題に対処してきました。 しかし、次第にKubernetes Manifest以外の生成にも目を向ける必要が出てきて、より包括的なアプローチが求められるようになりました。 設定量の増大 我々はアプリケーション開発者の関心事を減らすため、KubernetesやIstioをはじめとしてその他開発者支援のための多くのKubernetes Operatorを提供しています。 他にもGrafanaやPrometheus(+ Thanos + Trickster), Fluentd, Spinnakerを提供することによって監視基盤やデプロイパイプラインなども運用して開発者に提供しています。 それぞれにOperatorがあったりなかったりなかったら作ったりしていますが、それでも全てをKubernetes Manifestで設定することは叶いません。 これではManifest TemplatingソフトウェアでKubernetes Manifestを生成してからも数ステップの設定作業が必要となってしまいます。 更にビルドパイプラインや各種Lintをはじめとした多数のGitHub Actions、依存AWSリソースを作成するためのCloudFormationテンプレートも提供しているため、いずれにせよ設定量の増加が課題となってきていました。 (Kustomizeと同様にCI周りもモノレポだと楽になりそうですが、モノレポをちゃんとやろうとすると先述の権限分離に加えてVCS周りを頑張らなきゃいけなくなったりするのでリポジトリ戦略を変えるという判断にはなりませんでした) コードジェネレータで解決する こうした課題を解決するため我々はコードジェネレータ keelctl を開発しました。 こちらで用意したKubernetesのCustom Resource Definitionをインタフェースとして、開発者がそこに必要な項目を入力すると先に述べたようなアプリケーションの開発サイクルに必要なものが すべて 自動で生成されます。 生成されるものは以下のように多岐に及んでいます。(かろうじて秩序は保たれています) Kubernetes Manifest ConftestやDocker Imageへの動的解析など各種Lintを実行するGitHub Actions git-flowを実現するためのGitHub Actions ビルドパイプライン他各種AWSリソースを作成するCloudFormation Template ビルドされたDocker ImageやKubernetes ManifestをデプロイするためのSpinnakerのパイプライン PrometheusおよびAlertmanagerでのProduction Readyなアラート設定と通知先設定 GrafanaのProduction ReadyなDashboard 上記に関する説明やダッシュボードへのリンクなどのドキュメント まさに コマンド1発でKubernetes上にProduction Readyな環境を手に入れる コードジェネレータです。 ビルドパイプラインもついているので正真正銘コマンド1発叩いた瞬間からGitHubにpushするといい感じにデプロイされるようになります。 (小さいアプリケーションの参考実装が入ったGitHubのTemplate Repositoryも一緒に提供していて、そこにはDockerfileも入れているため開発初期からこれらを手に入れることができます) ドキュメントの自動生成は結構気に入っています。 そのアプリケーションのリポジトリ内にドキュメントを生成することでよくありがちなオレオレドキュメント乱立の防止をしたり、諸々の設定とライフサイクルを共にしていることでドキュメントが古い状態で放置されるあるいは中央管理されているドキュメントから古い情報が消されて置いて行かれるといったことが防がれています。 辛いことや面倒なことをアプリケーション開発者のために肩代わりするようなソフトウェアであるためやってることは結構泥臭くて、Custom Resource Definitionに入力された設定値をもとに筋肉であらゆるファイルを動的に生成するといったようなことをしています。 Custom Resource Definitionを使っていますが、以下のような点を考慮しながらCustom Controllerとしてではなくコードジェネレータとして作りました。 捨てやすさ 先に述べた問題をCustom Resource Definitionで抽象化して解決するということはKubernetesの上にPaaSを構築することと等しいです。 PaaSの採用を決めるにあたって最も懸念となることが、捨てやすさです。 PaaSはその性質上、利用者から見たインタフェースの抽象度が高く内部の処理もブラックボックス化されているため、別のPaaSへの移行やPaaSをやめる際に多くのコストがかかってしまいます。 Custom Controllerはいい仕組みですが、今回のような乱暴なユースケースではいざ我に返ってこのアプローチをやめようとした時に捨てづらく、やめる際にもコストを支払うことになってしまいます。 一方、コードジェネレータであれば成果物として生成されたファイルをそのまま使い続けられるように設計することが可能です。 そこでCustom Controllerを作るときの要領でCustom Resource Definition周辺のエコシステムを活用しながらも、Kustomizeでそのまま使えるKubernetes Manifestを生成したりするなどして捨てやすさを念頭に置いて開発されています。 Custom Resource Definition周辺のエコシステムは非常に強力で、Validation, Versioningやドキュメントの自動生成、エディタの補完などの恩恵を受けることができるためCuston Controllerでなくともインタフェースとして利用する価値がありました。 抽象度 PaaSをデザインするにあたっては、抽象度をどのようにコントロールするかも考えなければなりません。 先に捨てやすさを意識しているのでロックインはされませんが、抽象度はユーザ体験と拡張性に影響します。 実際に我々はここで一度失敗をしています。 keelctl 以前に開発していたKustomizeのWrapperのように振る舞うManifest Templatingソフトウェアでは、極力アプリケーション開発者がKubernetesのことを知らなくてもいいようにKubernetesの概念を完全に隠蔽する強い抽象化をしていました。 しかし、次第にアプリケーション開発者の要求が複雑化してManifest Templatingソフトウェアが追い付かなくなったり、Kubernetesに詳しいアプリケーション開発者が細かくコントロールしたいと結局実装を読むみたいなことが起きるようになってしまいます。 その失敗を経て、 keelctl で利用するCustom Resource DefinitionではKubernetes Manifestの部分で抽象化を行わないようにしました。 こんな感じです。 apiVersion : keel.lifull.com/v1alpha1 kind : KEELConfiguration metadata : name : &name keelctl-sample spec : ... applications : - base : metadata : name : *name spec : feature : redis : enabled : true replicas : 5 deployment : spec : strategy : type : RollingUpdate rollingUpdate : maxSurge : 25% maxUnavailable : 1 template : metadata : annotations : sidecar.istio.io/inject : "true" spec : containers : - name : &main-container server env : - name : TZ value : Asia/Tokyo ... overlays : - name : *test override : metadata : namespace : *test-namespace spec : deployment : spec : template : metadata : annotations : sidecar.istio.io/proxyCPULimit : 100m sidecar.istio.io/proxyMemoryLimit : 256Mi sidecar.istio.io/proxyCPU : 100m sidecar.istio.io/proxyMemory : 256Mi spec : containers : - name : *main-container image : *test-repository このようにDeploymentといったKubernetes Objectをそのまま露出させています。 これには、エディタの補完でupstreamのものをそのまま利用できたり、Kubernetes Manifestを生成する時の実装が楽、Kubernetesに詳しい人がそのまま弄れる、拡張性が高いみたいなメリットがあります。 実際にDeploymentと同列にIstioのVirtual ServiceやDestination Ruleなども設定できるようになっており、実装コストとyamlの秩序が許す範囲であればいくらでも拡張することができます。 (それぞれの apiVersion はCustom Resource Definitionで管理していて、それぞれに非互換の変更が発生した際はCustom Resource Definitionの apiVersion を変えて対応しています) その上でアプリケーション開発者の関心事を減らすべく、 topologySpreadConstraints や Pod Disruption Budget , Recommended Labels のような露出すべきでない情報を生成時の実装に閉じ込めていて、裏でいい感じにそれらをデフォルト値として生成してくれるようにしてKubernetes特有のベストプラクティスを知る必要がない状態にしました。 こうしてベストプラクティスを知る必要がない状態になってしまえばKubernetesに詳しくない人のための抽象化は不要で、必要な項目があらかじめ埋まっているテンプレートを用意したうえで各項目に丁寧なコメントを付与するだけで十分やっていけています。 難しいのはKubernetes ManifestではなくKubernetes特有のベストプラクティスなのでそれさえ裏に隠してしまえばこの程度で十分でした。 Kubernetes Manifestの公式ドキュメントはよくできているため、無用な抽象化はドキュメントの焼き直しにしかなりません。 Kubernetes Objectで表現できないような機能については雑に feature というキーを用意していて、ここでキャッシュ用のRedis/memcachedクラスタやLighthouseを実行してPrometheus用のMetricsを出すPrometheus Exporterとかを利用できるようになっています。 またKustomizeに倣って base と overlays というキーを用意していて、ここで共通部分の定義と環境ごとの出し分けを実装しました。 ここでも Strategic Merge Patch というupstreamの機能をそのまま利用することで実装をサボっています。 抽象度をうまくコントロールすることで、upstreamの成果を利用しながら利用者の知識レベルに依存しない使いやすいインタフェースを実現することに成功しました。 変更への追従しやすさ 同じことをCustom Controllerで実現すると更新の配布のしやすさはCustom Controller側に軍配が上がります。 Custom Controller側を弄るだけで利用者に等しく更新を配布することができるためです。 逆に更新の配布を考えなければGitHubのTemplate Repositoryで配るだけでも十分かもしれません。 そこで、コードジェネレータでも似たような更新の配布しやすさを実現すべくセルフアップデートの機能を実装しました。 セルフアップデートの機能があれば、コマンドを叩くだけでバイナリを最新の状態に保つことができます。 また、生成される成果物のテンプレートはgolang 1.16から入った embed を利用して全てバイナリに含めています。 (バイナリはそれなりに大きくなりますが2021年に問題があるレベルではありません) こうすることでテンプレートもバージョン管理されるため、利用者は以下のようなコマンドを定期的に実行することで手元の設定ファイルを最新に保つことが可能となりました。 $ keelctl self-update $ keelctl gen keel_configuration.yaml . こうして更新の配布を簡単にすることで、各設定を最新に保つだけでなくセキュリティ面での統制を効かせることにも成功しています。 更に .keelctl_version のようなファイルも生成することで、それぞれのリポジトリが利用している keelctl のバージョンを外からトラッキングできるようにもして統制を強化しました。 全社基盤をやっていて陥りやすいものとして、作った機能が使われない、責任分界点が曖昧になり更新作業などが行われない、といったものがあると思います。 keelctl ではCustom Resource Definitionを責任分界点としつつ、更新を半ば強制的に配布する仕組みを整えたことでそうした問題への対処に成功しました。 また、 .keelctlignore というファイルに .gitignore と同じ書式でパターンを記述すると任意のファイルをオプトアウトする機能を実装しています。 これを利用することで例えば今はKubernetes Manifestの生成はせずに、ConftestやDocker Imageへの動的解析など各種Lintを行うGitHub Actionsだけを生成したいといった要求を叶えることができます。 これにより既存のリポジトリに段階的に導入することが可能となり、利用先は今ではLIFULLの大部分にまで広がりました。 自分の書いたコードをすぐに全社に配布できることからチーム外からのContributionも多く来るようになり、 keelctl は日々目まぐるしく進化しています。 Open Application ModelとKubeVela 実は似たような試みとしてMicrosoftが主導する Open Application Model というプロジェクトとその実装である KubeVela があります。 oam.dev kubevela.io Open Application Modelはクラウドネイティブなアプリケーションを定義するための仕様で、KubeVelaはそれをKubernetes上で実行するための実装です。 apiVersion : core.oam.dev/v1beta1 kind : Application metadata : name : first-vela-app spec : components : - name : express-server type : webservice properties : image : crccheck/hello-world port : 8000 traits : - type : ingress properties : domain : testsvc.example.com http : "/" : 8000 このようなKubernetes Manifestを適用するとKubeVelaがCustom Controllerとして いい感じ にKubernetesに展開してくれます。 KubeVelaは Traits という概念で機能をコントロールすることができ、デフォルトで KEDA や Flagger などが組み込まれています。 例えば上記の type: ingress のようなものがそうで、このような設定を記述するとFlaggerによるCanary Deploymentなどを手に入れることができるといった感じです。 つまり、KubeVelaはOpen Application ModelをインタフェースとしてKubernetes上にPaaSを構築できる、 コマンド1発でKubernetes上にProduction Readyな環境を手に入れる ソフトウェアです。 Traitsは このようにPlatform Builderによって拡張可能 で、 keelctl の feature のようにキャッシュ用のRedis/memcachedクラスタを展開するためのTraitsを提供するみたいなことが可能となります。 type: webservice に相当するWorkload Typeも同様に拡張可能であるため、抽象度が高いことによって痒い所に手が届かないみたいな問題は少なくともWorkload Typeを拡張すれば解決できるでしょう。 keelctl の構想当初にOpen Application Modelは無かったのでLIFULLではこのようなアプローチになりましたが、Kubernetes上でPaaSっぽいことをやりたいのであればKubeVelaは有力な選択肢であると思います。 (今や keelctl はKubernetes Manifest以外にも手を出していたり、LIFULLが構築してきたKubernetesエコシステムを手放すという判断には中々なれないので直近での移行は検討していませんが...) 強いて言えば、KubeVelaがCustom Controllerであることの捨てづらさは理解して慎重に判断した方が良いということくらいでしょうか。 アプリケーション開発者の辛いことや面倒なことを肩代わりするために我々のようなPlatform Builderの努力を要するという点は keelctl でもKubeVelaでも同じでそれはPaaS提供者の宿命です。 keelctl を開発してきてみて ということで コマンド1発でKubernetes上にProduction Readyな環境を手に入れる コードジェネレータを開発した話でした。 やっていることは泥臭いですがもたらした恩恵は非常に大きかったです。 今まで楽観的に見積もっても2週間くらいかかっていたアプリケーションのローンチまでに必要な実行環境周りの作業、デプロイフローの構築やサーバの設定に監視周りの整備といったことが コマンド1発 で終わるようになりました。 他にも多くのアプリケーション開発者を支援する機能がチーム外からのContributionも受けながら提供されています。 そして、日々の改善はセルフアップデート機能によって多くいる keelctl 利用者に配布されて各種設定は最新に保たれ、こちらから利用状況がトラッキングできることで統制面でも役立っています。 コードジェネレータによってあらゆるものを自動生成するというアプローチは一見乱暴ですが、投資した時間に対して大きな成果が出ているし、捨てやすく作っているからと楽観視しています。 Kubernetesはその拡張性からこういったPaaSのような取り組みをしやすく、アプリケーション開発者の生産性向上やアプリケーション品質の向上に大きな影響力を発揮することができました。 そこからもう少し踏み込んでこういったコードジェネレータを開発することで更に影響範囲を広げることができ、我々 KEELチーム は単なるKubernetesチームではなくなり、より広く生産性や品質に責任を持つチームへと変化しつつあります。 広く生産性や品質に影響力を発揮したいKubernetesな各位はコードジェネレータの開発を検討してみてはいかがでしょうか。
何をしている人? こんにちは! 2017年に入社して5年目になります、志茂です! 2年半営業職を経験した後、未経験でwebアプリケーションエンジニアにジョブチェンジしました。 今回は未経験で異動するまで道のりとLIFULLでのキャリアの選択制度について、お話したいと思います。 プログラミングを始めたきっかけ まずは入社前の私ですが、私立文系と全くプログラミングと縁のない大学生活を送っていました。 就活を始めてインターンで出会ったLIFULLの社員の人柄にひかれそのまま入社しました。 初めてプログラムを書いたきっかけは、日々のルーティン業務を効率化できないかと考え、 Google Apps ScriptとChatworkAPIを使って、ルーティンタスクを毎朝通知するというものでした。 自分で作ったものが実際に動いて、ちょっと便利になっていくという体験をしていくうちに、 なんとなく「プログラミングを勉強したい」から、「エンジニアとしてユーザーに少しでも便利になるものを作ってみたい」という気持ちに変わっていました。 そう考えるようになってから、本格的に勉強を始めました。 勉強の方法は人それぞれだと思いますが、自分の場合は周りの環境から変化させるために、G's ACADEMY(ジーズアカデミー)さんというプログラミングスクールにお世話になりました。 転職ありきではなく、基礎から学んで、自分でサービスを一から作れるようになりたい方にとてもおすすめです! gsacademy.jp 背中を押してくれた直属の上司 仕事で何かを作るなら、思い入れと実現したい目的を共有できるサービスに携わりたいと考えていました。 そのため転職は考えず、社内で異動できないかと考え、動き始めました。 LIFULLではジョブローテーションを行っておらず、半期に一回社員一人ひとりのキャリアビジョンを本人と上司が共有し、 それに基づいて目標設定や人員配置を行う 「キャリア選択制度」 があり、 人事異動や職種変更、新規プロジェクトへの参加等の希望を随時申請することができます。 ただこれまでLIFULLの中で営業からエンジニアへの職種変更の事例は前例がなかったので、 ダメ元で 当時の上司に異動希望の旨と理由を相談したところ、 「エンジニアのこと詳しくないけど、やりたいことがあるなら応援するよ!!なかったら事例を作ればいいから、いろんな部署の人に相談してみよう!」 と背中を押してもらい、職種変更のために必要な関係者たちとの面談調整というタスクまで設定してもらいました。 そこから、エンジニアになるためのインプットはしっかり継続しながら、並行して関係部署との面談で「なぜエンジニアになりたいのか」についての想いを伝え続けた結果、 半年後にWebアプリケーションエンジニアにジョブチェンジすることができました。 会社からは、スキル面で言えば新卒のエンジニア内定者の水準に少し劣るレベルだったのですが、私自身の意志と熱意を信じてもらい、 初めは辛いけど、最後は気合いでがんばれ!のスタンスで送り出していただきました。 うまくいかない配属当初 配属でスタートから高速でキャッチアップして、成果を出す!!と意気込んでいたのですが、そう簡単ではありませんでした。 会社には最大限の配慮をしてもらい、自身が営業の時に携わっていた領域商材をそのまま開発できるようにしてもらい、 タスクの難易度も段階を経て、成長できる環境を与えてもらっていました。 それでも基本的な技術の理解が足りておらず、他のメンバーが数時間で終わる作業が何日もかかってしまう状況で、 周りは経験豊富なメンバーばかり、スキルのない自分は何も成果や価値が生み出せていないと、とても申し訳ない気持ちと焦りでいっぱいになりました。 そんな時に直属の上司が、 「プログラミングのスキルで足りないところは別のポータブルスキルでカバーして、周りの人にどんどん聞いて解決しよう!一つ一つ落ち着いて考えれば、必ずできるから」 と持ち歩いているスケッチブックで、構造やデータの流れなどを随時図示してわかりやすく説明してくれました。 そこから、自分に今できる最大限のことをしようと考えるようになり、 目の前のことに集中して、一つ一つ取り組むことを意識することができました。 いましてること 現在は「 住まいインデックス 」というエンドユーザーに、住まいにまつわる情報を提供して、自身にピッタリの住まいの探しの条件を決めることができるサービスを開発しています。 インフラ構築からサーバーサイド、フロントエンドもすべて5人いるチーム全員で担っています。 比較的新しいプロダクトになりますので、新機能を作っていくために、社内でもスキルの高いメンバーが集められています。 業務の中で一緒に働く経験豊富なメンバーたちから吸収できることがたくさんあり、日々新たなことを学んでいる感覚があります。 またスクラム開発を導入しているため、チームで議論する場が多くあることも学びが多くなっているポイントになっていると思います。 先輩達の思考や課題を解決する上での視点や観点を知ることができるので、毎日が成長の機会だと思って仕事をしています。 最近ではAWSのソリューションアーキテクトの資格を取得したこともあり、インフラの改修や運用を任せていただくことが多く、 自分の身につけたスキルがすぐに業務に活かせることがとても楽しいです。 これからやっていきたいこと 社内で初めて営業からエンジニアにジョブチェンジした前例を作ることが出来たので、 そのロールモデルになれるようビジネスサイドの経験や個性も活かしながらエンジニアとして成長をしていきたいと考えています。 まだ抽象的ではあるのですが、中長期的には技術の力とビジネスの力を組み合わせてサービスの成長を牽引し、 ユーザーやその先にある社会の課題を解決できるエンジニアになっていきたいなと思っています。 最後に LIFULLでは一緒に働く仲間を募集しています。 ゼロからやりたいこと、本人の行動と熱意を信じてをやらせてくれる環境があります。 私の記事を読んで、少しでもLIFULLに興味を持っていただけたら幸いです。
こんにちは。検索エンジンチームの加藤 宏脩です。 先日、検索エンジンチームでLIFULLが利用しているSolrのバージョンを7.xから8.xにバージョンアップしました。 今回のSolrバージョンアップから自社で制作した性能テスト、回帰テストツールを導入したおかげか 大きい障害はなく無事にリリースできました。 リリース後は検索精度、パフォーマンスも向上しておりほっとしているところです。 8.xへの移行時はいくつか問題がありましたが、中でもbqパラメータのNegative Boostの廃止対応がたいへんでした。 Negative Boostの廃止対応が必要なことはバージョンアップ時のテスト中に気付き、簡単な対応だと思っていたのですが 並び順を維持させようとすると速度劣化が激しくなったりと対応がかなり難航するということがありました。 この記事では、Solr 8.xへのバージョンアップ作業の障害となったNegative Boostの廃止をどのように 対応したのか話をさせていただければと思います。 bqとは Solrのパラメータの一つで、条件にマッチしたデータを重みづけして優先順位を上げたり下げたりする機能です。 bqについてのドキュメント https://solr.apache.org/guide/8_8/the-dismax-query-parser.html#bq-boost-query-parameter Negative Boostとは ここでいうNegative Boostとは条件にマッチしたらマイナス方向の重み付けをすることを指しています。 例1 # hogeの値が5のデータを-100の重み付けをする bq=hoge:5^-100 Negative Boost廃止についてのチケット https://issues.apache.org/jira/browse/LUCENE-7996 どう変更したか LIFULLでの利用例 擬似的なスキーマ name type multiValued indexed description multiValuesParam1 pint true true multiValues型のパラメータ1つ目 multiValuesParam2 pint true true multiValues型のパラメータ2つ目 boolParams1 pint false true bool型のパラメータ1つめ。0がtrue、1がfalse boolParams2 pint false true bool型のパラメータ1つめ。0がtrue、1がfalse 例2のように multiValuesParam[1 or 2] に一致して、 boolParams[1 or 2] がtrueだったときにマイナスの重み付けをしていました。 例2 n=複数個の数字 bq=((multiValuesParam1:(n) AND boolParams1: 1) OR (multiValuesParam2:(n) AND boolParams2: 1))^=-100 (multiValuesParam1:(n) AND boolParams1: 1) の条件を1とし、 (multiValuesParam2:(n) AND boolParams2: 1) の条件を2とした場合 優先順位は、以下のようになります。 (1と2の条件どちらも一致しない、 1と2のどちらかの条件に一致しない) > 1と2のどちらの条件も一致する 変更案 結論から言うと、現行の重み付けに一致させる案は本番環境に耐えうる速度にはならなかったので3番目の案を採用して少し優先順位を変更するようにしました。 1. 条件の反転 例2の条件に当てはまらないデータを重み付けをするようにしました。 クエリは例3のように n 以外のデータに絞り込みつつ、 それだけではパラメータが空だったときの条件が抜けてしまうため例4のような条件を加えるようにしました。 例3 multiValuesParam1:[* TO (n - 1)] OR multiValuesParam1:[(n + 1) TO *] 例4 *:* AND -multiValuesParam1:[* TO *] 結果は、優先順位は一致するが速度が非常に遅くなってしまいました。 原因はおそらく検索する範囲が広くなりすぎてしまったことによるところが大きいと思います。 またNOT条件はキャッシュができないので、二回目以降のアクセスも速度が遅くなってしまうという問題がありました。 2. bfで代用 次に例2の条件をbfで代用するように試してみました。 bfパラメータはスコアが0以下にならなければマイナスの重み付けが可能です。 全件に100の重み付けをしたあとに、例2の条件をbfで実装するようにしました。 bfには where in 的な便利な構文はないので例5のような実装をつなげるようにしました。 例5 or(eq(multiValuesParam1, n), eq(multiValuesParam1, m)...etc) 結果は、優先順位は一致するが multiValuesParam[1 or 2] に指定する値が多くなると速度が遅くなってしまいました。 また、Solrには指定できる句の数に上限があるため、指定する値が多すぎるとエラーが変えるようになってしまう問題がありました。 3. NOTで計算する量を絞って計算にかかるコストを減らす(できるだけ理想に近い順番を編みだす) 反転のところでも記述したようにbqだけで解決しようとするとNOTの使用は避けられないので、 NOTで計算する量を限界まで減らすようにしました。 方針としては、例2の条件に当てはまらないデータをプラスの重みづけしていくようにしました。 実装は簡単に説明すると、例6のように前段で弾けるものは先にtrueを返すようにして NOTの条件に到達するときは対になる multiValuesParam[1 or 2] が一致かつ boolParams[1 or 2] が1のデータだけが残っているようにします。 例6 ( ( (multiValuesParam1:(n) AND boolParams1: 0) OR (multiValuesParam2:(n) AND boolParams2: 0) ...etc ) OR ([ここでできるだけ計算量を減らす] AND -(multiValuesParam1:n OR multiValuesParam2:n)) )^=100 結果、優先順の前後は同じで中間部が多少入れ替わるというようになりましたが、速度は元の実装と変わらないくらいになりました。 このやり方だと、NOTの前の条件を詰め込める環境であればさらに速度を早くできそうです。 まとめ 今回は、Solr versionの8.xへのバージョンアップに伴うnegative boostの廃止の対応をしました。 私自身Solrに投げらているクエリを大きく変えるというのはチームにジョインしてから初めてで良い経験になりました。 複雑な条件でNegative Boostを使用している方の助けになれば幸いです。(少数だとは思いますが。。) 検索エンジンチームでは今回のような、バージョンアップ作業をブロックしてしまうような問題をいち早く発見して解決できるようにするため、 Solrの新バージョンのリリースを検知し回帰テスト、性能テストを自動実行するしくみの導入を進めています。 また運用の自動化などで作った時間で、感動を届ける検索を実現することに注力しています。 カジュアル面談もやっていますので、一緒に「 感動を届ける検索エンジンを実現する 」、ひいてはLIFULLが目指している「 あらゆるLIFEを、FULLに。 」することに興味がある方はぜひお話しましょう! ここまで読んでいただきありがとうございました。 hrmos.co
は ろーはろー!チバです。 LIFULL HOME'Sのユーザー向けメール配信・LINE配信などのCRMシステム を担う部署に務めています。 今年2月にリリースした「 LINEで新着物件通知を受け取る」機能の担当者です。 www.homes.co.jp PdM/PjMのスキル発揮に触れながら、 「LINE新着物件通知」とは? プロジェクトの立ち上げ プロジェクトの実行 プロジェクトの終結 PdM/PjMのスキル発揮とキャリア形成 についてスライドにまとめたので、どうぞ、ご笑覧ください💁 ㊗ LINE新着物件通知 リリース!! PJ進行に沿って話す、 PjM/PdMとして やったこと - slideshare ㊗ LINE新着物件通知 リリース!! PJ進行に沿って話す、 PjM/PdMとして やったこと from LIFULL Co., Ltd. www.slideshare.net エンジニアが書いた同じ施策の記事 www.lifull.blog 最後に 今後もユーザーの住み替えに役立つ情報を、LINEやメールに限らずにオムニチャネルで提供して参ります。 記事・スライドの感想をぜひぜひ、Twitterでツイートしてください 。 エゴサしている私が小躍りしてRTします🙌 また、現在 一緒にCRMシステムを爆進させる仲間を熱烈募集中 です! 同じ部門で働けるポジションの求人の最新情報は採用ページご確認ください💁 hrmos.co \株式会社LIFULLでぼくと握手!/
はじめに みなさんこんにちは。 品質改善推進ユニットQAグループでQAエンジニアをしている飯泉です。 今回はチームで行なっている 「本番障害からテストのヒントを抽出して活用する」 ための活動について紹介したいと思います。 本番障害からソフトウェアテストのヒントに活かす「シンプルチャーターエレメント」 本番障害レポートからソフトウェアテストのヒントを抽出した観点集を「シンプルチャーターエレメント」と呼んでいます。 本番障害レポートを分析してどのような観点でテストをすれば障害を防ぐことが出来るのかまとめて開発やテストで活用をしています。 本番障害レポートとは LIFULLでは本番環境でバグが発見された場合に本番障害レポートを作成してバグの解消状況の管理と再発防止策の検討を行っています。 本番障害レポートは以下のようなにまとめております。 障害の影響範囲 障害の概要 障害が発生したサービス・利用者 原因 対策内容 再発防止策 シンプルチャーターエレメントはどんな内容か 本番障害の概要、原因、発生手順、このシンプルチャーターエレメントから発見を期待できる欠陥、テスト観点などを記載します。 参考にしたものは 「Explore It!」 「Explore It!: Reduce Risk and Increase Confidence with Exploratory Testing 」 は探索的テストの技術書です。 この中にある「A Simple Charter Template(シンプルチャーターテンプレート)」という探索的テストに使えるシンプルなヒントの作り方から発想を得ています。 シンプルチャーターエレメントの内容は、バグ発見へのインスピレーションが得られるようにするため以下を考慮して作成し、レビューを通してから全社のものづくりチームへ共有する形で運用しています。 抽象化の粒度 ソフトウェア起因でかつ汎用性のある情報にするため、プロダクト依存の情報は排除する イメージとしては、フリーズドライの食品のように、お湯(プロダクト情報)をかけるとテストのヒントが複数出てくるにまとめる 本番障害などの情報を元に 探索的テスト時のテスト観点となるようにまとめる 「(どの) 対象となる画面・機能 で、(どんな) 前提条件・操作 の時、(どんな) 期待値 か」 その他ポイント シンプルチャーターエレメントの内容がバグを再現できる粒度になっていること 再現する手順が汎用的かつ再現性のある手順であること 活用方法 開発で活用する 設計時の考慮漏れのチェックやソースレビューの観点に使えます。 過去に発生した障害を参考に作られているので同じバグを作り込んでいないかチェックをする時に活用できます。 テスト分析やテスト設計で活用する 「バグを発見するため」のテスト観点の洗い出しや、テスト設計時にフォールト指向で考える際に参考になります。 バグ発見のインスピレーションを得られるような内容にまとめているので、どのようにするとバグが発生するか広く考えるためのヒントとして使えます。 探索的テストで活用する 元々探索的テストのために作られていたので、シンプルチャーターと探索的テストとの相性が非常に良いです。 探索的テストは複雑な条件・タイミングの操作を実行することに向いているので、 本番障害が発生した手順を再現したり、そこから派生した操作するといったことが行いやすく、バグ発見に繋がりやすいです。 最後に 失敗を恐れず失敗に寄り添う文化がLIFULLには根付いているため、 今回紹介したように失敗を糧に本番障害を減らすための活動ができるのだと実感しています。 自分がエンジニア時代にこの活動に出会えていたらもっと救われたのかもしれないと思っています。 (私はミスが多いエンジニアで失敗しないように必死でテストしていたら、いつの間にかQAエンジニアになっていました。) 失敗は恐ろしいことですが、失敗に向き合い寄り添えば未来への救いとなる知識に変わると私は信じています。 この記事で失敗を糧に少しでも次の成功へ繋がるヒントとなれば幸いです。
出典: オムニチャネルサービスの実施 単元 | Salesforce Trailhead いつもお世話になっております。 プロダクトエンジニアリンググループの孫です。 LIFULL HOME'SにおけるSalesforceとLINEの連携について紹介したいと思います。 背景 LINEのLIFULL公式アカウントを使い、簡単な対応はBotで対応し、それ以外はLINEのWebhook API機能を利用し、直接 LIFULL HOME'S 住まいの窓口 とやり取りができるチャット機能を、Salesforceで管理・運用する施策がありました。 ※ 現状このサービスはクローズされています。クローズされた背景については後日、別の記事として記したいと思います。 Salesforce Service Cloud 設定 外部からのチャット情報を受け取り、Salesforce内で対応させるためにはSalesforceのオムニチャネルの有効化が必要となります。 オムニチャネル LiveAgentにて送信されたチャット要求をSalesforce内で待機中のエージェントに連携させるルーティング機能です。エージェントの作業量やステータス、スキルなどを参照し、自動的に作業を振り当てます。スーパーアドバイザーを設定し、全体のチャット対応状況を監視・管理することも可能です。 設定 オムニチャネルの有効化 受信した作業をエージェントに転送するまで保持するキューの作成 ルーティング設定とプレゼンス設定の作成。この 2 つは連動してエージェントのワークロードを制御し、キュー内の作業に優先度を設定します。 作業要求を引き受け可能なユーザの選択 新しいキューを通じて受信されるケースのエージェント業務量と作業項目サイズの設定 細かい設定内容は以下のSalesforceドキュメントにまとまっているのでここでは省略します。 help.salesforce.com Webhook側の開発 全体図 LINE×Salesforceシーケンス図 上の図は構成を簡単に表現したものとなります。仕様によってケースや取引先のオブジェクトを作成・更新する処理を追加することも可能です。 LINEから連携されるUserIDとFollowEvent、TextEventなどを基にWebhookからSalesforceのLive Agent REST APIを叩き、ユーザ情報と相談内容などをSalesforceを更新する仕組みです。 このSalesforceのLive Agent REST APIを利用するとLINE以外でもFacebookやWebチャットなどを利用しSalesforceにデータをためることができます。 LINE → Salesforce developer.salesforce.com Live Agent セッションを作成する 新しい Live Agent セッションを作成するには、SessionId 要求をコールする必要があります。 チャット訪問者のセッションを作成する Live Agent REST API を使用して、チャット訪問者のセッションを作成または再確立するには、特定の要求を実行する必要があります。 チャット活動を監視する Live Agent 要求では、チャットセッション中に特定の活動がいつ発生したのかを指定します。 LINEから送信されたメッセージをSalesforceに連携する処理となります。 Salesforce → LINE developers.line.biz エージェントからのメッセージをLINEに送る チャット監視中のChatMessageからレスポンスから受け取ったエージェントのメッセージを送信する。 結果 LINEからのチャットをSalesforceのオムニチャネルから受け取り、Salesforceのオムニチャネルから送信されたメッセージがLINEから確認できます。 最後に 記事にまとめているのは基本的な正常パターンの流れとなります。実際の実装では多様なメッセージパターン(画像やスタンプなど)の扱いやエージェントのステータスによる処理、細かい仕様への対応への注意が必要ですが、Live AgentはLINE以外でもWebや他のスマホアプリなど色んな所から顧客問合せをSalesforceでまとめて対応できるメリットがある良い機能だと思いますので誰かの参考になれればと思います。
こんにちは!テクノロジー本部基盤開発ユニット改善推進グループ所属の王です。 基盤開発ユニットは常にLIFULLの各種サービスが依存する基盤システムの構築と改善のために、いろいろな取り組みをしています。 www.lifull.blog www.lifull.blog www.lifull.blog 今回は技術負債の解消の一つである、DB移行プロジェクトの詳細について紹介します。 DB移行プロジェクトとは? 現在LIFULL HOME'Sの各種サービスが依存している中心的なデータベースをOracle DatabaseからPostgreSQLに置き換えることを推進しているプロジェクトです。 背景の詳細は省略しますが、現状のDB運用体制を続けると会社の事業発展のボトルネックとなることが予想されているので、運用コストの削減、開発効率およびパフォーマンス改善の面から移行の必要が出てきています。 プロジェクトの概要 次はこのプロジェクトの進め方について、我々が取り組んでいることの紹介をさせていただきます。 DB移行手順 今回のプロジェクトの目的、アプリケーションが使っているDBをOracle DatabaseからPostgreSQLに変更するには、以下移行手順の元で進めています。 スキーマオブジェクトとアプリケーションの依存関係の洗い出し Oracle Databaseに依存するアプリケーションからSQL文を抽出して分析する、アプリケーションとデータベースのスキーマオブジェクトの対応関係を以下のようにまとめます。 Application SQL Schema Object SQL Type app1 sql1 table1 select app1 sql1 table2 select app1 sql2 table1 insert 以上の調査により、各アプリケーションがOracle Databaseの使用状況を明確にして、アプリケーションDB移行に必要な修正および移行の優先順位を決めます。 ソースデータベースとターゲットデータベースのデータ同期を確保する アプリケーションへの影響を最小限にするために、ソースデータベース(移行元)とターゲットデータベース(移行先)のデータの一致性を確保することが必要です。テーブルの移行を例として考えると、以下の条件を満足する必要があります。 テーブル構造の一致性 テーブルの定義がソース・ターゲットデータベースで正しく対応する必要があります。たとえば、カラム名、カラムのデータ型、インデックス、制約などのものはできるだけソースデータベースの仕様を再現することによりアプリケーションへの影響を最小化します。 テーブルデータの一致性 対応するテーブルが常に同じデータを持っていることを確保すること。 テーブルに対するトランザクションの一致性 ソースデータベースでテーブルへのデータ更新が、できるだけ遅延少なくターゲットデータベースの対応するテーブルに反映されること。 以上のデータベースのデータ同期を確保した上で、移行作業を始めます。 参照系SQLを先に移行する まずは各アプリケーションからOracle Databaseを参照するSQL文(SELECT文)の参照先をPostgreSQLに変更します。 後述するしくみによってソース・ターゲットデータベースのデータは同期されるため、許容できる範囲のタイムラグはありますがデータの不整合は発生しません。 参照系の後に更新系SQLを移行する 参照系のSQLをすべて移行した後に、更新系SQL文(UPDATE、INSERT、DELETE…)の参照先のDBを少しずつターゲットデータベースに変更します。 全体図 移行手順の全体図は以下の通りです 移行前 参照系移行 更新移行 DB移行に採用する技術 移行の全体図を一見するとそこまで複雑ではないと思う方がいると思います。ですが、Oralce Databaseを参照するアプリケーション数および参照するデータベーススキーマオブジェクト数が多いため、各アプリケーションとスキーマオブジェクトの依存関係が複雑になります。ゆえに、システム全体のDB移行の難易度が上がっています。 移行に必要な工数を削減するために、AWSから提供されている以下のツールを利用しています。 SCT (Schema Conversion Tool) AWS Schema Conversion Tool は、ソースデータベーススキーマ、およびビュー、ストアドプロシージャ、関数といったデータベスコードオブジェクトの大部分を自動的にターゲットデータベース互換フォーマットへと変換することにより、異種データベース間の移行を計画的なものにします。 上記AWS SCT の 公式ドキュメント の紹介の通り、異種データベース関のスキーマオブジェクト変換に使用されています。現在はこのサポートツールを利用して、Oracle Databaseのスキーマオブジェクトを正しい型でPostgreSQLに移行しています。LIFULLではデータベース内に複雑なDDLを持っているスキーマオブジェクトが比較的多いので、この自動変換ツールはプロジェクトを進める上で欠かせません。 下記はSCTの使用画面です。 GUIでソースデータベースのスキーマオブジェクトを指定すると、ターゲットデータベースに通用するDDLが自動出力されます。 AWS DMS (AWS Database Migration Service) AWS Data Migration Service(AWS DMS)はAWSが提供するDB間のデータ移行をサポートするサービスです。サービスの処理プロセスは以下の図のように示されています。 DMSプロセス 図が示すように、DMSはデータレプリケーション機能を持つAWSクラウドサービスです。ソース・ターゲットデータベースを指定すると、2つのデータベース間のデータ同期が実現できます。 詳しい説明はAWS DMSの 公式ドキュメント を参照してください 我々のDB移行プロジェクトでは、ソースデータベースとデータベースのデータ同期を実現するために、DMSを使用しています。ソース・ターゲットデータベースのデータ同期はアプリケーションの参照DBを切り替えるために必要なことですので、DMSは我々のDB移行プロジェクト内で重要な役割を果たしています。 以上2つの外部サービスを利用してDB移行の推進をしています。AWSが提供する ハンズオン を見ていただければより詳細を理解できるので、興味がある方は参照してください。 プロジェクトの体制 プロジェクトの体制についても少し紹介させていただきます。 DB移行プロジェクトは私が所属する基盤開発ユニット改善推進グループと基盤運用ユニット基盤グループが共同作業しています。 改善推進グループは主に必要なアプリケーションの改修に注力していてます。そして基盤グループはDB移行に使用される本番環境インフラ(DBおよびAWS DMSの関連リソース)の運用、検証および改善に注力しています。 そのほか、アプリケーションの改修には各アプリケーションの主管部署の協力も不可欠ですので、全社に渡り影響範囲が大きいプロジェクトとも言えます。 プロジェクトが完了するまでの課題 DB移行プロジェクトはLIFULLの技術負債を解消する重要な施策の一つであり、目的を達成するために我々は日々取り組んでいます。しかし、プロジェクトの完了までにまだ解決しないといけない課題がいくつもあります。 安定的なデータ同期のためにDMSのチューニングが必要 プロジェクトを進める上で、処理するデータ量が増えると同時にデータ同期の遅延が大きくなることまたはデータ同期の一時的な停止などの予想外の問題が発生しました。安定的なデータ同期を確保するため、AWSからのサポートしていただきながらインスタンスのサイジングやパラメータの調整、設定変更などDMS側のチューニング施策に取り組んでいます。 データ同期によるデータベースへの負荷が上昇する DMSへの負荷だけではなく、データ同期によるデータベースへの負荷が上昇することも無視できません。ソース・ターゲットデータベースを正常稼働させながらプロジェクトを進めるための施策も今いくつか進めています。 SQLの調査が不十分 移行が必要なSQL文への調査がまだまだ不十分で、移行の抜け漏れがアプリケーションの障害を起こす可能性があります。ですので、抜け漏れ検知のためのデータベースへのアクセス監視の強化などの施策を今取り組んでいます。 上記の課題はLIFULLのDB移行プロジェクトにとって大きなリスクであり、解決するためにプロジェクトメンバーが日々取り組んでいます。 以上DB移行プロジェクトの紹介となります、ここまで読んでいただきありがとうございます。参考になれば幸いです。 まだまだプロジェクトの完了は先が長いですが、LIFULLの技術負債をなくすには必要不可欠の一歩ですから、これから頑張って取り組んでいきたいと思います。今後プロジェクトの進捗が何かありましたら、また記事を出させていただきます。
いつもお世話になっております。検索エンジンチームの秀野です。 試験的な取り組みとして、社内通貨LIFULL COINをSlack上で送り合うピアボーナスの仕組みを作ったので、その紹介をします。 検索エンジンの話は1つもでてきません。 LIFULL COINとは LIFULL COINはトップダウンな評価でなく、お互いをフラットに評価できるプラットフォームとして作られました。 参考にした評価システムとして、日本古来のお天道様や、欧米だとアダム・スミスの公平な観察者、あとアニメのPSYCHO-PASSに出てくるシビュラ・システムなどがあります。 こういった仕組みを通して、会社の社是である「利他主義」ですとか、ガイドラインの可視化・推進を目標としていました。 また、交換する/価値を測る/貯めるといった通貨と同じ特徴を持っています。 そのため、LIFULL COIN Wallet というWebアプリケーションを使って、銀行口座のようにコインを管理できます。 基本機能として、下記のような機能があります。 残高の確認 送金と取引履歴 ベーシックインカム(週1) 投げ銭 LIFULL COIN Wallet Slackを使ったピアボーナス 始めの課題感 2020年、コロナ禍によってエンジニアにとっては待望の在宅勤務が始まったわけですけれども、コミュニケーション上の課題というものがご多分に漏れず弊社でもでてきました。 特に新規事業部のような小さいチームが複数集まっている部署で課題感があるようでした。 周りが何をやっているか分からないですとか、人事部のアンケートでも気持ちが不安定になっている人がちらほらいるようで、社会適合者の人たちは大変だなーと思っていました。 そんなこともあり、ピアボーナスとしてLIFULL COINを送り合い、状況の共有やいいね👍ができる仕組みを用意することになりました。 ピアボーナスの仕組み Slack のリアクションに連動してコインが付与される、というよくある仕組みです。 ピアボーナスの仕組み リアクションされた人、ここではペンギンにコインが付与され、リアクションした人、というかロボットにも少額が付与されます。 リアクションした人からリアクションされた人にコインが送られるのではなく、お天道様(LIFULL COIN Bot)から2人にコインが降ってくるイメージです。 「お天道様は見ている」のです。 将来的には、何かしら社員のアクティビティに反応して自動的にコインを付与したりしたかったです。 例えば、リファクタリングやPRに応じて開発者に付与されたり、本番環境のAPIのリクエスト数に応じて担当部署に付与されたり。 ブロックチェーンの送金処理 LIFULL COINは、内部でブロックチェーンを利用しています。 ブロックチェーンでは、通貨を扱う仕様が 標準化 されており、秘密鍵と公開鍵を使った送金フローの検証機能が元々備わっています。 (LIFULL COINでは Ethereum を元に開発された Quorum を使っています) ここで簡単にその送金の仕組みを説明します。 トランザクション これは、お天道様からペンギンに対してコインが送られている図です。 送金のトランザクション ブロックチェーンにはアカウントアドレスというものがあり、これが銀行の口座番号のような役割りを果たしています。 このアカウントアドレスは、公開鍵のハッシュから生成されます。 公開鍵は秘密鍵から生成されるものなので、アドレスは秘密鍵からユニークに生成される値ということになります(ECDSAを前提にしています)。 実際に送金する際は、どのアドレスから、どのアドレスに、いくら送る、というトランザクションと呼ばれるデータを作成してブロックチェーンに送信します。 お天道様の秘密鍵でトランザクションに署名することで、初めて送金が可能になります。 ブロックチェーンはトランザクションの署名を検証し、問題なければブロックに追加します。 これでペンギンに対しての送金が完了したことになります。 スマートコントラクト ブロックチェーンには、スマートコントラクトと呼ばれるプログラムをデプロイできる仕組みがあります。 スマートコントラクトは自身のアドレスを持っていて、トランザクションをトリガーになんらかの処理を行えるイミュータブルなプログラムです。 LIFULL COIN Botのコアになるプログラムは、このスマートコントラクトとして実装されていて、 コインの発行 口座の管理 コイン付与の実行 などの機能を担っています。 スマートコントラクト この2つのプログラムは実際に使っているコードで、LifullCoinコントラクトとOtentoコントラクトです。 更新系の関数は秘密鍵で署名しないと呼び出せないようにしたり出来るので、セキュアな実装が可能です。 ただ、不変ゆえ基本的にはバグがあっても直せないので恐ろしすぎます。 出来上がり ピアボーナスの処理の流れ ブロックチェーンの仕組みを踏まえて、こちらがピアボーナスの全体の構成と流れになります。 全体といいつつ実際は色々作ったのですが、それはまた別のお話… コインの流れを可視化するAthenaでの集計の仕組み 社員ADとCognitoのOpen ID Connect連携 社内のあらゆるID同士を相互変換するID Masquerade ブロックチェーン上のデータのバックアップ/リストア 余談ですが、draw.ioで図を書くとみんな同じ感じになるので手書き風にしてみました。 ピアボーナスの流れ 右側のブロックチェーンの青い四角がさきほど説明したスマートコントラクトです。 事前準備 事前にLifullCoinコントラクトからOtentoコントラクトに対して、お天道様の口座のコインを自由に送金する許可を与えておく必要があります(手順0)。 許可を与える処理には、お天道様の口座を扱う秘密鍵で署名する必要があります。 口座には1億コインあり、Otentoコントラクトには1億コイン全てを送金できる許可を与えてあります。 リアクション〜コイン付与と通知 リアクションがあった時は、左上のSlackアプリからフローが開始されます Slackサーバーからリアクション追加イベントがLIFULL COIN Bot(Slack bot)に送られてきます LIFULL COIN BotはID変換テーブルを参照して、SlackのチームIDとユーザーIDをブロックチェーンのアドレスに変換します コイン付与額と付与先のアドレスを含めたトランザクションを作成し、お天道様用の秘密鍵で署名します ブロックチェーン上のOtentoコントラクトに署名済みトランザクションを送信します Otentoコントラクトは公開鍵でトランザクションの検証を行い、対象者のアドレスにコインを送金します OtentoコントラクトからLIFULL COIN Botに送金結果を返します( PoW でなくRaftのためほぼリアルタイムで送金が完了します) LIFULL COIN Botはリアクションした人/された人に着金通知を送信します リアクションした人/された人のSlackアプリのメッセージタブに着金通知が表示されます UIなど アプリのホームタブ&メッセージタブ ↓Slackアプリのホームタブでは簡易的に残高が確認できます。 前述の着金通知メッセージです。付与額はある程度ランダムです。↑ 未登録者勧誘メッセージ&プロフィール登録モーダル ↓アドレス未登録でリアクションされた場合、登録を促すメッセージが届きます。 登録用のモーダルです。Slack上で登録できるようになっています。↑ 衝撃的な幕切れ 開発前、ピアボーナスを試す予定の部署ではSlackを利用していませんでした。 そこで開発中にSlackを導入し、普段使いしている状態でピアボーナスを導入するという流れでした。 開発が終わり導入できるようになった頃、Slackのワークスペースを作ったという話を聞かされました。 そう、誰も…Slackを導入していなかったのです。 これを「 傍観者効果 」といいます。 役割分担をしたからといって、必ずしも実行されるわけではないということを学びました。 どんな些細なことでも、必ず進捗確認をしていきましょう。
こんにちは、 アプリケーションエンジニアとして働いてます。キムと申します。 今日はこの最近経験したことの中で、アプリケーションを開発する途中や、リリース後にコードベースを管理する時重要なことの一つ「品質管理」について経験したことを共有したくて記事を準備しました。 背景 去年は新しく配属されたPJでアプリケーションの基盤から作るチャンスを頂きました。 当時、個人的にLintを投入したい思いがあったので、Go言語で最もよく使われていたgolangciというツールの基本的な部分を使えるように設定を行いました。 個人的に Lintを入れたかった理由は、自分の経験の中でコーディングルールが甘い状態が長く続けると、古いコードを読んだり、複数人のメンバーが同じ作業を行う、又はコードレビューをする等、他人のコードを読む時、人によってバラバラの書き方が混在し、場合によっては基本的なタイポイシューがあったりする指摘でレビューが長くなったりする不便がありました。 そこで、Lintを投入してたチームで経験した、Lintが存在する時のメリットを今回参加してるチームメンバーたちにも経験してもらいたかった思いでした。 すごく極端てきなイメージですが、十分にありえるシチュエーションです。 PJはどんどん進んで、最初より多い人数が入っていただきました。みんなどんどん新しい機能を開発し続けましたが、Lintがあったので、コードベースは基本的なルールを守り状態で管理できたと思います。 この時、部内では新しくCode Climateていうツールを利用し、コードのクオリティチェックを行い、より高いクオリティを目指しましょうていう話が出始め、私達のチームもこのツールを投入することを決めました。 これを適用しながら感じたことや、Golangiciと連携してもっと有効活用できる方法やカスタムルール作成方法などを共有したいと思います。 コード品質について アプリケーションは機能が増えるたびコードベースは大きくなります。 レポジトリに対して、コード品質管理はなぜ必要だと思いますか? サービスがリリースされた後、時間の経過とともに機能はどんどん増えるし、コードベースはどんどん複雑になっていきます。この時コードベースの管理状態をひと目に判断する方法として、コード品質管理を行っていると思います。 アプリケーションは他の商品とは異なって実態が目に見えない商品であり、ということで人の目には見えないところで問題が起きる可能性が存在します。 目に見えるエラーは原因把握も簡単にできるし対応も簡単ですが、目に見えないところから発生したエラーは原因を把握することも大変複雑で、対応するにはより高いコストがかかる可能性も高いです。 この問題は、チーム単位で作業するときにより頻繁に発生します。 同じ機能を作るとしても人によってコードの書き方や、考え方はそれぞれです。そのためコードレビューを行ったり、コードを作成する前にダイアグラムやシークエンス図などを準備して設計レビューをしたりするプロセスが発生してきました。 Active DiagramやSequence Diagramなどでお互い認識合わせや、効率的な処理を探してきました。 このプロセスの中、どうすれば少しでもレビューを簡単にできるのか、こういった機能を十分に活用して投入することで、コードはより統一感を持つことになり、時間が過ぎてもある程度ルールで守られ、読む人に安定感を渡します。 Lintチェックでは簡単な英語スペルチェックから、メソッド名の作成方法、変数の書き方をCamelCaseかsnake_caseにするかなどのチェック、1ファイルあたりの行数制限など様々なチェックを行っています。レポジトリに対して、コード品質管理はなぜ必要だと思いますか? サービスがリリースされた後、時間の経過とともに機能はどんどん増えるし、コードベースはどんどん複雑になっていきます。この時コードベースの管理状態をひと目に判断する方法として、コード品質管理を行っていると思います。 Lintチェックでは簡単な英語スペルチェックから、メソッド名の作成方法、変数の書き方をCamelCaseかsnake_caseにするかなどのチェック、1ファイルあたりの行数制限など様々なチェックを行っています。 簡単に言うと人によっていろんな差があります。 ## camel case CamelCase := "" ## snake case snake_case := "" if () { // 処理 } if () { // 処理 } 「こんなことまで気にするの?」と言われるかもしれませんが、こういった細かいところから問題は大きくなっていきます。 今回紹介しようとするレポジトリ管理サービスも同じです。関連サービスには独自、又は有名アルゴリズムによってコードのメンテンナンス状態や、テストカバレッジ状況を見やすく可視化してデータを提供することで該当サービスがどんな状態で管理されてるのかを一目に把握できるように提供してくれます。 上記でも話したように、アプリケーションは実態が目に見えない商品なので、このように可視化してくれるのはすごく役に立ちます。利用者には、該当アプリの信頼性を、関係者には今アプリにはどんな暫定的な問題があり、どんな改善が必要なのかの判断の軸になることもあります。 このように、ウェブ上でレポジトリの状態をひと目に見れます。 こういった機能を十分活用し、導入することで、コードはより統一感を持つことができ、時間が過ぎてもある程度ルールに守られ、後々読む人にも安定感を渡します。 もちろん、色々設定が必要とか、今すぐ始まるには面倒なことが多い等、今までのやり方と違うことで大変かもしれませんが、将来を考えたら今時間を使って投入することが確実にメリットがあると思っています。 準備 Code Climateの利用準備 Repository と、Code Climateへの連動(ここではGithub を利用します。) レポートをアップロードするための手段準備(ここではGithuib Actions を利用します。) golangci 公式ドキュメント Golangを利用して開発してるなら、最も注目するべきツールです。 Go言語が提供してる基本Lintはもちろん、世の中に名前が知られてる各種3rdパーティーモジュールも追加で設定を行うことで利用できる環境を提供してくれます。 Local環境はもちろん、Github ActionsなどCI/CDを利用する場合、自動チェックを行うことができます。 また、下で話しする Code Climateとも似てるチェック項目が準備されて、これを利用することでCode Climate側でチェックされる前に先に対応することも可能です。 チェック項目のカスタマイズについて PJのRootに設定ファイルを準備します。 Code-Climateのチェックと同じチェックがあるので、先に行うとCodeClimate側で指摘されないので、安心です。 nestif や、 gocognit の場合コードの複雑さを表す部分です。 CodeClimate側でも言語によって自動でチェックしているので、内容をある程度把握しておいたほうが良いと思います。 ## golangci.yml ## code-climate側と同じチェック linters-settings : nestif : # min-complexity : 4 gocognit : # minimal code complexity to report, 30 by default (but we recommend 10-20) min-complexity : 20 gofmt : # simplify code: gofmt with `-s` option, true by default simplify : true nakedret : # make an issue if func has more lines of code than this setting and it has naked returns; default is 30 max-func-lines : 100 issues : # Excluding configuration per-path, per-linter, per-text and per-source # 該当チェックでは、*_test.goファイルは除外する。意味 exclude-rules : - path : _test\.go linters : - errcheck - gocognit - nestif - gofmt ## 設定使うLinterを表示 linters : enable : - nestif - gocognit - gofmt - nakedret fast : false このように、どこで、どんな問題があるのかを教えてくれます。 Code Climate 公式ドキュメント Github 以外にも様々なレポジトリ管理サービス(gitlab,gitbucket等)と連動することで各種項目のチェックが可能し、ひと目に見れるUI/UXを提供してます。 メンテナンススコアー テストカバレッジスコアー コードスメール(設定値を超えてるもの) コード重複(似てるコードが存在してる) などの項目を簡単に確認できて、該当項目を連動されてるレポジトリ上にイシュー化されることもでき、Pull Requestを作成する時コードレビューにも使える機能もあります。 レポジトリと連動されてるときにウェブページ以外に、コードベースにも設定ファイルを追加して、より細かい設定が可能になる。 設定のカスタマイズについて CodeClimateの場合、 ウェブページでの操作 である程度コントロールができますが、コードで設定することも可能です。 golangciと同じくPJのRootに、設定ファイルを配置することで設定可能になります。 ※一緒に使えるPluginも多数あるので自分た ちのレポジトリで必要なものを選択して入れましょう。 version : "2" # required to adjust maintainability checks checks : # パラメータの数 argument-count : config : threshold : 4 # ロジックの複雑さ complex-logic : config : threshold : 15 # 1ファイルの最大行数 file-lines : config : threshold : 500 # メソッドの複雑さ method-complexity : config : threshold : 15 # 1ファイルあたりメソッド数 method-count : config : threshold : 20 # 1メソッドあたりの行数 method-lines : config : threshold : 50 # nest制限数 nested-control-flow : config : threshold : 4 # 1メソッドあたりRetrunの制限 return-statements : config : threshold : 4 similar-code : config : threshold : # language-specific defaults. an override will affect all languages. identical-code : config : threshold : # language-specific defaults. an override will affect all languages. exclude_patterns : - 除外したいファイルパターン CodeClimateのトップ画面を見ると トップページ、各種スコアーが一目で見れます。 このようにサマリーが見えます。 詳細設定を利用して連動されてるコードレポジトリ(Github,Gitlab,Gitbucketなど)にコメントをつけることの可能です。(レビュー機能です。) 全体の流れ テスト結果レポート転送について こちらのようにテスト完了した結果をCodeClimateに転送して、現Repositoryの状態を更新します。 全体図 上記案内した各設定が全部準備できたら、このような流れの運用が可能になります。 Github Actionsの利用方法によって、golangci-lintや、UNITテストのエラーをチャットワークや、Slackなどに送ることで、自分がPUSHしたコードがどんな問題があるのかを早めに把握でき、必要最小限の統一感を持つコードとして保存できます。 そして、最後にテスト結果をCodeClimate側に送ることでレポジトリの状態を管理することも可能になります。 自分が作成したこの例は、自分が配属されてるチームで使ってる方法の一つであり、これを見てより良い案があれば、チャレンジしてみてください。 最後に いかがでしょうか? 使える機能を考えると以外に簡単に設定できますね? 項目の設定はチームメンバーと一緒にどれぐらいの数字を設定するのかをディスカッションすることでみんなと、認識合わせもできるし、コード作成時Lintチェックで怒られながらどんどん設定したコーディングルールが身につけられて行けると思います。 もちろん設定した数値は、絶対的なものではないので後で修正しながらチームの状態に合わせて行くことも可能です。 私も今まで、簡単なLintチェックなどは自動化した経験はありますが、ここまで全部自動化してコードベースを管理するのは初めてだったのでかなりいい経験だと思っています。 余談ですが、badgeをREADMEに入れることで、レポジトリページに接続したらレポジトリのメンテナンススコアや、テストカバレッジスコアがすぐ目に見えることで、より具体的なチームの目標や、モチベーションにもつながると思います。 このようなBadgeをREADMEに配置することで、簡単に確認できます。 今までコード品質管理などについて特に興味がなかったとしても、この記事がきっかけでご自分のレポジトリにも品質管理ツールと導入を検討していただければいいかなと思います。 長い記事読んでいただきありがとうございます。