Raspberry PiのSDカードからデータをサルベージする

Raspberry Piを起動するとカーネルパニックになってしまった。VirtualBox内のLinuxでSDカードをマウントしようとするとマウントがずっと終わらない。fsckを実行してもエラーが発生してうまくいかない…。

なんとかデータのサルベージはできたのでその備忘録。

使用した環境

手順

  • SDカードをMacに認識させる
  • diskutil list を実行してサルベージするIDENTIFIERを確認(今回の対象はdisk2s2)
host$ diskutil list

...

/dev/disk2 (external, physical):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:     FDisk_partition_scheme                        *64.5 GB    disk2
   1:             Windows_FAT_32 boot                    66.1 MB    disk2s1
   2:                      Linux                         64.4 GB    disk2s2

...
  • ディスクユーティリティなどでdisk2s2がマウントされていないことを確認
  • ddを実行して中身を書き出す
host$ mkdir -p ~/raspi
host$ sudo dd if=/dev/disk2s2 of=~/raspi/raspi.img
  • 所有者を自分自身に変えておく(Docker内でマウントするときに困るので)
host$ sudo chown abcang raspi.img
  • docker内でマウントする
host$ docker run --rm -it -v ~/raspi:/raspi --privileged debian bash
docker# mkdir /mnt/raspi
docker# mount -o loop /raspi/raspi.img /mnt/raspi
docker# ls /mnt/raspi

これで /mnt/raspi にマウントされるので、必要なファイルを退避すれば完了

参考

ISUCON11の予選を突破しました!

今年もここ数年と同じメンバー(@mot, @syusui)で「チーム五年目」という名前で参加して、ギリギリ24位で予選を突破できました!! 本戦出場はISUCON 7以来なのでとてもうれしいです。

やったこと

言語はGoでやりました。(毎年ISUCONのときだけGoを書いている気がする。) 以下時系列順にざっくり起きたことを書いていきます。

  • mot: インフラ構築、kataribeとpt-query-digestを使えるようにする
  • mot: isu_conditionに(jia_isu_uuid, timestamp)の複合インデックスを作成
    • pt-query-digestで明らかにslowになってることに気がついたので対応
    • これだけで10000点を超えてびっくりした
  • syusui: ローカルで動かせるようにDB用のdocker-composeを用意
  • abcang: /api/trendでは最新のisu_conditionしか必要なかったのでLIMIT 1に変更
  • abcang: /api/trendのレスポンスを1秒ほどメモリにキャッシュ
    • 後に10秒に変えてみてもまだタイムアウトしたのでN+1を解決することに決めた
  • mot: ConditionLevelをカラムに持つように変更
    • Generated Columnsは使わず、愚直にinitialize時に変換したり、挿入時にConditionLevelも追加する形に
  • このあたりでDBの構成をどうしようかという話をして、最終的にisu_conditionのINSERTが重要になってくるだろうから水平分割にチャレンジするかということになりsyusuiが着手
  • abcang: /api/trendのisuの取得部分のN+1を修正
    • ついでにisuのimageを取得しないようにカラムをしぼったりもした
    • 今考えてみると、characterの順序について考慮してなくて挙動が変わってしまっていたがここはチェック対象外だったようだ…
  • mot: isu_conditionのPOSTをgoroutineで実行する形に変更
  • mot: dropProbabilityを変えてみて、一旦0.5に落ち着く
  • abcang: /api/trend用に最新のisu_conditionを1クエリで引けるようにする
    • 最新のisu_conditionを保持するテーブルを新しく作って、isu_condition追加時に更新するようにした
    • しかし、isu_conditionの追加時の処理がUPSERTではなくUPDATEになっていたため、新しいisuについて更新されない形になってしまった
    • 点数は上がったけどユーザーが増えなくなったぞ…?という話をしていた
  • mot: appとDBのインスタンスを分離してそれぞれ1台で動く形に変更
  • abcang: generateIsuGraphResponseがすべてのデータを取得していたので、特定の日付に絞って取得する形に変更
  • mot: 静的ファイルをnginxから返すように変更
  • abcang: UPSERTになってないことをsyusuiに指摘してもらって修正する
    • これによりユーザーは増えるようになったけど、スコアが全然出なくなってしまう
    • 仕方ないのでUPSERT処理をやめて、/api/trendは初期状態から変わらないようにした
  • syusui: 水平分割の準備ができたのでマージ
  • syusui: しかし整合性チェックに通らなくなってしまい、原因を探すも時間が迫ってきて結局諦めることに
    • なので最終的に構成はnginx+appが1台とDB1が台の合計2台
  • abcang: /api/trendは初期状態から変えないことにしたのでMax-Ageのレスポンスヘッダーを設定ようにした
    • よく考えたらメモリ側のキャッシュ時間も伸ばしておけばよかった
  • 最終的に最高スコアの108634点が出て、ここでコードフリーズすることに

f:id:abcang:20210823232423p:plain
スコアのグラフ

思いついたけど結局やらなかったこと

  • icon imageの改善
    • 画像はログインユーザーが登録したものしか表示されないのでそんなに問題にならないだろうと考えていて、計測してみて問題になったらやってみようという話で手をつけなかった
    • 今考えてみるとMax-Ageぐらいつけておけばよかったかもしれない(同じユーザーが何度もアイコンを取得していたかどうかは不明だけど)
    • isuのクエリ時にimageを除外する案もあったけど、結局あまり手を出せなかった
  • created_atとupdated_atの削除
    • DEFAULT CURRENT_TIMESTAMPになっているけど、一切使われてないので消すだけで若干INSERTが早くなるかも…?と思ったけど結局やらなかった
  • 不要そうなトランザクションの削除
    • SELECTしかしてないところでトランザクションがあったりと無駄な感じはあったけど、ボトルネックではないから後でいいか…と思っていたら結局直さないままになってしまった
  • /api/isuのN+1の修正
    • 1人のユーザーが登録するisuの数はたかだか知れているだろうから直さなくていいかと判断

感想

今回はしっかり計測しつつ遅いところから順番に修正できていたと思うのでよかったです。 ただ、/api/trendは最初の状態から一切替わらずユーザーが全く増えないという事になってしまったのは少し悔しかったです。 あと、得点計算についてはややこしくて理解を諦めてしまっていたので、これについては少しまずかったかな…と若干反省です。

予選を突破できたのはチームメンバーの力があってこそなので本当に感謝です。 過去に参加した本戦ではあまりスコアを伸ばせなかったので、今度こそは本戦でいいスコアが出せるように頑張りたいです。

最後に、運営の皆様ありがとうございました。本戦でどんな問題が出題されるのか楽しみです。

ISUCON 9予選の反省

ISUCON 9の予選に敗退しました。 前回のISUCON 8では同じように予選敗退して記事は書かなかったが、今回はよくない動きをしてしまったので戒めとして反省記事を書くことにした。(感想も書きます)

本番前

ISUCON今年はどうしようとTwitterでつぶやいたところ、ISUCON 6や7のときのチームメンバー(mot, syusui)が声を上げてくれたので、チーム3年目として参加することになった。

今まではrubyで参加していたけど、goで参加してみないか?とmotさんから提案があったのでgoで行くことになった。 goは一切書いたことなかったので、A Tour of Goを一通り読んでISUCON 8の過去問を触って、という感じで1週間の夏休みを使って勉強した。 これでISUCONをやるには問題ないぐらいにはgoが書けるようになったと思う。

本番やったこと

  • pprofを使えるようにした
  • 新着アイテム、カテゴリ別新着アイテムの並び順をredisから取れるようにした

以上という感じで、全然取り組めなかった。 pprofとかで遅そうな場所を把握した時間が12時ごろ、新着アイテムの並び順をredisから取れるようになったのが15時半ごろ、カテゴリ別新着アイテムは17時ごろに実装完了した。他に何もできなかった。

カテゴリ別の新着アイテムの取得の部分が遅いと気づてコードを見たときに、N+1クエリがあったのと一覧取得クエリに複数のIN句とOR条件があったのに気づいた。 一覧取得クエリはindexを張ったりIN句やOR句をなるべく使わないように修正する手もあるなと思ったけど、redisのsorted setを使えば一気に解決できていいのでは?と考えてそうすることにした。 この判断が本当によくなかったので大反省をしている。

やったことに対する反省点

  • 実装に時間がかかりすぎてしまった
    • 1, 2時間でできるだろうと思っていたけど、その2倍以上はかかってしまった
    • 練習時には無限に時間がある中でredisを使った実装も試してたので、サクッと行けるだろうと過信してしまっていた
    • そのため自分は他の部分に着手できなかった
    • ときには大規模な改修も必要かもしれないが、競技時間が短かったり改善するとボトルネックが別の場所に移りやすかったりなどの理由から、基本的には短時間で試せる改修を積み重ねて行くほうがいいなと思った
  • 時間がかかった割に効果が薄かった(と思う)
    • どれくらい改善したのかちゃんと計測してないのであれだが、ボトルネックではなかっただろうからおそらくindexを張るだけでも十分だった気がしている
    • 解決すべきボトルネックなのかもわからない状態で大規模な改修を試みるのはよくないと反省
    • index張るのは一瞬でできるわけだからそれを試してみてからでも全然遅くなかったと思う

その他の反省点

  • APIのアクセス傾向やレスポンスタイムをあまり把握してなかった
    • nginxのアクセスログもgo側のWebフレームワークで出力したアクセスログもほとんど見てなかった
    • 外部APIを叩く実装があったりDBのロックを取る箇所があったりとpprofだけではわからない部分が多かったので明らかに見るべきだった
    • アクセスログを見て、遅いエンドポイントから詳しくボトルネックになっている部分を掘り下げていくのがよさそうだなと思った
    • 自分自身はkataribeやalpを触ったことないので次回(あるのなら)までには勉強しておこうと思った
  • 結局DBのindexは全く追加してなかった
    • slow queryは出していて最初ちらっと見ただけで何もしてなかった…
  • 購入周りはロックで詰まったりするだろうなと薄々考えていたけど何もできなかった

その他感想

  • キャンペーン機能でアクセス数をこっち側で制御できるのはおもしろいなと思った
    • 講評の記事を見ると初出ではなかったらしいので過去問対策不足だったかも
    • キャンペーン機能の数値を変えるとログインの負荷が一気に上がることに気がついたのが後半だったので、今後同じような仕組みがあったら早めにいろんな値で試してみたほうがいいなと思った
  • Go Modulesよかった
    • go初心者でも依存モジュールのインストールに全然躓かなかった
  • bcryptの負荷が高かったのが驚いた
    • ログインでこんなに詰まるものなんだと驚いた
    • ログイン専用のサーバに分けて他の処理に影響が出ないようにすることは学びになった(競技中には対応できなかったが)
    • ISUCON 8の本戦で同じような問題が出ていたことを知って、これも過去問対策不足だったなと思った
    • ベンチを回せば回すほどパスワードのハッシュを更新できるのはどうなんだろう…と思ってしまった
  • 椅子が売れた数がポイントになって、椅子が売れるようにある程度調整してもいいというルールは実際のサービスっぽくて面白いなと思った
    • その反面、スピードアップコンテストとはちょっと違ってきている気も…という風にも少し思った(文句はないです)
  • 機能が盛りだくさんで難しかったけど面白かった
    • 商品の出品から決済、発送まで一通り機能があるのがすごいなと思った
    • 決済や発送周りはちゃんと外部APIとして用意されていて気合を感じた
  • 次回があれば今度こそ本戦行きたい…

2017年に趣味とかでやったこと

RCC OBOG Advent Calendar 2017 - Adventar の7日目の記事です.昨日はgol19さんの趣味のこととか作ったものとかです。

2017年に大学を卒業して社会人になったabcangです。ぱちお世代です。 書くネタがないなーと思いつつ登録して、結局書くネタが思いつかなかったので、

RCC老害各位の近況を教えてください。

とあるように近況を書く、とと言うより今年を雑に振り返ってみよう思います。

アニメ

大学のときから継続してアニメを見ています。だいたい趣味の時間の大半はアニメに使っていると思います。(たぶん) 昔は見たアニメをGoogleスプレッドシートに記録していましたが、去年ぐらいからAnnictに移行して、それからはAnnict上で記録しています。

annict.jp

見返してみると、去年放送のアニメは15〜20ぐらい見てたのに対して、今年放送のアニメは10前後とあまり見てないですね。世の中には放送されているアニメをほぼ全部見ている人もいるらしいのでにわかですね。

去年までは単純に見た作品と見たい作品を記録していただけですが、今年の冬頃に大規模なアップデートがあってGitHubの芝のような機能が実装されたので、 2017の春からは話数ごとに記録して芝を生やすようにしてみました。

f:id:abcang:20171206195402p:plain

Twitter連携をしているので見たアニメはどんどん流れていると思います。特定のアプリからのツイートをMastodonにも流すツールを作ったので、それを使ってAnnictの記録をPawooにも流しています。フォローワーさんがアニメの視聴記録を見て、「このアニメのタイトルをよく目にするけど面白いのだろうか」と興味を持つきっかけになってくれればと思って共有しています。邪魔だったらごめんね。

Annictは個人で開発・運用しているということなので応援していきたいです。

作ったもの

今年作ったプログラムとかを紹介したいと思います。

特定のアプリからのツイートをMastodonにも流すツール

上で紹介したツールです。自分のサーバなどで常時起動しておく必要がありますが、ターゲットのアプリを複数指定できるので便利です。

github.com

今はAnnictとはてなブックマークとSwarmをPawooにも流すようにしています。需要があるならWebサービスにするのもいいのかもしれません。

ただ、ユーザーの数だけストリーミングAPIを実行したくないですし、かと言ってポーリングにすると投稿されるまでに時間がかかったりして使いづらくなりそうでうーんと悩んでたりします。とりあえず自分も使いたいと思った人は声をかけてください。考えます。

PCの電源に連動してテレビが付くプログラム

自分は通常のディスプレイは持っておらず、PCをテレビに繋いで使ってます。通常のディスプレイはPCの電源が入ると自動的にディスプレイも付きますよね。テレビでそれを実現しようとしたものです。

github.com

これを使うにはRaspberry Piが必要で、テレビのCECを制御できるcec-clientを使っています。Raspberry Piから定期的にPCにpingを送って、返ってきたらテレビを付けて返ってこなくなったらテレビを消すという非常にシンプルな作りになってます。

そのため、実現しようとしたものと表現したように、使い勝手が悪いです。経験したもので一番多かったのが、テレビの入力をNintendo switchに切り替えてスプラトゥーンをやっていると、勝手にPCがスリープ状態に入ってテレビの電源が切れるというパターンです。

正直、リモコンを使ってテレビをつけるのがだるいだけなので、PCの起動に合わせなくても声で「テレビつけて」って言ったら電源が入ってくれるだけでも個人的にはいいんですよね。

そこでGoogle Homeを検討してみたんですが、どうやらいろいろやるにはIFTTTを経由する必要があるらしく、直接ローカルのマシンに対して通信できないのかーと買うのを迷ってます。

リクエストごとにSQLの実行ログを書き出すgem

Qiitaに書いているのでぜひ見てください。

qiita.com

ニコニコアニメスペシャbot

ニコニコアニメスペシャルbotは今年作ったものではないですが、今年はずいぶんとフォロー数が伸びて1年で450ぐらい増えました。

f:id:abcang:20171206213343p:plain

このグラフはSocialDogというサービスで表示したもので、フォロー管理やグラフの表示ができて便利です。以前はCheetahというサービス名ですが、使っているうちにいつの間にか変わってました。

ちなみにフォローワー数のグラフで段になっているところは、このゆゆ式の一挙放送のツイートが伸びたときです。ゆゆ式すごい、ゆゆ式を見ましょう。

Mastodon

今年はずっとMastodonを触ってました。ずっと前からOSS活動に憧れていましたが、Mastodonでその願いを叶えることができました*1。今ではコラボレーターになって(あまりレビューとかできてないですが)、コントリビュート数も40を超えて上から10番目になりました*2

f:id:abcang:20171206214814p:plain

最近は自分でも検証用のMastodonインスタンスを立てて、Mastodonで発生するエラーを収集したり、SQLの実行ログを取得したり、プロファイラを仕込んだりしてコントリビュートできることを探しています。その話はまたMastodon Advent Calendar 2017で書きたいと思います。

adventar.org

終わりに

今年はMastodonばっかりやってて他のことはあまりできなかったなーと今では思います。あとはアニメやニコ動を見るばっかりであまり生産的なことができてなかった気がします。

大学生のときは面白そうなことに取り組んだりしていた気がする(思い込みじゃないはず)ので、来年はやっていきたいなーと思ったりしてます。

あとは、今年は去年までに比べて全然絵を描けてなかったので来年は頑張ってみようかなと思いながら、iPadを買ったら本当に自分はお絵描きするのか?と自問自答しています。

明日は irgalyさんです。よろしくお願いします。