モノのインターネット(IoT)は私たちの身の回りに溢れています。スマートウォッチ、防犯カメラ、ペットの自動給餌器など、日常的に使われている機器には小さなセンサーが内蔵されており、インターネットにデータを送信することで、私たちはよりつながりやすくなっています。
IoTデバイスは大量のデータをプッシュします。センサーの種類にもよるが、ウェブサービスは1秒に数回から1時間に1回まで、デバイス(モノとしても知られている)からデータを受け取ることができます。デバイスのステータスは、残りのセンサーデータと一緒に送られてくるか、受信したデータから推測されます。
デバイスの現在の状態は、データ・プッシュのたびに提供されます。ステータス履歴は通常保存されません。毎日何万ものメトリクスを受信している場合、ステータス履歴の保存は費用対効果の高いソリューションではないかもしれません。
これは、Momento Cacheにとって完璧なユースケースです。短期間で頻繁に変化する情報を、瞬時にリアルタイムで更新することができます。それでは、Momentoでデバイスのステータスを追跡する方法を具体的に確認するために、ビルドに飛び込んでみましょう。
デバイストラッカーの構築
デバイス・トラッカーを構築するには、まずIoTアプリに含まれるコンポーネントを理解する必要があります。完全なソリューションは3つの部分で構成されます:
・デバイス・インターフェース: デバイス情報をウェブサービスに送信する、デバイスにインストールされたファームウェアまたはソフトウェアです。
・ウェブサービス: デバイス・データを取り込み、分析し、意味のある値にフォーマットするバックエンド・コード。
・ユーザー・ダッシュボード: エンド・ユーザーにフォーマットされたデータを提示するインターフェース。
この単純なサンプル・アプリケーションでは、シングル・テナント・アプリケーションを構築し、24時間受信した全デバイス・データのリストを管理します。また、キャッシュ内の特定のデバイスの現在のステータスを設定し、以前のステータスを上書きします。
// POST /devices/{deviceId}/data
const handler = async (event) => {
await initializeCacheClient();
const deviceId = event.pathParameters.deviceId;
const input = JSON.parse(event.body);
await Promise.all([
await cacheClient.set('iot', deviceId, input.status),
await cacheClient.setAddElement('iot', 'devices', deviceId, { ttl: new CollectionTtl(86400, true) })
]);
return { statusCode: 204 };
}
一意のデバイスIDを追跡するために、コレクションデータ型を使用します。セットはユニークな要素の順序なしコレクションなので、特定のIDを持つデバイスを何度追加しても、それを見るのは一度だけです。device
セットアイテムの生存時間は86400秒で、これは24時間です。
個々のデバイスのステータスを追跡するために、標準的なスカラーset
操作を使って値を格納します。最新の値だけを追跡すればよいので、このデータ型は完璧な選択です。
データが入ってくると、デバイス・リストが更新され、デバイスのステータスが上書きされます。たった7行のコードにしては、なかなかです!
ダッシュボードでは、現在のデータを取得する必要があります。過去24時間にウェブサービスにプッシュしたデバイスのリストを表示し、クリックせずに現在のステータスを提供できるようにしたいのです。
// GET /devices
const handler = async (event) => {
await initializeCacheClient();
let devices = [];
const deviceResponse = await cacheClient.setFetch('iot', 'devices');
if (deviceResponse instanceof CacheSetFetch.Hit) {
const deviceList = deviceResponse.valueArrayString();
await Promise.all(deviceList.map(async (deviceId) => {
const statusResponse = await cacheClient.get('iot', deviceId);
if (statusResponse instanceof CacheGet.Hit) {
devices.push({ name: deviceId, status: statusResponse.valueString() });
} else {
devices.push({ name: deviceId, status: 'unknown' })
}
}));
}
return {
statusCode: 200,
body: JSON.stringify(devices)
};
}
リストと現在のステータスを取得するために、まずデバイス名を含むセットを取得します。次に、リスト内の各デバイスに対してget
コールを並行して実行します。
デバイスのステータスがキャッシュ・ヒットしたら、そのまま返します。しかし、キャッシュ・ミスがあった場合は、そのデバイスからしばらく連絡がなかったことを意味します。デバイスからデータがプッシュされるたびに、ステータスを保持するキャッシュアイテムのTTL(time to live)をリセットします。TTLは、デバイスから連絡があると予想される間隔の長さの3倍になるように設定されます。
例えば、IoTデバイスから3秒ごとに連絡があると予想される場合、ステータスを保持するキャッシュ・アイテムのTTLを9秒に設定します。そうすることで、もし1つか2つのデータ・プッシュが私たちのサービスに失敗した場合、データを失効させる前にいくらか猶予を持たせることができます。
もしアイテムの有効期限が切れ、ルックアップ時にキャッシュミスが発生した場合は、unknown
ステータスを返し、デバイスがオフになっているか、修理不可能なエリアにあると見なします。
ベストプラクティス
IoTデバイスのステータスを追跡する際には、以下のベストプラクティスを念頭に置いてください:
・デバイスのリストを保存するには、set
を使用します。セットは自動的にエントリーの重複を削除します。これは、インジェストする大規模なデータセットで必要になります!
・デバイスのステータスやその他のシングルトン値をスカラー値として保存します。こうすることで、古い情報を現在の値で上書きすることができる。
・キャッシュアイテムの生存時間(TTL)を、デバイスの予想データ受信レートの3倍以上に設定する。こうすることで、デバイスにちょっとした不具合が発生したり、ネットワークが一時的に利用できなくなったりしても、寛大な対応ができるようになる。
準備はできましたか?
Momento Cacheは、IoTデバイスのデータに最適なユースケースです。高速かつ軽量で、デバイスからしばらく連絡がない場合は自動的にデータを失効させます。
私と同じようにワクワクしているのなら、そろそろ始めましょう!まずは Momento Console にアクセスして、無料の認証トークンを取得しましょう!完全なサンプルは GitHub のリポジトリを見てください。断片的なものから全体的なものまで、ご自由にお使いください!
ご質問、ご感想、コメント、懸念事項がおありですか?ぜひご連絡ください!Discordまたはウェブサイトからご連絡ください。