nisshiee.org

サーバーレスリレーを作ろうとした話

2025-12-06

この記事は、Nostr Advent Calendar 2025の6日目の記事です。5日目はロクヨウさんより『Nostrに居ない人向けの記事』、7日目はぱぶいさんより『なんか書く』です。

プロローグ

作り方

$ git submodule add https://github.com/nostr-protocol/nips.git nips
$ git submodule update --init --recursive
$ claude リレー作って

注) 嘘です(流石にそんな単純な指示では無理だと思う。でもそこそこイイ線いくかもw)

実際には、cc-sddを使って仕様駆動開発した。要件・設計はガッツリ人間がレビューした。コードは全てclaude codeが書いた。

最初の構成

NIP-01準拠は、以下のサーバーレス構成で作れる。とてもシンプル。イベントもDynamoDBに永続化しており、REQに過去イベントも含めて応答できる。

NIP-01準拠のサーバーレス構成図

細かい話をすると、Replaceable/Addressableなイベントを検索する用のGSIは、これらのイベントを受けるために必要。

次の構成

NIP-11に準拠するためには、NIP-01のWebSocketリクエストを受けるものと同じドメイン・パスで(Acceptヘッダーが違う)APIレスポンスする必要がある。このルーティングがAPI Gatewayにはできない。

そこで、API Gatewayの手前にCloudFrontを置き、Lambda@Edgeを使ってヘッダーによるルーティングを実装した。なお、CORSプリフライトにはLambda@Edgeで直接応答してしまっている。

NIP-11対応のCloudFront構成図

NIP-11にわざわざFunctionで動的に応答する必要は無いんだけど、limitationあたりを環境変数で管理してリレー本体の動的制御と同期しようと思ったらFunctionにしちゃった方がシンプルに済む。

課題

リレー作ったことある人ならわかると思うけど、結局、永続化したイベントを検索する(REQに応答するため)のが一番のボトルネックになる。

↑の構成だとDynamoDBにScanをかけてアプリケーション層でフィルタリングするしかない。GSIを作ってチューニングすることは可能だけど、クライアントが送信できるフィルターの自由度が高いので、Scanをゼロにするのは無理だと思う。

残念・・・・!

ここでサーバーレスを諦めた。

  • OpenSearch ServerlessとかAurora Serverlessをサーバーレスに含めて良いなら達成できるだろうが・・・
    • これらはミニマム料金が、遊びで使うには高すぎる
  • 外部サービスという手もあるが、依存をそんなに増やしたいわけではない
  • あと一応EFS経由でSQLiteという手を考えたけど、たぶん厳しい(筋も良くなさそう)

着地

とりあえずOpenSearch Serviceのマネージド版でインスタンスを立てた。

DynamoDB Streamを使って、DynamoDBのイベント格納用テーブルをトリガーにして、イベントをOpenSearchに入れたり消したりする処理をしている。REQを受けたらOpenSearchで検索する。

OpenSearch Serviceを追加した最終構成図

OpenSearchを使えばそこそこのスケーラビリティも確保できるだろうから、机上論では構成全体でそこそこスケーラビリティがあるはずである。「負荷が上がったらお金を投下するだけでスケールできる」を目指すのであれば悪くない構成になったと思う。

しかし実際には

そもそもNostrの住人数は高々知れてるし、予算も遊びの範囲だから・・・・

OpenSearch Serviceは一番小さいインスタンスを使っても、個人リレーとしてはオーバースペック&オーバーバジェットな気がする。

この記事の公開時はOpenSearchで動いているが、たぶん近々、SQLiteをEC2のもっと小さいインスタンスで動かすと思う(ただし、このあたりで、サーバーレスを目指した意義はほぼなくなる)。

使っていいよ

以下のURLでリレーを稼動させておくので、使ってやってください。

wss://relay.nostr.nisshiee.org

一応、ちゃんと免責を主張するための規約だけはあるので気にする人は読んでね。

エピローグ

  • Apple Watchのくだりはどこいった?
  • さぁ?
  • まぁDynamoDBにイベントが貯まるようにはなったから、何かやりやすくはなったんじゃね?
  • 来年のアドベントカレンダーに期待しよう