We’re sorry we missed you at re:Invent, but we can still meet!

サーバーレスとマルチクラウドの良い関係

操作の複雑さを軽減し、同時に携帯性を高める。

Ellery Addington-White
著者

Share

サーバーレスとマルチクラウドは開発者がよく耳にするバズワードだが、通常は一緒ではありません。通常、開発者がサーバーレスについて考えるとき、異なるクラウドに簡単に移行できない、実行中のクラウドと緊密に結合したアーキテクチャ・コンポーネントを思い浮かべます。同様に、マルチクラウドと聞くと、人々はKubernetes(k8s)に飛びつき、k8sがこの抽象化レイヤーを可能にする唯一の方法であるという思い込みをしがちです。この記事では、マルチクラウドについてどのように考えるべきかについての実践的なアドバイスを取り上げ、ワークロードをよりポータブルにするパターンを共有し、サーバーレスとマルチクラウドが実際にどのように両立できるかを示します。

マルチクラウドの本当の意味とは?

一部のベンダーは、クラウド間でまったく同じインフラ・スタックを使用するマルチクラウドを推し進めようと主張しています。ベンダーは、どんなコストをかけてでも(クラウドを導入したメリットのほとんどをあきらめることも含めて)、クラウドを導入する価値があると主張します。これは、お粗末な開発者エクスペリエンスと、高い管理オーバーヘッドを持つ最小公倍数のインフラサービスにつながる傾向があります。実際には、ビジネス・ロジックはポータブルである必要があるが、インフラは必ずしもポータブルである必要はありません。それでも、その仕事に最適なツールと、それぞれのクラウドのベストを選ぶべきです。

そのためには、インフラをポータブルにするのではなく、各クラウドでアプリケーションを実行するために必要な運用面積を小さくすることに注力すべきです。この考え方を採用することで、別のクラウドプロバイダーで立ち上げ、稼働させながら、どのような規模でもエンジニアとして迅速かつ独自に動けるようになります。運用表面積を小さくすることで、クラウド・プロバイダー間の移動が容易になり、重い腰を上げる必要がなくなります。

実際にはどうなのでしょうか?

そこでサーバーレス・マイクロサービスの出番です。クラウドベースのサービスではなく、APIアクセス可能なデータモデルサービスを使うのは理想的です。

APIルーティングをクラウドにとらわれないものにする

例えば、私のデモ・レポでは、Serverless Expressを使っているので、AWS、GCP、開発用ラップトップのいずれで実行しても、ルーティングは同じ動作になりあす。APIルーティングを不可知論的なものにしておくことで、アプリケーションコードをバンドルしてLambdaやコンテナで実行したり、VMや開発用ラップトップで直接実行したりすることが容易になります。

フルマネージドサービスとサーバーレスAPIを選ぶ

AWSではこのようなアーキテクチャになります:

そしてGCPではこうです:

クラスター・ベースのデータベースやアナリティクス・インフラストラクチャの代わりにサーバーレスAPI駆動のデータモデルを使用することで、各クラウド内で運用するために必要な複雑さを取り除き、運用面積を削減することができます。上記の例では、AWSとGCPの両方でフルマネージドキャッシュとしてMomento Cacheを使用しています。これにより、ネットワーク、オートスケール、クラスタ構成、GCPとAWSの管理の違いといった問題を扱うことなく、開発者のエクスペリエンス、運用モデル、パフォーマンスを両クラウドで一貫させることができます。同様に、コンピュート・レイヤーにはGCPのCloud RunとAWSのLambdaを使い、データの永続化にはGCPのFirestoreとAWSのDynamoDBを使っています。

より高いレベルのInfrastructure-as-Code(IaC)フレームワークを使用する

これは、ベストプラクティスを組み込んだシンプルなAPIをスピンアップするための、より高度なインフラストラクチャ構造を提供することで、運用の表面積を減らします。また、CDKやCDK-TF、PulumiAmptTerraformのような複数のクラウドをサポートするIaCフレームワークを選ぶようにすると、両方のクラウドで一貫した開発者エクスペリエンスを得ることができます。

コード内に良い抽象化を作ることに集中する

インフラストラクチャではなく、コードベースを柔軟にすることに集中することで、ベンダーや実装の切り替えが容易になります(CBSがファサードに投資したときに見つけたように)。新しいテクノロジーはこれからも登場し続けます。ストレージ、インメモリーキャッシュ、コンピュートなどのプロバイダーを入れ替えられるようにコードベースを柔軟にすることで、業界の進歩に合わせて新しいことを素早く簡単に試すことができるようになります。

ここでは、移植性を高めるためのインターフェースのもう1つの例として、DynamoDBやFirestoreを簡単に交換できるように、データストア用のインターフェースを作成します。まず、データクライアント用の標準インターフェースを定義します。

export interface DataClient {
createUser: (user: User) => Promise
getUser: (userId: string) => Promise
}

そうすれば、データクライアントの実装ごとに、APIの起動時に実装を入れ替えることができます。

DynamoImpl
import {DynamoDBDocumentClient, GetCommand, PutCommand} from "@aws-sdk/lib-dynamodb";
import {DynamoDBClient} from "@aws-sdk/client-dynamodb";
import {DataClient} from "../users";
import {getMetricLogger} from "../../../monitoring/metrics/metricRecorder";
// Clients --
const ddbClient = DynamoDBDocumentClient.from(new DynamoDBClient({}));

export class UsersDdb implements DataClient {
async createUser(user: User) {
await ddbClient.send(new PutCommand({
TableName: "momento-demo-users",
Item: user,
}));
}

getUser(userId: string): Promise {
return getUserDDB(userId)
}
}

export const getUserDDB = async (id: string) => {
const startTime = Date.now()
const dbRsp = await ddbClient.send(new GetCommand({Key: {id}, TableName: "momento-demo-users"}));
getMetricLogger().record([{
value: Date.now() - startTime,
name: "UpstreamProcessingTime",
labels: [{k: "upstream", v: "dynamodb"}],
}])
return dbRsp.Item as User
};
FirestoreImpl
import {Firestore} from "@google-cloud/firestore";
import {DataClient} from "../users";
import {getMetricLogger} from "../../../monitoring/metrics/metricRecorder";

// Clients --
const firestore = new Firestore({
projectId: process.env['PROJECT_ID'],
preferRest: true, // Drops response times in cloud run env
});

export class UsersFirestore implements DataClient {
async createUser(user: User): Promise {
await firestore.collection(users).doc(user.id).set(user)
}

async getUser(userId: string): Promise {
const startTime = Date.now();
const dbRsp = await firestore.collection(users).doc(userId).get();
getMetricLogger().record([{
value: Date.now() - startTime,
labels: [{k: "upstream", v: "firestore"}],
name: 'Upstream'
}])
return dbRsp.data() as User
}
};

最後に

クラウド・プロバイダー間の移動が容易になり、開発者の自主的なイノベーションが促進され、どのような規模でもビジネスを成功に導くことができます。

サーバーレスやマルチクラウドの旅についてご質問がある場合は、Discordサーバーにご参加ください。そして、今すぐMomento Cacheを使い始めましょう!

Share