サウナで分析基盤を構築し、漁業のサステナビリティを向上させる取り組みを考えた話

こんにちは、株式会社ライトハウスでエンジニアをしている平塚です。

今回はサウナで分析基盤を作った話を致します。

なぜサウナなのか

休憩時間に本気のリフレッシュできるからです。

逆に長時間働き過ぎると眠くなってくるので(個人の主観)夢中になってやりすぎ防止出来る面は 良いかなと思っています。

分析基盤を作成した場所

今回利用させて頂きました施設は両国湯屋江戸遊 です。

両国の江戸遊を選択した理由は複数あるのですが、以下の通りです。

会議室の利用

会議室は当日に伺うと埋まっている事が多いです、 事前予約が可能なので予約することをお勧めします。

サウナの種類

男湯には以下2種類のサウナが用意されています。

水風呂は1つあり、18度くらいに設定されています。

若干ぬるめかと思ったのですが、サウナの温度設定が良いのか 水質が良いのか分かりませんが水風呂がすごく気持ちよかったと感じました。

分析基盤とは

世の中ではデータの収集、蓄積、分析、可視化などの機能を有したものであるなど、色々ありますが ライトハウスでもそれら4つの機能を実現できる基盤を構築しています。

収集: Airflowを使用してISANAを利用したユーザのデータ(個人情報はマスクしています)や利用状況などの集計。

蓄積: Google BigQueryに保存。

分析:Redash Queryの利用。

可視化: Redash Dashboardの利用。

RedashのDashboard全社員が共通の指標を追うことができる状況を目指しています。

なぜEKSを利用したのか

AWSを選択する理由

AWS(S3やRDS)に大量のデータが存在するため、以下の理由から他のクラウドサービスではなくAWSを利用する選択をしました。

  • VPC内実行による通信コストの削減
  • VPC内実行による通信速度の向上
  • AWS利用実績

EKSを選択する理由

正直機能だけを考慮すればEC2やECSなどで十分ですが、 選択した理由は以下の通りです。

  • ただただKubernetesを触りたいという欲望
  • どれを使っても基盤部分は2,3時間で環境作れる気がする
  • BigQueryを利用しているのでいつでもGKEに移行できること

アーキテクチャの説明

KubernetesにRedashとAirflowを稼働させ、各種データソースから取得したデータを Bigqueryに保存し、Redashで分析します。

Redashを使用する理由

BIツールとして利用実績が十分あること。

私自身もコントリビュートしているためある程度バグが存在しても修正でき、 独自機能を追加することも十分可能であると考えたからです。

Redashの構築説明

redashの構築はコード付きで解説すると長くなるのでサンプルコードを作成しました。 ログインにはgoogle oauthを利用する想定で記載しています。

https://github.com/jasonsmithj/eks-redash

詳細な解説については次回以降で行います。

Airflowを使用する理由

ライトハウスに携わる以前はDigdagとEmbulkを利用していました。 今回Airflowの採用に踏み切った理由は以下の通りです。

  • Pythonを利用して自由度の高い処理の実装が容易である
  • GCPのマネージドサービスであるCloud Composerの実績が増えてきている
  • 今まで触っていなかった技術に触れたかった

Airflowの構築説明

redashの構築はコード付きで解説すると長くなるのでサンプルコードを作成しました。 ログインにはgoogle oauthを利用する想定で記載しています。

https://github.com/jasonsmithj/eks-airflow

詳細な解説については次回以降で行おうといます。

今後の展望

漁業という独特なドメインに対してIoTを利用しているため、 他の会社には無いようなデータが数十億レコード存在するので 様々な観点で分析する計画を進めています。

また、現在は取得できていませんが、外部データ(気象情報、海底地形、漁協の水揚げ)も取得し 漁業者だけでなく流通や水産資源保護などのトレーサビリティ、サステナビリティの観点でも分析を進めていきます。

まとめ

初めて扱う技術ではハマる事が多く、 合間にサウナを利用する事でリフレッシュできるため、 体感でtypoなどの単純なミスに気付くのが早くなりました。

また、ライトハウスでは漁業者に直接お会いするなど、 出張先のサウナで作業をする機会が多く九州や関西地域のサウナについても 紹介させて頂きますのでサウナ好きの方は楽しみにしてもらえると嬉しいです。

漁師に出会ったエンジニアがDynamoDBで困った話

こんにちは、ライトハウスの開発をしている熊谷です。

今回、ライトハウスのエンジニアはコード書くだけが仕事ではないということをお伝えしたいと思い、ブログを書きました。

それは、新しい機能やサービスについて考えることです。

開発に限らず社員全員がサービス改善の提案と実行をおこない、 希望をすればエンジニアも顧客に会い、直接ユーザの声を聞くことができます。

このような環境で私の体現した印象深い事例をお伝えします。

大阪ミートアップ

関西エリアの多くの漁師さんに集まっていただきました。 f:id:LighthouseInc:20200629121036j:plain

ご出席いただいた漁師さんには、以下のようなご意見を頂きました。

「漁労機器の一部として無くてはならない存在になりつつある」
「これからも、もっといいサービスを作る会社だと期待している」

ISANAを必要と感じ我々に期待をして下さっていると強く感じ、 自信を持って提供して行きたいと思うと共に、期待を裏切らないよう努力し続けて行きたいと感じることが出来ました。

また、ISANAを利用しているユーザはどのように利用しているのか、どのようなモノが理想なのか意見交換を行い、 漁法や地域によって課題が異なるとご意見を頂き、詳細を確認させて頂きながら現在改善を行っています。

顧客対応への同行

設計中の機能が必要とされているか確認したいという思いがあり、既存顧客のデバイスの不具合対応に3船団同行しました。

不具合対応で伺ったのであまり良い反応をされないだろうと思っていたのですが、実際には「わざわざ来てくれてありがとう」と言って頂き嬉しさと同時に、ご不便おかけして申し訳ない気持ちでいっぱいでした。 漁師の方々は本当にみんな優しいなと感じることができました。

また、不具合対応後に船団の方々をお話をさせて頂き、「いい魚探の反応や反応によっての魚種の判定を写真撮って若手の教育に使う」など若手の教育にISANAを利用していると伺い、これは力になれると確信しました。

地域の異なるいくつかの船団の方々のお話を伺い、改めてISANAは漁労機器の一つとして利用されているケースが多く、海上以外で利用されることがまだ少ないと感じ、 漁労機器を越えその先の世界観を実現させていきたいと考えている我々としては、それを実現するための一つの機能として漁獲記録を3月にリリースしました。

漁獲記録

漁獲記録という機能は手書きでノートに残していた漁獲高をアプリで管理するようにしたモノです。
「いろんな条件で、魚のいるポイントは違ったりするけど過去どこで/何を/どれくらい取ったか見たいな」という声を活かすことができました。
こちらの機能を使って過去の漁のデータを見ることで若い漁師さん成長に役立つことができます。

f:id:LighthouseInc:20200629121119j:plain ※機能の一部の画像です。検証用のデータで顧客のデータではありません。

まだ構想段階でしかないですが、サスティナビリティーやトレーサビリティーで活用していくこともできるんじゃないか。 結果的に魚価が上がって漁師さんに貢献できるのではないかと考えています。 この機能が評価頂き、水産業に関わる国内外のさまざまなプレイヤーが集まる、東京サステナブル・シーフード・シンポジウム2019でサステナブルシーフードアワードを受賞しました。 f:id:LighthouseInc:20200629121147j:plain

DynamoDBで一度に大量のデータが取得できない

漁獲記録を開発する時に、ハマったポイントがあります。

取得するデータというのは3秒に一回、魚探/ソナー/船上カメラ/位置情報のデータをそれぞれDynamoDBに保存しています。
そのデータをApp API(Rails)で取得してタブレットで表示してます。
検証環境でテストを行っていたところ取得したデータが一部取れていない事が判明しました。

船の機器の映像を保存してタブレットで表示されるまでの、アーキテクチャ図です。 f:id:LighthouseInc:20200629121208p:plain

ドキュメント確認したところDynamoの一度に取得には制限があることが判明しました。

Queryの結果セットは、呼び出しあたり 1 MB に制限されます。

「一回でそんなにいっぱい取ってくるな」ということですね。

取得するデータ量を計算してみました。

  • 1件あたりのデータ:約1KB
  • 1時間あたりのデータ数:3600秒 / 3(3秒に一回のデータアップロード) = 1200レコード
  • 1時間あたりのデータ量:1200 x 1KB = 1.2MB

つまり一度に取得できる期間の限界は50分ということがわかりましたので、余裕を持ち、30分毎データを分けて取得するように変更しました。

dynamodb = Aws::DynamoDB::Client.new
dynamodb.query(
 table_name: TABLE_NAME,
 index_name: 'PartitionKey-Time-index',
 select: 'ALL_ATTRIBUTES',
 limit: limit,
 consistent_read: false,
 scan_index_forward: false,
 key_conditions: {
   PartitionKey: {
     attribute_value_list: [partition_key],
     comparison_operator: 'EQ'
   },
   Time: {
     attribute_value_list: [from, to],
     comparison_operator: 'BETWEEN'
   }
 }
)

fromとtoはリクエストパラメータで取得したいデータの起点と終点を指定します。こちらは30分以上の期間を指定した場合エラーが出るようにチェックしています。 この調査で半日以上使ってしまいましたが、予定通りスプリント内にリリースできました。

全員が設計に関わる

受託で開発する場合は仕様が決まっているものを作ることが多いですが、弊社はサービス設計から全員が関わることができます。自分たちで仮説を立てて、顧客対応する担当者がヒアリングをしたり、希望すれば実際に漁師さんにお会いして声を聞くことができます。自分の作ったサービスに自信を持って働ける素晴らしい環境だと思っています!

ISANAの開発について

 みなさんこんにちは、ライトハウスで開発に携わっている石川です。

 当社は、現在主に漁業のサポートを行うプロダクトであるISANA(「いさな」と読みます。)を漁師さんに使っていただいています。今回はそのISANAの開発についてざっくりと紹介したいと思います。

 ただ、技術的な話に入る前に、ISANAが対象としている漁法について簡単に触れさせてください。

 漁業といっても多種多様な漁法が存在しますが、ISANAは主に船びき網漁とまき網漁の漁師さんを対象としたプロダクトとなっています。

 そこで「船びき網漁」と「まき網漁」について簡単に説明いたします。

対象の漁法

船びき網漁とまき網漁は以下の図のとおり、複数の船によって漁が行われます。

船びき網漁(ばっち網漁):2隻の漁船で袋状になった網を曳いて魚を獲る漁法

https://www.maff.go.jp/j/tokei/census/img/funa_biki2.jpg

まき網漁:魚群を網で巻くように包囲して、網を絞り込んで獲る漁法

  • 探索船:魚群を発見する船
  • 網船:運搬船を起点としてぐるっと網で魚群を囲いこむ船
  • 運搬船:捕獲した魚を保存する船

https://www.maff.go.jp/j/tokei/census/img/makiami2.jpg

 こういった複数船隻で行われる漁の場合、これまでは無線を使って各船の魚探やソナーの情報を口頭で共有を行い、漁を行うポイントを決めていました。

 しかし、以下のような複雑な形状を持つ画像の情報を口頭で伝えるのは至難の技ですよね。

f:id:LighthouseInc:20200605145547p:plain

 そこで、ISANAを使ってタブレットで船の位置情報と画像の共有(画面共有機能)を行い、より効率的な漁を行おうという訳です。百聞は一見にしかずです。

 なお、ISANAには、上述した画面共有機能の他にも、その日の出港から帰港までどういったルートを辿ったかを閲覧する機能(操業ログ機能)、投網ごとに漁獲量を記録する機能(漁獲記録機能)などがありますが今回は割愛します。

ISANAのシステム構成

 それでは、ISANAがどのように使われるかが分かったと思うので、続いては、どのようなシステム構成でサービスの提供がなされているかを紹介したいと思います。

ISANAのシステムは、大まかに以下の二つに分けられます。

  • 船上のGPS位置情報や魚探・ソナー画像をアップロードする側
  • アップロードされた情報をタブレットから閲覧する側

構成図にすると、以下の通りです。

f:id:LighthouseInc:20200605152501p:plain

船上のGPS位置情報や魚探・ソナー画像をアップロードする

 ISANAをご利用いただいている漁師さんの船にはISANA専用デバイスが取り付けてあります。

 このISANAデバイスは、船から電源供給を得ておりスイッチを入れると、接続されている魚探やソナー、船上カメラ、GPSの各機器から位置情報や画像データを受け取り、それを専用のAPIに向けて一定間隔で送信しています。

 それを受けとったサーバーサイド側では、画像データはAPIからS3に直接保存し、位置情報(緯度、経度、時間、電波強度、補足しているGPS衛星数)などはDynamoDBに保存しています。

 ISANAデバイスは既に100船団以上に設置されていますが、同時に稼働している船が多い時間帯だと一隻あたり数秒間隔でリクエストがなされるので、多い時ですと8000リクエスト/分にもなります。

 そのため、負荷が高まった際にDynamoDBへPUTされるデータに欠落が生じないように、途中でKinesisを噛ませています。

 私がJOINした頃のISANA開発初期プロトタイプ版ではDynamoDBではなくMySQLにデータに大量の位置情報を保存していて、データが増えるにつれてRSDBSでは捌ききれず画面が全く更新されなくなっていたのを覚えています(笑

 現在もMySQL(Aurora)は使っていますが、数秒間隔で更新される位置情報などはDynamoDBへ保存し、その他のデータについてはMySQLに保存という使い分けを行っています。

 なお、現在のところISANAデバイスのプログラムはPython、Producer, ConsumerはGolangで動いています。

アップロードされた情報をタブレットから閲覧する

 漁中の漁師さんは、操舵室にタブレットを設置し、ISANAの画像共有画面で各船の情報を把握しながら漁を行います。

 タブレット上では、ISANAはAndroid アプリとして動いていて、アプリが情報を取得するために叩くAPIRailsで動いています。この辺はよくある構成だと思うので詳細は割愛します。

 なお、当初は、AngularのWebアプリでしたが、Map上に複数隻の大量の航跡を表示する際にサクサクと動かなくなってきたので、Android アプリに乗り換えたという経緯もあります。

ユーザーの声

 ISANAを使っていただいているユーザさんの声を動画としてまとめているのでよろしければご覧ください。

課題

 もちろんISANAにも課題はあります。

 船によっては、携帯基地局から電波が届く範囲外で漁を行うこともあり、そういった状況下においては、ISANAデバイスからのデータの送信やタブレットからアプリの閲覧することはどうしてもできなくなってしまいます。 画面共有機能の更新間隔は数秒に一回となっていて、もっと間隔を短くして欲しいといった要望もありますが、SIMカードの通信容量の制約やコストの側面などにより実現に至っていません。

総括

 ISANAは様々な課題を抱えていますが、今後もUIや機能の改善を行っていき、漁師さんにもっとご利用いただけるプロダクトを目指して行きたいと考えています。

 ISANAを設置したい場合はこちらのフォーム画面よりお問い合わせください。