私の記憶が確かならば、昭和の初めから「オムライス」の一番美味しいところは決まっていた。
「卵の、裏側」
その理由は、温かいご飯に乗った半熟の卵が、その旨味を十分吸い取るから。
(『料理の鉄人』第02回放送より)
そして私の記憶が確かならば、モバイルアプリ登場以降、Obsidianユーザーを最も悩ませてきた問題。それが
「Vaultの、同期」
公式のデータ同期ソリューションである「Obsidian Sync」は有料、GoogleドライブやDropboxなどのクラウドストレージも、快適とは言い難い。
ローカルデータを扱うというObsidianの特徴が、そのユーザーを苦しめるという皮肉。
その問題に立ち向かうべく開発されたのが、データ同期を担うコミュニティプラグインSelf~hosted LiveSyncである。
もう一度言う。 オムライスで一番ウマいのは「卵の裏側」!
今回は「Self-hosted LiveSyncの裏側」を、この男と共に紹介しよう。
プラグイン開発者 vorotamoroz (ヴォロータ・モローズ) aka きみのぶ!
「データ同期」という難しい素材をいかに捌き、調理してきたか。
その裏側を、是非ともご賞味いただこうではないか。
「迫る!」シリーズはこのブログにソフトウェア開発者を迎え、執筆者ぷーおんが開発者へのインタビューを通してプログラムを丸裸にしていく、開発者 vs ユーザーの対談企画である。
開発のきっかけ
Pouhon: 今回は「迫る!」シリーズお二人目のゲストとして、きみのぶさんにお越しいただきました! よろしくお願いします。
きみのぶ: こちらこそ、よろしくお願いします!
Pouhon: きみのぶさんはかなりのObsidianフリークで、今回ご紹介するプラグインの他、「TagFolder」というプラグインも制作されています。
そのお話は次の機会にじっくりお伺いするとして、今回は「Self-hosted LiveSync」やObsidianの「データ同期」問題に切り込んでいければと。
まずこのプラグインを作ろうと思ったきっかけについて質問させていただきたいんですが、何か「これ」という出来事があったんでしょうか?
きみのぶ: Obsidian公式のデータ同期機能である「Sync」は会社的にNGなんだけど、同期したいというのが一番大きいと思います。
よくTwitterでポロリと言ってますが、僕の職場はいわゆる製造業で……クラウドサービスを使うのに凄く強烈な制限があるんですね。なので、なんとかして同期するには会社内にサーバを置くしか無い、そしてそれにつなげるクライアントを書かねば、という気持ちで一気に実装しました。
Pouhon: 職場によってはかなり厳しいですもんね。 そこで「PouchDB」というアプローチになるわけですか……。
PouchDBとCouchDB
Pouhon: Self-hosted LiveSyncを理解するためのカギとなる用語がこの「PouchDB (パウチDB) 」と「CouchDB (カウチDB) 」です。
これに関してはきみのぶさんご自身が、GitHubのページに「技術的な内容」として日本語で記されています。
ぜひ冒頭の図だけでもご覧いただきたいんですが、この図の内容を僕なりに解釈して補足すると、
- PouchDBとは、ローカル環境で動作する簡易的なデータベースである
- CouchDBとは、リモート環境で動作する簡易的なデータベースである
- PouchDBとCouchDBは互換性があり、相互に通信して内容を同期できる
という理解でよろしいでしょうか?
きみのぶ: はい! そうです。Obsidianのフロントマター (メタデータ) のような形……JavaScriptで言う連想配列 (オブジェクト) をそのまま登録できるデータベースですね。
実はCouchDBは知られざる「つよつよDB」でして、案外色々なところで使われています。そのCouchDBをブラウザで動くようにしたのがPouchDBです。
Pouhon: つまりSelf-hosted LiveSyncをインストールするということは、「Obsidian内部にPouchDBというデータベースを構築する」ことでもあると。
「じゃあリモート側のCouchDBはどうする?」というのが次の話になるんですが、こちらは複数のソリューションが用意されています。
IBM CloudantとFly.io
Pouhon: きみのぶさんがこれまでご提案されてきたのが「自前サーバ (完全なるセルフホスト) 」と「IBM Cloudant」です。
前者はサーバとなるマシン (パソコン) から用意する必要があるということで、初心者向けではないのでここでは省略するとして、IBM Cloudantはアカウント登録を済ませてしまえば、あとはこちらのページに従ってセットアップすれば使えると。
CouchDBのセットアップ手順としては、現在も変更などはありませんか?
IBM Cloudantの問題点と代替案
きみのぶ: 基本的にはそのままで大丈夫です。ただ場合によってはいくつかの問題が起こる可能性があります。
IBM Cloudantは使い始めると一番安定したサービスなんですが、なぜかアカウントが停止されてしまう事例があるようです。
さらにクレジットカードの問題もあります。利用自体は無料でできますが、アカウント登録にはクレジットカード情報が必要なんですね。しかし3Dセキュアが設定されて「いない」カードでないと登録できないという制約があって、ここが人によっては大きなハードルとなってしまっています。
このあたりで苦労してしまうのもよろしくないので、何かいい代替が無いかと探していました。色々と模索する中で、最近やっと発見したのが「Fly.io」です。
「使うのに難しすぎたらどうしよう?」とか「思ったよりお金かかったらどうしよう?」と思ってGitHubのDiscussionで意見を伺ってましたが、どうやらうまくいけそうで、今後はこちらを推奨しようと考えています。
Fly.ioのセットアップ
Pouhon: Fly.ioは僕も知りませんでした。調べてみたところ、Windowsの「Powershell」やMacの「ターミナル」といったコマンドプロンプトでインストールして、コマンドプロンプトでアカウント登録する形ですね。
きみのぶ: セットアップの手順はYouTubeにアップしているので、ひとまずはこちらを参考にしていただければと思います。この動画にはテロップも何も付いていませんが、テロップ付きの動画を後日改めてアップする予定です。
使用しているのはMacですが、Windowsもほぼ同様の手順でかまいません。
Pouhon: これはありがたい動画ですね! インストールから実際に使い始めるまで、全てが網羅されています。
ただコマンドプロンプトに慣れていない方にはハードルが高い気もするので、IBM Cloudantという選択肢も残しつつ、どちらか選んでねという感じになるんでしょうか?
きみのぶ: やはりハードル高いですよね……黒い画面に馴染みが無い方もかなり多いと思います。
日本語のUIが無いので、僕も「本当に無料で使えるかどうか」を見定めるまでめちゃくちゃ時間がかかりました(笑)
Fly.ioは「実質無料」
Pouhon: Fly.ioは従量課金制で、アップロードの転送量によって金額が変わってくるんですよね。ただ月々30GB以下のアップロードであれば、無料で利用できるという仕組みになっています。
「30GB」と言われてもなかなかピンとこないので、何か具体的な目安があればわかりやすいかなと思うんですが……。
きみのぶ: 僕のVault (300MB) を5台の端末に同期させて、だいたい月に1GBの転送量です。Vaultを数回作り直すと5GB程度ですね。
Pouhon: ほとんどの方は「実質無料」の枠に収まると。
きみのぶ: Self-hosted LiveSyncをまず使うにはIBM Cloudant。それで困った場合や、不自由を感じた場合はFly.ioという形がおすすめでしょうか。
Fly.ioはIBM Cloudantではできない細かな部分の設定が可能なので、ある程度vaultが大きくなった方にはおすすめしたいですね。
Self-hosted LiveSyncの初期設定
Pouhon: ここまでの手順でローカルのデータベースとリモートのデータベース、2つの要素が出揃ったということになります。
- プラグインのインストール (PouchDBの構築)
- IBM CloudantやFly.ioのセットアップ (CouchDBの構築)
ここからはプラグインの設定画面で、2つのデータベースを接続して同期する作業に入るわけですが、この設定項目がかなり多くて、初心者には厳しい印象でした。
しかしversion1.15以降ではセットアップウィザードが追加され、さらに日本語のドキュメントもご用意されたということで、これは嬉しいアップデートとなりましたね。
初心者に優しくなった設定画面
きみのぶ: 以前の設定画面は「みんなに必要な項目」と「踏み込んだニーズのための項目」がはっきり分離されていなくて、完全なマニュアルも無かったので、詳しくない方にはかなり扱いが難しかったと思います。
Pouhon: ざっくり50項目くらいがほぼ同列に並んでましたからね……あれはキツかった(笑)
きみのぶ: 今回お話していく中で不要な項目や、一般ユーザーはまず使わないような項目を洗い出せたので、とても良い機会でした。
Pouhon: それにしても、「修正する」とおっしゃってからのアップデートが異様な速さでしたね。
きみのぶ: 最初は不要な項目を削るだけのつもりだったんですが、勢い余ってマニュアルまで書いてしまいました(笑)
Pouhon: きみのぶさんの底力を垣間見た気がします(笑)
そんなわけで、複雑な設定項目のおかげで使用を断念してしまったユーザーの方にも、v1.15以降はかなりとっつきやすくなっているんじゃないでしょうか。
マニュアルを読んでもわからない点があれば、GitHubのIssueやTwitterアカウントにご連絡いただくということで。
きみのぶ: そうですね。お気軽にお問合せください。
使用上の注意とメンテナンス
Pouhon: 設定が完了してしまえば、後の作業は「競合の解決」程度なので難しくはありません。競合の解決に関しては少し後に補足するとして、他にこのプラグインを使う上での注意点は何かありますか?
きみのぶ: メンテナンスとしてのポイントは、
- プラグイン使用前に必ずバックアップをとっておく
- 定期的に「Remote Database configuration > Rebuild everything」を実行して、リモートのデータベースをクリーンな状態に保つ
- プラグインをアンインストールする場合は、事前に「Hatch > Discard local database to reset or uninstall Self-hosted LiveSync」を実行して、ローカルのデータベースを削除する
この3点ですね。また同期するフォルダは、
- GoogleドライブやDropboxなどのクラウドストレージではない場所に配置
してください。
できれば同期と並行して、定期的にバックアップを更新することをおすすめします。
Pouhon: 同期するということは「複数の場所に同じものが存在する」ということになると思うんですが、それでもバックアップは別で必要だと?
きみのぶ: そう思います。ただ、持って回った言い方をすると、「同期した結果」をバックアップしておけば事足りると思いますね。
バックアップのポイント
Pouhon: 「同期した結果」というと、たとえば
- 端末1と2で生じた変更が、リモートにアップロードされる
- 両方の変更を踏まえたデータが端末3にダウンロードされる
このとき端末3とリモートの内容は同じになるわけですが、これを「同期された結果」と考えてよろしいんでしょうか。
言うなれば「一旦安定した状態」?
きみのぶ: その通りです! その安定した状態も、何らかの要因によって簡単に変更され得るはずなので、プラグインで同期されたものは厳密にはバックアップではない、という感じですね。
僕はAndroid携帯で受信したものを「FolderSync」というアプリで数時間ごとにOneDriveに保存してますし、たまに同期先のデータベース名を変更して、ある時点のデータベースを温存してます。
コピペでも何でも良いと思いますが、簡単には変更されない場所にデータを保存しておくことは重要です。
Obsidian GitやRemotely Saveとの比較
Pouhon: もう1つ聞いておきたい話題として「Obsidian Git」や「Remotely Save」があります。
どちらもObsidianのデータを複数デバイスで同期するためのプラグインですが、これらと比較してのSelf-hosted LiveSyncの立ち位置や対象ユーザーの違いについてはどのようにお考えでしょうか?
きみのぶ: Obsidian Gitは僕も昔使っていました。ただやはりモバイルで使えないというのはなかなかのハードルでしたね。最近ではモバイルアプリにも対応したようですが、まだ発展途上の感は否めません。
Remotely saveはリリースされた当時、「これは比較されそうだな」と感じていたんですが、実は少し毛色が違うと思ってます。
Remotely Saveとの決定的な違い
きみのぶ: LiveSyncもGitも、ローカルにデータベースを持ってファイルの変更をトレースし、それをサーバに持ち寄るという思想でデータをやり取りしているので、必然的にデータの競合を検知することができるような仕組みになってますし、転送も必ず差分のみになります。
それに対してRemotely saveは「あくまでリモートに保存する」という延長にあるので、競合の解決には少し課題があるかなぁと。あとは「転送量が大きい」というのも、若干ネックですね。
Pouhon: 競合の解決がしやすいのは、確かにかなりのアドバンテージだと思います。クラウドストレージでは、これがなかなか難しいんですよね。
データの競合とは?
Pouhon: 「データの競合」について僕の方で少し解説しておくと、複数の端末で同じファイルに異なる編集があった場合、ファイル名は同じだけど、内容が異なるデータが両方リモート側に送られると。この時点でお互いのファイルは内容的に「競合している」わけですね。
このとき、理想としては双方の変更を正しくマージした1つのファイルが残るべきで、これを「競合が解決した」状態と言います。
しかし一般的なクラウドストレージではこれができない。どうなるかというと、「◯◯1.md」「◯◯2.md」という複数のファイルが生成されてしまう。
これに対応するには、ファイルの変更が「いつ」行われたかだけではなく、「どこを」「どんなふうに」変更されたかという点も考慮しなければならない。それができるのがLiveSyncやGitであるということですね。
きみのぶ: クラウドストレージを使うRemotely Saveでは、ファイルが生まれて、削除されて、また作成される、というパターンにも弱いです。
同期するタイミングによってはかなりヤバいことになってしまうというのは、やはり辛いところかもしれません。その点、LiveSyncやGitはいつでも任意の所に戻せます。
「同期」に必要な要素とは
Pouhon: つまり、バージョン管理や競合の解決ができる機能を備えてこその「同期」である?
きみのぶ: これは難しいですね。人によっては上書きで良いのかも……。
片方をもう片方に従わせるだけなら比較的簡単なのですが、どちらが主でどちらが従でもない関係で足並みを合わせて動くというのは、それを軸に据えて最初からやらないとできません。
ただ、足並みさえ合わせればちょっとの微調整で、お互いの現在地を一度に合わせることができる。この仕組みが「同期」だと思ってます。
Pouhon: なるほど……頻繁に起こる「ちょっとしたズレ」を調整できると。
逆にRemotely Saveを選ぶとしたら、そのメリットは何だと思われますか?
きみのぶ: Remotely Saveの強みとしては導入コストが低いことで、圧倒的に簡単なんですよね。このあたりは競合の解決を切り捨てても、簡単に使えることを優先したという潔さを感じます。
今後の予定について
Pouhon: 最後に今後についてお伺いしたいと思います。
Obsidianはversion0.16でタブ機能が実装されましたが、それに伴って近々大きなアップデートが予定されているということはありますか?
またLiveSyncに今後追加したい機能や、新たな方向性などあればお聞かせください。
きみのぶ: 実は予定は白紙ですね……ただ、ぼんやり思ってることは結構あります。
別ウインドウが出せるようになったあたりから、ドキュメント履歴やマージ用のペインみたいなものが欲しいなと思っていました。TagFolderでTagScrollを作って以来、ペインを作るのが少し楽しくなってますね。
Pouhon: ペインというと、たとえばサイドバーで開くタグ一覧とか、Calendarプラグインのカレンダー表示部分のような?
きみのぶ: そうです。もし標準でタブ機能が有効になったら、ずっと出してても便利じゃないかな、と思っています。
あとは大きなファイルの処理の最適化と、バックアップやデータベース最適化関連ですね。
LiveSyncは「いずれデータベースは再構築される」という開き直りのもと、データベースを富豪的に使用しているんですが、もう少し後始末しながら使えばファイル履歴を保ったまま使えそうだなぁ、と。
そんな感じで「新しい機能!」というよりは「地味に使いやすい」って感じにしていきたいですね。
Pouhon: データベースを「富豪的に使用する」というのは、具体的にはどんな感じなんでしょう?
きみのぶ: LiveSyncは、使わなくなったデータをほぼ消さないんです。
基本的には変更のあった部分を差分として保存していくので、転送量自体は多くありません。それでも普通に使っていると、データベース自体の容量はだんだんと大きくなります。
なので定期的に「Rebuild everything」でデータベースの内容を一旦捨てて再構築する事を推奨しているんですが、その時に履歴も全部消えてしまう。
そこで「使ってないもの」を正しく削除できれば、もしかすると現在の仕様よりも長く、同じデータベースを使えるんじゃないかと考えています。
Pouhon: よりクリーンでメンテナンスフリーな方向にシフトしていくということで、期待しましょう。
ということで、今回はきみのぶさんにゲストにお越しいただき、「Self-hosted LiveSync」についてお話いただきました。ありがとうございました!
きみのぶ: こちらこそ、ありがとうございました!
Pouhon: きみのぶさんには、もう1つのプラグインである「TagFolder」についても、後日お話を伺う予定です。そちらの方も楽しみにしております。