漁師に出会ったエンジニアが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分以上の期間を指定した場合エラーが出るようにチェックしています。 この調査で半日以上使ってしまいましたが、予定通りスプリント内にリリースできました。

全員が設計に関わる

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