オペレーションとサポートのためのローテーション・オン・コール:データ・チームでは必須

On-call rotation necessary for operation and support Data team

オペレーション、サポート、および技術部門のローテーション型オンコールスケジュールは、チームの残りのメンバーが優れた開発を行うことを可能にします

すべてのデータサイエンスまたはプロダクトチームが直面する共通の課題は、新しい(プロダクト開発)と古い(オペレーション、サポート)のタスクを調整することです。チーム全体が両方を扱う必要がある場合、一方ではチームは製品の期限を守り、新しい製品機能をローンチする必要がありますが、同時にチームはオペレーション面で作業し、既存の製品を修正し、商業的な質問やコールに対応することが期待されています。この状況は、予期しないコンテキストスイッチを引き起こし、最終的には効率の低下、期限の失敗、ストレスにつながります。

実際には、これはしばしば、特定のチームメンバーがこれらの追加タスクを引き受けたり、それを専門に行ったりする状況につながります。しかし、これは危険です。専門のチームメンバーのうちの1人が休暇を取ると、全社がそれを感じ、問題が発生する可能性があります。

したがって、効率的かつスケーラブルなデータチームは、オペレーションと新しい開発作業の両方をサポートし、以下を含むシステムを作成する必要があります。

  • チームメンバー間のオペレーショナルな作業や製品/顧客のサポート方法に関する良好なナレッジシェア
  • コンテキストスイッチが少ない中断されない開発作業
  • 予期しない期限を回避するためによく定義され、推定されたメンテナンス作業

ローテーションオンコールシステム

過去に私たちに非常にうまく機能したシステムの1つは、製品が稼働している場合に「アラート」だけを処理するローテーションシステムです。簡単に言えば、1人または複数のチームメンバーが特定の期間、指名され、純粋にオペレーショナルな作業に責任を持つローテーションシステムです。

オンコールの人は仕事をしているだけでなく、開発作業の外で起こる混乱からチーム全体を保護しています

この点を終えるために、このシステムにより、オンコールの人(指名された生存者)だけが「新しい開発」に該当しないすべての作業を処理できるようになります。その期間中、オンコールの人は仕事をしているだけでなく、開発作業の外で起こる混乱からチーム全体を保護しています。これには、以下が含まれます。

  • プロダクションパイプラインの問題を修正する
  • 商業/顧客の質問に答える
  • 顧客の電話サポート
  • 技術部門(バックログ)の削減
オンコールルーティンに含まれる特定のタスクの概要。

上記の図に示すように、「クラシックな」オンコールシステムを処理し、製品環境が機能することを確認することが最も重要です。ただし、プロダクションに問題がない場合、商業的なリクエストのサポート、顧客コール、またはバックログの削減などの他のタスクに時間を割くことができます。

どのような利点がありますか?

最初にこのシステムに切り替えることは簡単ではありません。すべてのチームメンバーがプロダクションパイプライン、商業サポート、および技術部門に責任を持つわけではありません。しかし、これはブロッカーになるべきではありません。オンコールの人がそれらのアイテムを所有し、最初の防衛ラインであることを適切に伝えることが重要ですが、いつでも助けを求めることができます。

長期的には、チームと組織全体に多くの利点がもたらされます。最も直感的な利点は、開発作業を見積もりやすくなり、チームがより効率的になることです(コンテキストスイッチが少なくなります)。これは、オペレーショナルな側面にも当てはまり、オンコールシステムに参加する人数がオペレーション作業の量を定義するため、コミュニケーションが会社やステークホルダーとより簡単になります。オンコールローテーションを使用するチームの20%がオペレーションに参加し、80%が開発に参加する場合、5人のチームの1人がローテーションに参加しており、すべてのシステムと既存プロダクトに関連する作業を維持しています。これは簡単に予測および見積もりができます。

オンコールローテーションを使用するチームにおける20%-80%のオペレーション-開発分布の概略図。

しかしながら、追加の利益が徐々に生じ、副次的な影響として現れます。全てのチームメンバーはフルスタックのデータサイエンティストになるでしょう。その理由は、各チームメンバーが製品、顧客、システム、モデル/ロジック、コードインフラストラクチャに関する一定の最小限の理解が必要であるからです。彼らは専門家である必要はありませんが、少なくとも1週間はそれらを単独で処理できる程度になるでしょう。また、貴重なチームメンバーが休暇に出かけた場合でも、オンコール担当者が常にチームをサポートするため、何の問題もありません。

さらに、このオンコール時間は時に多少ストレスを伴うかもしれませんが、データサイエンティストにはチームの外側を見る機会が与えられ、ビジネス側や顧客と協力することができます。これは非常に有益で報酬のある経験になるかもしれません。

このようなシステムを設定する方法

ここからは少し技術的になります(コードが好きな人は最後までスクロールしてください)。このようなシステムを設定することは非常に簡単ですが、いくつかのコーディングが必要になる場合があります。最も重要な部分は、チームやステークホルダーとのコミュニケーションで、どのように動作するのかを説明することです。

システム全体の目的は、チームをサポートすることであり、オーバーヘッドを増やすことではないため、完全に自動化することを強くお勧めします。それには、少なくとも3つのシステムが必要です:

  • プロダクションに接続されたページャーシステム:プロダクションが失敗した場合にアラートを出す(たとえば、OpsgenieまたはPagerduty)
  • オンコール担当者を検出し、別のシステムに伝えるスケジューリングシステム(たとえば、Apache AirflowまたはKeboola)
  • チームに連絡を取るために使用されるコミュニケーションプラットフォーム(たとえば、SlackまたはTeams)

これらのシステムが導入され、ページャーシステムとコミュニケーションプラットフォームへのAPIアクセスがある場合、あとはほとんど終わりです。残りの作業は、スケジューリングシステムでジョブを設定し、最初にページャーシステムからオンコール担当者を取得するAPIコールを実行し、その後、コミュニケーションプラットフォームのチャネル/グループ/タグを通知するためのAPIプッシュを実行することです。

以下は、Opsgenieからオンコール担当者を取得するためのAPIコールの例です:

curl -X GET \'https://api.opsgenie.com/v2/schedules/{schedule_name}/on-calls?scheduleIdentifierType=name&flat=true' \--header 'Authorization: GenieKey {token}'

その後、Slackでユーザーグループを上書きして、オンコール担当者のみを含めるようにするコマンドを実行します:

curl -X POST \-F usergroup={usergroup} \-F users={user} \'https://slack.com/api/usergroups.users.update' \-H 'Authorization: Bearer {token}'

このストーリーの最後には、このコードを自動的にスケジュールする方法の完全なコードバージョンがあります。これにより、Slackであなたのグループにタグを付けるたびに(@ teamのように)、オンコール担当者だけがタグ付けされ、他のチームメンバーに通知する必要があるかどうかを決定できます。また、ダグに新しいタスクを追加することができます。たとえば、会社やチームに誰がオンコールになっているかを通知したり、チケットシステムを調整したりする場合などです。

まとめ

チームの運用、商業、技術部門のローテーションスケジュールを持つことは、データチームをより効率的にします。コンテキストの切り替えを減らし、より良い時間見積もりを可能にします。さらに、チームの残りを守るために幅広い問題を自信を持って処理できるフルスタックのデータサイエンティストを育成することができます。

すべての画像は、特に注記されていない限り、筆者によるものです。

コードの追加:

Opsgenieからオンコール担当者を取得し、Slackのユーザーグループを上書きするAirflow dagの例です。コーディングが完璧ではないかもしれませんが(データサイエンティストが働いている)、理解できると思います:

# Importfrom airflow import DAG, XComArgfrom typing import Dict, Listfrom airflow.operators.bash import BashOperatorfrom airflow.operators.python import PythonOperatorfrom airflow.models import Variableimport json# Fetch secret tokensslack_token = Variable.get("slack_token")opsgenie_token = Variable.get("opsgenie_token")# Setup DAGdag = DAG(    dag_id,    schedule_interval=schedule_interval,    default_args=default_args,    catchup=catchup,    max_active_runs=max_active_runs,)with dag:        # Run BashOperator fetching from Opsgenie who is on call    def fetch_who_is_on_call(**kwargs):        fetch_who_is_on_call_bash = BashOperator(            task_id="fetch_who_is_on_call_bash",            bash_command="""            curl -X GET \            'https://api.opsgenie.com/v2/schedules/{schedule_name}/on-calls?scheduleIdentifierType=name&flat=true' \             --header 'Authorization: GenieKey {token}'            """.format(                schedule_name="schedule_name",                 token=opsgenie_token             ),            dag=dag,        )        return_value = fetch_who_is_on_call_bash.execute(context=kwargs)        fetch_who_is_on_call_bash        return return_value    # run BashOperator in PythonOperator and provide context    opsgenie_pull = PythonOperator(        task_id="opsgenie_pull",        python_callable=fetch_who_is_on_call,        provide_context=True,        dag=dag,    )        # Overwrite slack group with the person on call    def overwrite_slack_group(**kwargs):                # First: get who is on call from PythonOperator        ti = kwargs.get("ti")        xcom_return = json.loads(ti.xcom_pull(task_ids="opsgenie_pull"))        user_email = xcom_return["data"]["onCallRecipients"][0]        user_dict = {            "data_scientist_a": "A03BU00KGK4",            "data_scientist_b": "B03BU00KGK4",        }        user_id = [            user_dict[k] for k in user_dict.keys() if k == user_email.split(".")[0]        ]                # Second: Run BashOperator to overwrite slack group        overwrite_slack_group_bash = BashOperator(            task_id="overwrite_slack_group_bash",            bash_command="""            curl -X POST \            -F usergroup={usergroup} \            -F users={user} \            https://slack.com/api/usergroups.users.update \            -H 'Authorization: Bearer {token}'            """.format(                usergroup="usergroup_id",                user=user_id,                token=slack_token,            ),            dag=dag,        )        overwrite_slack_group_bash.execute(context=kwargs)        overwrite_slack_group_bash    # Run BashOperator for slack overwrite in PythonOperator    overwrite_slack = PythonOperator(        task_id="overwrite_slack",        python_callable=overwrite_slack_group,        provide_context=True,        dag=dag,    )    opsgenie_pull >> overwrite_slack    return dag

We will continue to update VoAGI; if you have any questions or suggestions, please contact us!

Share:

Was this article helpful?

93 out of 132 found this helpful

Discover more