RareJob Tech Blog

レアジョブテクノロジーズのエンジニア・デザイナーによる技術ブログです

英会話の教材をCloud Natural Languageで解析してみた

はじめに

昼休みの1時間、会社近くのゴールドジムへ通ってベンチプレスが日課なのですが、最近胸の形が良くなったと定評のある35歳の男、塚田です。

ちなみに好きなプロテインはリッチミルクです。

さて、トレーニングと同じくコツコツやる系といえば英会話です。 我々の提供しているレアジョブ英会話の中で重要な構成要素の一つは教材です。

レアジョブ英会話が提供している教材は自社で開発しており、様々な国籍の方が働いているチームで品質チェックを行い、 厳しいチェックをパスしたものが世に出ます。 今回はその人気教材の一つ、Daily News Articleを使って、GCPのCloud Natural Languageで自然言語解析を行いたいと思います。 www.rarejob.com

解析対象コンテンツ

今回はコンテンツをそのまま機械的に翻訳をかけるのではなく、 作業端末内にテキストとして保存したところから解析を始めています。 ちなみに解析したコンテンツはこちら。

www.rarejob.com

A new robot created by a team of Toyota engineers set a Guinness World Record after demonstrating its impressive free-throw shooting skills.

という出だしからわかる通り、Guinness World Record を取得したToyota engineers チームの話しです。

解析エンジン

GCP では主に、2つの自然言語解析機能が提供されています。

  • AutoML Natural Language (最小限の労力と機械学習の専門知識で高品質な独自のカスタム機械学習モデルをトレーニングすることで、感情の分類、抽出、検出ができる)
  • Natural Language API (Natural Language API の強力な事前トレーニング済みモデルにより、デベロッパーは感情分析、エンティティ分析、エンティティ感情分析、コンテンツ分類、構文分析などの自然言語理解の機能を操作できる)

今回は既に学習済みのモデルであるNatural Language APIを活用することにします。 Natural Language APIが提供する機能は以下の通りです。

  • エンティティ分析(analyze-entities)... ドキュメント(領収書、請求書、契約書など)の中のエンティティを識別し、ラベル(日付、人、連絡先情報、組織、場所、イベント、商品、メディアなど)を付ける
  • 感情分析(analyze-sentiment) ... テキストのブロック内で示されている全体的な意見、感想、態度の感情を読み取る
  • コンテンツの分類(classifyText) ... 事前定義された 700 以上のカテゴリでドキュメントを分類
  • 構文解析(analyze-syntax) ... 文の抽出、品詞の特定、各文の係り受け解析ツリーの作成

全部試してみた

エンティティ分析(analyze-entities).

実施コマンド

gcloud ml language analyze-entities --content-file=/tmp/original > /tmp/analyze-entities

結果

{
"entities": [
  {
    "mentions": [
      {
        "sentiment": {
          "magnitude": 0.1,
          "score": 0.1
        },
        "text": {
          "beginOffset": 6,
          "content": "robot"
        },
        "type": "COMMON"
      }
    ],
(中略)
  {
    "mentions": [
      {
        "sentiment": {
          "magnitude": 0.1,
          "score": 0.1
        },
        "text": {
          "beginOffset": 56,
          "content": "Guinness World Record"
        },
        "type": "PROPER"
      }
    ],
    "metadata": {},
    "name": "Guinness World Record",
    "salience": 0.03506625,
    "sentiment": {
      "magnitude": 0.1,
      "score": 0.1
    },
    "type": "EVENT"
  },

単語を取ってくれるようです。 特筆すべきは、Gusiness, World, Recordのように認識されてもおかしくないのに、 Guinness World Recordのようなワード(複合名詞)を1つの単語として扱ってくれます。

これについて調べてみると、 mentions には PROPER と COMMON の 2 つのタイプがあります。 PROPERの場合は、固有名詞。COMMONの場合は普通名詞という風に区別されています。

cloud.google.com

ちなみに、エンティティ分析は、学術的には固有表現認識(Named Entity Recognition )と呼ばれています。 機関名や人物名などを文章の中から識別する問題を解いており、以下のようなマスク処理(データの匿名化)で使われることがあるそうです。

固有表現認識を使って文書を黒塗りする - Qiita

感情分析(analyze-sentiment)

実施コマンド

gcloud ml language analyze-entity-sentiment --content-file=/tmp/original > /tmp/analyze-entity-sentiment

結果

{
"documentSentiment": {
  "magnitude": 5.2,
  "score": 0.3
},
"language": "en",
"sentences": [
  {
    "sentiment": {
      "magnitude": 0.9,
      "score": 0.9
    },
    "text": {
      "beginOffset": 0,
      "content": "A new robot created by a team of Toyota engineers set a Guinness World Record after demonstrating its impressive free-throw shooting skills."
    }
  },

各センテンス毎に全体的な態度(ポジティブかネガティブか)を特定する分析。 score と magnitude の数値によって表されるようです。

コンテンツの分類(classifyText)

実施コマンド

gcloud ml language analyze-entity-sentiment --content-file=/tmp/original > /tmp/analyze-entity-sentiment

結果

{
"categories": [
  {
    "confidence": 0.59,
    "name": "/Sports"
  }
]
}

文章全部を読んで、Sports ですね。というカテゴリーに分類されました。 自動でタグを打ちたい時とか便利かもしれません。

構文解析(analyze-syntax)

実施コマンド

gcloud ml language analyze-syntax --content-file=/tmp/original > /tmp/analyze-syntax

結果

{
  "language": "en",
  "sentences": [
    {
      "text": {
        "beginOffset": 0,
        "content": "A new robot created by a team of Toyota engineers set a Guinness World Record after demonstrating its impressive free-throw shooting skills."
      }
    },
    {
      "text": {
        "beginOffset": 142,
        "content": "Toyota Motor Corporation\u2019s robot, CUE3, completed 2,020 consecutive basketball free throws in a demonstration last May."
      }
    },
(中略)
    {
      "text": {
        "beginOffset": 970,
        "content": "In a separate demonstration meant to test CUE3\u2019s ability to make three-point shots, the robot was able to score 62.5% of the time."
      }
    },
    {
      "text": {
        "beginOffset": 1103,
        "content": "This figure beats NBA player Kyle Korver\u2019s single season record of 53.6% and two-time NBA MVP Stephen Curry\u2019s average of 43.6%."
      }
    },

(中略)
    {
      "dependencyEdge": {
        "headTokenIndex": 23,
        "label": "AMOD"
      },
      "lemma": "impressive",
      "partOfSpeech": {
        "aspect": "ASPECT_UNKNOWN",
        "case": "CASE_UNKNOWN",
        "form": "FORM_UNKNOWN",
        "gender": "GENDER_UNKNOWN",
        "mood": "MOOD_UNKNOWN",
        "number": "NUMBER_UNKNOWN",
        "person": "PERSON_UNKNOWN",
        "proper": "PROPER_UNKNOWN",
        "reciprocity": "RECIPROCITY_UNKNOWN",
        "tag": "ADJ",
        "tense": "TENSE_UNKNOWN",
        "voice": "VOICE_UNKNOWN"
      },
      "text": {
        "beginOffset": 102,
        "content": "impressive"
      }
    },

センテンスがキリのいいところで区切られます。 改行が \u になってしまうので、そのまま使うわけにはいかないので、ちょっと工夫が必要なようです。

単語も拾えます。 特に "tag": "ADJ", "content": "impressive" という情報はいろいろ流用できそうです。

We're hiring!

レアジョブは右肩上がりで成長している英会話事業会社です。 その中でも、完全自社コンテンツを持っているのは強みの一つで、 例えば今回の自動解析、自動分類によって、単語アプリを新しく世に出す事も選択肢になるでしょう。 我々は全方位で仲間を募集しています。 https://appeal.rarejob.co.jp/recruit/

興味ある人がいましたら、ぜひ一緒にランチでも食べながら「こんなことできそうだよね」って話しができたら嬉しいです。

nscdでDNS問い合わせを減らす

DevOps チームの うすい と申します。

標題の通り、減らしていきます。

nscdでDNS問い合わせを減らす

当社のレアジョブ英会話の主要なサーバは AWS 上にあるのですが、AWS では このような 制限が存在し、ある程度のアクセスに達すると DNS の問い合わせに失敗してしまいます。 実際にレアジョブ英会話でもレッスンが多い時間帯において、データベース接続エラーが発生しました。

そこで、DNS への問い合わせ件数を減らすために問い合わせ結果を各サーバ内でキャッシュすることとしました。

下記の記事も参考にしてください。

aws.amazon.com

上記記事では dnsmasq を使用していますが、今回は nscd を使いたいと思います。

インストール後、設定ファイルを変更して起動するだけとなります。 設定ファイルの例です。

#
# /etc/nscd.conf
#
# An example Name Service Cache config file.  This file is needed by nscd.
#
# Legal entries are:
#
#   logfile         <file>
#   debug-level     <level>
#   threads         <initial #threads to use>
#   max-threads     <maximum #threads to use>
#   server-user     <user to run server as instead of root>
#   server-user is ignored if nscd is started with -S parameters
#   stat-user       <user who is allowed to request statistics>
#   reload-count    unlimited|<number>
#   paranoia        <yes|no>
#   restart-interval    <time in seconds>
#
#   enable-cache        <service> <yes|no>
#   positive-time-to-live   <service> <time in seconds>
#   negative-time-to-live   <service> <time in seconds>
#   suggested-size      <service> <prime number>
#   check-files     <service> <yes|no>
#   persistent      <service> <yes|no>
#   shared          <service> <yes|no>
#   max-db-size     <service> <number bytes>
#   auto-propagate      <service> <yes|no>
#
# Currently supported cache names (services): passwd, group, hosts, services
#


#   logfile         /var/log/nscd.log
#   threads         4
#   max-threads     32
    server-user     nscd
#   stat-user       somebody
    debug-level     0
#   reload-count        5
    paranoia        yes
    restart-interval    60

    enable-cache        passwd      yes
    positive-time-to-live   passwd      600
    negative-time-to-live   passwd      20
    suggested-size      passwd      211
    check-files     passwd      yes
    persistent      passwd      yes
    shared          passwd      yes
    max-db-size     passwd      33554432
    auto-propagate      passwd      yes

    enable-cache        group       yes
    positive-time-to-live   group       3600
    negative-time-to-live   group       60
    suggested-size      group       211
    check-files     group       yes
    persistent      group       yes
    shared          group       yes
    max-db-size     group       33554432
    auto-propagate      group       yes

    enable-cache        hosts       yes
    positive-time-to-live   hosts       3600
    negative-time-to-live   hosts       20
    suggested-size      hosts       211
    check-files     hosts       yes
    persistent      hosts       yes
    shared          hosts       yes
    max-db-size     hosts       33554432

    enable-cache        services    yes
    positive-time-to-live   services    28800
    negative-time-to-live   services    20
    suggested-size      services    211
    check-files     services    yes
    persistent      services    yes
    shared          services    yes
    max-db-size     services    33554432

    enable-cache        netgroup    no
    positive-time-to-live   netgroup    28800
    negative-time-to-live   netgroup    20
    suggested-size      netgroup    211
    check-files     netgroup    yes
    persistent      netgroup    yes
    shared          netgroup    yes
    max-db-size     netgroup    33554432

定期的に nscd 自身には再起動してもらいたいので、paranoiayesにしてrestart-intervalを設定しています。 netgroup は使用していないのでenable-cachenoにしています。/etc/netgroupを nscd が見に行ってエラー吐いちゃいますので。 あと nscd が再起動されるとその度にログが吐かれるので、/var/log/messages 的なのがまぁまぁ増えますのでご注意ください。 また、AWS を使用しているとあるあるだと思いますが、各 Endpoint の後ろにいるインスタンスなりは AWS 側のタイミングで切り替わるので、再起動の間隔やキャッシュ保持時間などは調整する必要があるかと思います。

結果

tcpdump dst port 53 などしてみた結果です。

nscd 有効

tcpdump: listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
3624 packets captured
3636 packets received by filter

無効

tcpdump: listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
10444 packets captured
10449 packets received by filter
減らせました。

レアジョブ英会話は PHP で動いており、ABI が変更されたときに出るようなgetaddrinfo failedの発生にびっくりしたのですが、今回の設定で落ち着いた次第です。

見やすいページを簡単に作る

どうも!デザイナーの渡辺です!

最近エンジニアさんたちと同じ部署に配属されました!

これからたまに出てくると思います!
よろしくお願いしますヽ(=´▽`=)ノ



さてさて、せっかくデザイナーとエンジニアが一緒の部署になったということで、
デザイナーの知識を皆さんにお届けできればなと思います!
なので今回は誰でも簡単にできる、
見やすいページを作る小技をご紹介いたします。パチパチ

やることは簡単! 分ける・空ける・揃える

これだけですね(゚∀゚)
といってもなにをすればいいのって話ですよね!

それでは1つ1つ説明していきます!
(っ’-‘)╮ =͟͟͞͞ 【分ける・空ける・揃える】 ブォン

今回はこちらの情報をもとに説明していきます! f:id:yui_1027:20191024113611p:plain

分ける 大カテゴリ、中カテゴリ、タイトル、テキスト、イメージなど早い話が仕分けですね!
一体それがどんな役割を果たすのか明確にします!

空ける 余白を入れてグループとグループの間を空けます これだけでだいぶ見やすくなりました!

揃える 分けた要素はグループごとに同じ見た目に、
空けた余白は類似のもので同じサイズに揃える!
たったこれだけで断然見やすく情報を伝えられるページになります!

実はこれは小技というよりは、デザインの基本ですね!

逆を言えば、こういう部分に着目するだけで
そのページをデザイナーが作ったかそうでないかがわかります!

「あ、揃えるとこ揃えてない。これデザイナーじゃないな。フム」

こんな具合です |ω・)ミテマスヨ

ページを作るときは、騙されたと思って

分ける・空ける・揃える

を合言葉にぜひ作成してみてください!

それだけであら不思議!見やすいページの出来上がりヽ(=´▽`=)ノ
パワポなどでの資料作成でも使えると思います!

なんだこんな簡単なら、デザイナーもいけるんじゃね?ってなります!
これが簡単そうで意外と出来ないものなんですよ( ・´ー・`)ドヤ

しかしそれが出来たらあなたはもうデザイナー!
ようこそこちらの世界へ!(∩´∀`)∩ワーイ

「そんなの知ってるよ!当たり前じゃないか!」

そう思ったそこのデザイナーさん! 我々はデザイナーを募集しております!ヨッ

www.wantedly.com

見やすいページを作る合言葉は

分ける・空ける・揃える

覚えてくださいねー!
 それでは ノシ

レッスンルームのチャットUIを MessageKit に差し替えたときのツラミとレガシーコードとの向かい方

お疲れさまです。 APP/UI チームの玉置です。

最近のマイブームは鬼滅の刃(きめつのやいば)です。
ツイッターのタイムラインで鬼滅の刃のワンシーンを見てしまい「おっ、刀がメインのアニメか!」と思ってNetflix で動画を見始めたのがきっかけです。
当時の動画のワンシーンは登場キャラの善逸くんが雷の呼吸「雷の呼吸 壱の型 霹靂一閃」を解き放って敵キャラを瞬殺したシーンです。
善逸くんのキャラが「るろうに剣心」の十本刀の「宗次郎」にとても似ていてそのシーンだけで気に入ってしまいました。
(* 善逸くんは宗次郎のキャラとは全然違います)

そんなこんなで動画を見つけた日は善逸くんの上記のシーンまでの動画を徹夜で観ていました。

さて、そんな話しは置いとくとして今日は先月ずっと行っていた
レッスンルームのチャットのデザインで使っていたライブラリのリプレイス作業をずっと行っていました。
そして、やっと今月リリースできそうなのでその当時に色々思うことがありましたので文章化してみました。

リプレイスする前に使っていたライブラリについて

リプレイス前に使っていたライブラリは「JSQMessagesViewController」という名称のものです。

github.com

2016年頃まではチャットアプリでごく一般的に使われていた有名なライブラリです。
こちらのライブラリですが2016年に大体の開発が終了してしまって2017年1月で完全に開発がストップしてしまいました。

f:id:qed805:20190929184418p:plain
github_commit_log

現在は非推奨となっています。
レアジョブアプリはライブラリ管理でcocoapodsを採用しているため、ターミナルでpod installをした際にこのライブラリが非推奨というワーニングが表示されます。

f:id:qed805:20191014183045p:plain
depricated_JSQMessagesViewController

今はチャットライブラリで有名なものとして「MessageKit」というOSSがあります。
チャットアプリを開発する場合は自作するかこちらのライブラリを使うことが一般的になっています。

github.com

今回はこの「JSQMessagesViewController」からの脱却をメインに書いていきます。

リプレイスするきっかけと足枷になったこと

本当はすぐにでもJSQMessagesViewControllerを脱却したい気持ちがありました。

その理由を挙げるだけでも

  • 2017 年から公式が非推奨
  • 公式からのサポートが得られない
  • 事業的にリファクタリングよりも新規機能の開発が優先
  • リファクタリングのコストを支払っても利益が出ないため報われない
  • リプレイスにかかるコスト(工数見積が定かではない)
  • iOSのライブラリ管理ツールである「CocoaPod」からdepricatedというワーニングが表示

などの要因がありました。
また、当社にはカスタマーサポートの部署があり(以下、CSと省略します)、CSよりユーザー様から
「講師側から長い文章が送信されると最後の1行が途切れている」という問い合わせを受けていました。

f:id:qed805:20191014184124p:plain
最後の1行のメッセージの空白

この問題に対して臨時対応を5月頃に実施して解消されているはずでしたが今年8月にも別のユーザー様から同じような問い合わせを受けてしまいました。

そのため使っていただいているユーザー様のためにもできるだけ早くこの問題の根本原因を解消しなければならないと思い、
チームのタスク的にも8月までに必要なタスクを終えて9月は1ヶ月丸々リファクタリング期間を頂いたのでこれを機会にチャットUIライブラリを差し替える業務に本格的に着手することにしました。

リプレイスする上でのツラミ

実際にライブラリのリプレイスをすると決意してからが大変です。
今回のライブラリは「レッスンルーム」に直接影響を与える箇所ですのでデグレに気をつけなければなりません。
その他、個人的に感じたリプレイスする上でのツラミは

  1. 開発メンバーに申し訳ない感
  2. iOSのキーボードが意図通りに表示してくれない
  3. 差し替えたあとにiPad横画面でデグレが起きる

という三点でした。

それぞれ解説していきます。

開発メンバーに申し訳ない感

こちらはリプレイス云々とは関係ありませんが事前に工数見積をしていても全てが事前に見積もれる訳ではありません。
特に今回のようなレアジョブアプリのメイン機能である「チャット」のデザインだと寧ろデザイン崩れやデグレが発生している方が問題になります。
つまり既存仕様を全て正確に新しいライブラリで再現する必要がでてきます。
ただしどうしても新しいライブラリで「再現できない機能」はチームメンバーやプロダクトオーナーに相談して捨てることは可能だと思っています。

デグレ」と「捨てて良い機能」の定義はタスクや機能によって違いますが、
今回の定義では「事前に把握しているかどうか」です。

それはそうとして話しを戻しますが
今回のような見え方や挙動がだいたい同じデザインだと、作業中も私の中ではタスク全体として「達成感」はあまり感じられませんでした。
着手前と着手後で表向きとしては成果物が「同じ」ですので事業にインパクトを直接与える作業ではないのであまり楽しくなかったんですよね。

なので自分が楽しくないことにひたすら挑戦していたので(おまけに事業の売上に貢献していないことも含めて)
メンバーにその感覚が伝わってそうでリプレイス中はずっとメンバーに申し訳ない気持ちで一杯でした。

このツラさを解消できるKPTでいうところ、「Try」があればいいなと思いました。
そのためチーム全体が楽しくレガシーコードと向き合える方法があればリファクタリングが楽しいものになるんだろうなと思いました。

  1. iOSのキーボードが意図通りに表示してくれない

後述する内容ですがリプレイス先の「MessageKit」のInputBarAccessoryViewがうまく意図通りに動いてくれなかったため、全ての挙動を既存仕様に合わせることが難しかったです。
特にキーボードの表示・非表示の制御がiPhoneiPadに関わらず大変で着手中ずっとキーボードの制御に苦しめられました。
レアジョブアプリではチャットのviewがメインのViewControllerにCotainerとして乗っている設計でchildViewControllerになっています。

(main) RoomViewController > MenuViewController > ChatViewController (child)

という設計になっています。

この場合は ChatViewController で MessageKit のInputBarAccessoryViewを表示しようとすると初期表示時にInputBarAccessoryViewが画面外に隠れてしまう現象が起きます。

f:id:qed805:20191014193557p:plain
InputBarAccessoryViewが画面下にあるので表示されない

このような問題にも対応しなければなりませんでした。

念の為、この問題を解消するのに参考になったページを張っておきます。

github.com

github.com

  1. 差し替えたあとにiPad横画面でデグレが起きる

最後のツラミとして、今年5月頃に私が開発したものですがiPadのレッスンルームを横画面にも対応したのですが、MessageKitがそのあたりもいい感じに補正してくれると期待していたところ見事にそれを裏切ってくれました。

iPhoneでだいたい既存の同じ挙動になることを確認してからデグレ起きなかったらいいなと淡い期待を持っていましたが、

単純にJSQMessagesViewControllerからMessageKitに差し替えてもiPadを横画面にすると既存と全く同じ挙動にならなかったのです。
ライブラリリプレイスの本実装の調査前の段階である程度工数見積をしましたが、
iPad横画面ではその当時確認していませんでした。できなかったこともありますが。
そのため実際にこれを改修する前にデザインが崩れてしまう現象のパターンを洗い出して再度工数見積を行いました。

着手前に見積もっていた工数も残りわずかというか使い切ってしまいましたので、
恐怖に思いながらiPad横画面でのデグレ箇所の工数見積をしていました。

想定外のデグレ工数はメンタルに良くないですね。

実際のリプレイス作業

ということで長々と書いてしまいましたが、ここで実際にライブラリをリプレイスしたときに行った手順を復習します。

ライブラリ自体の調査と挙動の調査 (工数見積まで)

  • アプリの既存の動きの調査
  • MessagesKit自体のデザインの調査
  • MessagesKitがどこまで柔軟に対応できるか
  • 試しimport でどれだけのデグレが発生しているか

実際にライブラリをimportする (実際に着手開始)

  • MessageInputBar が使えず、InputBarAccessoryViewが必要
  • どのバージョンのInputBarAccessoryViewを使えばいいのか情報が少ないのでその調査を行う

そのためcocoapodのPodfileは下記のようにInputBarAccessoryViewをimportしました。

  pod 'MessageKit'
  pod 'InputBarAccessoryView', '4.2.2'

ハマリポイントの改修 (想定外の対応)

  • ChildViewControllerでは初期表示時にInputBarAccessoryViewが表示されない
  • レッスンルームを一つのViewController で管理できるかの調査 (既存設計を大きく変える方法の調査)
  • メインのViewController で becomeResponder()を読んでinputBarを意図的に表示させたときの調査 (既存設計を踏襲する場合の調査)
  • iPad横画面でのデグレの対応

上記のような流れになりました。

レガシーコードと向き合った感想と気をつけるべきこと

今回はレガシーコードではなくライブラリのリプレイス作業について解説してみました。
新規事業だとガンガン突き進めて事業にもインパクトを与えられますがレガシーなものを新しいものに書き換えるようなリプレイス作業は見た目が変わらないので作業していてもなかなか辛い部分がありました。

ですがレガシーコードは綺麗にせずにそのままにしておくと将来の負債となったりメンテナンスできなくなって「ゼロから作り直し」になったりする非常にセンシティブな部分でもあったりします。
現場によってはプロジェクトのソースコードを「1から作り直し」になってしまった所もあるのではないでしょうか。
モバイルアプリは最初の1,2年は開発していてとても楽しいですがさらに長く運用していると様々な要因で昔のレガシーコードが影響して開発スピードが著しく遅くなってしまう傾向がありますね。

またAppleGoogleSDKが年々新しくなって昔のソースコードがいきなり非推奨になったりします。
なので、時間がある時にできる限りソースコードを綺麗にして保守性を上げる開発体制が一番安全かなと思いました。

今回のチャットUIを新しくしたことでレアジョブアプリを使って頂いているユーザー様により快適にレッスンルームをご利用頂けると思うと開発者として報われる気持ちになりますね。

ということで長文になりましたがぜひレッスンルームを使って頂ければと思います。

10月25日「Global Engineer Night vol.1 Mercari x Quora x RareJobが考えるグローバルエンジニアの条件とは?」を開催します !!

こんにちは、レアジョブ 技術本部副部長 の @jumboOrNot です。

f:id:rj_tech_dept:20191017104430p:plain

10月25日「Global Engineer Night vol.1 Mercari x Quora x RareJobが考えるグローバルエンジニアの条件とは?」を開催します !!

Global Engineer Night vol.1とは

グローバル化の波は押し寄せており、日本と世界との垣根はどんどん下がる中、エンジニアにも国内外で活躍する場が増えています。Global Engineer Night (GEN)では、「日本でも海外でも垣根なく活躍できるエンジニアには、どのようなスキルセットが備わっているのか?」をテーマに、業界著名人をゲスト講師として招き、パネルディスカッションや交流会を開催します。

10月25日イベント概要

日時:2019年10月25日(金)19:00〜22:00 場所:東京都港区六本木6-10-1六本木ヒルズ森タワー18F 人数:60名(増枠しました!) 参加費:無料 詳細・お申込はconnpassのイベントページより。

どんなイベント?

日本と海外で要求されるスキルに違いはあるか? 英語の壁をどうやって乗り越えるか? エンジニアが世界で戦うためにはどんな準備が必要か?

などなど、普段なかなか聞けない本当にグローバルで活躍するために必要なことや、悩みをパネルセッションで聞くことができます。 今回は 広木さんをモデレーターにお迎えして、グローバルに活躍するMercari x Quora x RareJobの三社がいろいろな質問にお答えします。 当日は弊社エンジニアもスタッフとして参加したりしているので、懇親会でも是非お話しさせていただければと思います。

開催に向けて

グローバルキャリアってなんなんだ!そんなことを考えながら日々生きている私ですが、「海外で働く」「海外の人と働く」「海外向けのサービスを作る」等どんな形でも必要なのは英語力、、、だけじゃなくていろいろなスキルやマインドセットが必要だと私自身グローバルな企業で働きながら感じています。 うまく言語化できないこのハラハラやワクワク感みたいないろいろな感情をすごい勢いで乗り越えてきたであろう豪華パネリストの皆様から聞けるのは一参加者としてもとても楽しみです。

お待ちしております!

gen.connpass.com

デザインチームの運用をワークショップ形式で洗い出してみた

関東に台風が向かっております。 そのためコロッケを急いで買いに行かないといけないのですが、当番なので急いで書きます。

技術本部の副部長兼、デザインチームのリーダーのジャンボです。

皆さんは普段からの運用・作業の改善作業をどうやって洗い出しますか? 思いついても優先順位や難易度が読めずに結局着手できなくなっていませんか?

そんな時にオススメのやり方があります。

  1. ふせんかstormboardを用意する
  2. カテゴリ別に課題を洗い出す
  3. みんなで相談しながら優先度・効果のマトリクスで整理する

です。

早速ですが今回デザインチームでやってみた結果が以下です。(ちょっとぼかしてます)

f:id:jumbos5:20191011162100p:plain

赤ピンが上期で解決したものです。

エンジニアとの責務の分割や、サービスに対するUXに対するガイドラインなど解決が時間がかかりそうなものが右上に寄っています。一方でなんとなくルールはないけど、やったほうがいい・決めたほうがいいものなどは比較的すぐ実行でき効果が高いことがわかったので右下に整理されました。

最初は基準となるようなタスクを配置して、そのタスクとの相対的な位置をイメージして進めていくと進めやすいです。 これを作り右下から進めていくことで、チーム内での課題と優先度、そして効果のすり合わせをしながら良きデザインチームになっていければと思います。

www.wantedly.com

こういったプロセスをもっとよくしたい、もっと改善したい人を弊社では絶賛募集中です。

それではベランダのハーブが心配なので定時ダッシュでドロンします。 皆さんもplease keep safe.

EC2 Auto Scalingを導入する際のポイント

f:id:shino8383:20191004131442p:plain

おはようございます。レアジョブDevOpsチームのshinoです。

 

世間では消費税増税だとか軽減税率だとか話題になっています。

特に軽減税率は複雑ですよね。

私は考えることをやめました。 

 

さて、私は普段AWS上でレアジョブのシステム基盤に関わる業務を行っています。

AWSに移行した話

appeal.rarejob.co.jp

 

現在は、運用コストの削減、信頼性の向上、パフォーマンス効率の向上などの改善を主に行っています。

AWS上でアーキテクチャの設計や運用を考える際には、どのような点に気をつける必要があるのでしょうか?(突然の問題提起)

AWS上での設計や運用に関するベストプラクティスをまとめたAWS Well-Architected Frameworkなるものもありますが、こちらは非常に概念概念していて

「具体的にどうすれば?」

となる方も多いと思います。僕はなります。

 

今回はAWS上でのパフォーマンス効率化、特にEC2 Auto Scalingを導入する際にポイントとなることを言語化したいと思います。

 

 

EC2 Auto Scalingとは

Doc: EC2 Auto Scaling

端的に言えば

 

EC2インスタンス

リソースの使用状況に合わせて

自動で水平スケールする

 

サービスです。 

f:id:shino8383:20191004110903p:plain

他にも手動でのスケールやスケジュールベースのスケールもできますが、Auto Scalingを使う一番の恩恵は需要に合わせて自動スケールする機能だと思います。

 

すごく素敵なサービスに思えますが、無条件でAuto Scalingを導入できるわけではありません。

EC2 Auto Scalingを導入するためにポイントとなるアーキテクチャ設計があります。

 

EC2 Auto Scailing導入のポイント

既存のEC2クラスターにAuto Scalingを導入する際に気をつけることが大きく2つあります。

 

  1. インスタンス間の差異を無くす
  2. クラスターごとにエンドポイントを設ける

インスタンス間の差異を無くす

どういうことかというと

f:id:shino8383:20191004111738p:plain

 

AとBで設定に差があったらだめ、ということです。

・・・当たり前といえば当たり前なんですが。

 

例えばAはスレーブDB1を、BはスレーブDB2を直接参照しているような設定になっているとAuto Scalingできません。

自動で起動終了されるインスタンスは同じAMIから作られるので、同じクラスター内の既存のインスタンス間で差異がある場合は、差異がなくてもアプリケーションとして正常になるように改善する必要があります。

逆に言えば、アプリケーションの動作に関係ないcronが特定のインスタンスで動いていてそのインスタンスは消したくない、などという状況であればインスタンス間の差異があってもAuto Scalingの導入はできます。

その場合は、インスタンス保護を用いたり、Auto Scalingのインスタンス終了設定の「新しいものから消す」という設定と、最低起動台数の設定を組み合わせることで、既存のインスタンスを終了させずに保つことができます。

 

スケーラビリティを獲得するためにインスタンスをステートレスにしましょう。

 

クラスターごとにエンドポイントを設ける

ELBを使ってクラスターを形成していたらエンドポイントが既にあるはずなので、これも当たり前のように思えます。

ここで大事なのは、スケーラビリティを獲得するために意識的にエンドポイントを作る必要があるということです。

 

f:id:shino8383:20191004120724p:plain

 

 

例えば、APIがスレーブDBを参照する場合を考えます。

この場合、スレーブDBのエンドポイントを設けていれば全てのAPIインスタンスはそのエンドポイントを参照すればいいので、APIインスタンス間で設定に差異は生まれません。

しかし、エンドポイントを設けていない場合、特定のDBインスタンスを参照することになります。

APIインスタンスごとに特定のスレーブDBを指定するような設定を行えば、APIインスタンス間に差異が生まれ、Auto Scalingを適用することができなくなります。

 

また、一般的に、エンドポイントという抽象的なものに比べて、特定のDBインスタンスという具体的なものの方が変更の影響を受けやすいです。

つまり、変更される可能性が高いものに依存するということは、それだけ依存する側も変更を加える必要があります。

スレーブDBの台数を増やす場合などを考えると運用コスト的にもつらいことが想像できると思います。

 

Auto Scalingを用いることでインスタンスが勝手に増えて勝手に減るので、その変化の影響を受けない疎結合な依存関係を作る必要があるということです。

 

クラスター間の依存関係を作る際は、より抽象的なもの=エンドポイントに依存させることで、ステートレスな変更容易性を獲得し、疎結合アーキテクチャを実現させましょう。

 

あとがき

今回はEC2 Auto Scalingの導入に関して、アーキテクチャに必要なことをざっくり言語化しました。

導入する際は、どのAMIを使うか、どんなメトリクスをどんな閾値でトリガーとするかなどまだ考えなければいけないことはありますが、それはまたの機会に。

 

我々はこれからもAWS上での設計・運用のベストプラクティスを目指して邁進して参ります。

そんなチャレンジを一緒にして頂ける仲間を募集しております!

こちらからどうぞ

採用/求人情報 | アピール | 未来の教育を作る人のマガジン インフラエンジニア(AWS)