先日書いた Day One のバックエンドで障害 - portal shit! について、 Day One のヘルプページで詳細を説明する記事が掲載されていました。

301 Moved Permanently

301 Moved Permanently

help.dayoneapp.com

ウェブアプリケーションエンジニアの皆さんが読むと参考になるのではないかと思い、翻訳の可否をたずね許可をもらったので翻訳します。


2018 年 5 月の Day One 障害報告

執筆者: Paul Mayne (訳注:Day One の創業者)
今週更新(訳注:障害復旧日の午後に公開されました)

2018 年の 5 月 7 日から 10 日にかけて、 Day One は重大な Sync サービスの停止に陥りました。ユーザーの皆さんから堅牢な Sync サービスを期待されていることはわかっていますし、この出来事は我々の基準を満たすものでもありません。何が起こったのか、そして将来にわたってどのようにこの問題を回避していくかをユーザーの皆さんにお伝えしたいと思います。

簡単なまとめ

5 月 7 日にハードウェア障害が発生し、最初の Sync サービスの停止が発生しました。バックアップデータが不完全だったことが原因で、 5 月 8 日の Sync サービスの復旧処理中、一部のユーザーのアカウント ID が既存のユーザーのものと重複してしまいました。結果、一部の新規登録ユーザーは他人の記事を見ることができる状態となっていました。問題に気がついてすぐに Sync サービスを再び停止させました。対象のユーザーは 106 人で、これは我々のユーザー全体の 0.01% よりも少ない値です。

現在、 Sync サービスは正常に復旧しており、記事が他人に見られることはありません。近日中(訳註:すでにリリース済みです)に意図せず共有されてしまった記事を削除するアップデートを提供します。

End-to-end の暗号化を施していた記事は今回の事故の対象外です。

いかなる偶発的な個人情報の漏出も信用を毀損するものであると我々は認識しています。この不幸な状況にあって我々は、正直に状況を説明することが最善だと思っていますし、また信頼を回復するために全力を尽くしています。今回、個人情報の流出被害にあった 106 人のユーザーには終身の Premium メンバーシップを無償提供し、それぞれ個別に連絡を取っています。自分たちにできるあらゆることを行ってみなさんの信頼を回復していきたいと思っています。

障害の詳細

5 月 7 日月曜日、 Day One の社員が DB サーバーでハードウェア障害が発生していることに気がつきました。問題のあるサーバーをデータベースクラスターから取り除く作業とデータを残りのサーバーに分散する作業を始めました。

データの分散処理に失敗します。これが最初の障害です。すぐに Sync サービスを復旧させたかったため、新しいデータベースクラスターを作成して最新のバックアップデータを読み込むことにしました。新しいクラスターがセットアップされ、バックアップが読み込まれました。

5 月 8 日火曜日の早い時間に復旧処理が完了し、 Sync サービスを再開しました。当初は順調に動いているように見えました。しかし数時間で「自分の記事ではない記事が見える」という問い合わせが何人かのユーザーからありました。これは由々しき事態であり、我々はすぐに Sync サービスを再停止し、これ以上被害が拡大しないようにしました。

この時点で、問題と対応方法の調査を行う間、 Day One Sync を無期限に停止する旨をソーシャルメディアに投稿しました。何が原因なのか、何が起こっているのか、そしてもう問題が起こらないと確信できるまで Sync サービスは再開できませんした。

5 月 9 日水曜日の午前、問題の根本原因を突き止めました。復旧処理に用いたバックアップデータが不完全だったのです。記事データは完全なものでしたが、ユーザーアカウントデータに欠落がありました。具体的には、 3 月 22 日よりも後に作られたユーザーアカウントデータが含まれていなかったのです。その結果これらのユーザーはログインすることができていませんでしたし、特定の記事データが意図せず他人から見えてしまうという問題につながりました。

それぞれの記事データベースは “accountID” というフィールドを持ち、どのアカウントがその記事の所有者であるかを判断しています。全ての記事データは正しく復旧されましたが、ユーザーアカウントデータはそうではなかったため、データベースに所有者が存在しない記事ができてしまいました(例えば “My Travel Journal” という記事は 123456 というアカウントのものだったとしましょう。しかしそのアカウントが存在しなくなってしまったということです)。新しいユーザーアカウントの ID は連番で作られます。復旧されたデータは最新のユーザー情報を含んでいなかったため、 5 月 8 日に新規登録したユーザーは本来よりも小さな値の ID で登録され、既存のユーザーアカウントと重複することになったのです。その結果、これらの新規ユーザーはすでに存在する他人が書いた記事を読めるようになってしまったのです。

5 月 8 日の問題が発生していた期間のうちに、 326 アカウントが正しくない account ID で作成されました。その 326 個の ID のうち、 106 個が別人によって書かれた既存の記事データに結びついていました。 2018 年の 3 月 22 日から 23 日に作成されたアカウントは他人から記事が見られる状態になっていたということです。それらは account ID 1104506 から 1104831 の人たちでした。

現在のところそれらの記事のうちどれくらいが end-to-end の暗号化処理をされていたかはわかっていませんが、 end-to-end の暗号化をしていた記事は今回の問題でも他人に見られることはありませんした。

水曜日の調査の後、元のデータベースでデータの分散処理に失敗する問題を解決することが最善の選択肢だと判断しました。いくつか設定ミスがあり、データベースの負荷が高まる原因になっていることがわかりました。この負荷が原因でデータの分散処理が失敗していました。

水曜日の午後、この問題を修正し、元のデータベースクラスターで分散処理が正しく完了することを確認しました。しかしエンジニアチームとサポートスタッフが万全の態勢で臨めるよう、 Sync サービスの再開を木曜の朝まで遅らせることにしました。山岳時間で 5 月 10 日木曜の午前 8 時、 Sync サービスは再度有効化されました。

同期サーバーには大量の待機処理があったため、それらの処理が終わるまでは少しパフォーマンスに問題があるかもしれませんが、なるべく遅延が発生しないように対処しています。

今後どうするのか?

意図せず共有されてしまった記事を削除する機能が入った Day One.app のアップデート(バージョン 2.6.4 )をすぐにリリースします(訳注:すでにリリース済みです)。このアップデートをインストールすると、未ログイン状態のユーザーの端末からは非公開の記事はすべて削除されます。対象ユーザーはアップデートのインストール後 30 日以内に Day One アカウントにログインすることが必要で、このログインをもって Day One.app はログインユーザーを記事の所有者であると認定し、記事を復元します。 Day One.app は影響を受けるユーザーに対してこの変更内容を通知します。

今後、同様の問題が起こらないように、近々以下の改修を同期サーバーに対して施します。

  1. account ID の新規作成時、すでにその ID で記事が作成されていないかをチェックします
  2. 新規の account ID に対しては、連番の数字に加えてランダム生成された二桁の数字を末尾に付加することにします。将来、同じような問題が発生して連番 ID が若返ってしまったとしても ID の衝突が起こる可能性は非常に小さくなります。
  3. いくらかのユーザーアカウントがバックアップ対象から除外されてしまう問題を修正します。

他人に記事を見られてしまった 106 人のユーザーに対しては真摯に謝罪します。対象のユーザーには終身 Premium メンバーシップを提供するとともに、その他懸念点がないか個別に連絡をとっています。今回、大規模な情報流出は起こっていません。第三者がデータベースに侵入したということもありませんし、すべてのデータは我々のサーバーで安全に保管されています。しかしながら 106 人のユーザーの我々に対する信頼は失われてしまいました。信頼は獲得するものであり、与えられるものではないということを承知していますし、再び皆さんからの信頼を取り戻せる機会を得たいと思っています。ユーザーの皆さんには 2017 年 6 月にリリースした end-to-end の暗号化機能を利用することを推奨します。この機能は今回のような事故やその他の問題があったときにもあなたの個人情報を保護します。

今回の障害で Sync サービスを利用できなかった間、辛抱して下さったユーザーの皆さんに感謝します。皆さんが Day One を使って大事な思い出を記録していることを理解しています。今後、よりよくしていくことをお約束します。信頼を回復するため、全力を尽くします。

— Paul

Day One という日記書きソフト、愛用しているのだけど今週頭に障害が発生して日本時間で 2018/05/11 の明け方まで同期ができない状態になってた。

Sync Status | Day One Help

ユーザーとして不便だったけど復旧にかなり時間がかかったのがソフトウェア開発者の一人として興味深かった。何が原因で復旧が遅れたのか推測した。

Day One のバックエンドは AWS に構築してあるようで、負荷でサーバーがダウンしたのなら EC2 インスタンスを追加してサーバー再起動すれば良いはずなのですぐ復旧できるはずと思ったが、一向に復旧しない。復旧作業の状況報告ページにしきりに “server rebalance” というフレーズが出てきており、アプリケーションサーバーで “rebalance” なんてことはやらないから、どうもデータベースがクラッシュしたようだった。

Day One のバックエンドエンジニアの採用情報見たら技術スタックが書いてあって、開発言語は Scala で DB は Couchbase を使ってるとのことだった。で、 Couchbase では Shared Cluster の rebalance という作業が必要らしい。

Couchbase は CAP 定理のうち一貫性と分断耐性を保証していて、その代わりに可用性が犠牲になっている(Couchbase Server - Wikipedia)。 Day One では複数のクライアントからほぼ同時に同一ドキュメントに対して更新が走ることが多いし、 iOS からは不安定なモバイル回線経由で接続される。かつては Dropbox や iCloud も同期のバックエンドとしてサポートしていたが、コンフリクトしたり意図せぬデータ欠落などがあったと思われ、自前のバックエンドシステムに移行したのだろう。一貫性と分断耐性に特化した Couchbase はユースケースとして最適に思えるが、障害が起こるとリバランスに手間取り復旧の難易度が上がるようだった。

自分は大規模分散データベースみたいなやつは受託の会社に勤めてた下っ端の頃にしか使ったことがなく、自分でがっつり運用・構築したことがないので大規模データベースに対する知識が足りていないと思う。大した考察は出来ていないが、今後もバックエンド API おじさんとして余生を過ごしていく上で参考になる出来事だった。そのうち詳細な post-mortem が Day One のエンジニアによって公開されるようなのでこちらもあとで読んでおきたい。

あまりに復旧が遅かったのでこのままサービス終了するのではないかと心配になったが、何とか復旧出来たようである。 Day One のバックエンドの皆さんおつさまでした 🍵

🤩人気記事を表示するようにした - portal shit! で人気の記事を表示するようにしたけど、人気のエントリー(直近一ヶ月間でアクセス数が多い記事)に加えて、ホットエントリー(はてなブックマークでブックマーク数が多い記事)も表示するようにしてみた1ところ興味深い結果になった。

スクリーンショット 2018-02-08 10.09.53.png

短期的に膨大なアクセスを集める記事と長期的に安定したアクセスを集める記事は全く異なる。はてブのようなサービスで見つけられるのは前者で、後者のような記事を見つける場所が意外にネットにはないのではないかと思う。前者を動的な人気記事だとすれば、後者は静かな人気記事だと言えるだろう。こういう静かな人気記事だけを紹介するウェブサービスがあっても面白いのかもしれない。ちなみに人気のエントリーのリンク元は Google を除くとだいたいヤフー知恵袋か 2ch の過去ログが多い。


  1. このサイトの はてブの RSS を利用しています 

ツイッター歴10年を超え、どういうウプダテスをしたらファボをもらえるかはだいたい予想がつくようになってきたけど、それよりも前からやってるブログに関してはどうやったらバズるかがわからない。 mizch さんがブログを書く前にどのくらいブックマークが付くか想像できると言ってた気がする1けどそういうのすごいと思う。「もうちょい反応あるんじゃないかな」と思った記事が全然伸びなかったり、逆に完全に自己満足のために書いた記事がバズったこともある。ツイッターもブログも商売と同じで読み手に価値を提供することができたら良い反応があるものだと思う。ツイッターに関しては面白ツイートで読み手に価値を提供できている(自分が面白いと思うものが読み手にとっても面白いと評価されている)のだろうけど、ブログでは価値を提供できていない(少なくとも狙ってはやれていない)のだろう。

短文で面白おじさんを演じるのは簡単だけど、長文だととても難しくなる。自分で自分が書いた過去の記事を読んでも「滑ってるなぁ」という感じしかしない一方で、たとえば寿司について書いた記事はいま自分で読んでも「攻めてるなぁ」と感じる。また仕事で社内ブログに記事を投稿してもそこそこ反響得られてるので文章を書く能力が著しく低いわけではないのだと思う。

つまるところ自分はブログで記事を書くときに、自分の興味関心とオーディエンスの興味関心を一致させられていないのだろう。ツイッターや社内ブログでは読み手が誰であるかを把握するのが簡単なので事前にコンテキストを共有した上で記事を書ける。コンテキストが共有されているのでどんな内容が受けるかを想像しやすいのだ。しかしブログの場合は誰が読むかは見当がつかない。パソコン関係の記事が受けるのか、日記的な雑文が受けるのか、蓄財についての記事が受けるのか、あるいはそれ以外か、全く見当がつかない。

15年前にブログが流行ったとき、ブログはテーマを絞った方がいいというアドバイスをよく目にした。思えばそれは読者の種類を絞り、読み手とコンテキストを共有することで記事を書きやすくするためだったんだろうなぁと思う。

自分はなんでもブログに書くスタンスでやってきたので今更書く内容を絞ったりはしたくないんだけど、今年は読み手とのコンテキストの共有を意識してインターネットしていきたい。


  1. ブログを書き続けること - mizchi's blog読まれるテキストは読者へのおもてなしの構造を持っている - mizchi's blog あたりで書いてたような気がするけどそんなことなかった。ツイッターでの発言かもしれない。 これだった ブログで何を書くべきか - mizchi's blog 

connpass で募集されていた勉強会に参加したところ、イベント終了後にイベント管理者から一方的にメールマガジン的なものが送られてくるようになった。勉強会直前の確認メッセージや次回の勉強会の告知ならよく他のイベントからも届くが、そうではなく主催者の私信的な内容だったのでこのようなメールは不要だった。大抵の一斉送信メールにはフッターなどに購読解除ページへのリンクなどがあるが、 connpass から届くメールにはそのような文言はなかった。

スクリーンショット 2018-01-11 21.50.31.png

最初なぜこのような私信メールが届き続けるのかわからなかったが、自分が管理者になっているイベントで確認してみたところ、管理画面からイベント参加者に任意のメッセージを一斉送信することができるようだった。 connpass はイベントに参加登録すると自動的にイベントのグループに追加されるので、グループの管理者はグループメンバーにメッセージを一斉送信する仕組みがあるようだ。勉強会に参加しただけで一方的にグループのメンバーにされてしまうのは違和感がある。

とりあえず今回はメールマガジンは受信したくないと思ったので該当のイベントページから主催者に「勉強会に参加したときにこのようなメールを送り続けるという説明はなかった、メールマガジンを受信したくない」旨の問い合わせを行い、あわせて connpass にも「勉強会参加後に定期的にメールが届くようになった、同意なしにこのようなメールを送り続けるのを規約上容認しているのか」を問い合わせた。イベント主催者の方からは即座に返信があり、今後メールが届かないようにしてもらえた。 connpass の方(運営元のビープラウド社)からは一週間後に返信があり、自分でイベント主催者とやりとりしろという旨の文章と利用規約ページへのリンクが貼ってあるのみで、自分が尋ねた規約上容認しているかどうかへの回答は書かれてなかった。

そもそも自分が情弱だったのだが、勉強会参加後に自動的に登録されるグループから退会すれば主催者からの一斉送信メールは届かなくなるようだ。自分の場合には当該グループから退会すればよかったのにイベント主催者に苦情めいた問い合わせを行ってしまい申し訳なかった。ただ退会ボタンはぱっと見 disabled されており、到底クリックできるようには見えないし、そもそも退会することでメールが届かなくなるかどうかはわからない(ヘルプページをよく読まない限り退会することで何が起こるのかわからない)。

スクリーンショット 2018-01-11 8.36.11.png

そもそもメールのみの受信設定を行えるような画面があってもよいと思うのだが、調べてみたところ新しいイベントが公開されたときや資料がアップロードされたときの通知設定は行えるが、イベント主催者からのメッセージを受け取らないようにする設定項目は存在しなかった。

スクリーンショット 2018-01-11 8.36.31.png

connpass 内全体の各グループで適用される受信設定も同様で、イベント主催者からの恣意的なメッセージを受け取るかどうかの設定項目はなかった。

スクリーンショット 2018-01-11 8.36.40.png

いらないものを拒否する手順への説明が記されておらず、自分の意図に反して送られてき続けるメールは全て迷惑メールだと思うが、運営元に問い合わせる限りはこれらは規約違反でもなくイベント管理者は自由に行えるようなので、 IT 勉強会を主催している各社の採用担当の皆さんは一度でも勉強会に参加したことがあるカモの皆さんに求人メールを定期的に送り続けてやれば良いのではないでしょうか。

ウェブはバカと暇人のものから 10 年も経っていないけどインターネットの世界は大きく変わった。NHK を含む大手マスコミが Twitter を賑わせた事象の解説をニュースで行うほど。低所得の暇人しかいないというのも違ってきてる。 Facebook や Instagram には裕福な生活を満喫していて金持ちアピールに余念がない人たちが掃いて捨てるほどいる。アフィリエイターはカスばっかりというのも嘘で、おそらく士業についてる高収入な人たち1がマイル乞食をしてハワイに行ったりビジネスクラスに乗って箸でスッチーのスカートをつまみ上げてパンティーを覗いたりしてる様子を公開してる。ネットは決してバカと暇人だけのものではなくなってしまった。ネットに社会的地位や経済力がある人たちが流れ込んできている。スマートフォンが登場し、誰でもいつでもネットに接続できるようになった。金持ちもネットの魔力に抗えなくなってきたのだろう。明石家さんまは相変わらずブログをやってなさそうだが2、 SMAP は解散しジャニーズ事務所を辞めた連中はブログを書いてるし Twitter も始めたし AbemaTV に出てる。中川淳一郎さんのウェブに対する当時の考察は当たっている部分もあったとは思うが、自分が当時の書評記事の最後で書いているように Twitter 、 Facebook 、 Instagram など3が日本で本格的に浸透して結果的には全く違う状況になってしまった。本当に面白い。

ウェブはバカと暇人のもの

ウェブはバカと暇人のもの

梅田望夫さんの言うウェブの世界は頭のいい人しか相手にしてない、ってところからスタートして、ネットの否定というか、Web 2.0とか梅田望夫的楽観論の否定が延々繰り返される。ネットが普及しすぎたおかげでネット人口に占めるバカの割合が増えてしまったとか。以下印象に残った点を列挙...

portalshit.net


  1. 仕事をしていないせいで暇なのではなく確固たる社会的地位を築いた上で時間を自由に使える人々のこと。クレジットカードのポイントでマイルを貯めるためには年会費の高いカードを所持し、かなりの額の決済をカードで行わなければならない。 マイルを貯めたいと思ったら小学生に戻って人生やり直さないと無理なことに気がついた 

  2. 一応公式ブログはあるようだが宣伝記事が一つあるだけだった。 明石家さんまのブログ 

  3. 予想に反して Tumblr は大して流行らなかった。 David Karp は会社を辞めてしまった。 David Karp Is Leaving Tumblr. Read His Retirement Letter Here | Fortune 

DSC_4054

以下の文章は正月に「2017 年の Lokka へのコントリビュート目標」というタイトルで書いたまま下書きになってたものです。もう 2017 年も終わりそうだけど公開しておきます。


RubyKaigi 2016 で komagata さんと Lokka についてしゃべったのだけど、 Lokka の開発も停滞してしまっていて(ブログとしては大体の機能そろっていて完成しているとも言える)、 "lokka" でググると JavaScript 製の GraphQL クライアントがヒットして、 GitHub のスター数ではこっちの方が多かったりする。

kadirahq/lokka: Simple JavaScript Client for GraphQL

このままで紛らわしいからその名前こっちに寄越せ、とか言われかねない。もっと Lokka を盛り上げていきたい。

なので一度仕切り直しで今後の方針とかをどうするかを決めた方がよいのではないかと思っている。まずは Issue の棚卸が必要ではないかと思う。

加えて自分でも結構いろいろ lokka-plugin を作っているのだけど、個人のリポジトリに適当に上げてあるだけだとユーザーとしては利用しづらいと思う。そこで GitHub の Lokka org に lokka-plugins というリポジトリを作って、とりあえずそこにコードを集約するようにしたらどうかと思う。前に Rebuild で Jenkins の川口さんが話していたやり方。

OSS 、コードが素晴らしいことも大事だけど、利用しやすくないとユーザーに使ってもらえなくて盛り上がって行かないと思う。プラグインを使いやすい、作りやすいようにして裾野を広げていきたい。

ほかにも手軽に使ってもらうためにはいくつかやらないといけないことあると思う。 gem 化は是非とも必要だと思う。 Lokka 動かすために本体のソースコードごと管理しなければいけないのはやっぱり結構敷居が高いと思う。ディレクトリ作って Gemfile に gem 'lokka' と書いて bundle install し、 theme と db config さえ置けば動くようになるのがよさそう。ファイルをアップロードする仕組みについてもどうにかしたい。 Heroku 運用が前提のためファイルシステムを使うことができず本体にそういう仕組みがなかったのだと思う。 Amazon S3 や Google Cloud Storage 、 Dropbox 使えるようにするとかやり方を考えたい。

これらを推し進めるために、以下のことをやりたい。

  1. Lokka 開発者ミートアップを開催
  2. Slack にチームを作ってコミュニケーションできるようにする

1 は RubyKaigi のときに komagata さんに提案したけどそのあと動けてなかった。とりあえずは自分が komagta さんのところに会いに行くだけになるかもだけど、 Issue の棚卸と今後の方向性を固める会をやった方がよさげだと思う。仕事でも OSS でも意思や目的を共有しないと Project は先に進まないと思う。

2 に関しては Lokka は Lingr でコミュニケーションしていたが、いまは皆さん Slack を仕事で使っていると思うし Slack の方がコミュニケーションしやすいはず。というわけで Slack チームを立ち上げたい。1

という感じで 2017 年も Lokka の開発に関与していきたい。


転職して東京に行く機会がなくなり、結局 Lokka 開発者会議をやることはできなかった。プラグインの gem 化はおろかリポジトリへの集約も DataMapper => ActiveRecord への移行も手を付けられなかったが、それ以外で Lokka の改善は結構頑張ったと思う。

今年やった Lokka の改善

  • パーマリンク生成高速化 https://github.com/lokka/lokka/pull/220
    • Lokka はどのフォーマットで permalink を生成するかを DB に保存している
      • リンクを一つ生成する度に permalink のフォーマットを調べるためのクエリが流れる
    • ビュー内で各記事へのリンクは多数
      • めっちゃクエリが流れる 😱
    • request_store.gem を使ってリクエストごとに一回だけクエリが流れるようにする
      • テーマにもよるが記事一覧でパーマリンク生成のために 10 回くらい DB アクセスが発生していたところは 1/10 になる
      • 管理画面の記事一覧では 100 記事表示しているので 1/100 になる(爆速になった!!!、!)
  • 管理画面をスマートフォン最適化 https://github.com/lokka/lokka/pull/225
    • スマートフォンから管理画面が見やすくなるよう CSS を修正
    • 寝床からでもブログ書けるようになった!!!、!
  • ファイルアップロード機能を追加 https://github.com/lokka/lokka/pull/226
    • S3 にバケットを作ってもらいさえすれば GitHub のようにドラッグ&ドロップで画像をアップロード出来るように
    • めっちゃお手軽お気軽に画像アップロードできるようになって最高便利!!!、!
  • MySQL 絵文字対応 https://github.com/lokka/lokka/pull/230 😃
    • 今の時代、絵文字が使えないのはつらい 😅
  • Ruby 2.4 対応 https://github.com/lokka/lokka/pull/231
    • Lokka で Sinatra 、 DataMapper の次に依存度が高い PadrinoHelper のバージョンを上げることに成功(めっちゃ大変だった!!!、!)
      • 自分としては Rails 3 を Rails 4 に上げるくらいの働きをしたと思ってる😎

locale が i18n.gem がサポートしてるやつじゃないと 500 エラーになるという問題があって、こちらも自分のブログでは直してあるので修正する Pull Request を出したい。

P_BLOG のときもそうだったけど、どうも自分はユーザーの少なくなってきた CMS を細々と改造して使っていくのが好きみたいだ。このブログの開発・運用から学ぶことも多くて仕事にも役立っているので、まだしばらくは使い続けていきたいと思う。 Lokka は永遠に不滅です。


  1. 調べてみたらすでに lokka.slack.com は存在するみたいなんだけどこれって Lokka for CMS のやつですかね?