以下の内容はhttps://onk.hatenablog.jp/より取得しました。


Amazon Aurora DSQL を個人サービスのデータストアとして使う

データストアというかインフラ費が安くないと継続運用できないので、色んな (とはいえある程度メンテコストの低い) データストアを試しています。以前は SQLite3 + Litestream + S3 を試していました。

Aurora DSQL とは

PostgreSQL 互換の分散 DB です。マルチリージョンでのアクティブ・アクティブ構成ができる自動シャーディングされるデータストアで、イメージとしては Spanner みたいなヤツですね。

PostgreSQL との違い

公式ドキュメント に書いている以上にたくさん違います。(私が見ていた頃 (半年ぐらい前) からドキュメントだいぶ増量されている!)

書いてあるものとして

  • postgres database しか使えない
  • TRUNCATE が無い
    • DELETE FROMDROP TABLE を使え
  • 外部キー制約無い
  • Sequences が無い
  • CREATE INDEX が無い
    • CREATE INDEX ASYNC がある
  • 3,000行ずつ制限がある
    • A transaction can modify up to 3,000 rows, regardless of the number of secondary indexes

    • The 3,000-row limit applies to all DML statements (INSERT, UPDATE, DELETE)

他にも ALTER TABLE は制限がキツくて色々動かない。

  • ERROR: unsupported ALTER TABLE ALTER COLUMN ... DROP NOT NULL statement
    • NOT NULL 制約を後から外そうとしたらエラーになった
  • ERROR: unsupported ALTER TABLE DROP COLUMN statement
    • DROP COLUMN できない!!

ので、新しいスキーマでテーブルを作って、データを移して、RENAME TABLE するのがデフォルトかなーって所感です。

データを移そうとしたらこれもまた制限に引っかかったので、試行錯誤するのには本当に向いていないなと思います。オペレーションは慣れたら行けそうとも思う。実際そんなに困ってない。

  • 3000行制限: ERROR: transaction row limit exceeded
  • 10MB 制限: ERROR: transaction size limit 10mb exceeded

DSQL の先人としては以下のブログがありそうです。

ActiveRecord から扱う

幾つか違いはあるものの概ね postgres なので postgresql_adapter を拡張します。

特に困るものとしては

  • 接続時に IAM 認証が必須
  • DDL で CREATE INDEX が無くて CREATE INDEX ASYNC である
  • PK が……?

で、軽く探したらあったのでありがたく使わせて貰っています。

特に primary_keys は自分で対応を思いつけなかったので助かりました。

あと公式のサンプル。

面倒なのになんで使うの?

異常に安い。

まず無料枠がある。

https://aws.amazon.com/rds/aurora/dsql/pricing/#Free_tier

Each month, your first 100,000 DPUs and 1 GB of storage are free and automatically applied to your monthly bill.

DPU は多少しっかり使うと (毎時データをゴリッと読み書きするような Job 動かすとか) お金が掛かりますが、そうでないリクエスト数の少ないサービスなら無料なんじゃないか。

そして従量課金です。

私は普段は 無料〜$0.1 で、割とゴリゴリと使った月でも $5 とかで暮らしています。RDS や Aurora で postgres を立てるとこうはいかないので、少ないリクエストで動いている限りは従量課金は最高。

分散 DB の良いところ (マルチマスタを実現する技術) はまったく気にしていなくて 1 node として使っている目的外利用だろうから、今後どこかで値段が上がってウワーってなる気はしている。

まとめ

  • 安い DB を探していて Aurora DSQL に辿り着きました
  • 分散 DB なので高いかと思ったら逆に従量課金で安い
  • 幾つか非互換や制限はあるものの、まぁ乗りこなせる範囲じゃないか
  • 実際に私は運用できています

今年観た映画2025

ほとんどを TOHO シネマズ 二条 (自宅最寄り) と MOVIX 京都 (職場最寄りのシネコン) で見ている。T・ジョイ京都、イオンシネマ京都桂川アップリンク京都、出町座はそれぞれ 1-2 回ずつぐらい。京都は映画館が多くてメチャクチャ過ごしやすい。

44 本かー。去年が 43 本、一昨年が 46 本なので、このぐらいで安定かな。予告編を見ると見に行かなきゃって気持ちになるので割と継続的に行くことになっている。

一番見て良かったなぁって思ったのはベスト・キッドレジェンズだなー。これはもうこの作品自体がシリーズの集大成なのでほぼアベンジャーズです。

その後色々と調べたり映像見たりしたのはトワイライト・ウォリアーズ。九龍城砦つながりで GetBackers -奪還屋- を読み返したりもした。

多分私のまわりは見てないんだけどオススメしたかったのはロマンティック・キラー。

羅小黒戦記2はもっと話題になってくれ。秒速5センチメートル(実写)は API 納品する職業に就いた貴樹のシーンをたっぷり見られるのが良かったです。地獄の黙示録は今まで見たことがなかったので、劇場で見られて良かった。ダマガールは 2 年以上待っていたのでついに配給されて本当に良かったんだけど、どうしても「Kendama World Cup の映像をもっと見たい」って思ってしまった。アバターはいつも通りだけどいつもより良かった気がするな。ぜひ本物の黒で見てくれ。

今年買ったもの2025

あれ、去年も一昨年も書いてなかったな。

家具

去年の 12 月に引っ越したが、引っ越しを契機に買ったものはあまり無い。レイアウトが変わったので、ベッドのサイドテーブルとしてニトリチェントロ2 25DBR と、ウォールラックとして を買った。それぞれ物を置く場所として妥当に活躍していると思う。

  • IMIEE

電子レンジが急に壊れたので買い換えることになった。象印マホービンが電子レンジ出してるの知ってました?私は知らなかったので面白いかなと思って ES-GW26 を買った。(1ヶ月後に ES-GX26 が出て型落ちになるのは知ってたけど、買い換える必要があったんだから仕方ない)

あたためる時間を秒じゃなくて温度で指定するのはナルホドねとなった。

ガジェット

耳はイヤーカフ型の Shokz OpenDots ONE を買った。 イヤーカフ型の良品として、既に HUAWEI FreeClip を持っていたが、手が滑って買い足した。耳を挟む力は FreeClip よりかなり強めなので、耳から外れて飛んでいくことはなさそう。代わりに丸一日着けているとちょっと耳が痛いし、少し重い。アプリから Dolby Audio を ON にすると Google Meet でも全員いい声になって面白かった。来年に向けては HUAWEI FreeClip 2 を支援済みなので、この辺りがメイン耳になるのだろう。

  • SHOKZ

年 1 ぐらいで買い足している 7-8 インチタブレットでは HEADWOLF FPad 7 を買った。だいたい落として割るたびに買っていて、今回は Alldocube iPlay 50 mini Pro からの買い換え。買った直後に Alldocube iPlay 70 mini Ultra が出たのでちょっと失敗したと思っている。使い道は本やマンガを持ち歩くのと Slack/Twitter と、稀に動画を見るぐらいなんだけど、たまーに音出して動画見ようとしたときにスピーカーが片側にしか無いのは多少残念。

  • Headwolf

今年はモバイルバッテリーや充電器、USB-C をマグネットにする変換アダプタ等を CIO で揃えた。

  • CIO

あと面白として Jackery ポータブル電源 1000 Newのんべえ横丁 NBE-1 を買いました。2026-01-11 に 京都嵐山耐寒開運リレーマラソン に参加することになっているので、寒い中で温まるグッズを買っておく必要がある。絶対走りたくない、助けてくれ。

  • Jackery

その他

ガジェットはもちろんヘビーユースしているが、他もいくつか挙げておこう。

テンピュールのスリープマスク は日が出た後に寝るときに便利。ゆるふわPodcast EP281 2024年買ってよかったもの を聞いてコンバージョンした。1年経った今もまだ使っていて、本当に良かった。

IKEUCHI ORGANIC のバスタオル を京都の店舗で買った。Podcast IKEUCHI ORGANIC と 坂ノ途中 のなんでやってんねやろ? を聞いているので、買うかーと思って。聞き覚えのある声で益田さんが応対してくれたのは最高。

ローソン販売「ゼルダの伝説 ハイラルの紋章」タンブラーとショルダーバッグは RubyKaigi で移動中に買ったのでよく覚えている。ちょうどこのサイズのカバンが欲しかったんだよね。

あと日常使いのカバンが 北陸Ruby会議01 の移動中に壊れたので Nordace Siena Pro 15 を買った。これは誕生日プレゼントとして妻に買って貰った。移動中に被っている (色は違う) のを何度か見掛けている。

  • Nordace

あ。Nintendo Switch 2 は普通に遊んでます。C ボタンは一度も使ってないっていうかそもそも他人が必要なゲームはやらないのでアレなんだけど。初回に買えてしまった責任としてちゃんと使っている。

2 画面ファイラーを作ったら最高だった

作ってみたかった

ある日 Slack で雑談していて、

僕の考えた最強の< >ツール なんか作りたいよね。なにかないか。

って流れになった。定番どころで、OS、コンパイラ、ブラウザをまず想像したけど、そう言えばずっとファイラー作りたかったんだよなぁと思い出した。たぶん 15 年ぐらいずっと欲しいって言ってたと思う。

Windows を使っていた頃は あふw ユーザーだったので、あの体験が懐かしいなぁと思いながら暮らす日々でした。*1

2 画面ファイラーの良さは省略します。言うまでもなく最高なので。

作ってみた

やるかーと思って「double_drive」ってプロジェクト名を決めた。あとは AI と壁打ちしながら作ったのがコレです。

デュアルペインで直感的にファイル操作できる

curses を生っぽく使うのかなと考えていたけど、少し調べてみたら TUI な枠を描ける RubyGemsCPAN module がいくつかあったので、せっかくだし使ってみています。

ガワが出来たら中身書くのは簡単ですね。毎日ドッグフーディングしながら欲しいコマンドをどんどん足していくのを楽しんでいる。

主な機能

ごく普通の 2 画面ファイラーです。

自分好みのキーバインドや挙動にできるのは最高で、選択も確認ダイアログも出さずにいきなり c で反対側ペインにコピーしているし、テキストファイルのプレビューでは bat をそのまま起動しています。

アーカイブファイル (zip とか) の中に潜れるようにした瞬間からグッと使い勝手が良くなりました。Mac の Finder が苦手なところなので、それはそう。

他に自分好みの機能としては、例えば x でそのディレクトリをカレントにしたシェルを開くようにしている。この実装は system('tmux', 'new-window', '-c', $current_dir); としていて、tmux は基本立ち上げっぱなしなので、この方が嬉しい。evim を立ち上げるときも同じく tmux の window にしている。こういう細かいところに手が届くのは最高。

余談その1:初回の面白会話

bundle gem double_drive と打った後、Claude Code を立ち上げて

id:onk 新しい gem を作ります。TUI アプリケーション (ファイルマネージャ) です。まずは gemspec を埋めましょう。 https://github.com/onk/double_drive に push するつもりです

 

⏺ gemspecを更新しました。以下の変更を行いました:

  • summary: "A dual-pane terminal-based file manager" - デュアルペインのTUIファイルマネージャという要約
  • description: より詳しい説明を追加
  • homepage: GitHubリポジトリのURL (https://github.com/onk/double_drive)
  • metadata:
    • allowed_push_host を削除(RubyGems.orgにpushする場合は不要)
    • source_code_uriGitHubのURLを設定
    • changelog_uri も追加(一般的なベストプラクティス)

これでgemspecの基本情報が埋まりました。RubyGems.orgに公開する準備が整っています。

 

id:onk よくデュアルペインって分かったねw commit よろしく

 

⏺ コミットしました!double_drive という名前から推測しました😄

変更内容:

人間味があって非常に良い。

Ruby で書いていたけど Perl で作り直した

YAPC::Fukuoka の前からボチボチ触っていたのだけれど、YAPC の後に気持ちが乗っていたので「Perl で作るか」と思って作り直した。

やりたい気持ちの根っこは「Perl 5.42の最新機能はどこまで AI で書けるのか」という疑問の解消です。

package を封印して全て class 構文で書いてみたり、1, 0 を使わずに全て builtin boolean で書いてみたり。

面白かったポイント1:非同期処理

Perl の TUI ライブラリとして、Tickit に乗っかってみた。自分でメインループを回さなくても勝手に非同期に描画されるので、Ruby のときの tty gem とは書き味が違う。callback を多用することになった。

また、確認ダイアログを出して結果を受ける、みたいなのを書こうとして、callback が嫌になって Future::AsyncAwait を使うことにしたのも面白ポイントです。Perl でも async/await を書けるぞ! 本人が実装について語ってるブログ が面白かったので読んでくれ。

面白かったポイント2: class で書くとあんまり Perl っぽくない

全てがインスタンス作ってメソッド呼び出しになるんだよな。それはそうなんだけど。

元々 Perl では関数を import して右から左に書いていく (こういう書き方をするからパイプライン演算子が欲しくなるのだが) コードをよく書いていたと思う。

my $content = path($file)->slurp_utf8;
my $lines = [ map { chomp; $_ } split /\n/, $content ];

こういうのが結構減って、全てが class のインスタンスへのメソッド呼び出しに変わっていくなぁ、というのは面白い気づきだった。いや別に今まで通りに書けばいいんだけど、目の前にオブジェクトがあるとメソッドにしたくなる力が働くんだよね。

あと class を使って書くと綺麗にカプセル化されてしまっていて、Perl の bless で作られたオブジェクト指向でよく扱っていた内臓を直接触るかのようなメタプログラミングがすべて封じられている。めちゃくちゃテスト書きづらい……。

面白かったポイント3: Ruby がよくできすぎてる

akr さんの APIデザインケーススタディ を読んでくれ、という感じなんだけど。

こんなに楽して書いていいんですか、となることが多いね。FileUtils も Open3 も便利……。

面白ポイント4: CJK 対応

TUI ライブラリが全角幅に対応していないことが多いこと多いこと。Pull Request いっぱい出すことになるし、いやしかし描画は確実に遅くなるので自分がメンテナだったとしても入れるか悩むだろうし難しいなぁって思うから出すのも悩むし、困る。

あと Mac でファイルパスを扱っているので NFD/NFC 正規化問題も踏んでる。

面白ポイント5: TUI 上で画像表示

Sixel かなぁ、iTerm2 にして iTerm Image Protocol かなぁ、Kitty にして kitty graphics protocol かなぁ、と考えて、Kitty にしました。

ターミナル上の任意の場所に急に画像を出せるの、自分で使っていても一瞬ビックリするし便利で面白い。

Kyoto.なんか #7 で git の話をしたときの画像

Perl の最新機能を AI は使えたのか

何ら問題ないですね。class 構文もサブルーチンシグネチャも try-catch も builtin boolean も元気に使いこなしてくれる。

boolean は慣れてなくて最初のコードでは絶対 1 を返してくるし、ファイルの末尾に 1; も付けてくるし、try-catch 使わずに eval してくるので、手放しってわけではない。都度「v5.42 って言ったよね」と言うことで自分好みのコードを書かせている。

class と signature は本当に問題なく使ってくれる。

Claude (Sonnet 4.5 でも Haiku 4.5 でも) でも Codex (gpt-5.1-codex-max) でも、Copilot (Gemini 3 Pro) でも、Perl の扱いに関してはあまり差は感じてないなー。

まとめ

ファイラーを作るとあのカオスだった Downloads ディレクトリや .Trash ディレクトリが掃除できました。すごい成果だ。

毎日ドッグフーディングできる (機能を思い付いて改善できる) 遊び場があると楽しいですね。

https://github.com/onk/double-drive_perl

はてなエンジニア Advent Calendar 2025 6 日目でした

すっかり忘れてた orz

*1:そこまで本気で探してもいなかったので mc や ranger 等は使ってなかった

YAPC::Fukuoka 2025 に登壇してきた

函館でも登壇、広島は前夜祭登壇、京都で登壇、と割とずっと登壇機会をいただいている。

今回の資料は以下。

speakerdeck.com

今回はワークショップ枠がある、ということで、じゃあ弊社の講義を (資料は普段から公開してるし) そのまま実施しよう、というプロポーザルでした。せっかく Perl の名を冠した YAPC なんだから Perlトークも楽しんで聞いて欲しい!その前提を即席養成講座で叩き込むぞ!という場です。

1 時間まるまる言語仕様について話してみたけど、目的は達成できたかなー?

カンファレンスをより楽しむコツ

それぞれのカンファレンスには、前提として押さえておくとより楽しめる要素があると感じている。

  • RubyKaigi だと、型周り、JIT、Parser、CRuby 以外の Ruby 実装、新コミッタの業績
  • Kaigi on Rails だと、The One Person Framework、概念圧縮、Solid Trifecta

辺りを知っていると、会期中に出る話題がなぜ注目されているのかが分かってより楽しめると思う。

で、YAPC だと「Perl の昔と今」が知っておくべき前提知識だと思っていて、最近のコンテキストをインストールするのも目的に入れました。

特に Announcing Perl 7 辺りから加速している、よりよいデフォルト値に移行していく流れですね。

この後色々あって、デフォルトを変えると非互換が大きいとして use v5.42; を書く流れになっている。バージョン宣言を書くことで、例えば v5.36 からは間接オブジェクト記法が無効になっているし、v5.42 ではスマートマッチも無効になる。逆に有効になるものだと signatures や try が特に特徴的で、普通のことを普通に書けるようにする流れがある。この流れを頭に入れて、その上で色んなトークを聞いて欲しかった。

id:kfly8Zenn の本 とも似たモチベーションかもなぁ。

普通のことは普通に書けるのは入口として前提として、更に記号や暗黙の $_ の利用が多いのは逆にゴルフに向いているし全能感が出て楽しいよね。

※なお バッドノウハウと「奥が深い症候群」

踊り場

blog.yapcjapan.org

1日目に急遽発表された「踊り場」。いわゆる「カンファレンスの廊下」の延長としての枠ですね。廊下っぽい会話を作りたい!という id:Pasta-K の熱意で生まれた枠だと認識しています。

その踊り場で、私は「Day 1 最速振り返り」という枠を担当しました。ランチタイムなので、ある程度人が集まるのが確定していたという、立地条件で成功が決まっている枠でした。

スピーカーがそこそこ集まるだろうから、スピーカーに自分のトークの肝を説明してもらおう。スピーカーが居なかったらトークを聞いた人にマイクを渡して、どんなトークだったか、一番印象に残ったのはどこだったか、等を聞けば成立するだろう、という読み。

一応公開されているスライドは集めて読んで、その時間帯のツイートも一通り見てから司会に当たったんだけど、「めっちゃツイート見てるんですね」って言われたのは面白かったです。そんなまるでツイ廃みたいな。

ここだけのひみつ:20 セッションぐらいだから 1 枠 5 分程度で回したら全セッション網羅できるな、という計算違いをしていた

id:moznion の「OSS開発者なら学生参加者いっぱい集められる説」は学生と OSS 開発者との座談会になって非常に良いコンテンツだった。興味を持つリポジトリが無い人に、自分が飽きているリポジトリを譲ってメンテして貰うマッチングサービスは実際面白いんじゃないか。受け取っても大半が燃え尽きそうなので半年後とかに引き継ぎチェックを入れたいが。

id:rokuokun の「教科書では知れない令和最新 Perl ワード解説バトル」は、id:dankogai を呼んだのが勝因でしたね。

あと id:kfly8id:charsbar が答えるメンバーになっている、非常に豪華な場だった。

id:rokuokun の準備も上手くて、前日の 2025年秋のPerl を見て分かんなかった単語を「これ何ですか!」と聞いていくスライドだったので、そうそう、廊下ではそういう質問して欲しいんだよ〜〜って思いながら答えてました。

ボランティアスタッフ

当日スタッフが全然足りない〜〜って話を社の Slack (コアスタッフが何名か居る) で噂を聞いて、しゃーないなと手を上げた。たぶん YAPC では初スタッフ業。

前日のノベルティ詰め作業は楽しかったですね。

当日の受付は、電車の到着ごとに 30 人ずつ程度のバッチが発生していたけど、難なく捌き切れたと思う。

あとはお昼にランチへの誘導したり、人が足りないところにアサインされる感じで回っていました。

次回

私が話を聞きたい外タレは Paul Evans です。夢を言っておくとオードリータンの話は聞きたいですねぇ(言うだけはタダ)

最近はあんまり開発ど真ん中のトークをしていないので、来年は何かしら作った話を持って行きたいなー。頑張ります。

git v2.29 で追加された git-maintenance について

git-maintenance とは

git maintenance は、Git 2.29 で導入されたリポジトリのメンテナンス機構です。

porcelain command (高レベル API) *1 ですね。

従来の git gc と似ていますが、ユーザー入力をブロックしないし、適切にロック処理も行っているので、より安全で継続的な運用を意識した設計になっています。

github.com

git gc は今すぐ git maintenance run --task gc に置き換えられる。二重に動いてもロックされているので安全。っぽい。

git-maintenance の基本

  • git maintenance register すると .gitconfig に記録される
  • git maintenance start すると cron に登録される
    • Mac の場合は launchctl の plist
    • 登録された repository について、 git maintenance run --schedule=xxxly する
  • git config maintenance.strategy によって動作が変わる

hourly で prefetch するの面白い。変化が大きい && 自分がよく見るリポジトリだと待ち時間が減って便利かも。

strategy は v2.52 から geometric が増えるっぽいです。これは incremental-repack じゃなく git repack --geometric する戦略。Scaling monorepo maintenance - The GitHub Blog にあるように、大きな monorepo だと geometric の方が効果があるのかもしれない

git maintenance は普段から動いている

tech.mobilefactory.jp

git maintenance は、リポジトリへの書き込み操作(fetch、commit、merge、rebase など)の後に自動的に実行される最適化処理です。リポジトリのパフォーマンスを維持するために、不要なオブジェクトの削除やパックファイルの再編成を行います。

.git を更新する処理の前後で自動で走っています。

git-maintenance を有効にする (git maintenance register) と、cron で更新するようになるので git fetch 時に動かす必要が無いとして maintenance.auto = false になります。

感想

prefetch は使いどころがあるのかもしれない。

いやー、どうだろうな。ラップトップ PC で git maintenance register する意味があるかというと微妙な気がする。テザリングしている最中に .git 更新されても嬉しくはなさそうだし。でも開発用途なら prefetch は十分に美味しそうなので有効にしそう。

僕は git gc を時々手で打っていたけど、今後は git maintenance run --task gc にしようという気持ちになりました。(いや gc する必要はなくて incremental-repack で十分そうなので引数なしで打つと思う)

というか auto で動くので普段は意識しないか。

全般に「ユーザー操作の邪魔をしない」ように設計されているのかなという感想でした。

なんで気になったの

git の release note を Slack に流していて、v2.52.rc0 のタグが付いたのを見たので。

v2.52.rc0 を打ったコミット を見て、git maintenancestrategy: geometric って何だろう?って疑問からドキュメントを見てみた。という経緯でした。

*1:porcelain については Git - Plumbing and Porcelain を参照

Lambda + SQLite3 + Litestream + S3 でデータを保持してみた

できるかぎり AWS で Web アプリケーションを安く作れないかな、という試みの一環。アプリケーションの内容は特に重要ではなく、適当な Rails アプリです。

Litestream が Kaigi on Rails 2025 でも言及されていた ので、一回使ってみたくてやった、という内容です。

Litestream とは。SQLite の WAL を外部ストレージにストリーミングするツールです。概ねオブジェクトストレージ (今回は S3) へのレプリケーション (かつ PITR) が実現できると思えばヨサソウ。バイナリをポン置きで動くのも魅力。

litestream.io

背景と目的

Rails (に限らないかな。SSR するアプリ) を提供しようと思うと、少なくともアプリケーションサーバとデータストアが必要になる。

アプリケーションサーバについては、Lambda を使うと無料枠もあり、非常に低コストで運用できる。 データストアは RDS を使うと確実だが、継続して立ち上げ続けることになるのでコストが跳ね上がる。SQLite をローカルで使うと無料になるし、SQL から離れることになるが DynamoDB を使うと無料枠があるので安く運用可能である。

つまり Lambda + SQLite で構成すると、最小コストで運用できるはず、となるが、Lambda は実行環境が消えるという問題がある。

Lambda や ECS のようなサーバーレスな環境だと、タスク終了時にローカルストレージも破棄される。このせいでタスクが変わるたびにデータが消えてしまう。

対策としては

  • Lambda + EFS マウント
  • Lambda + S3 + Litestream (今回の構成)

になるんじゃないかな。ローカルのデータをリアルタイムにリモートにも送っておけば、生まれ変わっても引き続き使える、という対策です。EFS もまぁやったら動くと思う。

SQLite にはもう一つ課題があって、Lambda をスケールアウトできない。EFS のように複数 Task からマウント可能でも、SQLite への同時書き込みでデータが壊れる (はず)。 今回は Lambda の同時実行数 (reserved_concurrent_executions) を 1 に設定することで、単一の Task のみが SQLite にアクセスする構成にした。

アーキテクチャ概要

  1. Lambda 起動時に、S3 からリストアする
  2. アプリケーション起動前に Litestream でレプリ開始
  3. Rails アプリがリクエストを処理し、データを読み書きする
  4. SQLite への書き込みが発生したら、Litestream が随時 S3 にストリーミングする
  5. Lambda が終了しても S3 上に最新の状態が残っている

Lambda のコールドスタート時に毎回 restore が走るので起動が遅くなるが、まぁそもそもコールドスタートだからな。

Rails からは普通に sqlite3 として使うだけ。Litestream でのリストアやレプリケーションは Docker の entrypoint でいい感じにやります。

# Restore database replica if available
if litestream restore -if-db-not-exists -if-replica-exists -config /rails/config/litestream.yml /tmp/storage/production.sqlite3; then
  echo "Database restored from S3"
fi

# Start Litestream replication && exec puma
litestream replicate -config /rails/config/litestream.yml \
  -exec 'puma -b "tcp://0.0.0.0:8080" -e production'

db:migrate

reserved_concurrent_executions = 1 で運用しているため、db:migrate が実行できない。まぁ 2 個立ち上がるとデータ壊れるので正しいんだけど。

なので、以下の手順で migrate を実行している。(大変めんどくさいので migrate は Lambda 起動時にやっちゃうかも……)

  1. Lambda の前段 (CloudFront) でメンテに入れる
  2. Lambda の reserved_concurrent_executions を一時的に 0 に設定。今来ているリクエストを処理しきるまで待つ
  3. reserved_concurrent_executions を 1 に戻して、bin/rails-remote db:migratebin/rails-remote runner '<スクリプト>' を実行
    • bin/rails-remote は Lambda の環境変数RAILS_COMMAND を設定して invoke するスクリプトです
    • entrypoint では、litestream restore 後 puma 起動前に、RAILS_COMMAND が設定されている場合は litestream replicate -execrails コマンドを実行して終了する
  4. メンテを明け、HTTP リクエストを受け付ける

コスト感

全体構成としては CloudFront + Lambda FunctionUrl + SQLite3 + Litestream + S3。

CloudFront も Lambda も S3 もほぼ無料なのでほぼ無料で運用できている。データが増えてきたときに restore 時間がどう延びていくかはここから眺めていこうかな。まぁいい構成じゃないかしら。

その他

Litestream v0.5.0

ついこのあいだ (2025-10-02) v0.5.0 が出て、v0.3 系から migrate する必要がありました。

fly.io

litestream gem

litestream gem については特に使っていません。起動は Docker の entrypoint で管理していて苦労していないし、プロセスの親子関係としては Litestream が親の方がデータが正しくなりそうだし、これでいいかなーと思って。

非同期処理

ActiveJob は今のところ使ってないんだけど、使うとしたら solid queue の puma plugin でやるんだと思う。

バックアップ

まだ数日しか経ってないのでちゃんと見てないけど、S3 に snapshot が残っていそうなので、これで運用できるんじゃない……か?

redirect_to

CloudFront の裏に FunctionUrl で Lambda を置いていると、Host ヘッダが FunctionUrl のものになる。 redirect 時に CloudFront のドメインじゃなく FunctionUrl のドメインに飛んでしまって困った。

config.action_controller.default_url_optionshost を設定して、redirect_to foo_path じゃなく foo_url を使うようにして処理した。

ここで Rails 8.1 (最近出ましたね!) にちょうどいい機能が入っているので、有効に使うと良いんじゃないかな。

Allow hosts redirects from `hosts` Rails configuration by byroot · Pull Request #55420 · rails/rails · GitHub

感想

データストアを意識する必要がない、アプリケーションの Task だけ考えれば良いって環境、異常に気楽ですごい。これからは Solid シリーズが流行るだろう。

kinoppyd のトーク をぜひ聞いてみたい。

tech.smarthr.jp

参考URL




以上の内容はhttps://onk.hatenablog.jp/より取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14