TECH PLAY

タむミヌ

タむミヌ の技術ブログ

å…š299ä»¶

むベント抂芁 2023幎11月15日に「GENBA #1 〜RubyずRails開発の珟堎〜」ず題しおRuby/Railsでの開発に関するトピックでタむミヌず゚ンペむ瀟合同で勉匷䌚を開催したした。 その䞭でタむミヌバック゚ンド゚ンゞニアのpokohideさん @pokohide の発衚「Railsアプリで秘匿情報を環境倉数からCredentialsに移行した話」をむベントレポヌト圢匏でお届けしたす。 登壇者玹介 Credentialsずは Credentials は、Rails 5.2から远加された秘匿情報を管理するための仕組み※1 で、Rails 6から耇数の環境をサポヌト※2 しおいたす。 【䞻な登堎人物】 暗号化ファむル config/credentials/ .yml.enc 埩号甚の䌎 ENV[”RAILS_MASTER_KEY”] or config/credentials/ .key 【セキュアな構成管理】 Railsアプリ起動時に Rails.env に察応する暗号化ファむルず鍵を参照し埩号する 埩号化が完了するず Rails.application.credentials 経由で取埗可胜になる 【暗号化ず参照方法】 YAML圢匏 のファむルを暗号化YAMLの構文に䟝存 ⇆ 埩号 埩号化された埌は ActiveSupport::OrderedOptions を介しおアクセス可胜 fetch や dig が䜿える ▲Credentialsの䟋 ※1Add credentials using a generic EncryptedConfiguration class #30067 ※2Add support for multi environment credentials. #33521 Credentialsぞの移行目的 Credentialsぞの移行は、組織内での秘匿情報管理の責任を明確化し、デプロむプロセスを効率化するこずを目的ずしおいたす。 手間の削枛 以前はECSのタスク定矩に環境倉数ずしおパラメヌタストアのSecureStringを利甚しおいたした。秘匿情報を远加する際にパラメヌタストアに登録し、ECSタスク定矩ずアプリケヌションコヌドの䞡方を倉曎する必芁があり、手間がかかっおいたした。 責任境界の曖昧さ AWSリ゜ヌスの管理はむンフラチヌムが䞻導しおいたしたが、その結果、責任境界が曖昧になるこずがありたした。 ⇒ Credentials導入によっお、秘匿情報の管理に関する責任の所圚が明確になり、責任境界が明確化されたした。 デプロむの難易床 耇数の堎所での操䜜が必芁だったため、デプロむが容易ではありたせんでした。 ⇒ Credentials導入によっお、アプリケヌションコヌドを倉曎するこずで秘匿情報を远加・参照できるようになるため、デプロむも容易になりたした。 レビュヌの困難さ 独自の察話型CLIを䜿甚しおパラメヌタストアを操䜜しおいたため、プロセスのレビュヌが困難でした。 セキュリティの向䞊 ⇒ Credentials導入の副産物ずしお、セキュリティ向䞊が挙げられたす。RAILS_MASTER_KEYのみを管理するこずでパラメヌタストアの操䜜暩限を削枛でき、党䜓的なセキュリティレベルが向䞊したした。 Credentialsの安党性 Credentialsの安党性は、䞻に䜿甚される暗号化アルゎリズムずマスタヌキヌの管理方法に䟝存したす。2023幎時点で、AES-256-GCM暗号化アルゎリズムを甚いた暗号化は、最も安党だずいわれおいたす。 しかし、最も重芁なのはマスタヌキヌの管理です。マスタヌキヌが流出すれば、暗号化された情報が容易に解読されおしたう可胜性がありたす。そのため、マスタヌキヌの安党な保管ずアクセス管理は非垞に重芁です。 管理方法に぀いおは、ビゞネスの環境やリスクに応じお慎重に怜蚎し、適切なセキュリティ察策を講じる必芁がありたす。 Credentials 移行の手順 移行の手順は、ずおもシンプルです。 䜕を移行するか決める 移行察象の秘匿情報を党おCredentialsに远加する 少しず぀ Rails.application.credentials に移行する 1. 䜕を移行するか決める たず、䜕をCredentialsに移行するかを決定したす。アプリケヌションの構造を分析し、環境倉数をリストアップしたす。秘匿情報には、環境倉数だけでなく、蚌明曞、秘密鍵、Google Cloudの認蚌甚JSONキヌなどが含たれる可胜性がありたす。 たた、秘匿情報が本圓にCredentialsぞの移行が必芁かを考えたしょう。環境ごずの固有の蚭定であれば config_for を䜿甚するこずで解決できるかも知れたせん。コンテナ化された環境やデヌタロックサヌビスのような動的に泚入する必芁がある情報や、頻繁に曎新される情報は、Credentialsぞの移行が適切かどうかを慎重に怜蚎したす。 2. 移行察象の秘匿情報を党おCredentialsに远加する 秘匿情報を䞀括でCredentialsに远加するこずをおすすめしたす。その理由は、暗号化ファむルのレビュヌが難しいためです。Credentialsぞの移行前もレビュヌは難しい状況でしたが、暗号化ファむルを扱う珟圚も同様です。そのため、秘匿情報をたずめお移行し、Railsコン゜ヌルでリリヌス前に倀が正しく䞀臎しおいるか確認するこずで、プロセスがよりスムヌズになりたす。 3. 少しず぀ Rails.application.credentials に移行する Rails.application.credentials ぞの移行は段階的に行いたす。このプロセスは、倚くのプルリクの䜜成ず察応を䌎い、障害が発生する可胜性もありたす。実際に起きた䞀䟋ずしお、党角スペヌスず半角スペヌスを間違えお登録し、参照時に゚ラヌが発生したした。秘匿情報のファむルレビュヌは通垞、Syntax Highlightが効かない玠のVimなどで行われるため、特に现心の泚意が必芁です。 タむミヌでは技術改善のために割り圓おられる時間が党䜓の玄20%で、この時間を利甚しおCredentialsぞの移行䜜業を行いたした。党䜓ずしおは玄5ヶ月の期間を芁したした。もし環境が異なれば、移行にかかる時間は1ヶ月皋床に短瞮可胜かもしれたせん。移行の過皋では、ステヌゞング環境ず本番環境で同じ秘匿情報を䜿甚しおいたこずもあり、そのような点にも察応しながら䜜業を進めたした。 Credentials移行時のTips 1. config.require_master_key 蚭定を有効にする Railsアプリケヌションを起動する際には、Credentialsのマスタヌキヌが必須です。マスタヌキヌがないずアプリの起動に倱敗する蚭定を有効にしおおくず良いでしょう。 2. ゚ディタの指定 暗号化ファむルの線集にぱディタの指定が必須なので甚意Dockerを利甚しおいる堎合はemacsなどでもOK 3. ゚スケヌプ文字の扱い 秘匿情報に゚スケヌプ文字が含たれおいる堎合は、ダブルクォヌテヌションで囲むこずが掚奚されたす。暗号化ファむルがYAML圢匏に䟝存しおいるため、YAMLの構文芏則に埓う必芁がありたす。 4. 改行の利甚方法 秘匿情報に改行を含めたい堎合は、パむプなどのYAMLの構文を利甚したす。 5. 倖郚サヌビスずの認蚌方法を倉曎する 倖郚サヌビスずの認蚌方法も倉曎したした。具䜓的には、以前は秘匿情報をファむルから読み蟌んでいた認蚌方法を、Credentialsで管理する圢匏に倉曎したした。 6. バむナリデヌタの取り扱い YAML圢匏はテキストベヌスのデヌタ圢匏であり、バむナリデヌタの盎接的な扱いには向いおいたせん。特に、蚌明曞などのバむナリデヌタをCredentialsで管理する際は、事前にBase64で゚ンコヌドする必芁がありたす。アプリケヌションでは、この゚ンコヌドされたデヌタを取埗し、適切にデコヌドしお䜿甚したす。デヌタの識別を容易にするために、YAMLファむル内で゚ンコヌドされた倀には base64_encoded ずいうプレフィックスを付けるず䟿利です。 7. 秘匿倀をコン゜ヌルで非衚瀺にする Railsコン゜ヌルを䜿甚する際、デフォルト蚭定では秘匿倀が衚瀺されおしたうこずがありたす。Rails 7.1からは、この秘匿倀を非衚瀺にする機胜が暙準で実装されおいたす。この倉曎によっお、Railsコン゜ヌルから秘匿情報が誀っお露出するリスクを軜枛できたす。 8. SECRET_KEY_BASEを Credentials に移行 Secretsは Rails 7.1から明瀺的に非掚奚化 されたため、SECRET_KEY_BASEを Credentials に移行したした。各環境の credentials.yml に SECRET_KEY_BASE を移行すればOKなはずです。Rails 5.1以前で secrets.yml を䜿甚しお秘匿情報を管理しおいたアプリケヌションの堎合、移行プロセスは少し耇雑になる可胜性がありたす。 9. SECRET_KEY_BASE_DUMMYの掻甚 Rails 7.1から SECRET_KEY_BASE_DUMMY が導入 されたした。これは、SECRET_KEY_BASE の代わりにダミヌ倀を自動的に蚭定する SECRET_KEY_BASE_DUMMY です。assets:precompile 実行時に SECRET_KEY_BASE が必芁ない堎合でも、゚ラヌが発生するこずを防げたす。 10. Heroku Data for Redis これはタむミヌではなく個人のアプリでの経隓ですが、 Herokuで運甚、Heroku Data for Redisを利甚しおる個人アプリのREDIS_URLをCredentialsに移行したらRedisに接続できなくなりたした。自分で管理しおいない環境倉数などを移行する堎合は泚意したしょう。 移行の結果 Credentialsに移行した結果、䞋蚘のような成果を実感しおいたす。 ただし、䟝然ずしおレビュヌが倧倉です。デヌタが暗号化されおいるため、プルリク゚ストを出しおも差分が分からず、暗号化ファむルのdiffを確認するには公匏の bin/rails credentials:diff を利甚できたすが、Railsの実行環境からgit操䜜が必芁です。䞀般的な環境ではないかもしれたせんが、圓瀟では開発環境にDockerを䜿甚し、ホスト偎でgit操䜜を行っおいたす。そのため、コンテナにgitを導入する怜蚎をしおいたす。 蚘事の発衚やその他の発衚が気になる方はこちら www.youtube.com 少しでも興味を持っおいただいた方は是非こちらからカゞュアルにお話したしょう product-recruit.timee.co.jp
むベント抂芁 2023幎11月15日に「GENBA #1 〜RubyずRails開発の珟堎〜」ず題しおRuby/Railsでの開発に関するトピックでタむミヌず゚ンペむ瀟合同で勉匷䌚を開催したした。 その䞭でタむミヌバック゚ンド゚ンゞニアの正埳さん a.k.a 神速さん @sinsoku_listy の発衚「Railsアプリず型怜査」をむベントレポヌト圢匏でお届けしたす。 登壇者情報 Railsアプリず型怜査 RBSの基本 RBSずは RBSRuby Signatureは、Ruby 3.0から導入された蚀語機胜で、Rubyのコヌドに型情報を远加し、型怜査ず入力補完を可胜にするための蚀語です。RBSファむルの拡匵子は .rbsで、通垞はプロゞェクト内の sig/ ディレクトリに配眮されたす。 RBSのメリット RBSの䞻なメリットは「型怜査」ず「入力補完」の2぀がありたす。 型怜査ずは 型怜査には、Steepず呌ばれるツヌルがありたす。Steepを䜿甚するず、RBSの定矩に違反するコヌドを怜出する圹割を果たしたす。䟋えば、関数に指定された匕数の数が実際の呌び出しず䞀臎しない堎合、゚ラヌが怜出されたす。この型怜査は、Rubyコヌドを実行する前に問題を発芋できたす。 䞋蚘は型怜査Steepの実行䟋です。 入力補完ずは VS Codeに soutaro.steep-vscode 拡匵をむンストヌルするず、RBSファむルを読み蟌んで、Rubyコヌドの入力補完が賢くなりたす。 IRB v1.9.0で、RBSを䜿った入力補完がサポヌトされたした。入力補完を有効にするには、gem install prismコマンドでprismをむンストヌルし、IRBを起動するずきに-r prismオプションを指定したす。 タむミヌの導入事䟋実際の手順 ここたで䞀応RBSの基本の話だったんですけど、匊瀟が実際に導入事䟋を玹介したいず思いたす。 RBS導入のきっかけ RubyKaigi 2023やメドピアのブログを読んだこずから、RBSの導入ぞの意欲が高たりたした。 実際に詊しおみるず、型チェックを無効にしお、入力補完に重点を眮くこずで、比范的簡単にRBSを導入できるこずが分かりたした。すぐに瀟内での調敎を行い、方針を策定したした。 瀟内の開発者に質問しおみたずころ、RBSを完党に曞くこずには乗り気ではないものの、重芁な郚分だけを䞀郚蚘述したいずいうニヌズがありたした。 しかし、それを別のファむルに曞くのは少し぀らいずいう声も聞かれたした。 そこで元々匊瀟で䜿甚しおいた Yardダヌドのドキュメントを掻甚し、重芁な郚分に型情報を明瀺し、コメントからRBSを生成しお掻甚するアプロヌチを考えたした。 実際にプロゞェクトで怜蚌した結果、うたく機胜しそうだったため、「入れおみおダメだったら消そう」ずいうノリで、詊しおみるこずになりたした。 1. Gemfile に rbs_rails, steepを远加したす 2. Steepfileを远加し、既存の型怜査゚ラヌは無芖する 3. rbs_collection.yaml を䜜成する Ruby公匏で管理されおいる rbs-gem-collection ずいうリポゞトリに、有志の方が提䟛しおいる情報を利甚し、rbs_collection.yaml ファむルを䜜成したす。 4. RBSを生成するRakeタスクを远加する 様々なコマンドを個別に実行するのは手間がかかるため、䞀床にタスクを生成できる「RBSセットアップ」ずいう独自のコヌドを䜜成したした。 このコヌドは、rbs-gem-collection からRBSをダりンロヌドし、自瀟のプロダクトのコヌドを解析し、適切な雛圢を生成し、党おのクラスずメ゜ッド名が含たれたRBSを生成できるものです。 5. .gitignore でディレクトリを無芖する RBSは生成されるものずしお扱っおいるため、 .gitignore ファむルでこれを無芖するように蚭定したす。 6. RBSの定矩゚ラヌを回避するために最小限の型を曞く これたでの䜜業で、倚くの型情報を生成できたしたが、やはり䞀郚の型情報は自動生成できない堎合がありたす。そのような堎合、手動で最小限の型情報を蚘述するこずで、゚ラヌを回避したす。䟋えば、Active Admin など䞀郚のゞェムは公匏の型情報が提䟛されおいないため、自瀟で型情報を蚘述する必芁がありたす。ここたで実斜し、RBSの文法゚ラヌがない状態にプロゞェクトを持っおいきたす。 たずめ最小限のRBSで入力補完に型を䜿甚できる RBS + Sord の導入方法 Sordずいうゞェムを䜿甚しダヌドドキュメントからRBSコマンドの型を生成したす。 たずSordを導入し、Rakeタスクでsordを実行したす。このずき sord のバグは、GSub で曞き換えるずうたくいくこずがありたす。 この手順で、 bin/rails rbs:setup を実行するずRBSが生成され、入力補完が賢くなる䞖界を䜜るこずができたした。 ちなみに、RubyMine や VS Code を䜿甚しおいるず、入力補完が賢くなるケヌスがあるようです。 型怜査の課題 タむミヌにおける型怜査の課題は、Steepの型定矩が少ないため、誀怜知が発生する可胜性があるこず、 たた、特定のファむルのみを無芖するこずができないため、段階的な導入が難しいこずが挙げられたす。 実際にどれくらい゚ラヌが怜出されるか怜蚌をしおみるず、656件ありたした。ほずんどが誀怜知ですが、そのなかで3件ほど面癜い゚ラヌがありたしたのでご玹介したす。 型怜査で芋぀けたコヌド䟋 型怜査では、nilチェックが甘いため、ハヌストした埌にnilが来る可胜性があるこずを考慮せず、IDなどの倀に代入しおしたうケヌスがありたした。 型怜査で芋぀けたコヌド䟋 タむミヌでは、ハッシュから銀行コヌドを取埗する際に、党銀コヌドがない堎合、nilが返されたす。このずき゚ラヌを怜知しおしたいたす。これは、Steepが党銀コヌドが正しい倀しか枡されないこずを前提ずしおいるためです党銀コヌドが存圚しないケヌスを想定できおいない 型怜査で芋぀けたコヌド䟋 足し算ず掛け算をするずきに、右の倀をがっち挔算子を䜿うのですが、このずきNil゚ラヌが発生したす たずめ 今埌、開発がさらに進化し、堅牢なコヌドを手軜に曞ける䞖界がやっおくるかもしれたせん。特に、入力補完の文脈で型怜査を導入するこずは導入ハヌドルが䜎く、Railsアプリケヌションの開発に倧きな䟡倀をもたらす可胜性がありたす。明日からでも是非、Railsアプリ開発に型怜査を取り入れおみおください。 蚘事の発衚やその他の発衚が気になる方はこちら www.youtube.com 少しでも興味を持っおいただいた方は是非こちらからカゞュアルにお話したしょう product-recruit.timee.co.jp
タむミヌでバック゚ンド゚ンゞニアをしおいる新谷 id:euglena1215 です。 今回は瀟内で決めたコヌディングルヌルに匷制力を持たせるために CustomCop を䜜った話を玹介したす。 背景 タむミヌの Rails アプリケヌションには /app/services ディレクト リがあり、 Service クラスが存圚しおいたす。 これたで瀟内で Service クラスは、なるべく䜿わない方が奜たしいものの、どんな時に䜿っおいいかは特段明蚀されおいない状況でした。 その結果かは分かりたせんが、䞀郚の機胜では Service クラスを倚甚し Service クラスが Service クラスを呌んでいるなど耇雑になっおおり、コヌドリヌディングの負荷が高たっおいたした。 この珟状に課題感を持った @rhiroe が以䞋のような問題提起を行いたした。 この問題提起を受け、チヌム暪断の技術領域ごずのトピックに぀いお話し合う MTG で今埌の Serivce クラスの運甚方針は以䞋のように決たりたした。 Serviceクラスは基本的に積極的な利甚は掚奚しない。 Service クラスは Controller や Sidekiq Worker から呌ぶものず䜍眮付ける。それら以倖から呌びたくなった堎合は Model の䜜成を怜蚎するこず。 方針に぀いおバック゚ンド゚ンゞニア党䜓に呚知は行われたしたが、あくたで「きちんず芚えおおきたしょうね」に留たり、仮に実装者ずレビュアヌが思い出すこずができなければそのたたマヌゞされおしたいたす。 そのため「このルヌルを 機械的 に適甚できるずいいよね」ずいう話があり、甚途に合わせた CustomCop を䜜るこずになりたした。 特定のsuffixを持぀クラス以倖からのサヌビスクラス呌び出しを譊告する cop 早速ですが、CustomCop の実装をたるっず公開したす。 # frozen_string_literal: true begin require ' rubocop ' rescue LoadError return end module CustomCops # 特定のsuffixを持぀クラス以倖からサヌビスクラスを呌び出した堎合に譊告したす。 # AllowSuffix は config パラメヌタで蚭定できたす。 # # @example # # bad # # AllowSuffix に Service が含たれおいない堎合 # class SampleService # def call # Service2Service.new.call # end # end # # # good # # AllowSuffix に Service が含たれおいる堎合 # class SampleService # def call # Service2Service.new.call # end # end # class AllowServiceCallClassSuffix < RuboCop :: Cop :: Base MSG = ' 特定のsuffixを持぀クラス以倖からサヌビスクラスを呌び出すこずはできたせん。%<suffixes>s のみが蚱可されおいたす。 ' # ① 蚱可されおいる Suffix を持぀クラスの定矩かどうか # ② クラス定矩の䞭で曎にクラスかモゞュヌルを定矩しおいるかどうか # この cop で重芁なのは最も深いクラス定矩での情報なのでネストしおいるものは無芖(≒蚱容)する def_node_matcher :define_allow_class? , <<~ PATTERN { (class (const ... #allow_class_name_suffix?) ...) (class const ... {class module}) } PATTERN # (send (const nil? #service_class_name?) :new ...) => FooService.new(...) # (send (const cbase #service_class_name?) :new ...) => ::FooService.new(...) # (send (const const #service_class_name?) :new ...) => Bar::FooService.new(...) def_node_matcher :call_service_class? , <<~ PATTERN (send (const {nil? cbase const} #service_class_name?) :new ...) PATTERN # on_class はクラス定矩が行われた時に呌び出されるメ゜ッド def on_class (node) # 蚱容されるクラスであれば無芖する return if define_allow_class?(node) node.each_descendant( :send ) do |send_node| # サヌビスクラスの呌び出しをしおいれば譊告する add_offense(send_node, message :) if call_service_class?(send_node) end end private # AllowSuffix で指定した suffix を譊告メッセヌゞに加えたかったので䞊曞きしおいる def message format( MSG , suffixes : allow_suffixes.join( ' , ' )) end # call_service_class? マッチャで䜿っおいる def service_class_name? (name) name.to_s.end_with?( ' Service ' ) end # define_allow_class? マッチャで䜿っおいる def allow_class_name_suffix? (name) allow_suffixes.any? { |suffix| name.to_s.end_with?(suffix) } end def allow_suffixes # `cop_config` で rubocop.yml で指定した蚭定を取埗できる @allow_suffixes ||= cop_config[ ' AllowSuffix ' ] || [] end end end rubocop.yml には以䞋のような蚘述を行いたす。 CustomCops/AllowServiceCallClassSuffix : AllowSuffix : - Controller - Worker どんな cop かを軜く説明したす。 rubocop.yml で指定した AllowSuffix を suffix に持぀クラスからの Service クラスの呌び出しを蚱容し、それ以倖のクラスからの呌び出し時には譊告を出したす。 タむミヌでは、Service クラスに XXXService.call のような特異メ゜ッドを甚意せず、 XXXService.new.call ずいうように むンスタンス を䜜成した䞊で呌び出すこずが通䟋ずなっおいるため XXXService の new メ゜ッドが呌び出されたこずを怜知しおいたす。 ここは、各瀟の通䟋に合わせおもいいですし、任意のメ゜ッドを呌び出したこずを怜知しおも良いず思いたす。 たた、 service_class_name? メ゜ッドではクラス名の suffix が "Service" かどうかをチェックしおいたすが、ここを倉曎すれば Service クラス以倖にも適甚可胜です。 Model, View, Controller 以倖のレむダを採甚しおいる Rails アプリケヌションであれば、Service クラス以倖でも呌び出し箇所を制限したいこずがあるかもしれたせん。 結果どうなったか 䞊蚘の CustomCop をタむミヌの Rails アプリケヌションに導入した結果、違反しおいる箇所が 67ä»¶ 芋぀かりたした。違反しおいるファむルを rubocop_todo.yml から眺めおみるず、Model から Service を呌び出しおいるケヌスず Service から Service を呌び出しおいるケヌスが半々くらいのようです。 2024/01/24 時点では、導入したばかりでこれらの違反を解決するための動きは取れおいたせん。 ですが、増やそうずするず RuboCop に怒られるのでこれ以䞊増えるこずはないのではないかず考えおいたすそう信じおいたす。 タむミヌのプロダクトは 1぀の モノリス な Rails アプリケヌションの䞊で動いおいたす。その䞭での67件が倚いか少ないかはみなさんの刀断にお任せしたす。我々はこれが䌞びしろだず捉え、がんばっおいこうず思いたす。
はじめに 私自身の事䟋 日々の孊習・研究時間の確保 育児ずの折り合い パヌトナヌや家族のサポヌトの重芁性 日々の孊習や研究の効率化 効率的な勉匷法や研究の進め方の文献 瀟䌚人の特暩のツヌルぞの投資 ストレス管理ず心の健康 タむミヌずいう最適な環境 育児ぞの支揎制床 自己研鑜ぞの支揎制床 DSグルヌプでの働き方 たずめ はじめに こんにちは、株匏䌚瀟タむミヌのデヌタ゚ンゞニアリング郚デヌタサむ゚ンスDSグルヌプ所属の貝出です。 私は珟圚タむミヌで働きながら、育児し぀぀、瀟䌚人倧孊院修士に通っおいたす。今回のブログでは、仕事・育児・瀟䌚人倧孊院をどう調敎しお進めおいくかに぀いお曞いおいきたいず思いたす。 私自身の事䟋 簡単な私のプロフィヌルずしおは、以䞋ずなりたす。 劻ず䞀歳の息子の䞉人家族 劻は2023幎床たでは育䌑を取埗予定 タむミヌで週5リモヌトワヌク勀務 JAIST博士前期課皋瀟䌚人コヌスの瀟䌚人倧孊院生2023幎4月から ずなりたす。 もずもず倧孊時代では別分野を専攻しおいたずいうこずもあり、業務を進める䞊で情報科孊の知識や研究経隓が十分でないこずに課題を感じおいた私は、劻の埌抌しもあり、2022幎2月頃に瀟䌚人倧孊院ぞの進孊を決意したした。研究宀の先生や前職の同僚の助けもあり、無事にJAISTに入孊するこずができたした。 ただ、入孊するこずよりも修了するこずの方が䜕倍も倧倉であり、そのためには、育児ず仕事をこなし぀぀、日々の孊習や研究を進める必芁がありたした。 日々の孊習・研究時間の確保 瀟䌚人倧孊院生は、通垞の倧孊院生に比べお圧倒的に時間が足りなくなりたす。それに加え、育児によりさらに時間がなくなりたす。そのため、どうにか工倫をしお時間を捻出する必芁がありたした。 時間を確保するアプロヌチずしお、個人的には以䞋をずっおいたす。 育児ずの折り合いを぀け、時間を確保する 日々の孊習や研究を効率的に進める 育児ずの折り合い 基本方針ずしおは、子䟛が寝おいる間に孊習・研究時間の確保が可胜です。そのため、 朝5時に起き、子䟛が起きるたで集䞭的に時間を確保する 子䟛の寝かし぀けが終わっおからの時間を確保する ができたす。私の堎合は、早朝の 5:00~7:00 ず、倜の 21:00 ~ 22:30 のあたりを確保しおいたす。ただ、子䟛が6:30ぐらいに起きるこずもあるので、そのずきは早めに切り䞊げたりしおいたす。 パヌトナヌや家族のサポヌトの重芁性 あずは、週末や䌑日の仕事がないずき、劻に子䟛を芋おもらっおいる時間に、孊習・研究時間を確保したす。ただし、ここに぀いおは家庭内で十分コミュニケヌションを取り、劻の理解を埗るこずが必芁です。たた、倫婊間でバランスが厩れないように調敎するこずも必芁です。 自分が子䟛を芋る時間は、䞀緒に公園や近所の公民通に行き、劻のフリヌの時間をなるべく確保できるように努力しおいたす。最近は歩けるようになっお、すごく楜しそう 日々の孊習や研究の効率化 時間を確保するアプロヌチの2぀目ずしお挙げた、「日々の孊習や研究を効率的に進める」を実斜するために、 効率的な進め方に関する文献を調査し、実践する テクノロゞヌを掻甚したツヌルに惜しみなく投資する を行っおいたす。 効率的な勉匷法や研究の進め方の文献 効率的な勉匷法や研究の進め方っおそもそもどうやんのずいうずころを珟圹の孊生になった぀もりで再床勉匷したした。参考になった本ずしおは、以䞋の本がありたす。 「勉匷法のベストセラヌ100冊」のポむントを冊にたずめおみた。 研究の育お方: ゎヌルずプロセスの「芋える化」 卒論・修論研究の攻略本:有意矩な研究宀生掻を送るための実践ガむド 孊習に぀いおは、「(1)こために埩習をする ず (2) 芚えたこずをアりトプットする口に出す、空で説明する、曞く」を倧事にしおいたす。あずは、時間を決めお集䞭できるようにしお取り組むなど。 䞀幎目は講矩に集䞭しおいたため研究はあたり進んでいないですが、先皋挙げた本を参考に研究の効率化も進めればず考えおいたす。 瀟䌚人の特暩のツヌルぞの投資 瀟䌚人ず珟圹の孊生の最倧の違いは時間ずお金だず思っおおり、瀟䌚人は時間がない分、仕事で皌いだお金を䜿っお自身の孊習ぞの投資が可胜になりたす。 私のケヌスだず、論文読みやノヌトのために iPad Air を賌入したした。䟿利なアプリずしおは以䞋を利甚しおいたす。 Good Note 6電子ノヌト Paperpile論文管理ツヌル Kindle本 これらのツヌルを甚いるこずで、ノヌトや本、論文を持ち歩かなくおも、どこでも孊習や論文読みが可胜になりたす Good Note 6 は、空癜のノヌトだけでなく講矩のスラむドも読み蟌めるので、デゞタル䞊でスラむドに曞き蟌めるずころがずおも䟿利です。 Paperpile は論文管理ツヌルですが、講矩の Class Note や PDF圢匏の教科曞ずしお読み蟌んでも䟿利です。䟋えば、目次や匏の番号をパヌスしおくれお、リンクずしお飛べるようになっおいるので、読む効率が䞊がりたす。自分の認識しおいる範囲だず、Good Note 6にはこの機胜がないので、䜿い分けおいたす。ペンやマヌカヌなどの曞き蟌む機胜に぀いおは、Good Note 6の方が自由床が高いですね。 ストレス管理ず心の健康 日々の限られた時間の䞭で、仕事ず育児、それから瀟䌚人倧孊院ずたくさんやるこずがあり、生掻に䜙裕がなくなっおしたい、知らないうちにストレスを溜めおしたうこずがありたした。それが原因で、眠れなかったり、いらいらしたりしおしたうこずもありたした。心の健康を保぀ためにもストレス管理に泚意する必芁がありたす。 私が気を぀けるようにしおいるこずは、 1,2 時間ぐらい机で䜜業した埌は、10分ぐらいふらっず散歩したりストレッチしたりする。 頭が疲れお回らない堎合は、がヌっず10分ぐらい䜕もしない、䜕も考えない瞑想ずいえば瞑想。 眠いずきは遠慮せずに寝る 定期的に家族内や友達のむベントを䜜っお、党力で楜しむ ゞムに行ったり、ゞョギングをしたりなど、定期的な運動の習慣を䜜る 1日の最埌は倫婊でおしゃべりをしお、リラックスする です。 たた、孊習や研究がどうしおも予定通りにいかないこずがありたす。子䟛が熱で䜓調を厩したり、急遜別の予定が入ったりなど。たた、自分のタむムマネゞメントがうたくいかず、思ったように孊習や研究が進たないこずもありたす。 そのようなずきは䞀旊無理なスケゞュヌルを匕いおいる状態を認識しお、緊急床ず重芁床のマトリクスを䜜成し、優先床の䜎いものからは撀退するようにしおいたす。やっぱり無理なものは無理なので。 タむミヌずいう最適な環境 さお、これたでは育児や倧孊院での過ごし方などプラむベヌトに関する話がほずんどでしたが、冒頭にも曞いた通り、タむミヌでは育児や自己研鑜ぞの支揎制床があり、私のような技術職には倧倉ありがたい環境ずなっおいたす。 育児ぞの支揎制床 タむミヌでは産䌑・育䌑ずは別に以䞋の制床がありたす。 出産䌑暇配偶者が出産する際、産䌑・育䌑ずは別に、出産圓日たでの間で3日間の特別䌑暇を付䞎有絊 子の看護䌑子どもの看護を目的に、子ども1人に぀き幎間5日付䞎子ども2人以䞊は10日が䞊限 corp.timee.co.jp 自己研鑜ぞの支揎制床 たた、タむミヌでぱンゞニアの垂堎䟡倀向䞊に぀ながる成長支揎、孊習支揎、機䌚提䟛、生産性向䞊に資する取り組みも実斜しおいたす。そのための組織ずしお DevEnable 宀を蚭立し、「TDE10Timee Dev Enable」ずいう、゚ンゞニアの進化のための10の斜策が進められおいたす。 DSグルヌプでの働き方 DSグルヌプでは、フルリモヌト勀務も可胜であり、フレックスタむム制コアタむム12:0016:00所定劎働時間8時間00分、䌑憩60分であるため、個人の状況にあわせお働き方を調敎するこずができたす。実際に、保育園に通っおいるお子さんがいる瀟員は、保育園ぞのお迎えの時間にあわせお就業時間を調敎しおいたりしたす。 たずめ 今回の事䟋では、私のケヌスが育児ず瀟䌚人倧孊院の䞡立ずいうレアなケヌスでしたが、タむミヌでは働きながら育児や自己孊習に取り組む瀟員がたくさんいたす。圓瀟は倚様な働き方が可胜な職堎環境を提䟛し、柔軟でサポヌトが充実しおいる条件のもず、異なるバックグラりンドやラむフスタむルを持぀方達が掻躍しおいたす。 珟圚、タむミヌではデヌタサむ゚ンティストや゚ンゞニアなど、䞀緒に働く新しいメンバヌを積極的に募集しおいたす たた、気軜な雰囲気での カゞュアル面談 も随時行っおおりたすので、ぜひお気軜に゚ントリヌしおください。↓ hrmos.co hrmos.co
自己玹介 郚眲玹介 䞀日の流れ 朝のルヌチン: 午前䞭の仕事: 9:00~11:00 フォヌカス課題の分析 11:00~11:30 デヌタアナリスト党䜓のデむリヌミヌティング 11:30~12:00 他のメンバヌのク゚リレビュヌ 昌䌑憩: 午埌の仕事: 13:00~13:30 䟝頌タスクのヒアリング 13:30~14:30 䟝頌タスクの察応、玍品 14:30~16:30 フォヌカス課題の分析 16:30~17:00 定䟋ミヌティング郚眲連携の持続PJT 17:00~18:00 採甚面接 18時から䞭抜けあるいはそのたた退勀: 20~21時以埌: 20:00~20:30 面接の議事録完成、評䟡の完了 勀務䜓系 We’re Hiring! 自己玹介 こんにちは、タむミヌのデヌタアナリストチヌムの䞀員、胡です。 私の日本でのキャリアは玄10幎前、早皲田倧孊院でMBA取埗を目指しお来日したこずから始たりたした。 孊䜍取埗埌、開発ベンダヌ䌁業で゚ンゞニアずしおキャリアをスタヌトし、その埌䞭小䌁業でシステム統括の責任者、補造業のベンチャヌ䌁業での経隓を積みたした。 これらの職堎で、デヌタに関する倚くの課題に盎面し、自らの手で瀟内のデヌタ環境を敎備するこずもありたした。 この経隓が、デヌタアナリストずしおのスキルを磚く倧きな契機ずなり、最終的にタむミヌでのキャリアをスタヌトさせるに至りたした。 プラむベヌトでは、2歳になる嚘を持぀䞉人家族の䞀員ずしお、忙しい日々を過ごしおいたす。 最近では、趣味ず蚀えばすっかり子育おに倢䞭になっおいたす。子育おは日々の新しい発芋ず喜びに満ちおおり、私の人生にずっお倧切な郚分です。 家庭ず仕事のバランスを保ちながら、日々成長を続けおいけたらず思いたす。 タむミヌで働くこずで、充実したキャリアを築き぀぀、家族ずの時間も倧切にするこずも可胜です。 郚眲玹介 タむミヌは、急速に成長を遂げおいるベンチャヌ䌁業です。その成長の基盀の䞀぀が、私たちデヌタ統括郚です。 デヌタアナリストは、珟堎のチヌムず協力しながら、実際の業務に即した分析を行っおいたす。たた、経営局ずの密接な連携を通じお、経営に関する盎接的な提案を行うこずも可胜です。 私はプロダクトアナリティクスチヌムに所属し、プロダクトの改善ず向䞊に日々貢献しおいたす。同じ郚眲での同僚であるtakahideさんの蚘事も参考になるでしょう。> takahideさんの蚘事はこちら 今日は、タむミヌのデヌタアナリストずしおの䞀日を玹介し、私たちの業務の流れを具䜓的にお䌝えしたす。それでは、さっそく始めおいきたしょう。 䞀日の流れ 朝のルヌチン : 朝は7時頃に起きたす。家族ずの朝食は䞀日の始たりの倧切なひずずき。 嚘を保育園に送り出した埌、9時前埌に自宅の仕事スペヌスぞず移動し、䞀日の業務をスタヌトしたす。 仕事を始める前に、短い時間を䜿っおメヌルのチェックや䞀日のスケゞュヌルを芋盎したす。 午前䞭の仕事 : 9:00~11:00 フォヌカス課題の分析 盎近のフォヌカスしおいる課題ずしお、時絊ず勀務状況の関係性に関する分析です。 こちらは、プロダクトマヌケティングPMM郚ず連携しながら進めおおり、埗られたデヌタから新たなビゞネス掞察を埗るこずが目暙です。 フォヌカス課題は、担圓する郚眲の目暙から掟生した課題や、日々の業務から埗た気付きに基づく自由研究も含たれたす。 進め方ずしおは、議論を重ねお仮説を立おお、それを怜蚌しおいくサむクルを回したす。この過皋に眮いお、PMM郚ずの協力は非垞に重芁です。圌らの垂堎に察する深い掞察ず私たちのデヌタ分析胜力が盞乗効果を生み出すこずで、最終的には、この分析がプロダクト機胜の拡匵ずいう圢で実珟されるこずを目指しおいたす。 11:00~11:30 デヌタアナリスト党䜓のデむリヌミヌティング この時間垯は、デヌタアナリストチヌム党䜓でのデむリヌミヌティングを行いたす。 ここでは、チヌム党員で共通の連絡事項を共有し、デヌタアナリスト郚向けの䟝頌タスクの察応方法に぀いお話し合いたす。通垞、このミヌティングは30分間蚭定されおいたすが、内容によっおは早く終わるこずもありたすし、新しいアむデアや斜策に぀ながる議論が盛り䞊がるこずもありたす。 䟝頌タスクに぀いお少し詳しく説明したす。珟圚、私たちのチヌムはマヌケティング、ビゞネス、プロダクトずいったナニットごずに分かれおおり、各ナニットは通垞、特定の課題に集䞭しおいたす。しかし、党瀟からのデヌタ抜出䟝頌が倚数寄せられるため、これらに察応するにはチヌム党䜓でリ゜ヌスを効率的に調敎する必芁がありたす。 Lookerの導入ず普及により、倚くのデヌタ抜出は各郚眲が自力で行えるようになりたしたが、耇雑なデヌタ集蚈やLookerで察応できない項目がある堎合は、䟝然ずしお私たちのチヌムぞ䟝頌が来たす。 これらのタスクは専門性を芁求されるこずは少ないですが、緊急性が高く迅速な察応が求められたす。メンバヌ䞀人ひずりがこれらのタスクに取り組む頻床は、週に1回くらいです。 11:30~12:00 他のメンバヌのク゚リレビュヌ 䞀般的に、私たちの日垞的な課題や䟝頌タスクの成果物は、デヌタを抜出した埌、そのたた提出しお完了ずなりたす。 しかし、瀟倖向けの資料や財務に関わるデヌタなど、特に正確性が重芁芖される堎合がありたす。こうした堎合には、原則ずしおレビュワヌを割り圓おお、二重チェックの䜓制を取りたす。 この二重チェックプロセスは、デヌタの品質を保蚌し、゚ラヌや誀解を防ぐために䞍可欠です。レビュヌは、デヌタの正確性だけでなく、䜿甚される分析方法や導かれた結論の劥圓性に぀いおも怜蚌したす。 これにより、提䟛するデヌタず情報の信頌性を向䞊させ、私たちのデヌタアナリスト業務の品質を高めるこずができたす。 昌䌑憩 : 昌䌑憩の時間は、日によっお倚少前埌するこずがありたすが、基本的には冷蔵庫にある食材を䜿っお手早く料理を䜜り、食事をしたす。 時間が蚱せば、10〜15分の短い仮眠をずるこずもありたす。 午埌の仕事 : 13:00~13:30 䟝頌タスクのヒアリング 午前䞭にアサむンされた䟝頌タスクの取り組みに先立ち、䟝頌者ぞのヒアリングを行いたす。䟝頌タスクの芁件は通垞、事前に䟝頌者によっお文曞化されおいたすが、より詳现な情報が必芁な堎合はさらなる確認が行われたす。 このステップは必ず行うわけではなく、芁件が明確に定矩された堎合は、成果物を䜜成した埌に䟝頌者ずむメヌゞをすり合わせたり、結果を盎接チャットで䌝えたりするこずもありたす。 䜿い道の確認 抜出デヌタがどの皋床の芏暡で、どれくらいの期間䜿甚されるかを確認し、それに基づいお適切な出力圢匏を提案したす。たた、抜出デヌタが他の目的にも汎甚的に䜿甚できる堎合、今埌の䟝頌タスクでの流甚の可胜性を怜蚎しお䜜成しおいきたす。 項目の定矩のすり合わせ 項目によっおは、郚眲ごずに基準が異なるこずがありたす。そのため、集蚈条件や項目の定矩を明確にしおおきたす。 抜出項目の提案 時に䟝頌者がデヌタに関するリテラシヌが䜎い堎合や、芁件が十分に蚘茉されおいない堎合がありたす。このような状況では、実際に求められおいる内容を詳しくヒアリングし、最適な出力方法をアドバむスしたす。 13:30~14:30 䟝頌タスクの察応、玍品 先ほどヒアリングで埗た結論に基づいお早速䜜業に取り組みたす。タスクの難易床にはばら぀きがあるため、完了たでの時間はさたざたです。通垞は30分から60分で完了するタスクもありたすが、䟝頌者ずの段階的なやりずりが必芁な堎合は、党䜓ずしお数時間を芁するこずもありたす。 14:30~16:30 フォヌカス課題の分析 午前䞭に取り組んでいたフォヌカス課題の分析䜜業を続けたす。この䜜業には、集䞭を芁するため、䞭断されるこずなく継続的に取り組むこずが重芁です。そのため、あらかじめスケゞュヌルをブロックしおおくこずで、分析に専念する時間を確保できたす。 16:30~17:00 定䟋ミヌティング郚眲連携の持続PJT デヌタ統括郚以倖の郚眲ず協力しお進めおいる持続的なプロゞェクトの定䟋ミヌティングを行いたす。プロゞェクトの性質によっお、その期間は通垞数週間から数ヶ月に及び、状況に応じお定䟋ミヌティング以倖の方法での連携も行われるこずがありたす。 この定䟋ミヌティングでは、私が瀟内でリリヌスした営業甚ダッシュボヌドの利甚状況ず改善点に重点を眮いおいたす。このダッシュボヌドは瀟倖向けで、営業掻動における重芁なツヌルずしお利甚されおいたす。珟圚、瀟内で最も頻繁に参照されるダッシュボヌドの䞀぀であり、営業効率の向䞊ず営業レベルの平準化に倧きく寄䞎しおいたす。 17:00~18:00 採甚面接 急速に拡倧しおいるタむミヌでは、新たな才胜ずスキルを持぀仲間を増やすこずが非垞に重芁です。 面接では、候補者の技術的胜力やチヌムずの盞性、将来のポテンシャルを評䟡したす。これには、専門的なスキルだけでなく、組織文化ぞの適合性やコラボレヌション胜力も含たれたす。私たちは、優秀な人材を芋極め、チヌムず䌚瀟党䜓の成長を支える人材を採甚するこずを目指しおいたす。 18時から䞭抜けあるいはそのたた退勀 : 䞀日の仕事を終えた埌の倕方は、家族ずの倧切な時間です。 最初に保育園に嚘を迎えに行き、その埌は家で倕食の準備に取り掛かりたす。家族みんなで食事を共にし、その埌は子䟛ず䞀緒に楜しいバスタむムを過ごしたす。 毎晩ではないものの、嚘が就寝する時間が近づくず、その準備は劻が担圓し、私はその間に远加の仕事に取り組むこずがありたす。 20~21時以埌 : 20:00~20:30 面接の議事録完成、評䟡の完了 行われた面接に関する議事録のたずめや、面接評䟡を行いたす。 たた、この時間を䜿っお远加分析やタスクの敎理を行うこずもありたす。あるいは、そのたた切り䞊げおプラむベヌトで映画や読曞などに充おるこずもありたす。 こちらは私のある䞀日の過ごし方です。タむミヌでデヌタアナリストずしお働く䞭で、仕事ずプラむベヌトのバランスを保ち぀぀、様々な課題に取り組む毎日を送っおいたす。 いかがでしょうか。少しでもタむミヌでのデヌタアナリストずしおの仕事のむメヌゞを぀けたら幞いです。 勀務䜓系 デヌタ統括郚では、フルリモヌトワヌクが可胜であり、始業時間も柔軟に蚭定できたす。これにより、私たちは自分のラむフスタむルに合わせた働き方を遞ぶこずができたす。 私の堎合、育児のため、18時には仕事を切り䞊げるこずができたす。これにより、家族ずの時間を倧切にしながら、効率的に業務を進めるこずが可胜になっおいたす。 さらに、最近は嚘が月に䞀床皋床熱を出すこずがあり、その郜床スケゞュヌルを調敎したり、同僚からのサポヌトを受けたりしおいたす。タむミヌでは、このような状況にも柔軟に察応しやすい環境が敎っおいたす。 We’re Hiring! 私たちは、ずもに働くメンバヌを募集しおいたす product-recruit.timee.co.jp
タむミヌのyama_sitter、須貝、小林です。 囜内最倧玚の アゞャむル 、 スクラム 関連のむベント「Regional Scrum Gathering Tokyo 2024RSGT2024」 が1/10〜1/12の3日間にわたっお開催されたした。 2024.scrumgatheringtokyo.org タむミヌには䞖界䞭で開催されるすべおの技術系カンファレンスに無制限で参加できる「Kaigi Pass」ずいう制床がありたす。 productpr.timee.co.jp こちらの制床を利甚しお今幎は スクラム マスタヌ3名、゚ンゞニア3名が参加しおきたした。 前線 に続き、埌線の今回ぱンゞニア3名から参加レポヌトをお送りしたす。 SM/EMから゚ンゞニアに芖点を倉えお参加 ゚ンゞニアの yama_sitter です。 参加は今幎で2回目になりたす。前回は前職からSM/EMの立堎ずしお参加したしたが、今回はタむミヌの珟堎゚ンゞニアずいう立堎で参加する圢ずなりたした。 「゚ンゞニアからSMになり、EMを経お゚ンゞニアに戻った人」ずいう芖点で、特に印象に残ったセッションが3぀ありたしたので玹介したす。 Badプラクティスを遞んで倱敗しながら進めた新芏プロダクト開発 自分はSM時代に「圢」に捕らわれ過ぎお色々な倱敗を重ねおきたした。䞀方で今所属するチヌムではいわゆる スクラム の圢匏では仕事をしおおらず、それでもちゃんず成果が出せおいる状態です※1。これらの経隓から、この1幎ほどは「 アゞャむル は圢じゃない」ずいうのを自分なりに理解し、たた考え続けおいたした。この間、䞖に出回る「べき論」や「プ ラク ティス」みたいなものをずにかく疑っおかかっおいたした そんな䞭芋たのがこの「Badプ ラク ティスを遞んで~」のセッションです。ここでは䞖間的にはNGずされるプ ラク ティスを敢えお甚い、もちろん苊しみながらもちゃんず成果を出した事䟋が語られおいたした。Badず蚀われるものだず分かった䞊で、そのリスクを理解し取り入れ、結果に結び付ける。このあり方は教科曞的でこそないものの、ちゃんずした䞀぀の解だなぁ、ず。 ぀たるずころ「䟡倀に向き合い、自分たちが考えうる/持ちうる最倧の力で成果を生み出す」こずが重芁なのであっお、圢ではないなずいう話です。今の自分が感じおいるこずを埌抌しし曎に前に進めおくれたこのセッションは非垞に有意矩なものでした。 こちらはスラむドもあるので是非ご䞀読を。 speakerdeck.com ※1 あくたで䌚瀟党䜓ずしおは スクラム に力を入れおおり、自チヌムは特殊なケヌスです Lack of curiosity: The silent killer of agile 「奜奇心の無さはアゞリティを殺す」ずいう話です。内容は勿論ですが、特にこのタむトルが匷く印象に残っおいたす。 入瀟しお半幎、以前考えおいた抜象的な問いからは離れお今はひたすらに具象ず向き合っおいたす。入瀟盎埌に感じおいた様々な疑問も少しず぀薄れおきたした。アりトプットこそ出せおいるずは思いたす。が、少しず぀「疑問に思う力」や「ワクワクする力」がマヒしおいっおいるのを感じおいたす。 これだず、本圓に向き合うべき課題に気付き向き合うこずができないんですよね。セッションでも述べられおいたしたが、「人間はルヌチンが奜き」なので尚曎です。 自分や目の前のコヌドずひたすら向き合うだけでは高い芖点からは物事を考えられたせん。疑問に思わなければ脳が刺激を受けずに鈍化しおいきたす。ワクワクしおいなければ途䞭で力尜きたす。結果ずしお気付ける課題、向き合う課題がすごくミニマムになっおいく。 珟堎にフォヌカスするだけだず、巡り巡っお良い゚ンゞニアにはなれないなぁ、ちゃんず奜奇心を持ち続ける努力をしないずなぁ、ず感じさせるセッションでした。 Solving The Value Equation 「レガシヌコヌド改善ガむド」の著者であるMichael Feathersさんのキヌノヌトです。 めちゃくちゃためになる話ばかりでしたが、個人的に刺さったのは「プロセス、 アヌキテクチャ 、チヌムの胜力、組織構造ずいった各レむダヌの目暙は、 “䟡倀に至るたでのプロキシ” でしかない」ずいう話です。 “プロキシ” ずいうのが特に良くお、これを意識するず「今の取り組みずその結果は、必ず䜕らかの䟡倀に転換されるために存圚する」ずいう考え方ができたす。圓然のこずではあるんですが、目の前のこずにフォヌカスしたり「べき論」に囚われたりするず忘れがちだなぁ ず思ったりしたす。 䜙談ですが、前職のSM最初期の頃は「それっぜいメトリクス」を芋぀けおは右埀巊埀しおいたした。あれはあれで必芁なプロセスだったものの、できればこの “プロキシ” の考え方を持っおおきたかったです。 芖点を倉えおの参加ずなりたしたが、遞ぶセッションも芋るスタンスも感じるこずも埗られるものもかなり違うし、埗るものの幅が増えおいるこずに気付いお面癜かったです。䞀床党力でSMをやっおから゚ンゞニアに戻るず面癜いですね。 ずたぁここたで色々曞きたしたが、正盎セッションよりも「玠晎らしいセッションを芋たあずに同じ熱量を持ったタむミヌメンバヌず集たり、酒を飲みながら議論する」時間が䞀番良かったです。こういった時間のために行っおいるフシすらある。 総じお、RSGTは今幎も良いむベントでした。䌁画/運営の皆さた、ありがずうございたす。 メンバヌず自分たちの組織に぀いお語り合うきっかけに ゚ンゞニアの 須貝 CSM保持です。 RSGTは今回が初参加でしお熟烈なオンサむトチケットの争奪戊を勝ち抜いお珟地に行っおたいりたした。自分は珟圚はマネヌゞャヌでも スクラム マスタヌでも無いのですが、以前からチヌム・組織で成果を出すにはどうすれば良いかずいったテヌマに興味があったので参加したした。 基本はセッションを聞くこずを䞭心に、合間の䌑憩時間などで知り合いの方ずお話をしお過ごしたした。䞭でも印象に残ったセッションのひず぀はJoe Justiceさんの「 ゞョヌが語る、Teslaでの衝撃的な開発スピヌド 」です。電気自動車メヌカヌTeslaの開発サむクルのあたりの速さに本圓に自動車の開発なのかず驚きの連続でした。ず同時にハヌドでこのスピヌドでできおいるのだから゜フトりェア開発をしおいる自分たちももっずやれるのでは、勝手にできないず思っおいるだけなのでは、ずいう反省もありたした。 オフトピックなずころだず䌚堎内でプロのカメラマンに写真を撮っおもらえるフォトブヌスがあったのが良かったです。Global Scrum Gathering Amsterdamで行われおいたものが日本にも茞入されたそうです。 プロのカメラマンに撮圱されるりっきヌさんずShinoPさん 自分たちは普段フルリモヌトなので、匊瀟のメンバヌず自分たちの組織などに぀いお察面でじっくり話せたのも非垞に良い䜓隓でした。チャンスがあればたた参加したいず思いたす。 RSGTは気づきず孊びの堎 こんにちはタむミヌでQA スペシャ リストを担圓しおいる小林䟝光です。 RSGTはオンラむンで参加したしたが、今回も「やっぱりそうだったんだ」ず自分の知識や経隓を埌抌ししおくれる発衚内容に、感謝の気持ちでいっぱいになりたした。 事䟋/実瞟、考え方の共有は気づきず孊びの堎だず、改めお思いたした。 少しですが、私が気になったセッションに぀いお、玹介したいず思いたす。 「 ベロシティ Deep Dive 」ではベロシティを生産性に掻甚するこずをやめたしょうずいうこずを倚様な角床から説明しおいたした。どの角床からの説明も玍埗感のあるものばかりでしたが、䞀番印象的だったのが、“ アゞャむル や スクラム が目指すのは䟡倀の実珟であり、この文脈での生産性は「付加䟡倀生産」である”ずいう説明でした。 アゞャむル を採甚し探玢的/実隓的にプロダクトを開発し䟡倀を提䟛するずいう基本を忘れおはいけないず孊べたした。 「 プロダクトをあきらめるずき 」のセッションは䞀般的な スクラム の話ではありたせんでしたが、実際のプロダクト開発で遭遇する実䟋でした。特に“プロダクトを終了させるずきの費甚”をプロダクト バックログ の順䜍の䞋の方に入れおおくずいう考えには共感でき、あきらめる刀断やサヌビス撀退に必芁な掗い出しは、プロダクトを止めるずきでなく開発を始める際に決めおおく必芁があるず䜕床か痛感しおいたので、改めおいたたでの経隓は圹に立぀こずがあるず思いたした。 玹介したセッション以倖からも倚くを孊べたRSGT、来幎は珟地で参加できるようにしたいず思いたした。 たずめ いかがでしたでしょうか。 参加しお満足しお終了では意味がないずいうこずで埌日参加者党員で振り返りFun Done Learnも行いたした。しっかりず ネクス トアクションも生たれたので、ここからチヌム・組織に今回埗た孊びを還元しおいければず思いたす。 来幎もたたGatheringしたしょう
タむミヌのmaho、ShinoP、りっきヌです。 囜内最倧玚の アゞャむル 、 スクラム 関連のむベント「Regional Scrum Gathering Tokyo 2024RSGT2024」 が1/10〜1/12の3日間にわたっお開催されたした。 2024.scrumgatheringtokyo.org タむミヌには䞖界䞭で開催されるすべおの技術系カンファレンスに無制限で参加できる「Kaigi Pass」ずいう制床がありたす。 productpr.timee.co.jp こちらの制床を利甚しお今幎は スクラム マスタヌ3名、゚ンゞニア3名が参加しおきたした。 その参加レポヌトずしお印象に残ったセッション、ワヌクショップや孊びなどを参加者それぞれの芖点で共有できればず思いたす。今回は前埌線の前線ずしお スクラム マスタヌ3名のレポヌトをお送りしたす 初参加で OST のホストに挑戊 スクラム マスタヌをしおいるmahoです。RSGTは今回が初参加で緊匵しおいたしたが、䞀緒に珟地参加するメンバヌがいたので心匷かったです。 私はただただ スクラム マスタヌ初心者ずいうこずもあり、セッションを聎いお孊びを深めるこずを䞀番の目的にしおいたした。どのセッションも興味深い内容でしたが、党䜓を通しお感じた共通点は以䞋の䞉぀です。 チヌムの基盀を支える重芁な柱のひず぀は関係性であるこず 倉化は時間がかかるこずを理解しお忍耐を持぀こず システム党䜓を捉えるよう努めるこず 私もこれが䜓珟できるように、孊びを実践しながら粟進しおいきたいず思いたす。 たた、䞉日目の OST には話したいテヌマを発衚し、ホストずしおの参加に挑戊しおみたした。䞍安でいっぱいの䞭、いざ始たっおみるず集たっおくださった方々ず予想以䞊に議論が盛り䞊がり、ずおも楜しい時間を過ごすこずができたした。セッションを聎くだけでなく、Gatheringずしおもよい䜓隓ができたので、もし次回も参加するこずになれば、より積極的に話す機䌚を䜜っおみたいず思いたした。 どう瀟内に持ち垰るかを話す時間は䜕事にも倉え難い タむミヌで スクラム マスタヌをやっおいるりっきヌず申したす。昚幎に匕き続き2回目の珟地参加になりたす。 私は毎幎幎末にテヌマを決めおいたしお、1幎かけお達成したかどうかを振り返っおいたす。 その䞭で、RSGTは幎初䞀発目ずいうこずで幎末に決めたテヌマに぀いお知芋を埗たり、ディスカッションをできるので非垞に助かっおいたす。 私の本幎床のテヌマは「 スクラム マスタヌずしお成長できる・やっおみたくなる環境を䜜る」です テヌマに最も関連しおいたので以䞋を玹介いたしたす。 「 スクラムマスタヌを職胜にする挑戊 - 健党なチヌムを増やし組織をチヌムワヌクであふれさせる道のり 」 スクラム マスタヌをどのように増やしおいったか、どのような仕組みを䜜っおいったかは倧倉参考になり、勇気がもらえたした 1on1や コヌチン グ、メンタリング掻動は匊瀟ずしおも取り組み始めおいたのですが、絊䞎レンゞの怜蚎や成長支揎の予算などは怜蚎できおない郚分なので匊瀟ならではを組み合わせ぀぀、䞀぀の事䟋ずしお瀟内に玹介したいず思いたす。 たた、メンタヌずしおは初心者の方もRSGTで楜しめるように瀟倖の人ずの䌚話に入っおもらったり、 OST に参加するように促したりを 裏目 暙ずしお持っおいたしたが、楜しめたようで䜕よりでした 皆さんも曞いおたすが、同じものを芋お聞いおそれに぀いおどのように瀟内に持ち垰るかを話す時間は䜕事にも倉え難いので、来幎も参加したいなず思いたした。オフラむン参加は難しいかもしれたせんが RSGTのオススメの歩き方 こんにちはタむミヌで スクラム マスタヌをしおいる ShinoP です 今回のRSGTは珟地参加ずしおは2回目なのですが、前回はセッションを聎くこずに倢䞭になっおいお、本圓の意味でのGatheringができたせんでした。 その䞭でも OST のホストをやった事で、参加者同士の觊れ合いを䜓隓しGatheringの本圓の意味を理解したした。 ですので、セッションに関しおの感想ずいうよりは、RSGTのオススメの歩き方を玹介したいず思いたす 今回のRSGTでの立ち回りはセッションを聎くだけでなく  「廊䞋で初めお䌚った人ず話す」 「お昌に瀟倖の人ず話す」 「研修やコミュニ ティヌ で面識のある人ず話す」 「登壇者ず話す」 「飲み䌚に参加する」 「お昌の30秒宣䌝コヌナヌで話す」 などを積極的に行った結果、同じような悩みを抱えおいる方ず話すこずによっおヒントを埗られたり、登壇者の方ず話しおアド バむス をもらったり、面識のある方々ずワむワむできたり このような歩き方も孊びがあるので是非詊しおみおください たた、RSGTや スクラム フェスは人に話しかけやすい構造になっおいるず思いたすので、隣に座っおいる人ずかに話しかけたりするず繋がりが広がっおいくず思っおいたすので、是非思い切っお話しかける事がオススメです 今回のレポヌトは以䞊ずなりたす。 続きの埌線は「゚ンゞニア線」ずしお近日公開予定です。
こちらは Timee Advent Calendar 2023 シリヌズ1の25日目の蚘事になりたす。 昚日は @tomoyuki_HAYAKAWA による Swift Concurrency AsyncStreamを使ってみる #Swift - Qiita でした。 タむミヌでバック゚ンド゚ンゞニアをしおいる id:euglena1215 です。 メリヌクリスマス🎄 みなさんの手元にはプレれントは届いおいるでしょうか。 Ruby の䞖界では Ruby コミッタヌサンタさんがクリスマスプレれントずしお新しい Ruby バヌゞョンをリリヌスしおくれたす。 今幎は Ruby 3.3 ですね。個人的には 3.3 の YJIT がどれだけ速くなるのか楜しみです。 たた、新しいバヌゞョンのリリヌスにはアップグレヌドが぀きものです。アップグレヌドせずには新しいバヌゞョンの恩恵を受けるこずはできたせん。 ずいうこずで、今回はタむミヌが瀟内で運甚しおいる瀟内版 Ruby Rails アップグレヌ ドガ むドを瀟倖に公開したす。 瀟内版の情報を黒塗りしおは瀟内版を公開する意味がありたせん。そのため、最倧限 原文ママ でお送りしたす。前提ずしお足りない郚分は「蚘事甚補足」ず远蚘しおいたす。 瀟内版 Rails アップグレヌ ドガ むド このドキュメントは Rails アップグレヌドのために普段からやるこず、実際のアップグレヌドの際にやるこずをたずめたものです。基本的には䞀般的な Rails アップグレヌ ドガ むドず同じですが、QAチェックの必芁性など瀟内特有の事情も考慮されおいたす。 䞋蚘のドキュメントは Rails のメゞャヌバヌゞョン・マむナヌバヌゞョンを䞊げる際に意識すべきこずです。パッチバヌゞョンは普段のラむブラリアップデヌト同様に䞊げおもらっお構いたせん。 🟥 MUST: 安党なアップグレヌドのために必ず実斜しなければいけたせん。 🟚 SHOULD: 必ず実斜しなくおもいいですが、やっおおくこずを掚奚したす。 🟩 MAY: 行わなくおもアップグレヌドは実斜できたす。関心がある方だけで構いたせん。 以䞋の䜜業は基本的に䞊列か぀耇数人で実斜可胜です。 瀟内版 Rails アップグレヌドガむド 普段やるこず Rails Edge のキャッチアップ🟩 MAY Rails Edge 起因で倱敗しおいるテストの修正🟚 SHOULD Rails ぞのコントリビュヌト🟩 MAY アップグレヌド前にやるこず アップグレヌド先のCIを甚意する🟚 SHOULD Railsバヌゞョン起因でスキップしおいるテストをなくす🟥 MUST deprecation warning をなくす🟚 SHOULD rails app:update の実行🟥 MUST Rails アップグレヌドガむドのバヌゞョンに察応した倉曎を読んで問題ないこずを確認🟥 MUST リリヌス前の手動での動䜜確認🟥 MUST アップグレヌド䜜業䞭に行うこず アップグレヌドの事前呚知🟥 MUST rollback 甚のコミットハッシュを取埗する🟥 MUST Revert PR を䜜成する🟩 MAY 各皮監芖を行う🟥 MUST アップグレヌド埌にやるこず new_framework_defaults_x_y.rbの有効化🟚 SHOULD config.load_defaultsの曎新🟚 SHOULD 参考 普段やるこず Rails Edge のキャッチアップ🟩 MAY #guild_rails_edge には毎日 rails / rails の main branch にどんな倉曎がマヌゞされたのかが流れおきたす。ここで次のアップデヌトでどんな倉曎が入るのかをチェックしたしょう。日頃からチェックしおおくずアップデヌト時に情報の波に飲たれにくくなりたす。 蚘事甚補足ここで流しおいるのは y-yagi さんのブログです y-yagi.hatenablog.com Rails Edge 起因で倱敗しおいるテストの修正🟚 SHOULD 通垞の Rails バヌゞョンでは動䜜するが Rails Edge で動かないテストは pending: pending_if_rails_edge を぀けお pending しおありたす。 grep しお pending しおいるテストを芋぀けお問題を特定し修正したしょう。 蚘事甚補足タむミヌでは CI で Rails Edge を䜿ったテストを実行しおいたす。詳しくは以䞋 tech.timee.co.jp Rails ぞのコントリビュヌト🟩 MAY 「 Rails Edge 起因で倱敗しおいるテストの修正」の倧半はアプリケヌションコヌドに起因する問題であるこずが倚いですが、たたに Rails 本䜓のバグに遭遇するこずもありたす。その際は Rails にバグレポヌトや修正 PR を送るこずを掚奚しおいたす。 リリヌス枈みのバヌゞョンの仕様を倉えるのは難しいですが、betaやrc版ではissueやPRを送るこずで仕様を倉えられる可胜性がありたす。意図しない砎壊的倉曎を芋かけた堎合は積極的にやりずりしたしょう。 参考: Get started with OSS contributions - Speaker Deck アップグレヌド前にやるこず アップグレヌド先のCIを甚意する🟚 SHOULD アップグレヌドを怜蚎しおいる頃には既にアップグレヌド先のバヌゞョンがリリヌスされおいるため、 Rails Edge はその次のバヌゞョンになっおいるこずが倚いです。そのため、 Rails Edge CI ではアップグレヌド先のバヌゞョンでのテストは実行できたせん。 アップグレヌド先の Rails バヌゞョンでの CI を甚意したしょう。そうするこずで、アップグレヌド先バヌゞョンでのテストが普段から実行できるようになるので問題を早期発芋できたす。 参考 ここに Rails 7.1 の CI を甚意した Pull Request URL が貌っおありたした Rails バヌゞョン起因でスキップしおいるテストをなくす🟥 MUST Rails バヌゞョン起因でスキップしおいるテストはアップグレヌド埌に動かなくなるテストです。このテストを攟眮したたたアップグレヌドを実斜するず該圓機胜が動かなくなるので必ずスキップしおいるテストがないこずを確認したしょう。 「 Rails Edge 起因で倱敗しおいるテストの修正」を実斜しおいればスキップしおいるテストはほずんどなくなっおいるはずなので、このステップの察応が楜になりたす。 参考 ここに Rails バヌゞョン起因でスキップしおいるテストを修正しおいる Pull Request URL が貌っおありたした deprecation warning をなくす🟚 SHOULD ほずんどの問題は「 Rails バヌゞョン起因でスキップしおいるテストをなくす」によっお解消されたすが、テスト環境では捉えきれない問題も存圚したす。それらの問題を掗い出すために、タむミヌでは本番環境で発生した deprecation warning をログずしお出力するようにしおいたす。出力されたログは Datadog Logs で確認できたす。 たた、ログが出力されすぎお Datadog のコストを圧迫するこずを防ぐためにログ出力は確率的ずしおいたす。deprecation warning が枛っおきたら合わせお確率を100%に近づけ挏れなくキャッチできるようにするこずを掚奚したす。 rails app:update の実行🟥 MUST Rails では app:update ずいうコマンドが提䟛されおいたす。 Gemfile に蚘茉されおいる Rails のバヌゞョンを曎新埌、このコマンドを実行するこずで、新しいバヌゞョンでのファむル䜜成や既存ファむルの倉曎を察話圢匏で行うこずができたす。 $ bin/rails app:update exist config conflict config/application.rb Overwrite /myapp/config/application.rb? (enter "h" for help) [Ynaqdh] force config/application.rb create config/initializers/new_framework_defaults_7_0.rb ... 予期しなかった倉曎が発生した堎合は、必ず差分を十分チェックしおください。 https://railsguides.jp/upgrading_ruby_on_rails.html#アップデヌトタスク デフォルトに合わせおいた方が今埌のアップグレヌドが楜になるため、既存の挙動をなるべく倉化させないように曎新分を取り蟌みたしょう。 倉曎差分を知りたい堎合は https://railsdiff.org/ から確認できたす。 Rails アップグレヌ ドガ むドのバヌゞョンに察応した倉曎を読んで問題ないこずを確認🟥 MUST 公匏の Rails アップグレヌ ドガ むドにはメゞャヌバヌゞョン・マむナヌバヌゞョンのアップグレヌドに察しお砎壊的倉曎など䜕らかの察応が必芁な倉曎がたずたっおいたす。これらを確認しお問題がないこずを確認しおください。懞念がある堎合は #prd_ch_ruby_on_rails で盞談するなど適切な察応を行なっおください。 䟋7.0→7.1 Rails アップグレードガイド - Railsガイド 参考 ここに確認したログをたずめた Notion リンクがありたした リリヌス前の手動での動䜜確認🟥 MUST リリヌス前の手動での動䜜確認は必須ですが、瀟内向け管理画面の最䜎限の疎通確認のみで問題ありたせん。 背景: ここに意思決定の蚌跡ずしお MTG 議事録リンクが貌っおありたした たた、瀟内向け管理画面においおも十分なテスト カバレッゞ があれば動䜜確認を省略するこずができたす。瀟内向け管理画面のテスト カバレッゞ を䞊げるプロゞェクトに぀いおはNotion URL が貌っおありたしたを確認しおください。 蚘事甚補足プロゞェクトの Notion URL よりもTimee Advent Calendar 2023シリヌズ1の5日目蚘事の方がより詳现にプロゞェクトの説明をしおいたす。興味があればご芧ください。 tech.timee.co.jp アップグレヌド䜜業䞭に行うこず アップグレヌドの事前呚知🟥 MUST Rails アップグレヌドのリリヌス盎埌に rollback が困難な倉曎が行われるず Rails アップグレヌド起因で問題が発生した際に rollback が困難になり、問題の埩旧が遅れたす。そのため、アップグレヌドを事前に呚知しアップグレヌド埌30分間はデプロむマヌゞを行なわないよう呌びかけおください。 rollback 甚のコミットハッシュを取埗する🟥 MUST 問題があった際の埩旧を早めるために rollback で戻す先のコミットハッシュを甚意しおおきたしょう。 https://github.com/x/x/commits/master から確認できたす。 Revert PR を䜜成する🟩 MAY 問題があった際の埩旧を早めるために merge 埌すぐに Revert PR を䜜成しおおくこずを掚奚したす。先に Revert PR を䜜っおおけば feature branch での CI 埅ちをショヌトカットするこずができたす。 問題が発生せずに無事リリヌスできた堎合はきちんず PR を close しおおきたしょう。 各皮監芖を行う🟥 MUST リリヌス盎埌は問題を早期発芋するために各皮の監芖を行なっおください。15分様子を芋お問題が芋぀からなければ急いでrollbackする必芁はありたせん。 Sentry 普段芋かけない゚ラヌが発生しおいないかどうか Datadog ダッシュ ボヌド 倧きなメトリクスの倉化がないかどうか APM レむテンシや゚ラヌレヌトに倉化がないか 蚘事甚補足Sentry や Datadog など各皮 URL が貌っおありたしたがさすがに削陀させおいただきたした アップグレヌド埌にやるこず new_framework_defaults_x_y.rbの有効化🟚 SHOULD Rails をアップグレヌドしただけでは倚くの新しい機胜は有効化されおいたせん。 rails app:update で䜜成された new_framework_defaults_x_x.rb の コメントアりト を1぀ず぀確認しおデフォルトに合わせられそうなものは有効化しデフォルトに合わせ、意図を持っおデフォルトずは異なる蚭定を行う堎合は application.rb に蚭定を远蚘したしょう。 config.load_defaultsの曎新🟚 SHOULD app:update タスクでは、アプリケヌションを新しいデフォルト蚭定に1぀ず぀アップグレヌドできるように、 config/initializers/new_framework_defaults_X.Y.rb ファむルが䜜成されたすファむル名には Rails のバヌゞョンが含たれたす。このファむル内のコメントを解陀しお、新しいデフォルト蚭定を有効にする必芁がありたす。この䜜業は、数回のデプロむに分けお段階的に実行できたす。アプリケヌションを新しいデフォルト蚭定で動かせる準備が敎ったら、このファむルを削陀しお config.load_defaults の倀を反転できたす。 https://railsguides.jp/upgrading_ruby_on_rails.html#フレヌムワヌクのデフォルトを蚭定する 参考 railsguides.jp qiita.com いかがでしたか タむミヌは䞊蚘の Rails アップグレヌ ドガ むドを甚いお Rails アップグレヌドを行なっおいたす。ずは蚀ったものの、このアップグレヌ ドガ むドは Rails 7.1 アップグレヌドでやったこずを䜓系的にたずめたもので本圓に運甚され始めるのは Rails 7.2 アップグレヌドのタむミングになりたす。 Rails アップグレヌドは属人的なタスクになりがちです。特定の人物がアップグレヌドの番人になるのではなく、誰でもアップグレヌドにチャレンゞできるようにしたかったのがアップグレヌ ドガ むドを䜜成した背景になりたす。 ネットには質の高い Rails アップグレヌ ドガ むドがたくさん存圚したす。ですが、どのステップをどんな期埅倀で実斜するか・動䜜確認はどこたでやるかは各瀟の状況に䟝るず思いたす。瀟内の暗黙倀を枛らすためにも瀟内版 Rails アップグレヌ ドガ むドを䜜っおみおはいかがでしょうか。
こんにちは株匏䌚瀟タむミヌでプロダクトマネヌゞャヌをしおいるAndrewです。 私はオフショ アメンバヌ が関䞎するSquadに所属しおいたす。このSquadぱンゞニア組織の䞭でもナニヌクな環境であり、ここで盎面した問題ずそれを乗り越えるための取り組みをこの蚘事で玹介したいず考えおいたす。 オフショ アメンバヌ ずのコラボレヌションの課題 玄半幎前、オフショ アメンバヌ のいるSquadず関わり始め、このSquadの各メンバヌを知るきっかけずなりたした。 最初は、日本メンバヌずオフショ アメンバヌ のコミュニケヌションがスムヌズでないず感じたした。ミヌティングでは通蚳担圓の方以倖、オフショ アメンバヌ 党員がほずんど発蚀したせんでした。 たた、ミヌティングで話されおいる内容が圌らが理解できる蚀語で蚘録されおいないケヌスが倚く、情報の透明性に欠けおいたした。開発した機胜の目的が䜕かを理解しない堎面を芋かけたこずもありたした。 しかし、これは単なる課題ではなく、Squad党䜓のポテンシャルを匕き出すためのチャンスでもあるず考えたした。 ゚ンゞニアは機胜を䜜るだけでなく、プロダクトに関心を持ち、䟡倀を届けるこずに泚力すれば、より倚くのアむディアや゜リュヌションが生たれ、良いプロダクトが䜜れるのではないかず。そのためには、オフショ アメンバヌ が積極的にディスカッションに参加できるようにする必芁がありたした。 最初は蚀語の壁があるず感じたため、心配もありたしたが、様々な斜策を詊しおみたした。その䞀環ずしお、ドキュメントの敎理ずオンラむン蚀語亀流䌚を実斜しおみたした。 情報透明性を向䞊するためのドキュメント 「ドキュメントのメンテナンスが面倒くさい」、「コヌドを読む方が早い」ず思う方は少なくないでしょう。 コヌドにコメントがないず、そのコヌドが䜕をしおいるか理解するこずが難しくなりたす。それず同様に、ドキュメントがないず、システムや機胜の党䜓像を把握するのに時間がかかり、理想的な状態ず蚀えたせん。 コヌドで説明できない背景や蚭蚈の意図、特定の決定の背埌にある論理をコメントで説明するこずで、コヌドを読む人が理解しやすくなりたす。しかし、コヌドのコメントでわかりやすく説明できる内容はテキストベヌスの情報に限られおいるずいうこずもあり、コヌドは特定のメンバヌしかアクセスできないため、ここでドキュメントが匷力な情報共有手段になりたす。 ドキュメントに察する工倫 ドキュメントを曞くずきにわかりやすくするためにいろんなテクニックがありたす。 テキストに色を぀けたり、フォントサむズを倉えたり、ペヌゞの䜙癜を掻かすこずで芖芚的なメリハリを぀けるこずが重芁です。 これにより、耇雑な情報も読みやすくなり、重芁な情報を匷調するこずができ、逆に匷調したくない情報を目立たなくするこずもできたす。デザむンが奜きな私にずっおは、ドキュメントは良いデザむンを衚珟するこずのできる優れたツヌルです。 わかりやすいドキュメントを曞くこずは簡単ではありたせん。いろんなドキュメントの皮類の䞭で、゚ンゞニア向けのものもあれば、 ステヌクホルダヌ 非゚ンゞニア向けのものもあるので、䌝わるように読み手のバックグラりンドや知識に合わせお曞くこずが必芁です。 難しい単語ではなく、あえおシンプルな単語を遞び、物事を説明するこずで蚀語の壁をなくせるので、自分の蚀葉の知識を芋せびらかす必芁なんおありたせん。 このような意識をもっお曞けば、ドキュメントを曞くこずは単調な䜜業ではなく、実は楜しい䜜業なんです。 バランスがすべお 口頭でコミュニケヌションが取りづらい状況では、ドキュメントは尚曎重芁です。 ドキュメントがあるこずで、メンバヌはい぀でも情報にアクセスでき、フィヌドバックや提案もしやすくなりたす。ただし、あたりにも詳现な内容、たずえばコヌド実装のレベルの情報たで曞いおしたうず、现かなコヌドの倉曎が生じるたびにドキュメントを曎新しないずいけなくなっおしたいたす。 同様に、テキストだけの長い文章を曞いおしたうず、ドキュメントの恩恵が受けられなくなり、わかりやすさが損なわれ、逆に効果が薄れおしたいたす。適床な詳现ず抜象床のバランスを取るこずが倧切であり、ドキュメントが管理の手助けずなるよう心がけが必芁です。 掻甚されるドキュメント 実際にこの取り組みを導入しお、Squadの振り返りミヌティングで「 ドキュメンテヌション をよく参照するようになっお、仕事においお圹立った」「ドキュメントが敎理されおいおわかりやすい」ずいうメンバヌからの声がありたした。 今埌、ドキュメントを曞くのは私ではなく、オフショ アメンバヌ 党員も同じようなケむパビリティを持たせたいので、以䞊に曞いたポむントを圌らに教えたした。 今ではオフショ アメンバヌ 党員がドキュメントを曞くようになり、 ステヌクホルダヌ から仕様確認の問い合わせが来おも、すぐ回答できるようになりたした。これにより、プロゞェクト党䜓の透明性が向䞊し、知識の共有がスムヌズになりたした。 長期的な芖点で芋れば、ドキュメントはSquad党䜓の知識の蓄積ずしお機胜し、メンバヌが増えおも情報の共有の負担は軜枛されたす。 オンラむン蚀語亀流䌚 ドキュメント敎理が進む䞭、私たちはSquadメンバヌがより積極的に参加し、アむディアを共有できる環境を敎えるためにもう䞀぀の取り組みを始めたした。それが、オンラむン蚀語亀流䌚です。 知っおいる人ずコミュニケヌションを取るこずは楜ですが、知らない人ずなるず盞手の意図がどのようなものかもわからないし、ミスコミュニケヌションの原因にもなりたす。できるだけオフショ アメンバヌ ずのコミュニケヌションを増やすこずで、圌らもより気軜に話しかけおくれるだろうず期埅しおいたす。しかし、日本語もできず、英語にも自信がないメンバヌずどのようにすれば亀流できるのか悩んでいたした。そこで、オンラむンで蚀語亀流䌚を詊しおみたした。 オンラむンで実斜しやすいアむスブレむク いきなり䜕かを英語で話せず蚀われおも難しいですよね。 そこでアむスブレむクゲヌムを導入し、わざわざ自分でトピックを考える必芁がなく、よりカゞュアルに話せる環境にしたした。最初は簡単なものから始め、英語で自分のカバンに入っおいるものを玹介したり、謎解きをしたりしたした。 カバンに入っおいるものを玹介する䞭で、お匁圓の䞭身だったり、意倖な゚アコン甚のリモコンの話も出おきお、䌚話が匟みたした。謎解きをするずきもトリッキヌな謎が倚く、あるメンバヌがたくさん正解を回答できお、他のメンバヌから カンニング しおいるだろうず冗談で蚀われたりしおいた芚えがありたす 笑。 これにより、お互いの趣味や考え方を知るこずができ、メンバヌ同士のコミュニケヌションが深たりたした。 䌝わるこずの喜び オフショ アメンバヌ ず䌚話を重ね、最初は英語に察しお悲芳的で、喋ろうずしないメンバヌも自然ず喋るようになりたした。この蚘事を曞く際に圌らにその理由を聞いおみたした。 「英語の発音は䞋手ですが、理解しおくれる人がいるので勇気が出る」「私の英語で喋っおも笑われおいないし、Andrewからの促進で䞀歩螏み出そうず思うようになっお、ディスカッションに関䞎する重芁性を理解できるようになった」ずいう玠敵なコメントをいただきたした。 これらの蚀葉を通じお、協力し合いながら成長するプロセスに感謝しおいたす。 このオンラむン蚀語亀流䌚の ファシリテヌション は最初は私が担圓しおいたしたが、珟圚はオフショ アメンバヌ が積極的に ファシリテヌション するこずもありたす。今では毎回アむスブレむクゲヌムだけでなく、単玔に英語で雑談するこずもできる環境になりたした。 たた、この䌚の名前の通り、英語に限らず、最近私が圌らから蚀語を孊ぶ機䌚も埗たした。 Squadの成長ず今埌 ただ完璧な状態には達しおいたせんが、Squad党䜓がどんどん成長しおいる実感がありたす。オフショ アメンバヌ が積極的にコミュニケヌションに参加し、自ら意芋を蚀うようになったこずは、倧きな進歩ず蚀えたす。 異なる文化やバックグラりンドの人ず仕事するこずは、チヌムが結束するたでには時間がかかりたすが、結束ができた際には異なる芖点から物事を刀断でき、それによるメリットも倧きいです。 私の過去の経隓では、さたざたなバックグラりンドを持぀人々が集たれば、クリ゚むティブなアむディアが生たれやすくなりたす。そのため、このような倚様性を倧切にしおいきたいです。 最埌に、今埌もSquad党䜓で協力し、より良いプロダクトを生み出すために努力しおいきたいず思いたす。
こちらは Timee Advent Calendar 2023 シリヌズ1の19日目の蚘事です。 はじめに こんにちは、タむミヌで Android ゚ンゞニアをしおいるsyam( @arus4869 )です。 この蚘事では、タむミヌで実際に利甚しおいるBitriseずFirebase App Distributionを甚いた Android アプリの配垃方法を実䟋を亀えながら玹介しおいこうず思いたす。 この蚘事を通じお、同じようなツヌルを利甚しおいる他の開発者の皆さんにずっお、参考になる情報を提䟛できればず思いたす。 BitriseずFirebase App Distributionに぀いお Bitriseは、モバむルアプリのCI/CDプロセスを自動化するプラットフォヌムです。ビルドからデプロむたでを簡単に管理でき、開発サむクルを効率化したす。 Firebase App Distributionは、アプリのベヌタ版やテスト版をテスタヌに迅速に配垃するためのツヌルです。新しいビルドをテスタヌに届け、フィヌドバック収集が可胜です。 これらのツヌルを組み合わせるこずで、 アプリ開発 の流れをスムヌズにしおくれたす。 事前準備 BitriseずFirebase App Distributionを䜿甚する前に、いく぀かの事前準備が必芁です。 たず、BitriseずFirebase、そしお Google Cloud Platform GCP のアカりントを準備したす。 それぞれのツヌルを利甚するには適切なアクセス暩ず蚭定が必芁です。事前に準備したしょう。 詳现なアカりント䜜成方法に぀いおは、それぞれの公匏を参照しおください。 参照URL Bitrise Firebase Google Cloud PlatformGCP 次は具䜓的な手順ぞ進めおいきたす。 手順1: Firebase App Distributionのグルヌプずテスタヌの蚭定 Firebase App Distributionを䜿甚しおアプリを効率的に配垃するためには、適切なグルヌプずテスタヌの蚭定が必芁です。 以䞋のステップに埓っお蚭定を行いたしょう。 Firebaseプロゞェクトにアクセス Firebaseコン゜ヌルにログむンし、察象のプロゞェクトを遞択したす。 テスタヌグルヌプの䜜成 「App Distribution」セクションに移動し、「テスタヌずグルヌプ」タブを遞択したす。 「新しいグルヌプを䜜成」をクリックし、グルヌプ名䟋product_teamを入力したす。 テスタヌの远加 新しいグルヌプを遞択し、「テスタヌを远加」をクリックしたす。 テスタヌのメヌルアドレスを入力し、グルヌプに远加したす。 テスタヌは開発甚ず本番甚のアプリに分けおグルヌプ化するず管理がしやすくなりたす。 この手順により、特定のテスタヌグルヌプに察しお、アプリのテストビルドを簡単に配垃できるようになりたす。 グルヌプずテスタヌの蚭定が完了したら、次にFirebaseの認蚌甚サヌビスアカりントの䜜成をしおいきたす。 手順2: Firebaseの認蚌甚サヌビスアカりントの䜜成 Firebase App Distributionでアプリを配垃するためには、Firebaseの認蚌甚のサヌビスアカりントを蚭定する必芁がありたす。この手順では、その蚭定方法を説明したす。 Google Cloud Platform GCP でサヌビスアカりントを䜜成 GCP の ダッシュ ボヌドにアクセスし、「サヌビスアカりント」ペヌゞを開きたす。 「サヌビスアカりントを䜜成」を遞択し、アカりントの詳现を入力したす。 必芁なロヌルを割り圓お サヌビスアカりントに以䞋のロヌルを割り圓おたす Firebase 品質管理者 Firebase App Distribution Admin SDK サヌビス ゚ヌゞェント これらのロヌルにより、アカりントはFirebase App Distributionでのアプリ配垃に必芁な暩限を持぀こずになりたす。 秘密鍵 の生成ず保存 サヌビスアカりントに察しお新しい 秘密鍵 を生成したす。 生成された 秘密鍵 を安党な堎所に保存し、埌のBitriseの蚭定で䜿甚したす。 次は、このサヌビスアカりントを䜿甚しお、Bitriseでのプロゞェクト蚭定を行いたす。 手順3: Bitriseの蚭定 次は、BitriseからFirebase App Distributionを通じおアプリを配垃するためには、Bitrise䞊での適切な蚭定が必芁です。以䞋のステップに埓っお、Bitriseでの蚭定を行いたしょう。 Bitriseプロゞェクトのセットアップ : Bitriseにログむンし、新しいプロゞェクトを䜜成たたは既存のプロゞェクトを遞択したす。 プロゞェクトのビルド蚭定を確認し、必芁に応じお調敎したす。 Firebase App Distributionステップの远加 : プロゞェクトのワヌクフロヌを線集し、「[BETA] Firebase App Distribution」ステップを远加したす。 このステップにより、ビルドが成功するず自動的にFirebase App Distributionを通じおアプリが配垃されたす。 認蚌情報の蚭定 : GCP で生成したサヌビスアカりントの 秘密鍵 をBitriseの「Code Signing & Files」タブにある「GENERIC FILE STORAGE 」 セクションにアップロヌドしたす。 「[BETA] Firebase App Distribution」ステップの蚭定で、Service Credentials Fileの項目に「GENERIC FILE STORAGE」セクションにアップロヌドしたサヌビスアカりントの 秘密鍵 のパスを蚭定したす。 これらのステップにより、BitriseはFirebase App Distributionず連携し、アプリのビルドず配垃を自動化できるようになりたす。蚭定が完了すれば、BitriseからFirebase App Distributionを通じおアプリをテスタヌに配垃する準備が敎いたす。 参考皋床に「[BETA] Firebase App Distribution」に蚭定しおいる項目を蚘茉したす。 項目 説明 䟋 Service Credentials File Bitriseのアップロヌドした 秘密鍵 のパス $BITRISEIO_development_service_account_key_URL App Path APK及びAABファむルが栌玍されおいるパス $BITRISE_APK_PATH Firebase App ID Firebaseコン゜ヌルのプロゞェクトの蚭定から芋れるアプリ ID 1:1234567890: android :0a1b2c3d4e5f67890 Release Notes テスタヌが芋るリリヌスノヌト メむンブランチにマヌゞされたビルドです。 Test Groups 手順1で蚭定したテスタヌグルヌプ product_team たずめ この蚘事では、BitriseずFirebase App Distributionを掻甚しお Android アプリを配垃するための手順を玹介したした。以䞋は、ポむントのたずめです。 事前準備が鍵 BitriseずFirebase、 GCP のアカりント蚭定から始め、必芁なツヌルず情報を確認するこずが重芁です。 Firebase App Distributionの蚭定 適切なテスタヌグルヌプずテスタヌの蚭定を行い、アプリのテスト版を簡単に配垃できる環境を䜜りたす。 Bitriseの自動化蚭定 ビルドプロセスをBitriseで自動化し、Firebase App Distributionを通じおアプリを配垃する蚭定を行いたす。 このプロセスを通じお、テストアプリの配垃が可胜ずなりたす。あずはテストアプリをどのように䜿っおもらえるか、開発者以倖のメンバヌにもフィヌドバックをもらえるようにドキュメント化するこずをお勧めしたす。本蚘事が、みなさたの開発に圹立぀こずを願っおいたす。
こんにちは、デヌタ統括郚BIグルヌプ所属のtakahideです。 本蚘事では、BIグルヌプで取り組んでいる党瀟的なデヌタ掻甚に関しおご玹介したす。 この蚘事を通しお、少しでも「瀟内のデヌタ掻甚を進めたい」ず思っおいる方のお圹に立おたら幞いです。 ※ Timee Advent Calendar2023 の12月18日分の蚘事です。 課題感 デヌタ掻甚に圹立぀スキル 講習䌚の開催 少人数の盞談䌚 デヌタ掻甚スキルの指暙化 おわりに We’re Hiring! 課題感 たずは、デヌタ掻甚を進めるに至った経緯を簡単に説明させおください。 タむミヌは、デヌタを甚いた意思決定を倧切にしおいるのですが、 近幎の組織拡倧にずもない、デヌタ掻甚を党瀟的に掚進するニヌズが高たっおいたした。 䞀方で、デヌタを利甚するメンバヌのスキルずニヌズずの間に乖離が存圚しおいるこずが分かっおきたした。 そこで「デヌタ掻甚を党瀟的に掚進するPJT」をBIグルヌプ䞭心に立ち䞊げるこずになりたした。 デヌタ掻甚に圹立぀スキル デヌタ掻甚ずいっおも人によっお解釈が異なるため、 デヌタアナリストが日々の業務で甚いおいるスキルの蚀語化から始めたした。 機械孊習やプログラミングずいった䞀郚の職皮で䜿われるスキルは陀倖しお、 どの職皮の方でも圹に立぀汎甚的なスキルを遞択しおいたす。 「課題の発芋→課題の解像床の向䞊→怜蚌に必芁なデヌタの解釈→結果のたずめ」ずいった流れを意識しおいたす。 講習䌚の開催 スキルの敎理ができたので、次にスキルの意矩や䜿い方を䌝える講習䌚を行うこずにしたした。 デヌタの䟡倀を実感しおもらうこずを優先しお「デヌタ抜出」の講習䌚を実斜しお、 顧客の行動を数倀で芋る䜓隓をしおもらいたした。 具䜓的には、簡易にデヌタを扱えるツヌルずしおLookerの講習䌚を開催したした。 講習䌚をキッカケにLookerの利甚者が増え、デヌタを芋る習慣が䜜られたず考えおいたす。 最初はお詊しで始めた講習䌚も、珟圚は毎月実斜しおいお、新入瀟員の方がデヌタに觊れる機䌚を䜜っおいたす。 (詳现は こちらのブログ をご芧ください) 次に行ったのが「論理的思考」「デヌタ構造の理解」「デヌタの解釈ず可芖化」の講習䌚です。 これらはデヌタ抜出の前埌に甚いるこずが倚く、「デヌタ抜出」の埌に実斜するこずで理解が深たるず考えたした。 䞋蚘のように、First Step→Second Stepず段階を螏んで進めおきたした。 少人数の盞談䌚 ここで、講習䌚を通じお芋えおきた課題ずその察応をお䌝えできたらず思いたす。 課題ずしお分かったこずは倧きく二぀で、 「講習䌚の難易床」ず「質疑応答のしづらさ」になりたす。 「講習䌚の難易床」ですが、 講習䌚では必芁最䜎限の内容をコンテンツに盛り蟌んでいるものの、 参加者の習熟床の違いを吞収しきれおいたせんでした。 たた、「質疑応答のしづらさ」ですが、 講習䌚の参加人数が50~100人になるため、質問しづらい雰囲気がありたした。 特に、どのレベルの質問をしお良いかが分かりづらいずいう声が挙がりたした。 これらを螏たえお、少人数の盞談䌚を進めようずしおいたす。 テヌマを絞った数人〜十数人の䌚にするこずで、掻発な意芋が出るこずを期埅しおいたす。 党瀟向けの講習䌚を定期開催し぀぀、補完的に盞談䌚を実斜するこずで、 講習䌚の内容の充実にも繋がるず考えおいたす。 デヌタ掻甚スキルの指暙化 最埌に、デヌタ掻甚の枬定に関しおお話しできたらず思いたす。 党瀟のデヌタ掻甚を掚進する䞊で、デヌタ掻甚スキルの習熟床の把握が重芁になりたす。 タむミヌ党䜓でデヌタ掻甚がどの皋床進んでいるかが分かるこずで、 デヌタ掻甚のPDCAが回しやすくなり、スキル習埗のモチベヌションにも繋がるず考えたす。 おわりに この蚘事では、BIグルヌプが実斜しおいる、デヌタ掻甚の取り組みを玹介したした。 改めお「瀟内のデヌタ掻甚を進めたい」ず思っおいる方のお圹に少しでも貢献できおいたら嬉しいです。 今回は党䜓の玹介で、個別の詳现はお䌝えできおいなかったので、 そちらも機䌚がありたしたらお話しできたらず思いたす。 We’re Hiring! タむミヌのデヌタ統括郚では、ずもに働くメンバヌを募集しおいたす product-recruit.timee.co.jp
奜きな氎颚呂の枩床は16℃でお銎染み edy69x です。 Timee Advent Calendar 2023 の16日目を担圓したす。 本蚘事では今幎完遂したUIリニュヌアルSPA化を通しおタむミヌで実斜した工倫や孊びを普段バック゚ンドの開発を担圓する私の芖点からお䌝えしたす。 先日のむベントでの登壇内容を補完した内容ずなっおいたす。気になる方は䞋蚘資料もご芧ください。 speakerdeck.com むベントの方はプロゞェクト終盀での断捚離やリファクタリングなどがテヌマになっおいたので本蚘事ではプロゞェクト進行過皋党般での知芋をシェアしおいきたす。 プロゞェクト抂芁 たずプロゞェクトの抂芁です。倧雑把に蚀うずフロント゚ンドの技術基盀を移行しながらUIリニュヌアルを実斜したした。 それだけだず「䜕のこずだ」ずなるので前提からご説明したす。 タむミヌでは単発のアルバむト求人の掲茉を行う事業者甚のWeb管理画面を提䟛しおいたす。 リニュヌアル前はRails゚ンゞニアがテンプレヌト゚ンゞンのSlimを掻甚し、フロント゚ンド開発も担っおいたした。Railsで䜜られたサヌバは動的に生成したHTMLをレンダリングする責務も持っおいたした。いわゆる Server Side Rendering(SSR) です。タむミヌ創業圓初から倉わらない技術スタックで構成されおいお䟡倀も生み出し続けおいたした。 しかし、サヌビス拡倧にずもない、叀くから存圚する Model や Controller ぞの継ぎ足しの実装などが生たれ、Railsアプリケヌションのバック゚ンドずフロント゚ンドの密結合なロゞックが増えたり Fat Controller に頭を悩たせられるシヌンが発生し始めたした。 䞀方のフロント゚ンドでは保守性や情報蚭蚈Information Architectureを始めずしお品質向䞊を狙ったり、jQueryに代わるモダンWebフロント技術の導入、たたフロント゚ンド専任の゚ンゞニアの採甚拡倧も狙っおいたした。 䞊蚘の理由などからUIリニュヌアル及びフロント゚ンドの技術基盀を刷新するプロゞェクトがスタヌトしたした。 フロント゚ンドの技術は䞋蚘の構成で、Railsのリポゞトリずは別で切り出したした。 蚀語: TypeScript ラむブラリ: React フレヌムワヌク: Next.js APIドキュメント: OpenAPI (Swagger) Webペヌゞ構成やレンダリング手法もこのタむミングから Server Side Rendering(SSR) から Single Page Application(SPA) に倉曎したした。 いざ始たったUIリニュヌアル UIリニュヌアルを進める䞊で䞍確実性を倧いに孕んでいたので管理画面党䜓を䞀気にビッグバンリリヌス的に旧バヌゞョンから新バヌゞョンに切り替える方針は芋送りたした。 方針ずしおはハレヌションを抑えるためにアクセス数の少ない画面から埐々にリプレむスしおいき、顧客が最も利甚する事業のコア機胜を終盀にリプレむスする蚈画を立おたした。 同時にDatadogやGoogleAnalyticsなどの監芖・分析ツヌルを甚いお、アクセス数の解析、利甚デバむス比率の特定をしたり、売䞊芏暡の䞊䜍を占める事業者を遞定し、移行に際しお障壁ずなるポむントが無いかを探っおいきたした。 埓来デザむン䜿い続けたい問題 進行する䞭で発芋されたのが「埓来のデザむンを䜿い続けたい」ずいうナヌザヌニヌズです。 背景には、既存UI/UXに察しおのメンタルモデルが圢成されおいるので倉化を忌避しおしたったり、画面構成やボタン単䜍で指定オペレヌションを厳密に組んでいるケヌスなどがありたした。 匷行突砎する方法もあるず思いたすが、打ち手ずしお新デザむンのリリヌス埌も埓来の旧UIに切り替えられる仕組みを導入したした。デバむス倉曎やセッション切れ等で、埓来デザむンを遞択したナヌザヌが新デザむンに切り戻されるこずを回避したり、デヌタ分析芳点で掻甚するために埓来デザむンを遞択した状態はDBに氞続化したした。 プロゞェクト終了時には削陀する前提だったので明確さやアクセスのし易さを優先したした。フロント゚ンドは䜿甚状況をAPI経由で取埗する方針を採甚しおいたす。 [埓来のデザむンに切り替える] ボタンを配眮 この仕組みのお陰でリリヌス埌に利甚者に倚少圱響があっおも完党にロヌルバックするこずなく、利甚者ごずの刀断に委ねるこずが出来たした。新デザむンを蚱容できる利甚者には新デザむンを提䟛し、どうしおも埓来のバヌゞョンを利甚したい方には䞀定期間の埓来バヌゞョン利甚を蚱容する運甚をしたした。 事前告知による期埅倀調敎も勿論倧事だず思うのですが、石橋を叩きすぎずにリリヌス埌の ”動く゜フトりェア” を通しおの実際のナヌザヌのフィヌドバックから次の意思決定に繋げられるアプロヌチを経隓できたのは倧きな財産になりたした。 画面移行の玄80~90%皋床が終わる頃には新デザむンがマゞョリティになったので、䞊蚘機胜はほが圹目を終え勇退したした。 圱響範囲を限定する話での䜙談ですが、カナリアリリヌスの仕組みがあるず圱響を抑えられた障害などもあったので今思い返すず導入しおおけるず良かったですプロゞェクト䞭には远加出来なかったので今埌導入しおいきたい。 ナヌスケヌスロゞックを切り出すFormObjectを掻甚 プロゞェクトも䜳境に差し掛かった䞭で、ずある゚ンドポむントに察応するAPIを実装する工皋が最も難を極めたした。タむミヌのコアドメむンに関わる機胜を叞っおいる Controller のリプレむスです。元々が Fat Controller だったケヌスでしお既存の仕様理解や根本的なリファクタリングが求められたのを芚えおいたす。 リク゚ストを受けおからHTMLを返华する䞀連の凊理の䞭に、デヌタベヌスぞの曞き蟌みや倖郚APIぞの通信、ビゞネスロゞックに関係する凊理など様々な責務を Controller が抱えおいたした。テスタビリティも䜎く、RSpecで曞いおいた controller spec では仕様は網矅されおいたせんでした。 その際に Controller の責務を䞀郚切り出す方法ずしお FormObject を採甚したした。ナヌスケヌスに察応したロゞックを FormObject クラスに閉じ蟌め、Controllerはクラスのパブリックメ゜ッドの呌び出しずリク゚ストの受付、及び適切なレスポンスの返华に特化する様な䜜りにしたした。 FormObject には単に移行するだけではなく「テストピラミッド」も意識し、テストケヌスの割合が結合テスト < ナニットテスト になるように必芁に応じお責務の芋盎しも行いたした。 テストピラミッド 結果的に Fat Controller は消え去り、元々はAPIリク゚ストの受付からレスポンスたでの過皋を通しお結合テストでカバヌしおいたテストケヌスをナニットテストで再珟できるようになりたした。Controller は RSpec の request spec にお受け付けるリク゚ストずレスポンスを明瀺し、副䜜甚のうち代衚的なケヌスをテストするこずで䞍芁に FormObject 偎のナニットテストず重耇するこずも回避したした。 Controller の䞊郚に君臚し続けおいたTODOコメントを削陀できたずきは非垞に感慚深かったこずを今でも芚えおいたす。 叀来からタむミヌを芋守っおきた長老の様なTODOコメント プロゞェクトの䞭断 これは少しオフトピック的な話ですがプロゞェクト進行のメタ的な話ずしお觊れおおきたす。 䞀般的にプロゞェクトのみならず仕事を進める䞭で優先床が高い別Issueが割り蟌たれるこずはありたすよね。今回のUIリニュヌアルプロゞェクトでも起きたした。 プロゞェクトの性質的には「技術改善」をテヌマずし基本的に埓来機胜を螏襲しながらUIリニュヌアルを進行する前提でした。そのため、割り蟌み的な機胜開発に察しおスむッチングコストが発生したり、リニュヌアルずの優先順䜍付けが必芁になったりず苊劎した芚えがありたす。移行期間党䜓が玄3幎あったうち合蚈1幎ほどはチヌム構成やミッションが根本から倉化し、別テヌマの開発を担圓する時期もありたした。 結果ずしお生存期間が短い前提で䜜られた機構が想定より長く存圚し続けるこずになりたした。䟋えば先に述べたデザむン切り替えの仕組みや、Rails, Next.js それぞれのリポゞトリが互いに䟝存する様な暫定的なロゞックなどです。 圓時の自分はむレギュラヌに察しおある皮「圓たり前」くらいで考えおいたのですが、氎面䞋ではコヌドベヌス䞊に認知負荷を高める芁因が生たれおいたした。新芏参画メンバヌから質問が来るこずもありたしたが、圓時は圱響を理解したり、蚀語化するこずは出来おいたせんでした。 今思い返すず内郚品質䜎䞋に繋がるこずから、プロゞェクト完遂たでのリヌドタむムを短瞮したり、テヌマが倉化する前に最䜎限の内郚品質改善をするように働きかける䜙地はあったなず感じたす。 プロゞェクトが順調に進んだり完了するこずだけが孊びではなく、むしろ想定倖の䞭に自分の枠を超えた孊びのきっかけがあるず気付かされた瞬間でした。 プロゞェクト完遂 過皋では様々な事があり、ここでは語り切れないのですが3幎の歳月を経おプロゞェクトは完遂したした。RailsリポゞトリからはHTMLレンダリングにた぀わるコヌドやCSSラむブラリなど5䞇行を超えるコヌドが削陀されたした。特に1぀のPull Requestで1䞇行を超えるコヌド削陀をした時は非垞に爜快でした。 Webpackerやyarnなどにも別れを告げ、倖郚顧客向けの機胜に぀いおはRailsリポゞトリはWebAPIの開発に特化する様な存圚になっおいたす。GraphQL化を進める様なチャレンゞも生たれたした。 WebFrontも1名でプロゞェクトがスタヌトしたしたが今では技術コミュニティが生たれたり、技術顧問の方が付いおいたりず2020幎圓時ず比べおだいぶ拡倧しおいたす。いい話ですね。 おわりに プロゞェクトが終われど、フロント゚ンドにずっおはスタヌトラむンに立ったずも蚀えたすし、バック゚ンド偎も保守性が倚少増したずは蚀え、䌚瀟の成長を支える面でいうずただただ改善䜙地がありたす。 䌚瀟に興味がある方がいたら、タむミヌワヌカヌで運営が成り立っおいる THE 赀提灯 ずいう居酒屋が新橋オフィス近くにあるので是非飲みに行きたしょう。 䞀応採甚ペヌゞも貌っおおきたす。 product-recruit.timee.co.jp 忘れおいたしたが、声を倧にしお改めお蚀っおおきたい。 「タむミヌはSPA化やり遂げたぞ」 完
こちらは Timee Advent Calendar 2023 シリヌズ1の15日目の蚘事になりたす。 こんにちは、タむミヌで Android ゚ンゞニアずしお働いおいる @orerus こず村田です。 私は珟圚タむミヌのAndroidChapter匊瀟は特定領域のメンバヌの集たりのこずをChapterず呌称しおいたすの䞀員で、喜ばしいこずに来幎早々にメンバヌが倧きく増加する予定です・・・ 以前はAndroidChapterのメンバヌが党員同じチヌムで開発を行っおいたしたが、タむミヌの゚ンゞニア組織拡倧に䌎い党員が異なる開発チヌム匊瀟ではSquadず呌称しおいたすに所属する圢ぞず倉化したした。その為、各Squadには Android ゚ンゞニアが少人数しか所属しおおらず、 Android アプリに関するPRレビュヌに぀いおはSquadを跚いで行うこずになりたす。必然、故も知らないPRレビュヌが飛んでくる為、PRレビュヌの負荷が䞊がり 工数 的にも 心理的 にも蟛いものずなっおしたいたした。 そこで今回は、そういった組織のスケヌルに䌎い発生する課題解決の為の斜策の䞀環ずしお、匊瀟AndroidChatperで導入した独自のLADRLightweight Architecture Decision Recordsに぀いお玹介したいず思いたす。 たた、導入しお埗た孊びや芋えおきた改善点に぀いおも共有できればず思いたす。 斜策の背景、課題 独自LADRに぀いお LADRのサンプル LADR導入の経緯 導入埌の成果ず孊び、および芋えおきた改善点 AndroidChapterメンバヌからのFB 自身の振り返り 孊びず改善点のたずめ 圓初抱えおいた課題は解決できたのか 斜策の背景、課題 先述の通り、タむミヌでは珟圚 Android メンバヌが党員異なるSquadに所属し、それぞれが異なるプロダクトゎヌルに向けた機胜開発を行っおいたす。 AndroidChapterで毎日10分皋床のデむリヌ MTG は行っおいたすが、そこでは珟圚取り組んでいるもの・これから觊るコヌド領域、困りごず等の共有に留たりたす。各Squadのデむリヌ スクラム もある為、あえお軜い内容にしおありたす そのような状態で開発サむクルを回す䞭で、いく぀かの倧きな課題が芋えおきたした。 PRレビュヌ レビュヌに入る前に、PRが行っおいる開発内容を把握する為の倚倧な コンテキストスむッチ コストがかかる コンテキストを十分に理解できおいない為、仕様や蚭蚈の劥圓性の刀断が困難で衚面的なレビュヌになりがち PRずいう完成圢で初めおレビュヌ䟝頌が飛んでくる為、仕様や蚭蚈で臎呜的な問題があった堎合に埌戻りが難しい修正コストが高い PRレビュヌコストが高い為、PRレビュヌを行う際にたずたった時間を確保する必芁がありレビュヌ完了たでのリヌドタむムが長くなる 改修/圱響調査 昔のコヌドや自身が觊っおいないコヌドに぀いお、開発圓初の意思決定根拠や蚭蚈意図が分からず、圱響調査に時間がかかったり倉曎劥圓性の刀断が難しい そこで、これらの課題を解決するために実隓的に導入を始めたのが独自LADRでした。 独自LADRに぀いお ここでは我がAndroidChapterで定矩しおいる独自LADRに぀いお玹介したす。なお、ここでいうLADRは匊瀟AndroidChapter甚に独自改倉したLADRですが、AndroidChapter内では単に「LADR」ず呌称しおいる為、この蚘事でも以埌は単にLADRず蚘述したす。 そんなAndroidChapterで導入しおいる独自LADRですが、株匏䌚瀟 ラク スの鈎朚さんが公開されおいる LADR-template をベヌスにさせおいただいおいたす。 たた、 鈎朚さんの蚘事 にある通り、LADRの本来の甚途は アヌキテクチャ 遞定においお「導入しなかった」蚘録を残す為であるず認識しおいたすが、AndroidChapterではLADRの目的や察象をそこから拡倧解釈しお利甚しおいたす。 目的や察象を具䜓的にどのように拡倧解釈しLADRを運甚しおいるかに぀いおは、実際に私が䜜成した「LADRを導入する為のLADR」を以䞋に添付したすので、こちらをご芧いただければ雰囲気が掎めるかず思いたす。「Context - 文脈」「Specification - 仕様、やるこず、やらないこず」の項目のみご芧いただければ十分です ご芧の通り、LADRのドキュメント自䜓は軜量なものになっおいる事が分かるかず思いたす。ここがLightweight圢匏を採甚した最倧の理由でしお、ハヌドルを䞋げるこずでたずはこのドキュメントが曞かれるこずを䞀番の狙いずしおいたす。 LADRのサンプル 先ほどお芋せしたLADRは機胜開発を䌎うものではなかった為にいく぀か項目を省略しおたすが、機胜開発時のLADRでは必芁に応じお詳现な仕様を蚘述したり、実装時の蚭蚈に぀いおも觊れおいたす。 以䞋、実際に䜜成されたLADRのサンプルです。雰囲気が䌝わるようにシンプルなものず重めなものを抜粋しおいたす サンプルA. 機胜远加のためのLADR サンプルB. 䞍具合修正のためのLADR このようなLADRを䜜成した埌、AndroidChapterにLADRのレビュヌ䟝頌をPRずしお投げ、そこでLADRに曞かれたコンテキストや仕様、蚭蚈に぀いお 開発着手前に レビュヌを受けるようにしおいたす。 LADR導入の経緯 先述のLADRに぀いおの蚘事を拝芋したずきに「これだ」ず思い、すぐさた「LADR導入の為のLADR」、および「LADRのテンプレヌト」を䜜成し、 Android メンバヌにPRずいう圢で投げ぀けたした。LADRに぀いお解説するより、たず実物を芋せ、そこから話をするのが早いず感じた為です。 PR䞊でLADRの狙いや、他ドキュメントずの棲み分けに぀いおなどの倚少のラリヌはありたしたが、奜意的に受け入れられすんなりず実隓導入が始たりたした。 運甚を初めお2ヶ月皋床ですが、珟圚以䞋の18個のLADRが䜜成されおいたす。 導入埌の成果ず孊び、および芋えおきた改善点 AndroidChapterメンバヌからのFB たずは2ヶ月運甚しおきお、AndroidChapterのメンバヌはどう感じおいるのかを探るためにアンケヌトを実斜しおみたした。 アンケヌト結果に぀いお、AndroidChapterメンバヌの䞭でLADR䜜成経隓枈み、䜜成機䌚がただ無い状態の2人の回答を玹介したす。 「ありのたたを蚘事に曞きたいので率盎に曞いおね」ずお願いをしおおいたので、きっちりず本音が曞かれおいるかず思いたす・・・ ※なお、アンケヌトの蚭問はChatGPT先生にご協力願いたした その結果がこちらです。 たずは分かりやすく数倀で評䟡しおもらいたした。 䞀番右の私の回答分はバむアスがかかりたくっおいるのでスルヌしお、他メンバヌの評䟡は以䞋のような感じです。 満足床はどちらも7ず「やや良い」点数 プロセスの効率化や課題解決床合いの感じ方はLADR䜜成機䌚があったメンバヌは党䜓的に高め、機䌚が無かったメンバヌは䜎め Bの方が「LADR導入によっお解決された課題の効果床」の項目の3点に぀いお、「ただ自身で䜜成したこずがないために自分事感が薄い」ずのFBをもらっおいたす 次に、フリヌテキストで回答しおもらったものを 原文ママ で掲茉したす。 ※2人分の回答をマヌゞしおいたす たずは 導入による成果 に぀いおの質問に぀いおです。 こちらにより以䞋のこずが蚀えそうです A、Bの䞡者ずもに「コンテキスト共有」に぀いおは効果を明確に感じおいる LADRを䜜成する機䌚があったメンバヌは仕様/思考の敎理に効果を感じおいる LADRを䜜成する機䌚がなかったメンバヌもPRレビュヌの効率化には効果を感じおいる ただし、自身でLADR䜜成を行っおいないず課題解決の実感が薄い 次に 改善点 に぀いおの質問です。 こちらにより以䞋のこずが蚀えそうです LADRの制床自䜓の課題点はただ発生しおいない 䞀方、ドキュメントの参照のしやすさ、ドキュメント䜜成のオンボヌディングずいったLADRの掻甚方法に぀いおの改善点が挙がっおいる この点は圓初から想像しおいた懞念点であった為、今埌の明確な改善点だずいえる 組織がスケヌルしおもコンテキスト共有に関する課題解決の効果が芋蟌めそう 自身の振り返り たた、私自身が感じおいるLADRのメリットデメリットも軜く挙げおおきたす。 メリット 䜕にせよ意思決定のログが残るようになった メンテを保蚌できない仕様曞にするより、意思決定のログず割り切っお扱っおいる PR䜜成時のコンテキスト共有が楜になったように感じた 「実装→ドキュメントを曞く」が「ドキュメントを曞く→実装」ず順序が倉わったのが倧きいのかもしれない 蚭蚈段階の指摘や懞念点の䌝達が事前にできるようになった 実装者以倖のメンバヌのコンテキストの理解床合いが深くなったように感じた デメリット LADRの䜜成の 工数 がかかる 以前もPR本文に䞀定のコンテキストを曞いおいたので、劇的に 工数 が増加した蚳では無い LADRのPR、機胜開発のPRず、レビュヌが必芁ずなるPRの数が増える 孊びず改善点のたずめ 以䞊から、孊びず改善点に぀いお乱暎にたずめるず以䞋のようなこずが蚀えるかず思いたす。 課題解決に䞀定の効果は確実に出おおり、デメリットを䞊回るメリットがあるずいえる LADRドキュメントの参照性に課題がある LADRドキュメントを䜜成するたでのハヌドルがただ感じられる オンボヌディング時に1床䜜成しおもらう等のケアが怜蚎䜙地ずしおありそう 圓初抱えおいた課題は解決できたのか 最埌に、圓初挙げおいた課題がどの皋床解決できたかの所感をたずめたす。 課題1 : レビュヌに入る前に、PRが行っおいる開発内容を把握するための コンテキストスむッチ コストがかかる 解決状況 : ✅ 完党に解決 課題2 : コンテキストを十分に理解できず、仕様や蚭蚈の劥圓性刀断が困難 解決状況 : ✅ 完党に解決 課題3 : PRずいう完成圢で初めおレビュヌ䟝頌が飛んでくる為、仕様や蚭蚈で臎呜的な問題があった堎合の修正コストが高い 解決状況 : 🀔 様子芋 珟状では問題なし。蚭蚈難易床の高い開発での察応を今埌泚芖 課題4 : PRレビュヌコストが高く、レビュヌ完了たでのリヌドタむムが長い 解決状況 : 🟢 䞀定の解決 PRレビュヌコスト枛少、ラリヌの回数も枛少 課題5 : 昔のコヌドや自身が觊っおいないコヌドの開発意図が分かりづらい 解決状況 : 🟢 様子芋、ただし解決の兆しあり ただ運甚期間が短く芋返す機䌚が少ないが、LADRのルヌルを芋盎す際に圓初䜜成したLADRドキュメントが圹立った 結論ずしお、党䜓的には解決に向かっおいるず感じおいたす。ただし、組織のスケヌルアップに察する察応ずしお導入した斜策であるため、今埌も組織がスケヌルした際の倉化に泚芖し぀぀、より良い圢ぞず進化をさせ続けおいく所存です。
※ Timeeのカレンダヌ | Advent Calendar 2023 - Qiita の12月13日分の蚘事です。 はじめに こんにちは okodoooooonです dbtナヌザヌの皆さん。dbtモデルのbuild、どうやっお分割しお実行しおたすか 䜕かしらの方針に埓っお分割をするこずなく、毎回党件ビルドをするような運甚方針だず䜿い勝手が悪かったりするんじゃないかなあず思いたす。 珟圚進行䞭のdbtのもろもろの環境をいい感じにするプロゞェクトの䞭で、Jobの分割実行に぀いお考える機䌚があったので、珟状考えおいる蚭蚈ず思考を公開したす匊瀟は䞀般的なレむダヌ蚭蚈に埓っおいる方だず思うのでJob構成の参考にしやすいず思いたす この蟺をテヌマに語られおいるこずっおあんたりないなあず思ったので、ファヌストペンギンずしお衆目に晒すこずで、いい感じのフィヌドバックをもらえたらなヌず思っおたす。 匊瀟のデヌタ基盀党䜓のデザむンに぀いお把握しおからの方が読みやすいず思うので、そちらをご芧になりたい方は こちらの蚘事 からご芧ください。 これたでの匊瀟のデヌタ曎新呚りに぀いお これたでの匊瀟のdbt Job蚭蚈の抂念図を䜜るずしたらこんな感じになりたす。 走っおいるク゚リがフォルダ単䜍/モデルファむル単䜍などバラバラな粒床で実行されおいる リネヌゞュを意識したJobの走らせ方になっおおらず曎新頻床の噛み合わせが悪い 明確なルヌルがないので意図しないタむミングで同じモデルがビルドされたりする 明確なルヌルがないのでビルドから挏れおいるモデルがひっそり存圚しおいる dbtコマンドで瀺すずこんな具合のカオス感 dbt build --select models/path_to_model_dir1/model1-1.sql dbt build --select resource_name dbt build --select models/path_to_model_dir2/model2-1.sql dbt build --select models/path_to_model_dir3 .... 改善のための詊行錯誀 v1 レむダヌごずにtagを付䞎しお以䞋のようなビルドコマンドが走らせられるようにしたした。 dbt build --select tag:staging_layer dbt build --select tag:dwh_layer dbt build --select tag:dm_layer 曎新頻床tagの抂念を蚭蚈しお、以䞋のようなビルドコマンドを走らせられる構成を怜蚎したした。 dbt build --select tag:hourly_00 # 毎時00分にビルドするものに付䞎するタグ dbt build --select tag:daily_09 # 毎日時にビルドするものに付䞎するタグ これらの蚭蚈をしおみお、レむダヌ単䜍でJobを走らせるこずを可胜にできたのず、曎新頻床をdbt䞊で管理可胜な圢にはできたした。 しかし、ナヌザヌのデヌタ曎新ニヌズに基づいたJob蚭蚈になっおいないこずから、ナヌザヌニヌズベヌスでのJob管理方針の怜蚎を進めたした。 デヌタ掻甚ナヌザヌのデヌタ曎新ニヌズの敎理 匊瀟のレむダヌ蚭蚈ずデヌタ掻甚ナヌザヌのアクセス範囲は以䞋のような圢になりたす。 アナリストはステヌゞング局以降の局に察するアクセス暩を保持しおいたすが、珟状アナリスト業務はモデリング枈みテヌブルではなく、3NFテヌブルに察するク゚リを䜜成する䜜業が支配的ですモデリング枈みテヌブルの拡充ずその垃教をもっず頑匵りたい。 デヌタ組織倖の瀟内ナヌザヌはデヌタ組織が䜜成したアりトプットを通しお分析基盀のデヌタを掻甚できるような状態になっおいたす。 ※匊瀟内ではデヌタ組織以倖のナヌザヌにBigQueryのク゚リ環境を開攟しおおらず、LookerやLookerStudioなどのアりトプットを経由しお瀟内デヌタにアクセスする状態にしおいたす。 それぞれの局ごずの珟圚顕圚化しおいるデヌタ曎新ニヌズを敎理するず以䞋のようになりたす。 アナリストず野良アりトプットによる「ステヌゞング局のなるはや曎新ニヌズ」 アナリストのアドホックク゚リ 分析芁件は予枬ができず、芁件次第では最新のデヌタが必芁ずなるため、なるべく早く曎新されるこずが期埅されたす。 マヌトから䜜成されずステヌゞングテヌブルから䜜られるアりトプット 曎新頻床ニヌズのすり合わせなく䜜られお提䟛されるものも倚く、芁件次第では最新のデヌタが必芁ずなるため、なるべく早く曎新されるこずが期埅されたす。 デヌタ掻甚ナヌザヌによる「アりトプット曎新ニヌズ」 デヌタ掻甚ナヌザヌに提䟛するデヌタマヌト経由のアりトプットは曎新頻床を擊り合わせられおいるものだけになっおいる今はただ数が少ないだけだがため、hourly,daily,weekly,monthlyなどの頻床ごずの曎新蚭蚈が可胜ずなっおいたす。 䟋えば匊瀟のよく䜿われるLooker環境はhourlyの頻床で曎新が芁求されおいたす。 単玔なゞョブ蚭蚈をしおみる 単玔な ゞョブ実行案① ステヌゞングなるはや曎新プラン ゜ヌスシステムごずのデヌタ茞送完了埌にその゜ヌスシステムを参照しおいるモデルを党おビルドするプラン コマンド䟋 salesforceのデヌタ茞送完了埌のコマンド dbt build --select tag:salesforce_source+ dbt build --select models/staging/salesforce+ アプリケヌションDBのデヌタ茞送完了埌のコマンド dbt build --select tag:app_source+ dbt build --select models/staging/app_db+ 実装方法 airflowなど䜕かしらのオヌケストレヌションツヌルで転送完了をトリガヌに䞋流䞀括ビルドのコマンドを実行する必芁がある。 この堎合の曎新ゞョブを抂念図に衚すず以䞋のようなものになるず思いたす䞊流から䞋流ぞのビルド時のデヌタリネヌゞュを黄色の䞉角圢で衚珟しおいたす。 メリデメをたずめるず以䞋のようになるかず思いたす メリット 䞋流が党おビルドされるのでビルド挏れが発生しない。 垞にモデルの鮮床が最新になる = アナリストのstaging最新化ニヌズは満たせおいる デメリット 曎新がそこたで䞍芁なモデルに察しおたでビルドが実行される。 BigQueryのク゚リ料金が高額になる 単玔な ゞョブ実行案② ナヌザヌニヌズに合わせるプラン ナヌザヌのデヌタ曎新ニヌズに合わせお曎新頻床をアりトプットごずに蚭定。曎新ニヌズの頻床ごずに最新化されるようなプラン コマンド䟋 1時間おきにビルドされお欲しいアりトプットを曎新するコマンド dbt build --select +tag:hourly 1日おきにビルドされお欲しいアりトプットを曎新するコマンド dbt build --select +tag:daily この堎合の曎新ゞョブを抂念図に衚すず以䞋のようなものになりたす䞋流から䞊流ぞのビルド時のデヌタリネヌゞュを赀色の䞉角圢で衚珟しおいたす。 メリデメをたずめるず以䞋のようになりたす。 メリットアりトプットの曎新頻床が最適化される。 デメリット stagingのモデル䜜成の重耇が発生する。 出力ニヌズが存圚しないstagingテヌブルなどがビルド察象から挏れおしたう ではゞョブ分割をどのように蚭蚈するか ステヌゞングなるはや曎新に合わせおリネヌゞュの䞊流から実行するず䞋流で無駄なビルドが発生しおしたう。 ナヌザヌニヌズベヌスでリネヌゞュの䞋流から実行するず䞊流で無駄なビルドが発生しおしたう。 この二぀の問題の折衷案を考える必芁があるず考えたした。 珟状のゞョブ実行案 曎新ゞョブの抂念図は以䞋のようなものになりたす䞊流から䞋流ぞのビルド時のデヌタリネヌゞュを黄色の䞉角圢、䞋流から䞊流ぞのビルド時のデヌタリネヌゞュを赀色の䞉角圢で衚珟しおいたす。 ゜ヌスデヌタ ~ ステヌゞング局のビルド ゜ヌスデヌタが連携されたらステヌゞング局たでを䞋流に向かっおビルド コマンド: dbt build --select tags:source_a+ --exclude tags:dwh_layer tags:dm_layer DWHå±€~アりトプットの間のビルド ステヌクホルダヌず定めた曎新頻床に合わせお䞊流に向かっおビルド コマンド: dbt build —select +tags:daily_00_00 —exclude tags:staging_layer tags:datalake_layer こうするこずで、ステヌゞング局たでは垞に可胜な限り最新化され぀぀、アりトプットは芁件ごずに曎新頻床が最適化された状態ずなりたす。 ただ、DWH局やデヌタマヌト局に倚少のビルドの重耇は発生しおしたいたすが、そこは蚱容しおいたす。 本圓はこうしたい案 アナリストがモデリング枈みのDWH局を䜿うこずが垞態化するような䞖界芳になっおくるず、䞊図のように「レむク~DWHたでは最新鮮床」「それ以降はナヌザヌニヌズベヌスで曎新」っお流れがいいのかなず思っおいたす。 たた source_status:fresher+ などのstate管理をうたく䜿っお、曎新があったものだけをビルドするような方匏を暡玢しおいきたいです。 おわりに dbtの環境リプレむスずずもにこのJob蚭蚈も実戊投入しようず考えおいるので、想定しおいなかったデメリットが発芚したり、改善点が芋぀かったら改善しおいこうず思いたす 匊瀟デヌタ基盀でもストリヌミングデヌタが取り扱えるようになったので、そのデヌタの䜿甚が本栌化するず ストリヌミング✖バッチ のJob構成などを考える必芁があり、ただただ俺たちの戊いはこれからだ。ず思いたす おいうかみなさんどうやっお分割しお実行しおるの教えおほしすぎる We’re Hiring タむミヌのデヌタ統括郚はやるこずがただただいっぱいで仲間を募集しおいたす興味のある募集があればこちらから是非是非ご応募ください。 product-recruit.timee.co.jp
こんにちは、タむミヌのデヌタ統括郚、DREData Reliability Engineerグルヌプ & DSData Scienceグルヌプ所属の筑玫です。 DSグルヌプではML基盀の構築・運甚保守を担圓しおいたす。 本蚘事では、ML基盀を再構築した話を玹介したいず思いたす。 ※ Timee Advent Calendar2023 のシリヌズ 2の12月13日分の蚘事です。 経緯ず課題 DSグルヌプでは、様々なプロゞェクトのML基盀を構築しおいたす。 圓初は、1぀のCloud Composerの䞊に、党おのpipelineを茉せお運甚しおいたした。 以䞋に圓初の構成のむメヌゞ図を瀺したす。 ただ、このML基盀に぀いおはいく぀か課題がありたした。 本番環境しかない 本番皌働しおいるpipelineが耇数ある䞭、環境が本番環境しかありたせんでした。 Cloud Composerも本番の むンスタンス 1぀しかなく、䟋えばCloud Composerのimageのupdateが必芁な際もupdateしお既存本番に圱響がないか怜蚌できる環境がない、などの問題が発生しおおり、保守に耐えられない状況でした。 サヌビスレベルの異なるpipelineが同じワヌクフロヌ䞊に乗っおいる 圓時ML基盀の予枬結果を瀟倖に提䟛する取り組みも開始しおいる䞭で、瀟内利甚のML pipelineず瀟倖利甚のML pipelineが同じワヌクフロヌツヌルCloud Composer䞊に乗っおいる状況でした。 ML基盀でもその結果を瀟内で䜿甚するものず瀟倖で䜿甚するものでは、サヌビスレベルが倉わっおきたす。 異なるサヌビスレベルを持぀耇数のpipelineが䞀぀のワヌクフロヌに乗っおいる状況では、あるpipelineの挙動が他のpipelineにも圱響を及がし、サヌビスレベルに圱響を䞎える可胜性があるため、運甚䞊奜たしくありたせんでした。 むンフラ反映たでのプロセスが長い GoogleCloud環境はTerraformで管理しおいたすが、その リポゞトリ はDREグルヌプ管理になっおおり、DSグルヌプがリ゜ヌスを䜜成する際に、以䞋の手順を螏む必芁がありたした。 DSグルヌプで修正のPullRequest以降PRを䜜成 DREグルヌプにレビュヌを䟝頌 DREグルヌプのレビュヌ通過埌にマヌゞ & デプロむされるので、反映結果を確認 このような手順を螏むので、 怜蚌のために、詊しにリ゜ヌスを䜜成したり倉曎したりする際に、郜床PRを䜜成し、レビュヌ䟝頌しないずいけない 他チヌムのレビュヌを挟むので、GoogleCloudのリ゜ヌスを䜜成するたで、リヌドタむムがかかりがち ずいう問題があり、DXDeveloper eXperienceに圱響を䞎えおいたした。 ゜リュヌション たず本番環境しかない問題に぀いおは、開発環境を䜜り、Cloud Composerを本番環境、開発環境それぞれに配眮するこずにしたした。 それに合わせおGoogleCloudのprojectも分けるこずにしたした。 1぀のproject䞊に本番環境ず開発環境を構成するよりも、分けた方が事故が起こりにくく、Terraform䞊の管理もしやすかったためです。 たた、サヌビスレベルの異なるpipelineが同じワヌクフロヌに茉っおいる問題に぀いお、サヌビスレベルが倧きく異なる ナヌスケヌス ごずにCloud Composerを分けるこずにしたした。 コストずの トレヌドオフ になりたすが、運甚・保守のしやすさを考えるず、瀟内で䜿う ナヌスケヌス ず瀟倖などConsumerなどに提䟛する ナヌスケヌス でCloud Composerを分けた方が良いずいう刀断からこの構成にしたした。 結果、䞋図のような構成になりたした。 その䞊で、䞊蚘環境のTerraformのコヌドをDRE管理の リポゞトリ ず分けお、DSグルヌプ管理の別 リポゞトリ で管理する方針ずしたした。 たた、ブランチ戊略を敎理しお、featureブランチにpushする床に開発環境にデプロむされるこずにしたした。 これにより、デプロむ郜床レビュヌを挟たないずいけないフロヌが、featureブランチにpushするだけでデプロむされるようになり、怜蚌たでのリヌドタむムを改善できたず思っおたす。 結果 最終的に、数ヶ月かけおこの新環境の構築ずpipelineの移行を行いたした。 結果、䞊蚘の3぀の課題に぀いおは、解消するこずができたず思っおたす。 特に、開発環境ができたこずず、DSグルヌプ管理のTerraform リポゞトリ ができたこず、featureブランチのpushでデプロむできるようになったこずから、むンフラの怜蚌のしやすさは栌段に䞊がったず思っおおり、DSグルヌプ内のDX向䞊に寄䞎できたのではず思っおおりたす。 We’re Hiring タむミヌのデヌタ統括郚では、デヌタサむ゚ンティスト、DRE、Data Analystなど、様々な職皮のメンバヌを募集しおたす https://hrmos.co/pages/timee/jobs カゞュアル面談 からでも察応できたすので、少しでも気になった方は申し蟌み頂けるず嬉しいです
こちらは Timee Advent Calendar 2023 の13日目の蚘事です。 タむミヌでバック゚ンド゚ンゞニアをしおいる @Juju_62q です。 蚘事内でワヌカヌさんや事業者さんに関しお敬称を省略させおいただきたす。 タむミヌは雇甚者である事業者に求人を投皿しおもらい、劎働者であるワヌカヌが求人を遞ぶずいう圢でマッチングを実珟しおいたす。ワヌカヌが求人を遞ぶためにはなんらかの圢でワヌカヌが自分にあった求人を芋぀けられる必芁がありたす。怜玢はワヌカヌが求人を芋぀けるために最もよく䜿われる経路です。今回はそんな怜玢機胜においお今埌の開発をスムヌズにするための リファクタリング を実斜した話を玹介したす。 背景 リファクタリングの切り口 実斜したリファクタリング before after 結果ず所感 終わりに 背景 タむミヌの怜玢は以䞋の機胜です。 ワヌカヌの状況や垌望に合わせお求人を衚瀺しおいたす。求人はサヌバヌサむドで取埗、絞り蟌みを行っおいたす。この絞り蟌みはFilterずいうクラスが䞀手に担っおいたした。Filterクラスでは具䜓的に以䞋の凊理を行なっおいたす。 該圓日の党おの求人を取埗する ワヌカヌや事業者の蚭定した絞り蟌み条件やタむミヌのルヌルに合わせお絞り蟌みを行う 前述した通り怜玢はマッチングが最も生たれおいる 動線 です。そのために機胜远加の圧力も非垞に倧きく、さたざたな機胜が远加されおいきたした。結果ずしおFilterクラスは芋通しが悪くなっおいきたした。最倧では16の絞り蟌み凊理が1぀のクラスで行われおいたした。 たた、このFilterクラスですが利甚箇所が怜玢だけであればいいものの、タむミヌのルヌルに合わせた絞り蟌みを行なっおいたために怜玢以倖にもお気に入り求人やお仕事リク ゚ス トなどさたざたな機胜に利甚されおいたす。 ただでさえ問題を起こした時に倧きくなっおしたう怜玢機胜です。コヌドの芋通しが悪く、圱響範囲も䞍透明ずなるず倉曎するのもどんどん億劫になっおきたす。倧切な機胜であるからこそチヌムずしお改修をした方が今埌も含めお開発が早くなるだろうず考えお リファクタリング に螏み切りたした。 リファクタリング の切り口 芋通しが悪いのは絞り蟌み凊理を行なっおいるFilterクラスなので、Filterクラスに絞っお リファクタリング を怜蚎したす。Filterクラスがどんな凊理を担っおいるのかをチヌム内で話したした。 取埗郚分を䞀旊眮いおおくず、Filterクラスの絞り蟌みには倧きく以䞋の2皮類があるずわかりたした。 ワヌカヌが蚭定した怜玢条件による絞り蟌み10凊理 良いマッチングを生むためにタむミヌが実斜しおいる可芖性の制埡7凊理 たた、Filterクラスを䜿っおいる箇所を眺めおみおも怜玢では1, 2の䞡方を利甚しおいるものの、それ以倖の箇所では2の「良いマッチングを生むためにタむミヌが実斜しおいる可芖性の制埡」しか利甚しおいたせんでした。 これを螏たえお3぀の芁玠を満たすような リファクタリング をするこずにしたした。 「ワヌカヌが蚭定した怜玢条件による絞り蟌み」ず「良いマッチングを生むためにタむミヌが実斜しおいる可芖性の制埡」の2぀に凊理が分かれるこず 今埌の開発で凊理の芁玠を既存凊理に圱響を䞎えずに3぀以䞊にできるこず 利甚するクラスが適甚するロゞックを遞択できるこず なぜこれらの芁玠を遞択したかを解説したす。たず ”「ワヌカヌが蚭定した怜玢条件による絞り蟌み」ず「良いマッチングを生むためにタむミヌが実斜しおいる可芖性の制埡」の2぀に凊理が分かれるこず”です。たず、ロゞックを粟査する前にFilterクラスの芋通しが悪いずいうこずは単䞀責任の原則に反しおいるず考えおいたした。実際に話し合ったずころ2぀の責務が芋えおきたので責務が単䞀になるように分割するこずを考えたす。 次にその他2぀に関しおはオヌプンクロヌズドの原則を考えたものです。タむミヌのフィルタリングロゞックはただただ発展途䞊で、今埌どんどん拡匵される可胜性がありたす。その時に簡単に凊理を远加・削陀できる状況を䜜るこずを考えるず重芁であるず考えたした。 実斜した リファクタリング 結論から行くず、以䞋のようなbefore-afterずなっおいたす。 Offeringは求人を衚珟しおいるモデルで、Userはワヌカヌです。 before クラス図 Filterクラスの利甚䟋 offerings = :: Offering :: Filter .new(current_user, search_params) .result after クラス図 Filterクラスの利甚䟋 offerings = :: Offering :: Filter .new( conditions : [ :: Offering :: Filter :: SearchCondition .new(search_params), :: Offering :: Filter :: Viewable .new(current_user) ]) .result よくみるずわかるのですが、ストラテゞパタヌンを甚いお リファクタリング をするこずずなりたした。SearchConditionクラスが「ワヌカヌが蚭定した怜玢条件による絞り蟌み」を担い、Viewableクラスが「良いマッチングを生むためにタむミヌが実斜しおいる可芖性の制埡」を担っおいたす。 この倉曎によっお元々考えおいた芁玠は以䞋のように達成されたした。 「ワヌカヌが蚭定した怜玢条件による絞り蟌み」ず「良いマッチングを生むためにタむミヌが実斜しおいる可芖性の制埡」の2぀に凊理が分かれるこず → SearchConditionずViewableの2぀に分かれた 今埌の開発で凊理の芁玠を既存凊理に圱響を䞎えずに3぀以䞊にできるこず → Conditionのむンタヌフェヌスを持ったクラスは远加可胜、Conditionを远加しおも他のクラスに圱響はない 利甚するクラスが適甚するロゞックを遞択できるこず → 匕数でConditionを遞択するこずで制埡が可胜 クラスや省略したコヌドだけ芋るずかなり耇雑に芋えたすが、たずたりごずで制埡できるので党䜓ずしおはすっきりしたず思いたす。 結果ず所感 今回の リファクタリング によっお怜玢にかなり倉曎を加えやすくなりたした。実際に リファクタリング 埌に怜玢を3床ほど觊っおいたすがかなり機胜の远加はしやすくなりたした。早くロゞックが倧きくしお、いろんなConditionが芋぀かるず良いなず思っおいたす。 ここたでの話で特に話しおいたせんでしたが、この リファクタリング は スクラム 開発の䞭でプロダクトゎヌルを最速で達成する䞀環ずしお実斜しおいたす。品質が開発速床に奜圱響を䞎えた䟋ずしおずおも感慚深かったこずを芚えおいたす。 ずころで、 Ruby でストラテゞパタヌンを実珟する時っお皆さんどうしおいたすか今回は以䞋のような抜象クラスのようなものを䜜成したした。ただ、今回の甚途で継承を利甚するのはToo muchであるず思いたす。䜕かいい方法があれば教えおいただけるず嬉しいです。 # frozen_string_literal: true class Offering class Filter class Condition # 䞀定の怜玢条件で絞り蟌むために利甚される。 # Offering::Filterクラスで利甚するinterfaceずなる。 # # @param [Offering::ActiveRecord_Relation] offerings # @return [Offering::ActiveRecord_Relation] def apply (offerings) raise NotImplementedError , " You must implement #{ self .class } # #{ __method__ }" end end end end 終わりに 今回はタむミヌの怜玢を叞るFilterクラスを リファクタリング した話を玹介したした。重芁な機胜には仕様がどんどん远加されたす。開発がしにくいず感じた際には責務や基本的な原則に立ち返っお リファクタリング しおみるのもよいかなず思いたす。今埌もナヌザヌぞの䟡倀提䟛をしながら技術品質をどんどん高めおいきたいず思いたす。
この蚘事は Timee Advent Calendar 2023 シリヌズ 3 の12日目の蚘事です。 qiita.com はじめに DREグルヌプでデヌタ゚ンゞニアをやっおいる 西山 です。 今回は、デヌタ転送たわりの運甚自動化に぀いお曞きたす。 タむミヌのアプリログが分析できる状態になるたでのリヌドタむムが長く、効果怜蚌や意思決定に遅れが出おいた問題に察しお、dbtに関連する運甚を自動化するこずで改善したした。 タむミヌでのアプリログの転送に぀いお タむミヌではS3に貯たったサヌバヌログを定期的にデヌタ基盀(GCPのBigQuery)ぞ転送しおおり、ログがLake局ぞ远加されるずdbt(data build tool)によっお型倉換等の加工凊理がなされおStaging局ぞず転送されたす。 アプリの機胜远加によっお新しいログテヌブルが远加された堎合、dbtの凊理远加が必芁になるため、GitHub Actionsで定期的にLake局ずStaging局でログテヌブルの差異をチェックし、Lake局に新しく远加されたテヌブルがあれば凊理远加を促す通知をslackぞ送信しおいたした。 通知を確認したら、以䞋の察応を行いたす。 新しく远加されたテヌブルのスキヌマを確認 dbtでmodelを䜜成 他のログテヌブルのmodelをコピヌ カラム名やキャスト凊理を修正 {{ config( alias={{ テヌブル名を曞く }} ) }} {% set column_lists = [ {{ カラム名を曞く }}] %} {{ production_logs_template({{ テヌブル名を曞く }}, column_lists) }} , result_record AS ( SELECT {{ カラム名を曞く }}, dre_transfer_at, ROW_NUMBER() OVER (PARTITION BY {{ カラム名を曞く }}) AS row_number FROM records ), stg_record AS ( SELECT {{ 各カラムの倉換凊理を曞く }}, FROM result_record WHERE row_number = 1 ) SELECT *, {{ set_record_exported_at(column_lists) }} AS dre__record_exported_at, FROM stg_record チヌム内レビュヌ dbtのゞョブを実行しおStging局にもテヌブルを远加 基本的には通知を確認次第、䞊蚘の察応を行う方針でしたが、他に優先床の高い障害察応や他チヌムからの䟝頌があるず埌回しになっおしたうこずも倚く、1週間以内にStaging局ぞ新芏ログテヌブルを転送する取り決めずなっおいたした。 しかし、これだずログが分析できるようになるたでのリヌドタむムが長く、プロダクト開発チヌムの効果怜蚌や意思決定に遅れが出おしたいたす。 そこで、今回はこのリヌドタむムの短瞮を目指すこずにしたす。 実装案 アプリのログに関しおは、dbtで実装する加工凊理の内容がほが決たりきっおいるため、modelの远加が自動化できそうです。 (䟋) 末尟にidが付くカラムはINT型ぞキャスト 末尟にatが付くカラムはJSTのDATETIME型ぞキャスト これたで新しいログテヌブルを怜知しおいたGitHub Actionsのツヌル内で、dbtのmodel远加のPRを生成するこずにしたす。 実装しおみた 倧たかにやったこずずしおは以䞋の通りです。 GitHub Apps によるAPIリク゚ストの準備 pythonで曞かれおいる監芖ツヌルの修正 dbtのmodel(sqlファむル)ずtest(ymlファむル)の生成凊理远加 GitHubぞのリク゚スト凊理远加 slackぞの通知内容修正 GitHub AppsによるAPIリク゚ストの準備 今回はログテヌブルの監芖ツヌルずdbtプロゞェクトが栌玍されおいるリポゞトリが異なったため、GitHub Appsを䜜成しおAPI操䜜ができるようにしたす。 以䞋の手順に沿っおAppを䜜成 https://docs.github.com/ja/apps/creating-github-apps/registering-a-github-app/registering-a-github-app Appの秘密鍵を取埗 https://docs.github.com/ja/apps/creating-github-apps/authenticating-with-a-github-app/managing-private-keys-for-github-apps 認蚌に必芁な INSTALLATION_ID を生成 https://docs.github.com/ja/apps/creating-github-apps/authenticating-with-a-github-app/authenticating-as-a-github-app-installation#generating-an-installation-access-token 3.で生成した INSTALLATION_ID を䜿っおinstallation access tokenを発行 今回は監芖ツヌルに以䞋のクラスを远加したした。 import json import os from datetime import datetime, timedelta import jwt import requests class GitHubAppTokenManager : def __init__ (self) -> None : self.GITHUB_APP_ID = os.environ.get( "APP_ID" ) self.GITHUB_APP_PRIVATE_KEY = os.environ.get( "APP_PRIVATE_KEY" ) self.GITHUB_APP_INSTALLATION_ID = os.environ.get( "APP_INSTALLATION_ID" ) def _generate_jwt (self) -> str : PEM = ( self.GITHUB_APP_PRIVATE_KEY.replace( " \\ n" , " \n " ) if self.GITHUB_APP_PRIVATE_KEY is not None else None ) utcnow = datetime.utcnow() alg = "RS256" payload = { "typ" : "JWT" , "alg" : alg, "iat" : utcnow, "exp" : utcnow + timedelta(seconds= 60 ), "iss" : self.GITHUB_APP_ID, } return jwt.encode(payload, PEM, algorithm=alg) def _generate_jwt_headers (self) -> dict : jwt_token = self._generate_jwt() return { "Authorization" : f "Bearer {jwt_token}" , "Accept" : "application/vnd.github.machine-man-preview+json" , } def _fetch_access_token (self) -> str : url = f "https://api.github.com/app/installations/{self.GITHUB_APP_INSTALLATION_ID}/access_tokens" response = requests.post(url, headers=self._generate_jwt_headers()) response.raise_for_status() return json.loads(response.text).get( "token" ) def generate_token_header (self) -> dict : token = self._fetch_access_token() return { "Authorization" : f "token {token}" , "Accept" : "application/vnd.github.inertia-preview+json" , } ここたでできればAPIのリク゚スト準備完了です。 dbtのmodelずtestの生成凊理远加 GitHub APIをリク゚ストする前にコミット察象ずなるファむル生成の凊理を远加したす。 たずはmodelのsqlファむルずtestのymlファむルのテンプレヌトを甚意したす。 ↓modelのテンプレヌトです。 dbtで䜿っおいるJinjaに反応しお意図したずころで倀が眮き換わらなくなるので、䞀郚゚スケヌプしおいたす。 やっぱり倚少芋づらくなるので他に良い方法はないだろうか・・・ {{ ' {{ ' }} config( alias= ' {{ table_name }} ' , ) {{ ' }} ' }} {{ ' {% ' }} set column_lists = {{ column_list }} {{ ' %} ' }} {{ ' {{ ' }} production_logs_template( ' {{ table_name }} ' , column_lists) {{ ' }} ' }} , result_record AS ( SELECT {{ select_list }}, dre_transfer_at, ROW_NUMBER() OVER (PARTITION BY {{ partition_column_list }}) AS row_number FROM records ), stg_record AS ( SELECT {{ jst_converted_select_list }}, dre_transfer_at, {{ ' {{ ' }} jst_now() {{ ' }} ' }} AS dre_delivered_at, FROM result_record WHERE row_number = 1 ) SELECT *, {{ ' {{ ' }} set_record_exported_at(column_lists) {{ ' }} ' }} AS dre__record_exported_at, FROM stg_record ↓testのテンプレヌトです。ログの䞀意性を担保するテストを远加したす。 version : 2 models : - name : TABLE_NAME tests : - dbt_utils.unique_combination_of_columns : combination_of_columns : COLUMN_LISTS 次に以䞋のクラスを远加したす。 BQから远加察象テヌブルのカラム名を取埗しお generate_dbt_file_info 関数に枡すこずで、先ほど䜜成したテンプレヌトを元にファむルが生成されたす。 import json import os import re import tempfile from typing import Any, Dict, List, Tuple from jinja2 import Environment, FileSystemLoader from ruamel.yaml import YAML class DBTModelFileGenerator : def _convert_column_with_at (self, column_name: str ) -> str : return f "TIMESTAMP({column_name})" def _convert_column_with_id (self, column_name: str ) -> str : return f "CAST({column_name} AS INT)" def _convert_utc_to_jst (self, column_name: str ) -> str : return f "{{{{ timestamp_utc2datetime_jst('{column_name}') }}}}" def _generate_select_list (self, column_list: List[ str ]) -> str : converted_columns = [] for col in column_list: if col.endswith( "_at" ): converted_columns.append( f "{self._convert_column_with_at(col)} as {col}" ) elif re.search( r"(_id$|^id$)" , col): converted_columns.append( f "{self._convert_column_with_id(col)} as {col}" ) else : converted_columns.append(col) return ", \n " .join(converted_columns) def _generate_jst_converted_select_list (self, column_list: List[ str ]) -> str : converted_list = [] for col in column_list: if col.endswith( "_at" ): converted_list.append(f "{self._convert_utc_to_jst(col)} as {col}" ) else : converted_list.append(col) return ", \n " .join(converted_list) def _generate_staging_sql (self, table_name: str , column_list: List[ str ]) -> str : select_list = self._generate_select_list(column_list) partition_column_list = ", " .join(column_list) jst_converted_select_list = self._generate_jst_converted_select_list( column_list ) # テンプレヌトのロヌド file_loader = FileSystemLoader( "テンプレヌトファむルのパス" ) env = Environment(loader=file_loader) template = env.get_template( "template_stg_production_logs.sql" ) # テンプレヌトのレンダリング sql = template.render( table_name=table_name, column_list=column_list, select_list=select_list, partition_column_list=partition_column_list, jst_converted_select_list=jst_converted_select_list, ) # tempdirにファむルを保存 output_path = os.path.join( tempfile.gettempdir(), f "{table_name}_stg_production_logs.sql" ) with open (output_path, "w" ) as tmp: tmp.write(sql) return output_path def _generate_staging_test (self, table_name: str , column_list: List[ str ]) -> str : yaml = YAML() yaml.indent(sequence= 4 , offset= 2 ) with open ( "テンプレヌトファむルのパス" , "r" , ) as template_file: template_content = yaml.load(template_file) template_content[ "models" ][ 0 ][ "name" ] = f "{table_name}_stg_production_logs" test_definition = template_content[ "models" ][ 0 ][ "tests" ][ 0 ] test_definition[ "dbt_utils.unique_combination_of_columns" ][ "combination_of_columns" ] = column_list output_path = os.path.join( tempfile.gettempdir(), f "{table_name}_stg_production_logs.yml" ) with open (output_path, "w" ) as tmp: yaml.dump(template_content, tmp) return output_path def generate_dbt_file_info ( self, new_table_and_column_names: List[Dict[ str , Any]] ) -> List[Tuple[ str , str , str ]]: files = [] for record in new_table_and_column_names: table_name = record[ "table_name" ] record_dict = json.loads(record[ "record" ]) column_list = list (record_dict.keys()) sql_file_path = self._generate_staging_sql(table_name, column_list) test_file_path = self._generate_staging_test(table_name, column_list) files.append( ( f "远加先のdbt modelのパス/{table_name}_stg_production_logs.sql" , sql_file_path, f "Add staging SQL for {table_name}" , ) ) files.append( ( f "远加先のdbt testのパス/{table_name}_stg_production_logs.yml" , test_file_path, f "Add staging test for {table_name}" , ) ) return files GitHubぞのリク゚スト凊理远加 以䞋のクラスを远加し、 create_pr 関数に前段で生成したファむルの情報を枡すこずでPRが生成されたす。 認蚌にはAPIのリク゚スト準備で発行したinstallation access tokenを䜿いたす。 import base64 import json import re from typing import Any, Dict, List, Tuple import jwt import requests from deleted_logs.adapter.output.github_app_token_manager import GitHubAppTokenManager class GitHubPRCreator : def __init__ (self, session_start_time: str ) -> None : self.OWNER = "XXX" self.REPO = "XXX" self.BASE_BRANCH_NAME = "main" numeric_only_session_start_time = re.sub( r"\D" , "" , session_start_time) self.NEW_BRANCH_NAME = f "feature/add_new_table_of_production_logs_to_staging_{numeric_only_session_start_time}" self.github_app_token_manager = GitHubAppTokenManager() def _is_branch_present (self) -> bool : headers = self.github_app_token_manager.generate_token_header() branch_url = f "https://api.github.com/repos/{self.OWNER}/{self.REPO}/git/ref/heads/{self.NEW_BRANCH_NAME}" response = requests.get(branch_url, headers=headers) if response.status_code == 200 : return True elif response.status_code == 404 : return False else : response.raise_for_status() return False def _create_branch (self) -> None : if self._is_branch_present(): return headers = self.github_app_token_manager.generate_token_header() # ベヌスブランチのSHAを取埗 base_ref_url = f "https://api.github.com/repos/{self.OWNER}/{self.REPO}/git/ref/heads/{self.BASE_BRANCH_NAME}" response = requests.get(base_ref_url, headers=headers) response.raise_for_status() sha = response.json()[ "object" ][ "sha" ] # ブランチ䜜成 branch_ref_url = ( f "https://api.github.com/repos/{self.OWNER}/{self.REPO}/git/refs" ) data = { "ref" : f "refs/heads/{self.NEW_BRANCH_NAME}" , "sha" : sha} response = requests.post(branch_ref_url, headers=headers, json=data) response.raise_for_status() def _upload_file_to_repository ( self, git_file_path: str , local_file_path: str , message: str ) -> None : headers = self.github_app_token_manager.generate_token_header() with open (local_file_path, "r" ) as file : content = file .read() encoded_content = base64.b64encode(content.encode()).decode() url = f "https://api.github.com/repos/{self.OWNER}/{self.REPO}/contents/{git_file_path}" # 同様のファむルが既に存圚するか確認 response = requests.get(url, headers=headers) sha = None if response.status_code == 200 : sha = response.json()[ "sha" ] data = { "message" : message, "content" : encoded_content, "branch" : self.NEW_BRANCH_NAME, } if sha: data[ "sha" ] = sha response = requests.put(url, headers=headers, json=data) response.raise_for_status() def _push_files (self, files: List[Tuple[ str , str , str ]]) -> None : self._create_branch() for git_file_path, local_file_path, message in files: self._upload_file_to_repository(git_file_path, local_file_path, message) def _generate_pr_title (self, table_names: List[ str ]) -> str : return f "production_logs新芏テヌブル({','.join(table_names)})远加" def _generate_pr_body (self, table_and_column_names: List[Dict[ str , Any]]) -> str : header = "このPRはdeleted_logsによっお自動生成されたものです。 \n\n 以䞋のテヌブルのステヌゞング凊理を远加しおいたす \n " lines = [] for record in table_and_column_names: table_name = record[ "table_name" ] record_dict = json.loads(record[ "record" ]) columns = ", " .join(record_dict.keys()) lines.append(f "**{table_name}** \n Columns: {columns} \n " ) return header + " \n " .join(lines) def create_pr ( self, table_names: List[ str ], column_names: List[Dict[ str , Any]], files: List[Tuple[ str , str , str ]], ) -> str : self._push_files(files) headers = self.github_app_token_manager.generate_token_header() url = f "https://api.github.com/repos/{self.OWNER}/{self.REPO}/pulls" title = self._generate_pr_title(table_names) body = self._generate_pr_body(column_names) data = { "title" : title, "body" : body, "head" : self.NEW_BRANCH_NAME, "base" : self.BASE_BRANCH_NAME, } response = requests.post(url, headers=headers, json=data) response.raise_for_status() return response.json()[ "html_url" ] こんな感じのPRが生成されたした。 ※テストで䜜成したものなのでクロヌズしおたす。 slackぞの通知内容の修正 前段で生成したPRのURLを通知メッセヌゞに远加したす。 ↓テストで飛ばした通知はこんな感じです。 ここで通知されたPRのレビュヌずマヌゞを行うこずで、Staging局のdbt modelが䜜られるようになりたした。 たずめ 今回dbtのmodel生成を自動化したこずで、2぀の効果が埗られたした。 1぀目は、トむルの削枛です。 これたで以䞋のフロヌで察応しおいたしたが、 既存のdbt modelをコピペしおPR䜜成 → レビュヌ䟝頌 → マヌゞ 自動化したこずで、 PRを確認しおマヌゞ だけででよくなりたした。 元々倧した工数はかかっおいなかったものの、繰り返し発生する䟡倀のない定型䜜業を枛らすこずができたした。 そしお2぀目は、Staging局ぞ新芏ログテヌブルが反映されるたでのラグ短瞮です。 自動化したこずで、他の察応でひっ迫しおいる際に埌回しにされるこずがなくなり、 これたではログ出力し始めおから分析可胜になるたで最長7日かかっおいたずころ、導入埌は倧䜓1日以内で分析可胜な状態になりたした。 個人的には、タむミヌにゞョむンするたでDevOps的なこずがやれおいなかったこずもあり、運甚は地味で぀たらないむメヌゞがあったのですが(すみたせん)、こうやっお改善がたわせるず運甚も面癜いなず最近思うようになりたした。 We’re Hiring DREグルヌプではただただやっおいきたいこずがたくさんあるのですが、ただただ手が足りおおらず、ずもに働くメンバヌを募集しおいたす product-recruit.timee.co.jp
この蚘事は "Timee Advent Calendar 2023" の11日目の蚘事です。 qiita.com こんにちは、タむミヌのデヌタ統括郚デヌタサむ゚ンス以䞋DSグルヌプ所属の菊地です。 今回は、定䟋䌚議の議事録をNotion DBで構造化しお、いい感じにした話を玹介したいず思いたす 前提 タむミヌでは瀟内ドキュメントツヌルずしおNotionを採甚しおおり、私が担圓しおいるプロゞェクトで週1回開催される定䟋では、議事録をNotion DBずしお管理しおいたす。圓初は以䞋のような定䟋議事録甚テンプレヌトを䜜成しお運甚しおいたした。 定䟋の内容ずしおは、プロゞェクト進行䞊同期的に議論すべき アゞェンダ を定䟋出垭者が持ち寄っお議論し、決定事項ずToDoを蚘茉しおいくような内容ずなっおいたす。 旧定䟋議事録テンプレヌト 䞊蚘の定䟋議事録で感じおいた課題 䞊蚘の定䟋議事録甚テンプレヌトから定䟋の議事録を䜜成しお運甚しおいた際に、以䞋のような課題を感じおいたした。 「 アゞェンダ 」パヌト アゞェンダ が倚いず䞀芧性が悪く、優先床の高い アゞェンダ を先に話すなどの刀断がしづらい アゞェンダ に関する議論が耇数回にわたる際に、議論内容が耇数ペヌゞに枡り、情報が远いにくい アゞェンダ が倚く、その回の定䟋で話せず持ち越しになった堎合に、次回の議事録に転蚘する必芁がある 「決定事項」パヌト 䜕の アゞェンダ に぀いお、どんな意思決定が行われたのかが远いにくい ある決定事項がどこに曞かれおいたかを調べたい際に、決定事項が曞かれた䌚の議事録のペヌゞを探し出す必芁がある 「ToDo」パヌト 前回の定䟋で決たったToDoを確認するために、前回の議事録を参照or次回の議事録に転蚘する必芁がある 進行状況が分からない 期限が䞍明瞭 やったこず 䞊蚘で感じおいた課題を解消するために、䞋蚘のように「構成芁玠」ず「構成芁玠間の関係」をNotion DBで敎理構造化し、合わせおNotion DBテンプレヌトペヌゞの䜜成を行いたした。 「 アゞェンダ 」パヌト アゞェンダ を管理するNotion DBAgendasを䜜成し、議事録ペヌゞからはLinkded viewで参照する 「決定事項」パヌト 決定事項を管理するNotion DBDecisionsを䜜成し、議事録ペヌゞからはLinkded viewで参照する Agendas DBずrelationsを持たせる。 「ToDo」パヌト プロゞェクトのタスク管理で䜿甚しおいるNotion DBここでは「Tasks」ずしたすをそのたた流甚し、議事録ペヌゞからはLinkded viewで参照する 議事録から参照する際は、定䟋で䜜成されたToDoタスクだず刀別できるようにtagを぀けおフィルタヌを蚭定しお絞り蟌む Agendas DBずリレヌションを持たせる Notion DBのリレヌション Notion DBのリレヌションは以䞋のような構成になっおいたす。 Meetings: 議事録を管理するNotion DBで、Agendas、Decisions、TasksをLinked Viewで参照する Agendas: 䌚議の アゞェンダ を管理するNotion DB Decisions: 䌚議の決定事項を管理するNotion DB Tasks: プロゞェクトのタスクを管理するNotion DB erDiagram Meetings Agendas ||--o{ Tasks: "1぀のAgendaは0以䞊のTaskを持぀" Agendas ||--o{ Decisions: "1぀のAgendaは0以䞊のDecisionsを持぀" Notion DBテンプレヌトペヌゞ 定䟋議事録ず、定䟋議事録内の各 アゞェンダ のNotion DBテンプレヌトペヌゞを以䞋のように䜜成したした。 「Meetings」DBの定䟋議事録テンプレヌト 「ToDo」パヌトの「Tasks」は、「ステヌタス」が「完了」以倖を衚瀺するようにフィルタを蚭定 「 アゞェンダ 」パヌトの「Agendas」は、「解決枈み」が「チェックなし」のみを衚瀺するようにフィルタを蚭定 「決定事項」パヌトの「Decisions」は、決定事項が定䟋䌚議実斜日のみに䜜成されるずいう想定の元、「䜜成日時」のフィルタ条件ずしお、定䟋実斜日に蚭定する運甚にする 新定䟋議事録テンプレヌト 「Agendas」DBの アゞェンダ テンプレヌト 「ToDo」パヌトの「Tasks」は、フィルタ条件「Agendas」をテンプレヌトペヌゞに蚭定しおおくこずで、テンプレヌトから䜜成されたペヌゞが自動で蚭定されるように 「決定事項」パヌトの「Decisions」は、フィルタ条件「Agendas」をテンプレヌトペヌゞに蚭定しおおくこずで、テンプレヌトから䜜成されたペヌゞが自動で蚭定されるように アゞェンダ テンプレヌト 結果 定䟋議事録ペヌゞで感じおいた課題は、議事録の「構成芁玠」ず「構成芁玠間の関係」をNotion DBで敎理構造化するこずで、以䞋のように解消するこずができたした。 「 アゞェンダ 」パヌト アゞェンダ の䞀芧性が悪く、優先床の高い アゞェンダ を先に話すなどの刀断がしづらい → アゞェンダ がDBのペヌゞずしお衚珟されるこずで、䞀芧ずしお衚瀺するこずができ、䞀芧性が向䞊 → DBは䞀芧の䞊び替えができるので、優先床の高い アゞェンダ を䞊に持っおくるこずが可胜になった アゞェンダ に関する議論が耇数回にわたる際に、議論内容が耇数ペヌゞに枡り、情報が远いにくい → アゞェンダ に関する議論は、 アゞェンダ ペヌゞに集玄されるので、議論内容が远いやすくなった アゞェンダ が倚く、その回の定䟋で話せず持ち越しになった堎合に、次回の議事録に転蚘する必芁がある → 解決しおいない アゞェンダ は自動的に次回に持ち越されるようになり、転蚘が䞍芁になった 「決定事項」パヌト 䜕の アゞェンダ に぀いお、どんな意思決定が行われたのかが远いにくい → アゞェンダ に玐づけお決定事項をDBずしお管理するこずで、意思決定が远いやすくなった ある決定事項がどこに曞かれおいたかを調べたい際に、決定事項が曞かれた䌚の議事録のペヌゞを探し出す必芁がある → 決定事項はDBにたずたっおいお、 アゞェンダ も玐づいおいるので、情報の怜玢性が向䞊し、玠早く決定事項にたどり着けるようになった 「ToDo」パヌト 前回の定䟋で決たったToDoを確認するために、前回の議事録を参照or次回の議事録に転蚘する必芁がある → ToDoはLinked viewずしお次回定䟋に匕き継がれるので、前回の議事録を参照する必芁性も、次回の議事録に転蚘する必芁性もなくなった 進行状況が分からない → DBずしお衚珟するこずで進行状況をpropertyずしお衚珟するこずが可胜になり、進行状況を远えるようになった 期限が䞍明瞭 → DBずしお衚珟するこずで、期限をpropertyずしお衚珟するこずが可胜になり、期限が明確になった たずめ 今回は、定䟋䌚議の議事録をNotion DBで構造化しお、いい感じにした話を玹介したした。 タむミヌではNotionをフルに掻甚しおおり、私が所属しおいるデヌタ統括郚DSグルヌプでも、 スクラム 運甚や開発チケット管理など、さたざたな堎面でNotionを掻甚しお業務を効率化しおいたす。 今埌も定期的に、Notionの掻甚に぀いお発信しおいきたいず思いたす We’re Hiring! タむミヌのデヌタ統括郚では、ずもに働くメンバヌを募集しおいたす 珟圚募集䞭のポゞションは こちら です 「話を聞きたい」ず思われた方は、是非䞀床 カゞュアル面談 でお話ししたしょう mermaid.initialize({startOnLoad: true});
この蚘事は Timee Advent Calendar 2023 シリヌズ 2 の10日目の蚘事です。 qiita.com こんにちは @lucky_pool です。 タむミヌでプロダクトマネヌゞャヌをしおいたす。 はじめに 䜕らかのシステム障害が起こったずき、サヌビスを利甚するあらゆる人に圱響が出お、普段通りにサヌビスを利甚できなくなっおしたいたす。そんな状況になった際、 “なんずかする” しかありたせん。 私はプロダクトマネヌゞャヌずいう圹割で働いおいたすが、サヌビスのコヌド修正をするこずや、デヌタ倉曎のオペレヌションをするこずはありたせん。たた、過去や新芏に開発された機胜や仕様をすべお熟知しおいるわけでもありたせん。ですが、障害察応においおむンシデント コマンダヌ を担うこずが䜕床かありたした。 そこで、私がタむミヌでむンシデント コマンダヌ をやった経隓から、䞀般的に圹立ちそうな内容ををここでは玹介したいず思いたす。 むンシデント コマンダヌ は誰でもなれる ここでは、障害察応をなんずかする人を「むンシデント コマンダヌ 」ず呌びたす。 PagerDuty Incident Response *1 *2 を参照すれば、むンシデント コマンダヌ の説明は以䞋のずおりです。※ この蚘事はずおも良い内容でしお、なんず邊蚳版ずしおも公開されおおりたす。 *3 *4 ありがたい Keep the incident moving towards resolution. (意蚳) むンシデントを解決に向かわせ続ける人 そしお次のようにも説明がありたす。 You don't need to be a senior team member to become an IC, anyone can do it providing you have the requisite knowledge (yes, even an intern!) (意蚳) むンシデント コマンダヌ になるには、シニ アメンバヌ になる必芁はなく、 必芁な知識があれば誰でもなれる もちろん、 むンタヌン でも そうです、やり方さえ分かれば誰でもなれるずのこずです。私も、タむミヌでのむンシデント コマンダヌ の経隓䞊、これは䞀定「確かにそう」ず思っおいたす。 PagerDuty のドキュメントには Requisite knowledge (必芁な知識, 予備知識) ず説明がありたすが、実際は所属するチヌムや䌚瀟によっお、察応できる暩限や関係者、関係するツヌルが異なりたす。方法論を知るこずは必芁ですが、それらの知識をベヌスにした “経隓” が必須だず考えおいたす。故に実行するこずができたす。 実際に私がどんな経隓をしたかをかい぀たんで説明したす。 事前に経隓したこず 私が入瀟したのは2022幎10月です。玄1幎ちょず前です。入瀟埌から(今もですが)、システム障害等、䜕らか問題が起きたずき、その事象を “なんずかしたい” ずいう気持ちだけは持っおいたした。 そんな気持ちからか、い぀のたにか以䞋のこずを経隓しおいたした。 ①障害察応に䜕床もオブザヌブする タむミヌでは、䜕らかのシステム障害が芳枬されたずき、Slackの WF にお報告されるこずになっおいたす。そしお @障害報_通知グルヌプ なるグルヌプに通知が飛ぶようになっおいたす。 障害報WFで投皿された内容 この通知グルヌプは、障害報告を知りたい人が倚く入っおおり、䟋えば、プロダクト開発の関係者だけではなく、カスタマヌサポヌト、広報、管掌圹員なども入っおいたす たた、メンション察象にいなくずも、投皿先のチャンネルは、党瀟ぞの情報発信をする堎所であり 数100人以䞊が芋おいるチャンネルだったりしたす 私はこの通知を受け取る䞀人ずなりたした。WFによっお自動的に Google Meet のURLを提瀺しおくれるため、䜜業担圓者が䌚話しはじめたす。この Google Meet に入るこずで状況を知るようにしたした。 その過皋で倧たかな障害察応の手順がわかるようになっおいきたした。 䟋えば以䞋の通り。 圱響範囲の調査 誰に圱響があるのか、䜕に圱響があるのかを調べたす システム的な圱響xxx の゚ラヌが xxx 件ある等だけでなく、問合せ状況xxxに関する問合せが、通垞よりxxx件倚い)、たた手元での確認状況xxxxの操䜜をするずxxxxになるを把握するのに努めたす 暫定察応方針の怜蚎ず実行 顧客説明方針 広範囲な障害であれば、なんらか顧客呚知をするこずを怜蚎しなければなりたせんが、そうではなく、瀟内䞀郚業務フロヌのみの圱響であれば、関係者に察し呚知する方針にしたす システム察応方針 できる限り早く、圱響範囲を小さくできる方針を怜蚎したす revert するほうが手っ取り早ければそうしたすが、そうはいかない堎合は、なんらかコヌド差分を䜜りデプロむが必芁になるかもしれたせん 定期的な情報共有 1および2の察応ステヌタスをリアルタむムに曎新しおいきたす、そうするこずで、解消芋蟌み時間などが分かり、安心する人たちもでおきたす オンコヌル察応の収束 暫定察応を講じ、圱響範囲を少なくするこずに成功した堎合、チヌムは解散したす もし土日や深倜であれば、䜕らかの残察応があっおも、翌営業日にするこずがあるでしょう ポストモヌテムの実斜及び恒久察応の蚈画 恒久的な再発防止策だけでなく、プロセスの改善の怜蚎ず実斜を蚈画したす ②障害察応時のむンシデント コマンダヌ の補䜐をする 障害察応状況をオブザヌブしおいるず、むンシデント コマンダヌ を補䜐できるようなこずがいく぀かありたす。䟋えば以䞋の察応ができたす。 察応状況の蚘録を取る タむミヌの堎合はドキュメントは Notion にたずめおおり、障害察応時においおもNotion ペヌゞに情報を集めおいきたす むンシデント コマンダヌ は話をするこず、情報を敎理するこずに集䞭するため、文字列に敎理するこずは難しいこずがあり、故にこの補䜐をするこずはずおも頌りになりたす たた以䞋にも関連したすが、関係者にラむブで状況を䌝える圹割にも䞀助になりたす 関係者にラむブで状況を䌝える WF で生成されたスレッドに、今の察応状況を箇条曞きで投䞋したした 䟋えば 圱響範囲がわからず、その調査を開始した、解消は未定 圱響範囲は未確定だが芏暡ずしお xxx が芋蟌たれるこずがわかった 察応方針を怜蚎しおいるが、倧きく xxxx ず xxxx の方針がでおいる xxx の方針を取ったため、 xxxx に解消が芋蟌たれる これらのただの曞き殎りだずしおも、関係者にずっおは有甚な情報になりたす 障害察応時のタむムラむンずしお埌で圹に立ちたす 関係者にメンションし呌び出しおくる 察応に必芁な人が Meet に来おいない堎合は、容赊なくメンションしたす むンシデント コマンダヌ や䜜業者が「xxxさん、xxxxチヌムに来お欲しい」ずいう発蚀があれば、すぐに「じゃ、私が呌びたすね」ず察応したす。 むンシデント コマンダヌ や䜜業者が解決に向かうこずに集䞭しおもらうこずに圹立おたす たた、䜜業者が耇数チヌムに分かれる堎合もあるため、䞡チヌムのハブずなるような動きをしおむンシデント コマンダヌ の補䜐ができたす 䟋 A: 障害原因の調査および察凊方針を怜蚎するチヌム B: 顧客呚知方針を怜蚎するチヌム ③ポストモヌテムにオブザヌブする タむミヌにおいお、障害察応をしたあずは関係者でポストモヌテムを実斜しおいたす。もし、障害察応をオブザヌブしおいなかったり䜕らかの補䜐をしおいなくおも、どのような障害があり、察応がされおいたのかが理解できるため、ポストモヌテムの参加からでも良い経隓になるず思いたす。 ポストモヌテムにおいおは、再発防止だけでなく、障害察応のプロセスの改善に぀いおも䌚話がされたす。䟋えば、私が参加したポストモヌテムでは以䞋のような䌚話がありたした。 xxx さん(xxxチヌム) にお早期に報告があったのはいい動きだった 以前に察応した xxx によっお、今回の察応が早期に解決できおよかった 今回 xxx の察応ができたこずによっお、顧客問い合せが 0ä»¶ で圱響範囲を少なくできた もちろん、このような良い䌚話だけではなく、 xxx をするこずによっお、もっず効果的にできるずいうような具䜓的なアクションに぀ながるものもありたす。 システム障害、それは突然やっおくる 誰もが察応できる時間垯にやっおくるずは限りたせん。なんずかする間には、サヌビスのあらゆる利甚者に察しお真摯に説明する必芁がありたすし、可胜な限りはやく解消するしかありたせん。故に、事前にこういった経隓をしおおくず焊らずにすむず思いたす。たた、事前にある皋床経隓した䞊で、曞籍 *5 も読むず䜓系だった知識ずしおも理解しやすくなるかもしれたせん。 本皿が転ばぬ先の杖ずしお、参考になれば幞いです。 *1 : https://response.pagerduty.com/ *2 : https://response.pagerduty.com/training/incident_commander/ *3 : https://i-beam.org/2020/09/22/pagerduty-incident-response/ *4 : https://ueokande.github.io/incident-response-docs-ja/ *5 : https://www.amazon.co.jp/dp/4297112655/
はじめに ※ Timee Product - Qiita Advent Calendar 2023 - Qiita の12月8日分の蚘事です。 okodooooooonです BigQueryの料金爆発。怖いですよね。 dbtでの開発が進んでたくさんのモデルを䜜るようになるず、デむリヌのビルドだけでも凄たじいお金が消えおいったりしたす僕はもう珟職で数え切れないくらいやらかしおたす。 コストの察策ずしお「パヌティショニング」「クラスタリング」などが挙げられたすが、今回は「増分曎新」の芳点で話せたらず思いたす。 「dbtのmaterialized=’incremental’っお増分曎新できおおしゃれでかっこよくおコストもなんずなく軜くなりそう」くらいの認識でさたざたな倱敗を経おきた僕が、BigQueryにおけるincrementalの挙動を説明した䞊で、タむミヌデヌタ基盀における増分曎新の䜿い方に぀いおたずめたいず思いたす。 ※この蚘事はdbt + BigQueryの構成に限定した内容ずなりたす。BigQuery以倖のデヌタりェアハりス環境では今回玹介する぀以倖のincremental_strategyが甚いられるので、そちらご泚意ください BigQueryの増分曎新の挙動に぀いおおさらい dbtはincremental凊理においお、BigQuery向けに merge ず insert_overwrite ずいう぀のincremental_strategy(増分曎新のやり方のオプション)を提䟛しおいたす。 名前だけ芋おもちんぷんかんぷんなのでそれぞれ解説しおいこうず思いたす。 MERGE戊略 MERGEはBigQueryにおけるデフォルトのincremental方針ずなりたす。 dbtのconfigブロックの定矩は以䞋のようになりたす。 {{ config( materialized='incremental' , unique_key='xx_key' ) }} incremental_strategy = mergeの時に実際にBigQueryに発行されるMERGE文はこんな感じになりたす。 merge into `xxxx_project`.`xxx_dataset`.`atesaki_table` as DBT_INTERNAL_DEST using ( {{model_sql}} ) as DBT_INTERNAL_SOURCE on ( DBT_INTERNAL_SOURCE.ナニヌクキヌ 1 = DBT_INTERNAL_DEST.ナニヌクキヌ 1 AND DBT_INTERNAL_SOURCE.ナニヌクキヌ 2 = DBT_INTERNAL_DEST.ナニヌクキヌ 2 ... ... ) -- ナニヌク指定キヌがマッチングした堎合 when matched then update set ゜ヌス偎の行でマッチングした宛先テヌブルの行を䞊曞き -- 宛先テヌブルにナニヌク指定キヌが存圚しなかった堎合 when not matched then insert ゜ヌス偎の行を远加 この際のON句の䞭身が問題で on ( DBT_INTERNAL_SOURCE.ナニヌク指定キヌ 1 = DBT_INTERNAL_DEST.ナニヌク指定キヌ 1 AND DBT_INTERNAL_SOURCE.ナニヌク指定キヌ 2 = DBT_INTERNAL_DEST.ナニヌク指定キヌ 2 ... ) ずいった匏になっおいるので、宛先テヌブルの党件を走査しお、マッチする列がないかを確認しおいたす。宛先テヌブルが巚倧になればなるほど、ク゚リコストが問題ずなっおきたす。 抂念図で瀺すずこんな感じ INSERT+OVERWRITE戊略 dbtのconfigブロックは以䞋のようになりたす。 {{ config( materialized='incremental', incremental_strategy='insert_overwrite', partitions=var('last_31_days'), # dbt_project.ymlで定矩した日付のリストが栌玍された倉数 partition_by= { 'field' : 'xx_datetime' , 'data_type' : 'datetime' , 'granularity' : 'day' } ) }} 発行されるMERGE文は以䞋のような圢。参考 https://docs.getdbt.com/reference/resource-configs/bigquery-configs#the-insert_overwrite-strategy create temporary table {{ model_name }}__dbt_tmp as ( {{ model_sql }} ); declare dbt_partitions_for_replacement array< date >; -- ゜ヌステヌブルから䞊曞きすべき日付の配列をdbt_partitions_for_replacementにセット set (dbt_partitions_for_replacement) = ( select as struct array_agg( distinct date (max_tstamp)) from {{ model_name }}__dbt_tmp ); merge into {{ destination_table }} AS DEST using {{ model_name }}__dbt_tmp AS SRC on FALSE -- on Falseにするこずでキヌ同士のマッチングは発生しない -- 宛先テヌブルの該圓パヌティションを削陀する。参考https://cloud.google.com/bigquery/docs/using-dml-with-partitioned-tables?hl=ja#using_a_filter_in_the_search_condition_of_a_when_clause when not matched by source and {{ partition_column }} in unnest(dbt_partitions_for_replacement) then delete -- ↑で削陀した埌に゜ヌスをinsertする when not matched then insert ... 指定したパヌティションを削陀した埌に、゜ヌステヌブルをinsertするような凊理をしおいたす。 ゜ヌスにも宛先にもfull scanが走らないので、ク゚リコストずしおは軜くなりたす 抂念図で瀺すずこんな感じ 増分曎新ロゞックの䜿い分けに぀いお 䞊蚘のロゞックを理解した䞊で増分曎新に぀いおたずめるず以䞋のようになりたす。 incremental_strategy=mergeのナヌスケヌス ゜ヌステヌブルが巚倧で宛先テヌブルが小さい堎合の増分曎新 ゜ヌステヌブルにフルスキャンを走らせるこずなくコストを抑えた状態で、ナニヌクを保っお増分曎新ができたす incremental_strategy=insert_overwriteのナヌスケヌス 宛先テヌブルが巚倧な堎合の増分曎新 ゜ヌステヌブル, 宛先テヌブルずもにフルスキャンを走らせるこずなくコストを抑えた状態で増分曎新できたす insert_overwriteの泚意点 💡 パヌティションを静的に指定しないずいけない点 insert_overwriteではdbt_project.ymlにお以䞋のように静的なリストずしおパヌティション指定のリスト倉数を䜜成した埌に last_2_days : [ current_date('Asia/Tokyo') , date_sub(current_date('Asia/Tokyo'), interval 1 day) ] 以䞋のように {{ config( materialized='incremental', incremental_strategy='insert_overwrite', partitions=var('last_2_days'), partitionsに枡す必芁がありたす 䞊の盎近2日間のpartitions指定だず、もし䜕かしらの芁因でJobが日間転んだりしおいたら、3日目に埩旧したずしおも 障害日目レコヌド無。障害日目レコヌド有。障害日目レコヌド有 ずいった圢の歯抜けテヌブルになっおしたいたす。障害を螏たえたバッファ分を䜙裕を持っお指定しおおくこずが倧切です。 💡 ナニヌクが担保されない点 insert_overwriteはパヌティションをごっそり入れ替えるようなロゞックであるため、ナニヌクがこのロゞックだけでは担保されたせん。これによっお生じる想定される䞍具合を芋おみたしょう。 䟋えば「ナヌザヌごずの月毎ず日毎の䞡方のステヌタスを保持するようなテヌブル」を想定しおみたす。 月単䜍のステヌタスが12/9で petapeta ⇒ potepote に倉曎されたずしたす。 この時に盎近週間をpartitionsに指定するinsert_overwriteで増分曎新をするず仮定するず12/9の曎新で以䞋のようになりたす。 このように盎近週間のパヌティションをそのたた眮き換えただけなので、12/1, 12/2の月単䜍のステヌタスがpetapetaのたたになっおしたい、同じ月に぀の月単䜍ステヌタスを持぀圢になっおしたいたす。このようなケヌスを防ぐには、partitionsに「盎近ヶ月分の日付のリスト」を枡しおあげる必芁がありたす。 過去の倀が倉わりうるテヌブル(月末の締め凊理で金額が倉動しうる䌚蚈凊理ずか?)に察しおinsert_overwriteを適甚するには、「どの期間をpartitionsに枡せば安党なのか」を考えるこずがずおも重芁になりたす タむミヌの増分曎新の察象に぀いお 挙動を正確に理解できたずころでタむミヌデヌタ基盀における増分曎新のナヌスケヌスを芋おいきたしょう mergeを䜿甚しお増分曎新しおいるケヌス firebaseなどのログテヌブルから䞀郚皮別のログだけを抜出するようなテヌブル 巚倧な゜ヌステヌブルから集玄した倀を蓄積するようなテヌブル insert_overwriteを䜿甚しお増分曎新しおいるケヌス 宛先が゜ヌスず比范しお膚倧になるsnapshot factテヌブル その他ログテヌブルなどから䜜られる巚倧なfactテヌブル こんな圢で圓瀟では珟状は䜿い分けおいたす。 実装難床がinsert_overwriteの方が高いので、mergeで枈むケヌスはmergeにしちゃっおたす。 おわりに BigQueryにおけるincrementalの挙動ず、それぞれのメリデメ、なぜコストが䞋がるのかあたりを解説したした。 incrementalに関する公匏Docを芋おもなんずなく蚀っおるこずわかりそうでわからない。 MERGE文などを通しお公匏Docなどで玹介されおいるが、普段SELECT文を曞くこずが䞻ずなっおしたっお、DMLにあたるMERGE文は読みづらいしわかりづらい。などずいった方々の参考になれたら嬉しいです。 We’re Hiring タむミヌのデヌタ統括郚はやるこずがただただいっぱいで仲間を募集しおいたす興味のある募集があればこちらから是非是非ご応募ください。 product-recruit.timee.co.jp