IoTプロジェクトでの技術的な反省点2017年

ITアーキテクトブログ
8 min readDec 30, 2017

--

フューチャーアーキテクト(裏) Advent Calendar 2017 の17日目です。

SI系、エンプラ系のエンジニアとして色々なおもしろい経験をさせてもらった2017年でしたが、今になって思えばもっとこうすればよかったという点もたくさんありました。特に技術的な面を振り返ります。

tl;dr

  • IoTでは、デバイス接続をいかにスムーズにして台数を増やすかが大事なので、デバイス側が楽になる側に倒すことが正義
  • オンプレ運用はやっぱり大変だ
  • クラウドのベストプラクティスは従わない理由がない

2017年にやったこと

IoTという文脈でやったことは主に2つでした。

  • 工場のデジタル化・コネクテッド化を推進する、いわゆるIndustorial IoT(IIoT)
  • 物流などでトラックにセンサーをつけて分析する、いわゆるモビリティIoT

特にIIoTは昨年からカウントして約1年間やっており、基礎的な機能群はとっくに保守運用フェーズに入っているのでこちらを中心に振り返ります。

採用技術・構成について

  • 工場内の制御はPLC(Programmable Logic Controller)と呼ばれるもので行っていることが多く、データ抽出はGOT(Graphic Operation Terminal)と呼ばれるHMI(Human Machine Interface)に付属しているEthernetアダプター&FTP機能でデータを転送
  • 大量に発生するセンサーデータを捌くため、工場内のオンプレ側にエッジサーバと名付けたIAサーバを冗長構成で配備、クラウド側とのゲートウェイに
  • クラウド側はRESTのAPI on ECS → Apache Kafka → Spark Streaming on EMR → HBase on EMRという流れでデータ投入

実際には、加工データの可視化分析だけではなく、ちょっとしたPLC制御までクラウド経由でエッジサーバで行っています。また、Redashで可視化していたり、一部のデータはfluentdで吸い上げたり、Embulkでバッチ加工していたりと、様々なデータパイプラインもありますが、今回の反省ポイントにはあまり関係しないため省略します。

IIoTシステム概要図

アーキテクチャについて反省

IIoTシステムの事例は全く公開されているものがなく、ベストプラクティスに乗っかれなかったため、手探りながら多くの技術的判断をしました。腕の見せ所で面白いところでもありますが、未だにその判断に迷うところもであります。

HMI・IAサーバ領域

(a)HMIからIAサーバへのデータ接続は、HMIからのプッシュ方式ではなく、IAサーバからのPull方式の方が良かった(かも)

  • (背景)数百~千ほどの接続が発生するとのことで、IAサーバの責務を小さくするため、HMIからセンサデータをプッシュしてもらうことにしています
  • (反省)この判断は判断で間違っていなかったですが、製造機器のHMIの設定は、AnsibleやChefのようなプロビジョニングツールどころか、Shellでの自動化ができません。そもそもOSはLinuxではなく、リレー回路によるシーケンス制御をそのままマイコンに移植したような存在で、開発は独自のGUIクラインとツール経由で行います。そのためオープン系で好きにやれるプラットフォーム側と異なり、時間が非常にかかるため、エッジはもっと多くの仕事を行っても良かったかもしれません。

…わたしはそこまでPLCについて熟知していないので、間違っていそうでしたらコメントいただければ助かります。

(b)エッジ処理を行いたいため、工場内(要はオンプレミス環境に)IAサーバを立てたこと

  • (背景)接続されるデバイス(正確には設備や器具)が数百~千に及ぶかもしれないということで、ある程度のスペックと信頼性を持たせるたに、IAサーバを2台冗長でも準備しました
  • (反省)IAサーバじゃなくて、Raspberry PieやBeagleBoardといったライトなIoTプラットフォームゲートウェイにチャレンジすればと思っています。IAサーバも良いんですが、やはり故障時のメンテが面倒です。OSのセキュリティパッチアップデートのためにVuls入れますか?と言われると流石に方向性が違うので辛いです。ラズパイだからメンテナンスしなくてよいというわけではなく、例えば常に3,4台と多めに稼働させておき、もっとライトに稼働・停止させたりUpdateできると楽ですね。クラウドでのサーバ使い捨てと同じ運用思想で通せると嬉しかったです。
  • (注意)当初の前提と異なり、設備が中々コネクテッドしなかったために言えることでもあります。接続スピード的には予想の1/20以下でした。設備接続はそんなにスピード感を出せないということをもっと広く世の中に伝えたいですね。

(c)エッジ処理の処理ベースをApahce Camelを使ったこと

  • (背景)接続される機器・器具はPLCにも多用にあります。プロトコルももしかすると、HTTP/JMS/SMTPなどでPull/Pushの組み合わせであったり、フォーマットもXML, CSV, JSONなどと読み切れない部分がありました。そのため、大量のプラグインを備え、メッセージやコンテンツを元にルーティングを行えるApache Camelをベースに組みました。
  • (反省点)なんやかんや、様々なロジックをCamelに組み込んでいくとコンポーネントの再利用は何それ?といった形で複雑化していってしまいました。これはCamelの適用箇所というより、Camelの開発の仕方が悪かったという自分のスキル不足な面もあるかもしれません。当初と読み違えていたのは、大体の接続機器がFTPインターフェースを持つということです。そのため、まだ見ぬ多くのプロトコルに対応するためにCamelを導入するのは牛刀でした。仮にHTTPが必要だったとしても、その度に必要なサービスを追加して対応すれば良いと思います。ルーティングや何やらも、結局オンプレにデプロイするのが面倒ですし、もうfluentdでFTPファイルをS3に直接アップロードして、クラウドの潤沢なコンピューティングリソースでETLなり分析をすれば良いと思います。

クラウド領域

(d)レイヤーアーキテクチャ遵守できていない処理があった

  • (反省)例えば、APIを提供するECSでは基本的にKafkaにPublishしますが、一部の小さなセンサデータは直接HBaseにPutすることにしました。これが大失敗で、HBaseの再起動オペレーションがSparkStreamingを停止することで対応できなくなるなど、運用的に大変な自体に陥っています。要はECSは更新オペレーションでKafkaにもHBaseにも依存している状態です。機能配置的にどうなんだと言う話ですね。

(e)ストリーミング処理はSpark Streaming

  • (背景)KafkaからデータをHBaseに永続化するためのストリーミング処理はSparkStreamingを選択しました。理由は、リアルタイムな異常検知などを行なう際には、ウィンドウ処理など時系列処理を行なう必要があると考え、当時はSparkの運用実績もありこちらを採用しました
  • (反省)Kafka →HBaseのデータ永続化だけを見れば、Sparkではなく単純にKafkaをSubscribeするスタンドアロンアプリでも良かったなと思います。とは言え、Spark Streamingは固く安定しているのでこれはこれで良いものですが。

(f)永続化先にHBaseを採用

  • (背景)HBaseを選んだ理由の一つは、当初は機械学習の学習データを作るインプットをHBaseから得るためで、DynamoDBのReadCPを上げるよりはいっそHBaseの方が運用コストが低かろう、自由度が高いだろうという判断でした。
  • (反省)やはり運用が辛いですね、EMR。特にHMasterが単一障害点になるのが辛く、AWSさんから定期的に通知されるEC2の再起動オペレーションが、運悪くHMasterのノードだと、安全を期すために、EMRクラスタの再作成をする必要があります。では、DynamoDBを選べたかというと、それ以外の大人な事情があるので仕方ないですが、S3にしておけばよかったというのは本当に反省です。何かしたいことがあればS3からEMRで処理させれば良いのです。データレイクはS3一択というのが当時はイマイチ理解できていなかったのが敗北かもしれません。

まとめ

  • 技術的に色々と手直して綺麗にしたいところはありますが、デバイス(設備)からクラウドまでデータが流れて可視化・分析できるのは楽しい
  • エンジニアの失敗しましたよ事例、もっと読みたいのでみんなも書きましょう!

--

--

ITアーキテクトブログ

エンタープライズ系の開発についてTipsやポエムを中心に書きます