投稿者: sumito.tsukada

  • ピープルウエア を読んだ

    ピープルウエア を読んだ

    読んだ動機

    業務をしていたプロジェクトリーダーを努めさせてもらった一年半の長い長いプロジェクトがようやく終わりを迎える。

    振り返ってみたら、不確実性との戦いだった。手探りにプロジェクトを進め、ひっくり返ることもあった。

    不確実性との戦いは今回担当したプロジェクト特有のものではない。おそらくきっと、人生につきまとってくるもののひとつだ。

    それであればこの機会に不確実性についての取り扱いについてきちんと学びたいと思うに至った。

    そこで ヒロキさんの Qiita にたどり着いた。

    https://qiita.com/hirokidaichi/items/95678bb1cef32629c317#%E4%B8%8D%E7%A2%BA%E5%AE%9F%E6%80%A7%E5%88%86%E6%9E%90%E3%82%AF%E3%83%AA%E3%83%86%E3%82%A3%E3%82%AB%E3%83%AB%E3%83%91%E3%82%B9

    トム・デルマコの著書はとてもいい知見に溢れているものの、自分からしたら比喩がわかりにくいこともあり、あまりすすんで読もうとはしてこなかったが、

    知見を得たいとの一心で久しぶりに トム・デルマコ本。 ピープルウエア を読むことにした。

    学んだこと

    一言で言うと、この本は不確実性を直接対処するものではなく、生産性の高いチームを育てることで不確実性にも対応できるようにするといった本だ。

    管理者が陥りやすい錯覚

    個人的にはここで挙げられている項目が現在の自分が考えていた感覚とドンピシャだった。

    7つ記載があったが、その中の3つがとても良かった。

    • 生産性を飛躍的に向上させる方法があるはずだが、見落としてきた
      上記錯覚に対する反論として以下が挙げられていた
      基本的なものを見逃すものはない。
      新しい方法を求め努力してきた。これからやろうとしている情報のどれもが、実際に生産性を高めることはない。
      人は、何かに熱中したり、学んだり改善したりと思っているものである。

    • 他の管理者は自分より、2倍、3倍の成果を上げている
      この錯覚に対する反論は以下のとおり。
      そんなこと気にすることはない。開発やテストの部分に照準を合わせているに過ぎない。
      他にもドキュメント作ったり、顧客と折衝したりする必要がある。
      小さな視点で人と比べるのは良くない。

    • バックログが多いから生産性をあげなければならない。
      プロジェクトの完成時にコストを計算すると、当初予算を遥かに上回るのが常識。
      開発資金がなかった為に完成できなかったから、バックログになったもの。
      生産性の向上は、バックログをこなすために必要なのではない。
      バックログに溜まったタスクを潔く捨ててしまうことで得られる。
      (わかるけどこれはちょっと極端だ)

    生産性の高いチームを育てる

    人が楽しいと思える仕事に必ず「挑戦」がある。

    挑戦はチームのメンバーが一緒になって努力する目標が与えられるからこそ必要になる。挑戦は時にチームを一つにまとめる道具になる。最良の仕事仲間を持った時、人は愉快な気分になるものだし、力を尽くす。その時チームの相互作用がフルに働く。この瞬間、メンバーも楽しいと感じる。

    チームが結束し始めると、成功の確率はぐんと高まる。このフェーズに入ったチームを率いることはリーダーとしての楽しみにもなるようだ。

    結束の強いチームの特徴として、退職率の低さがある。

    自己防衛を取ることのリスク

    チーム編成を妨げ、プロジェクトを崩壊させる確実な方策与えられた仕事をこなす能力が部下にない場合、プロジェクトは失敗する。
    しかし、与えられたグループでやっていこうと一旦決めたなら、最良の戦術は部下を信頼すること。
    部下を信頼する代わりに、プロジェクトの成功を保障しようとして自己防衛の手段をとれば事態は悪化する。

    最良の上司の定義

    「管理」などないかのように、チームが和やかに一致団結働かせることができる人。

    管理されていることを部下に気づかせずに、そんなやり方を繰り返しやれる人。

    健全な会社にするための戦略的要素

    • 品質を高める
      チームのメンバーが品質至上主義になると、市場が求めている以上の品質が備えた製品を常に生産するようになる。
    • 満足感を与える打ち上げ
      (コロナ禍なので飲み会は難しいけど、自分の担当プロジェクトが完遂しら何かしないとな。)

    読み飛ばしたところ

    この本が書かれた時と時代は変わり、リモートワークが定着したことでオフィスに全員が出社する頻度はかなり減った。本書ではオフィスの環境についても書かれてあったが、そこはざっと読んだだけで、ほとんど読み飛ばした。

    ここの部分はリモートワークについて語ってる Youtube大学で語っていることを取り入れることにした。

    まとめ

    時代は変わってもチームビルディングについてのポイントは変わってない。

    名著から学ぶことは多い。

  • Model name must be alphanumeric:

    Model name must be alphanumeric:

    API gateway にinsert する際、エラが発生

    Your API was not imported due to errors in the Swagger file.
    Unable to create model for 'user_id': Model name must be alphanumeric: user_id
    Unable to create model for 'staff_id': Model name must be alphanumeric: staff_id
    

    これは正規表現でいうところの

    [a-zA-Z0-9]+

    のみ model name としての利用を許容しており、アンダースコア含めた名前は API gateway に許容されていないため。

    swagger としては アンダースコアが利用可能なので、API gateway も許容してもらいたいところだ。。

    以下のように対処する

    paths:
      /hoge:
        post:
        requestBody:
            content:
              application/json:
                schema:
                  type: object
                  properties:
                    booking_deadline:
                      $ref: '#/components/schemas/hogeline'
    
    
    components:
      schemas:
        Event:
          type: object
          properties:
            hoge_line:
              $ref: '#/components/schemas/hogeline'
    

  • DMM.com を支えるデータ駆動戦略 を読んだ

    DMM.com を支えるデータ駆動戦略 を読んだ

    誰も正解を持っていない中プロダクトを開発しなければならない。不確実性との戦いである。

    情熱を科学で支える。データ駆動戦略とは、データを駆動させることで事業の優れた価値を見つけ、組織がデータを中心に意思決定する世界。このゴールのイメージがとても重要になる。

    本書ではデータ駆動する上でスクラムなどの開発手法の話にも言及があるが、その辺はすっ飛ばして、あくまでも”データ基盤” を作る上で必要な情報のみまとめる。

    データ駆動戦略を用いた事業の捉え方と、プロセスは以下の順番を遡ると説いている。

    1. 事業でどうやって収益を得ているか知る。
      何をインプットとするか。
      インプットに対してどのような処理が行われているか
      何をアウトプットとしているか

      時には1ユーザーの売り上げベースでミクロの視点で見る必要もあり、
      合計の売り上げで見るマクロの視点で見る必要がある。

    2. その後、事業構造を KPI で表現して予測可能性を作る。
      KPI を作るにあたり、 KGI (Key Goal Indicator) の理解や、
      CSF (Critical Success Factor) に関する知識が必要。

      KGI – CSF -KPI

      といったツリー構造になる。
       
    3. KPI から見えた課題に対して施策を実行していく。この際、費用対効果が高い KPI を選定する。

      KPI として訪問者数を目標値として老いたとする。
      キャンペーンなどの施策を行いながら、訪問者数を増やしていく。

      この時重要なのは、施策の優先順位付けに時間をかけるのではなく、
      施策の実行スピードを重要視することである。

    4. 仮説検証のサイクルを回す。必ず成功する施策はない。失敗を許容し多くの施策を回す。

      不確実性の高い事業の中で、全て成功するとは限らない。失敗を許容する仕組みを用意する

    5. KPI サイクルを高速に合理的に回す

      スピードを上げる。


    データ基盤を作る上では、まずはデータを集約することが第一歩にな理、データパイプラインが必要になる。

    データ集約は組織全体で行わないと効果が限定的になり、局所最適化になってしまう。

  • 「いちプレーヤー」から「マネージャー」に頭を切り替える思考法 リーダーの仮面 を読んだ

    「いちプレーヤー」から「マネージャー」に頭を切り替える思考法 リーダーの仮面 を読んだ

    さまざまなリーダーシップや組織論についての本があるが、本屋さんの中で平積みされていたので気になっていた本。

    「素顔」のままで疲れ果てるか、「仮面」をかぶり、生まれ変わるか。

    という背表紙の一文にはドキッとさせられる。

    本書に書かれていたことと、私自身の経験も照らし合わせながらまとめていこうと思う。

    リーダーの責務の一つに

    部下を成長させ、チームの成果を最大化させることがある。

    リーダーがチームの成果を最大化させるためにリーダが見るべきポイントはわずか5つだけである。

    この5つのポイントにフォーカスし、それ以外のことは任せる、見守る、スルーするようにする。選択と集中。まさにそのように感じた。

    組織マネジメントには数学や物理のように公式のような決められた型がある。

    トラブルに見舞われ、リーダーとしてどう振る舞えばいいか悩むことに出くわすが、この5個に立ち返るだけで良い。自分の所感も含めて記す。

    1. ルール

    場の空気ではなく、言語化されたルールをつくることが重要だ。

    ルールを作り、それを守らせるのがリーダーのすべきこと。

    ルールを作って、規則正しく動くのであれば精神的に疲れることもない。

    ルールを作る際は、主語を明確にするのがポイント。

    ルールが重要であり、他人に「気遣い」を期待することなどあってはならない。

    他人に期待してしまい、それが期待通りされなかった時は辛い。

    最初から「気遣い」などに期待しないと割り切ることが重要。本当に必要であればそれはルールに盛り込むことだと説いている。

    2. 位置

    対等ではなく、上下の立場でコミュニケーションする

    責任者がハッキリしていないと部下は働きにくい。

    3. 利益

    人間の魅力ではなく、利益の有無で人を動かす

    みんなで利益を目指せば迷子にならない。これはとても重要なことであり、目的が一緒であれば手段は部下に選ぶ裁量渡しても良いのではないかと個人的には思う。

    チーム全員を「組織の利益」に向かせるための仕組みがとても重要。

    「成長」という利益を追い求める限り、会社との利益相反を起こさず永遠に利益を得続けることができる。

    4. 結果

    プロセスを評価するのではなく、結果だけを見る

    5. 成果

    目の前の成果ではなく、未来の成長を選ぶ

    総括として、いかなる時も個人的な感情は決して表に出さない。

    ルールに基づいてチームを動かし、そして結果だけをみて冷静に評価する。

    本書では 1on1 などのコミュニケーションも否定しているし、合う人合わない人が明確に分かれそうだ。しかし中間管理職として疲弊する人にとっては、このような考え方もあるのかと非常に勉強になった。

    そもそもリーダーシップとは?

    またリーダーシップと、マネジメントについては鴨頭さんの動画が非常にわかりやすかった。

    リーダーシップとは

    マネジメントはこちら

    同じ動画(開始位置が違うだけ)なのでサムネが一緒になってしまっているが。

    自分はこの表現がとてもわかりやすかったので紹介。

  • モノリスからマイクロサービスへ を読んだ

    モノリスからマイクロサービスへ を読んだ

    マイクロサービス化を促進させたく、また今我々がマイクロサービス化に向けてとっているアプローチが正しいのかを確認する上で本書を読むことにした。

    事前にいくつか言葉の定義をしっかりしておく必要がある。

    代表的な登場人物として、マイクロサービスと、モノリスだ。

    それぞれの定義と、メリット、作り出す問題は以下の通りだ。

    マイクロサービスについて

    マイクロサービスの定義

    ビジネスドメインに基づいてモデル化された独立してデプロイ可能なサービス

    サービス同士が疎結合である必要がある。

    マイクロサービスのメリット

    各サービスの作業を並行して行えるため、多くの開発者がお互いの作業を意識する必要がなく作業を行うことができる。

    マイクロサービスが作り出す問題

    マイクロサービスが作り出すのはメリットだけではない、

    ネットワーク通信によりサービス間の通信が発生することになり、今までの処理以上にレイテンシーはかかってしまう。

    また、サービスをまたいだデータベースのトランザクションも非常に難しい。

    マイクロサービスによるメリットをきちんと享受しないと、デメリットだけ発生する可能性もある。

    この問題に対して以下の問いに対し明確になっている必要がある。

    • 達成したいことは何か
    • マイクロサービスの他に代替案はなかったのか
    • どうすれば移行がうまく行くか分かっているか

    モノリスについて

    モノリスの定義

    マイクロサービスを語るとき、しばしばその対義語として使われることがあるが、この本ではデプロイの単位として捉えている。

    システム内の全ての機能を一緒にデプロイする必要があった時、モノリスとして表現している。

    全てのコードが単一プロセスとしてデプロイされているシステム。

    モノリスのメリット

    マイクロサービスと比べてしまうとモノリスで

    • 監視
    • トラブルシューティング
    • エンドツーエンドテスト

    などを行うのは容易と感じる。とにかく1個に集約されている状態は開発運用するのにメリットも確かにあった。

    これはマイクロサービスを運用していると、このモノリスの当たり前がいかに我々に染み込んでいたかを感じる。

    モノリスが作り出す問題

    そもそもマイクロサービスに舵を切る理由である。

    モノリスはさまざまなサービスが1つに集約されている。そのため長年運用していると機能拡張が難しくなる。

    マイクロサービス化を始める時の大切なポイント

    マイクロサービスに踏み切る際考えるべきポイント

    • 自分たちにはどれくらいの数のマイクロサービスを扱えるか
    • マイクロサービスの境界線をどのように定義するべきか。

    この辺が重要になる。

    マイクロサービスへの移行計画

    茨の道になることもある。ビジョンと戦略を生み出す必要がある。

    ビジョンとは・・・仲間を集めてどのような変化をもたらすことを望んでいるのか

    戦略とは・・・そこに到達する方法

    これらをメンバーと共有する必要がある。一人では到底難しいプロジェクトになる。

    サービスのインターフェースを定義する際に重要になるのが

    サービスがどのように利用されているかというサービス利用者の観点からサービスをデザインしていくところである。それがマイクロサービスへの道のりの一歩になる。イベントストーミングがそれになる。

    イベントストーミングとは

    技術的なステークホルダーと非技術的なステークホルダーが一緒に共有ドメインを定義する共同で行うべき作業。

    イベントストーミングはボトムアップで行う。

    システム内に発生する「ドメインイベント」を定義することから始め、

    イベントを集約にまとめ、集約を境界づけられたコンテキストへまとめていく。

    移行に於けるチェックポイントとして

    時折立ち止まって振り返るための時間を組み込むことが重要

    情報を分析し、軌道修正が必要かどうかを判断する

    マイクロサービスでのトランザクション

    ACID トランザクション(DB の一貫性を保つトランザクション)は全てのデータベースが持っているわけではない。

    解決策が2つある

    2フェーズコミット

    投票フェーズと、コミットフェーズの2つに分ける。

    • 投票フェーズで状態の変更が可能かを確認し、レコードにロックをかける。
    • コミットフェーズで確定させる。

    サーガ

    複数の状態変更を調整できる。レコードをロックさせない。

    各ステップのビジネスを明確にモデル化させる。

    ロールバックするにはロールバック用の処理を用意する必要がある。(開発コストもリスクも高くない?)

    以上、メモ。良いマイクロサービス移行の旅を。

  • mysql で ストアドプロシージャ を登録・変更・削除する

    mysql で ストアドプロシージャ を登録・変更・削除する

    ストアドプロシージャは サーバーに格納できる一連の SQL です。これが一度登録されると クライアントは個々のステートメントを繰り返し発行す必要はなくなります。

    ユーザー作成

    ユーザーに権限を付与する

    GRANT SELECT, INSERT, UPDATE, DELETE, CREATE ROUTINE, ALTER ROUTINE, EXECUTE ON `database`.* TO 'user'@'10.1.%';

    ひとつひとつ説明する。

    SELECT, INSERT, UPDATE, DELETE これは普通の DML なので省略する。

    CREATE ROUTINE … ストアドプロシージャを作成する権限

    ALTER ROUTINE … ストアドプロシージャを削除・変更する権限

    EXECUTE … ストアドプロシージャを実行する権限

    ストアドプロシージャを登録する

    ストアドプロシージャーを実行する際、 delimiter を一時的に変更すると登録しやすい。

    delimiter // 
    create procedure sample()
        -> begin
        -> select count(*) from user;
        -> end
        -> //
    
    delimiter ;

    ストアドプロシージャを確認する

    SHOW PROCEDURE STATUS;

    SHOW PROCEDURE STATUS;
    +------------------+---------+-----------+--------------------+---------------------+---------------------+---------------+---------+----------------------+----------------------+--------------------+
    | Db               | Name    | Type      | Definer            | Modified            | Created             | Security_type | Comment | character_set_client | collation_connection | Database Collation |
    +------------------+---------+-----------+--------------------+---------------------+---------------------+---------------+---------+----------------------+----------------------+--------------------+
    | database | sample  | PROCEDURE | root@%             | 2021-06-29 14:47:44 | 2021-06-29 14:47:44 | DEFINER       |         | utf8                 | utf8_general_ci      | utf8mb4_general_ci |
    | database | sample1 | PROCEDURE | user@10.1.% | 2021-06-29 14:57:08 | 2021-06-29 14:57:08 | DEFINER       |         | utf8                 | utf8_general_ci      | utf8mb4_general_ci |
    +------------------+---------+-----------+--------------------+---------------------+---------------------+---------------+---------+----------------------+----------------------+--------------------+

    ストアドプロシージャを実行する

    call sample1();
    +----------+
    | count(*) |
    +----------+
    |   188376 |
    +----------+
    1 row in set (0.00 sec)
  • コンテナ内の mysql にリクエストされたクエリを確認する

    コンテナ内の mysql にリクエストされたクエリを確認する

    開発している際 コンテナの mysql にどのようなクエリ走ったのか確認したいことがある。

    スロークエリを 0秒に設定することで、DB にリクエストされた 全クエリを確認することができる。

    mysql> show variables like 'slow%';
    +---------------------+--------------------------------------+
    | Variable_name       | Value                                |
    +---------------------+--------------------------------------+
    | slow_launch_time    | 2                                    |
    | slow_query_log      | OFF                                  |
    | slow_query_log_file | /var/lib/mysql/5c364d250748-slow.log |
    +---------------------+--------------------------------------+
    3 rows in set (0.00 sec)
    
    mysql> 
    

    slow_query_log が OFF になっている場合、出力されない。

    set global slow_query_log_file = '/tmp/mysql-slow.log';
    set global long_query_time = 0;
    set global slow_query_log = ON;

    上記コマンドを実行し、再度確認すると、スロークエリが出力されるようになってる。

    mysql> show variables like 'slow%';
    +---------------------+---------------------+
    | Variable_name       | Value               |
    +---------------------+---------------------+
    | slow_launch_time    | 2                   |
    | slow_query_log      | ON                  |
    | slow_query_log_file | /tmp/mysql-slow.log |
    +---------------------+---------------------+
    3 rows in set (0.00 sec)
    
    mysql> 
    

    スロークエリが 0秒に設定されたか確認するのは

    show global variables like 'long_query_time';

    コマンドを実行する

    mysql> show global variables like 'long_query_time';
    +-----------------+----------+
    | Variable_name   | Value    |
    +-----------------+----------+
    | long_query_time | 0.000000 |
    +-----------------+----------+
    1 row in set (0.00 sec)
    
    mysql> 
    

    結果

    
    SET timestamp=1624328575;
    INSERT INTO `xxx_transactions` (`id`,`operation`,`request`,`requested_at`,`response`,`responsed_at`,`metadata`,`status`,`failure_code`,`failure_message`,`created_by`,`created_at`) VALUES (105,'request',NULL,NULL,NULL,NULL,NULL,'succeeded',NULL,NULL,'123456789','2021-06-22 02:22:55.1492209');

    無事流れたクエリを確認することができた。

  • 【解決法】go1.16でビルドエラー「no required module provides package github.com」が発生する場合

    【解決法】go1.16でビルドエラー「no required module provides package github.com」が発生する場合

    go1.16 で golang を書いて build すると、タイトル通りのエラーが表示された。

    調べてみると go 1.15 までは go buildgo test などのコマンドを実行すると、 go.modgo.sum の内容をよしなに更新されていたが、go 1.16 からは自動では更新されなくなったようだ。

    これを解決するには

    $ go mod tidy

    とすることで、go のモジュールに書かれている不足分のパッケージを go.mod に書き込んでくれる

    % go build -o hoge.go
    main.go:7:2: no required module provides package github.com/hackebrot/turtle; to add it:
            go get github.com/hackebrot/turtle
    
    
    % go mod tidy
    go: finding module for package github.com/hackebrot/turtle
    go: downloading github.com/hackebrot/turtle v0.1.0
    go: found github.com/hackebrot/turtle in github.com/hackebrot/turtle v0.1.0
    go: finding module for package github.com/hackebrot/go-repr/repr
    go: finding module for package github.com/google/go-cmp/cmp
    go: downloading github.com/google/go-cmp v0.5.5
    go: downloading github.com/hackebrot/go-repr v0.1.0
    go: found github.com/google/go-cmp/cmp in github.com/google/go-cmp v0.5.5
    go: found github.com/hackebrot/go-repr/repr in github.com/hackebrot/go-repr v0.1.0
    
    % go build -o hoge.go
    

    参考情報

    https://golang.org/ref/mod#go-mod-tidy

  • bashで入力の冗長を減らす

    bashで入力の冗長を減らす

    何かと bash/zsh で作業していると、直近の引数を再度入力したくなることがある。
    たとえば、ディレクトリを作って、その中に移動する場合などだ。

    実は bash や zsh には直前の引数を再度入力する特殊変数が存在する。

    % pwd   
    /tmp

    この /tmp ディレクトリから新規ディレクトリを作成し、そこに移動する場合、
    このように表現することで移動することができる。

    % mkdir hoge; cd $_ 
    % pwd
    /tmp/hoge

    $_ という変数が特殊変数という扱いになり、直前の引数を再度入力することができる。

  • fargate platform 1.4 で service を起動できない

    fargate platform 1.4 で service を起動できない

    今まで fargate で service を動かせていたが、platform 1.4 では動かせないことがあった。その対処法を紹介。

    pseudoTerminal option があるが、falase だと起動した後に停止してしまう。解決策としては、

    pseudoTerminal を false から true にすること。

    そもそも pseudoTerminal とは擬似ターミナル。

    Docker Remote API の コンテナを作成する際、セッションの TTy にマッピングして docker run にマッピングするオプション。

    1.3 まではこの設定が false でも動かすことができたが、1.4 ではこれを true にしないと動かすことができないようだ。