読者です 読者をやめる 読者になる 読者になる

Fedora22で突然dnfが使えなくなって解決した話

dnf updateするかーとおもっていつものように

sudo dnf update

とすると

Traceback (most recent call last):
  File "/bin/dnf", line 36, in <module>
    main.user_main(sys.argv[1:], exit_code=True)
  File "/usr/lib/python2.7/site-packages/dnf/cli/main.py", line 198, in user_main
    errcode = main(args)
  File "/usr/lib/python2.7/site-packages/dnf/cli/main.py", line 84, in main
    return _main(base, args)
  File "/usr/lib/python2.7/site-packages/dnf/cli/main.py", line 117, in _main
    cli.configure(map(ucd, args))
  File "/usr/lib/python2.7/site-packages/dnf/cli/cli.py", line 1006, in configure
    self.base.plugins.run_init(self.base, self)
  File "/usr/lib/python2.7/site-packages/dnf/plugin.py", line 104, in run_init
    plugin = p_cls(base, cli)
  File "/usr/lib/python2.7/site-packages/dnf-plugins/system_upgrade.py", line 359, in __init__
    super(SystemUpgradePlugin, self).__init__(base, cli)
TypeError: must be type, not None

とエラー。

調べてみると https://github.com/rpm-software-management/dnf-plugin-system-upgrade/commit/4bbbf1ec0c3f387249d30dd103ff4d002c17f574 に行き着いた。 Python2のユニコード周りのバグらしい...

Unfortunately, Fedora 21 and Fedora 22 don't have that

ほんとに不運だ...

ちゃんと修正されたソースコードはあるのでそれをDLして現状のものを置き換える(念の為バックアップもとっておく)

# cd /usr/lib/python2.7/site-packages/dnf-plugins/
# cp system_upgrade.py{,.bak}
# wget https://raw.githubusercontent.com/rpm-software-management/dnf-plugin-system-upgrade/4bbbf1ec0c3f387249d30dd103ff4d002c17f574/system_upgrade.py

これで解決した。

PyCon2015に参加してきました #PyConJP

1日目

Pragmatic Logging and Metrics

Pythonっぽい話かなと思ったら、わりとインフラよりのお話。 「fast/once/context」を実現するためにどうするか? まずはSentryの紹介。 アプリケーションの例外をSentryに送って、そこからSlack等へ配布。 fluentdに近いイメージ?

次にGrafanaとかいろいろ。 メトリクスを収集して表示的な感じ(いろいろあって把握しきれてなかった...)

そして、各種のログ出力をいい感じに整形して渡してくれるstructlogというのを書いたよという話。

Python と型ヒント (Type Hints)

Python3.5で導入された型ヒントについて。 大雑把にいうとイケメンではあるけれども、 それと同時に弊害・理想と現実という問題もあるというのも現実というような感じの内容。

プログラム全体が対応していないとあんまり意味がないっていうのはC++constみたいな感じだなって思った。

今後漸次的型付け(Gradual Typing)ってのは色々なところでいわれはじめそうな気がするので、 はやめに把握しておきたい。

組合せ最適化を体系的に知ってPythonで実行してみよう

タイトル通り。 組み合わせ最適化の紹介と実用例。 基本的にには解きたい問題をパターンに落とし込んでソルバに入れてあげれば答え出るねという感じ。

組み合わせ最適化問題は 標準問題と数理問題という二面から捉えることができる。 一般的に標準問題のほうが、早くとけることが多い。

わりと数学的なようで実用面結構ありそうだなという感触だった。 解くということに関しては、もうライブラリが充実しているので各アルゴリズムの特性とかを理解するのが良いのかなという感触。

なぜWeb画面自動テストはうまく行かないのか

Seleniumでいけそうだけど、現実問題(マルチブラウザ、パラメータ変更コスト、環境容易コスト)からうまくいかないのでラッパー作りましたという話。

環境に依存しないCoreと、あって状態(パラメータ)を記述するファイルというのはServerspecとかも そういうような感じになっていてWeb画面自動テストに限らずテストのフレームワーク作る際の定石なのかなという印象。

MinecraftPythonで遊ぶ

登壇者が若くて驚いた。 mcpiをつかってPythonからMinecraftをいじると楽しいよという話。

Minecraftで遊んだことないけど、こういう遊び方もあるのかと3000円払いたくなってきた。 発表の中でいわていた学習というコンテキストで語られる機会の多いmcpiだけど、そうじゃなくて楽しいからやってみる っていうのとても大事だなって思う。

いま求められるコミュニティの多様性と未来

コミュニティについてのパネルディスカッション。 色々と考えさせられた。

この中で入りやすいコミュニティ大事という話があったけど、 C++のコミュニティとかここらへん真逆なあれだよなっていう感じがした。

懇親会

ビールばっかり飲んでたw 前から会いたいなーっておもってたこくたんと話せてよかった。 Twitterと同じように面白い人だった。

2日目

PythonとPyCoRAMでお手軽にFPGAシステムを開発してみよう

物理デバイスをつくるプログラムが書くの大変なので、 Pythonラッパーを作ってみましたというお話。

FPGAはあまり興味わかなかったけど、 Python構文木をいじれるってのは面白いなって思った。

uWSGI/Dockerを利用したWebサービス運用事例

わたしはgunironユーザだったけど、 パフォーマンスも良さそうだし、機能豊富だしuWSGI使ってみようと思った。 uWSGIのReuse-Portがダウンタイムを最小にしていい感じにできるらしい。

Dockerはよく言われる壊れることを前提にする的な話だった。

セカイノカオ by チーム・カオ

発想がぶっ飛んでた。 こういうアートとITの融合みたいなのおもしろいなーって思う。

Rise of the Static Site Generator

WordPressみたいなCMSな動的サイトは確かに便利なんだけど、 重かったり、攻撃の対象になったりとか色々と問題が多い。 そこでStatic Site Generator(有名ドコロだとMT?)で解決しましょうという話。 Python製のPelicanが紹介されていた。

唯一聞き取れた英語セッションだったのでうれしかった。(もっと英語力高めたい....)

※あとでまた追記するかも

YAPC::Asia Tokyo 2015に行ってきました!#yapcasia

YAPC

投稿おそくなりました。ブログを書くまでがYAPCです!

最初はYAPCの存在すらよく知らなかったのですがかるぱねぎらさん(@karupanerura)にチケットを譲っていただき行ってきました。

めっちゃPerl, Perlしているのかなーと思いきやそんなことはなく、IT系の人たちが集まるお祭りって感じでした。 以下気になったセッションの感想を書いていきます。

Managing Containers at Scale with CoreOS and Kubernetes

Kubernetesとは何者なのか? デモとともに紹介していくというセッション。 個人的に最近Dockerに興味を持っていてそろそろ複数のコンテナを扱いたいなーって思っていたので、 ちょうどタイミングのいいセッションでした。

ポイントとしてはKubernetesはスケジューラでありレプリケーションコントローラでPod(同一ホストで起動しなくてはならないDocker群)の数を一定に保つようにするということですかね。 死活監視をしているので、ホストサーバが死んだ場合自動的に最適な別ホストにDockerを立ち上げてくれます。 また、スケールアウトや逐次アップデート、いくつかだけアップデートなどもコマンドをひとつ叩くだけでよしなにやってくれます。 ただ、逆に突然別ホストに移動する可能性があり、死んだDockerは削除されてしまうのでKubernetesで管理するものは基本的にステートレスなDockerクラスタに適応する感じで、永続化したいものはnfsマウントするなりAWSだったらS3に預けるなりしないとダメとのこと。

うっかりをなくす技術

インフラエンジニアとしてお仕事をさせていただいてもらっているので、ミスを出来る限り減らしたいという理由からとてもためになるセッションでした。

人間だからミスをしてしまう。そのミスをいかに減らし、またミスっても大事に至らないようにするかというお話。 まず、意識レベルを高めるということ。指差し確認などが有効なよう。 また、ミスは勘違いから生まれるので、勘違いしないような設計が大事で、そのためにはどうするかというと人の視点にたって手順を作ったりコードを書くとよい。読みやすいコードについてはリーダブルコード読みましょう!というお話でした。また、どうしてもトリッキーな実装になってしまう時はコメントに残す、コメントと実装の乖離をなくすにはみんなでコードレビューが有効。

また、ハインリッヒの法則からnear missを減らせば重大なミスは減らせるが、そもそもnear missは気づきにくいのでどうやって見つけるかが重要。具体的にはGitHubのIssueにヒヤリハットの要因を集めてまとめておくと良いとのこと。

最後にコーディングする上で言語による制約をうまく使いましょうという話。副作用を閉じ込める関数型言語はつよい。

ISUCONの勝ち方

ISUCONで勝つために聞いてきました!

まず、そもそもなぜ早くしなくてはいけないのか? ユーザ的な面だと遅いとUXが下がり、また検索順位に影響するとのこと。 そして、お金的な面で当然速いほどサーバ台数を減らせるのではやいとコスト削減になる。

方針として紹介されていた最初の1時間は問題把握・方針の決定、最後の30分は再起動テストにあてるってのは、去年やっていたのであとはのこりの6:30でいかにチューニングするかですね... また、参考になったのは「決まったことはメモとして書き出す」というの。 計測した情報とかは書き出すようにしてましたが、することに関しては今からします宣言して作業程度だったので、これは実践しようと思いました。 また、レギュレーションを読めというのこれ大事ですね...しなくていいチューニングをしないように。  技術的な面だとまずMySQLでは「コストの高いクエリより実行回数がおおいクエリが効いてくることもある」というの。とりあえずスロークエリにすべて吐き出す設定でベンチまわすのもありかもですね。long_query_time=0でそれが実現できるらしいです。あとは「いつもB+木を」。secondery indexのリーフにはprimary keyがいて、そこからprimary keyの探索が走るというの知らなかったので意識していきたいです。あとはそもそもoffsetがなくなるようにKVSとかとの連携も重要ですね。 Frontだとh2oはやいというはなし聞いたのでちょっと試してみます。

MB-SystemのMBIOの構造

お久しぶりです。

研究関連でMB-Systemのソースコードをよんで修正する機会がありましたので、その時にキーワードとなったMBIOのしくみについてまとめます。

はじめに

MB-Systemとは「MB-System is an open source software package for the processing and display of bathymetry and backscatter imagery data derived from multibeam, interferometry, and sidescan sonars. This software is distributed freely (and for free) in the form of source code for Unix platforms. 」で要するに海底地形データの処理に使用するソフトウェアです。ということでかなりマニアックな領域、情報系とはおよそ関係ない領域のことなので書いてもあんまりじゅようないかなーと思いつつ、私自身どこかにまとめとかないと忘れそうなのでまとめておきます。

MBIOとは

一口に測深データといってもベンダ・機関・機器・versionによって使用しているフォーマットが大きくことなります。 そこでMB-Systemでは測深データを読み込んだ後MB-System独自のデータ形式に変換し統一的に扱えるようにしています。 そのデータ形式(構造体)と操作(関数)を提供するのがMBIOです。ライブラリ化されているので外部からも使えます。 MBIOを使うことで元のデータ形式に依存しない操作ができるようになるわけです。 もちろん各フォーマットへのエクスポートもサポートしています。

MBIOに新フォーマットを対応させる際の作法

今回わたしがやったのは修正ですので、新フォーマットに対応させるということはしていませんが、 調べる途中でだいたい見えてきたのでかいておきます。もしかしたら抜けがあるかもしれません。

src/mbio/配下にmbr.cというファイルを作り(は任意。フォーマット名にするといいかもしれません)、 対応させたいフォーマットからMBIOに変換するための関数を実装します。慣習的に下記のようにmbr_register*という名前になっているようです。

int mbr_register_*(int verbose, void *mbio_ptr,
                int *error);

ここでverboseは出力のレベル、mbio_ptrはMBIOの構造体へのディスクリプタerrorはエラーが起こった時の書き込み先のポインタが渡されます。 基本的にmbio_ptrに、がしがしデータとそれらを扱う関数をセットしていけばおkです。 他のフォーマットの実装を参考にしつつ実装すると楽かと思います。 また、実装しない関数はNULLを入れておくのが作法なようです(ある関数が使えるかどうかの判定が多くの場合NULLかどうかでされている)

つぎにmb_format.hを編集してフォーマットIDを割り当てます。 1000番台の値を割り当てとけばまず、衝突することはないでしょう。 mb_format.hに追記します。

#define MBF_* ID

これと先ほど作成したbr_register_*を紐付ける処理を書きます。 mb_format.cのmb_format_register関数の中に下記のようなelse ifの羅列があるので、そこに追記しましょう。

        else if (*format == MBF_*)
                {
                status = mbr_register_*(verbose, mbio_ptr, error);
                }

また同じくmb_format.cにmb_get_format関数というフォーマットを取得し返す関数があります。 これに新しく追加したフォーマットの判別処理を書きましょう。 例えば独自フォーマットの拡張子が.fooとすると下記のようになります。

        if (found == MB_NO)
            {
            if (strlen(filename) >= 5)
                i = strlen(filename) - 4;
            else
                i = 0;
            if ((suffix = strstr(&filename[i],".foo")) != NULL)
                suffix_len = 4;
            else if ((suffix = strstr(&filename[i],".FOO")) != NULL)
                suffix_len = 4;
            else
                suffix_len = 0;
            if (suffix_len == 4)
                {
                if (fileroot != NULL)
                    {
                    strncpy(fileroot, filename, strlen(filename)-suffix_len);
                    fileroot[strlen(filename)-suffix_len] = '\0';
                    }
                *format = MBF_*;
                found = MB_YES;
                }
            }

基本的に

            if ((suffix = strstr(&filename[i],".foo")) != NULL)

            else if ((suffix = strstr(&filename[i],".FOO")) != NULL)

                *format = MBF_*;

の部分を書き換えればよさ気な雰囲気です(基本的に拡張子しかみてないんですね...

以上をするとフォーマットを自動判別して適切な変換関数を呼び出しあとはよしなに扱ってくれます。

ISUCON4予選に参加しました

ということで昨日09/28にサークルの人(わたし、りょい君、kakira君)でチーム「☆(ゝω・)vキャピ」として参加しました。

当日まで

2回ほど勉強会を開きました。一回目は肝になりそうな部分をそれぞれがまとめて発表し勉強するという形式。 具体的には負荷とはそもそもなにか?(わたし),MySQLまわり(kakira君),memcachedまわり(りょい君)って感じにしました。これはわたし担当分は普段さわっているから、kakira君は競技プログラマなのでこのあたりデータ構造とかアルゴリズムとか関連付けて理解できそう、りょい君がこのメンバの中で一番Perlかけるので実装の際にしっているとつよいって感じで割り当てました。 AMIからの起動とか軽い動作確認などもこの日にしました。 そして、予選の方針として「推測するな計測せよ」というのを徹底していこうということ、 またそれとあわせ最初一時間はチューニングを始めずに統計をとる、ソースコードを読むなどして構造を理解最初のボトルネックを探す、そして最後の1時間は再起動したらうまくいかなくなり失格なんてことののないようチューニングをやめ確認をしているというふうにすることに。 また、選択した言語はのこり二人が読み書きできるということでPerlにすることに。(個人的にはPythonがよかった...)

二回目の勉強会ではISUCON3の過去問を解くという形。

開始直前

始まる前にチャットサーバとか、ディスプレイの設定(デュアルディスプレイにした)とかそういうことをしておきました。チャットサーバにはDevHubというものを使わせていただきました。これを採用した理由は普通にチャットできる部分とメモとしてマークダウンで書いておいておける場所がある点。チャットはURL貼るという用途に しか使いませんでしたが(普通の会話は口頭でしていた)、メモは色々わかったことなどを各々が書き込んで結構使いました。結構役に立ちました。↓予選後のスクリーンショット

f:id:ikaro1192:20140928173547p:plain

予選開始

とりあえずAMIを立ち上げベンチマークを走らせます。(10:11) 最初に決めたようにわたしはサーバ周り、りょい君、kakira君にはアプリケーションのソースコードを読んだり、サイト構造を把握してもらったりをお願いしました。

まず、psやnetstatからサーバで動いているプロセスリッスンしているポートを把握。前回までと大きく構成変わっているのはwebサーバデフォルトでhttpdではなくnginxであること、 memcachedが動いていないことでしょうか? そしてわたしは各種計測ツール導入。入れたものとしてはdstat,percona-toolkitなんかをいれました。 また、nginxでアクセスログの先頭に処理時間を表示するように設定。ついでに設定を見るとワーカーが1だったので(一時間はチューニングしないという話でしたが単純な変更で済むので)ワーカを4にして再起動。 MySQLについてもスロークエリを出力するように設定して再起動。また、今回はsupervisordがRuby実装ということで使うPerl実装に切り替えました。 ほんとはSSHもisuconユーザでログインできるように設定するはずだったのですが、なんか焦ってしまいできない...こんなところで時間潰すのももったいないので他の人には不便をしいますが(ほんと申し訳ない...)、とりあえず一旦やめ再度ベンチマークを走らせます。(10:44) 最初走らせた手応え、前回までの感じで大体workload8あたりがベストなのでこの時点でその程度の値にして実行。その結果スコアが3200ぐらいになり

となりました。やったね!暫定一位!このままいければよかったんだけど...

dstat,topの結果をみているとロードが最大3〜4前後であること、IOというよりCPUがネックになっていそうなこと、時々ポンとIOが来ること、やっぱりMySQLCPU使用率が高いことがw狩りました。また、ログ出力の関係からか常にディスクアクセス(書き込み)が発生しています。また、メモリは全然使い切れていないようなのでメモリにのせる実装が良さそうですねとか考えました。 スロークエリの結果からはなんかlogin処理であるクエリが殆どをしめているっぽいです。login_logというテーブルを参照しているのでログインまわりかなとか考えつつ。 また、ページごとのアクセス数の偏り、なんかをみてみても静的ファイルを除いてログインまわりに結構アクセスが来ています。↓

 5611 /
3087 /login
565 /mypage
2 /report
1 /tmUnblock.cgi

ソースコード解析しているkakira君からも該当クエリがめっちゃ効率わるいという話だったので、とりあえずここをチューニングしようという話に。 ソースコードが単純であることからmemcachedに全部のっければいいのでは?という話に。 これはメモリ上にのせるというよりも検索コストをさげるのとSQLでCPU使ってるのでKVSとしてO(1)でアクセスするという意味合いがつよいです。

ということでソースコード書き換え開始とその前にisuconユーザのホームディレクトリ配下をgit管理するようにしました。 kakira君がSQLソースコードをよみ大まかな設計をし、りょい君が実装していきます。わたしはそれにアルゴリズムまわりにちょっと口を出す程度。 わたしはnginxで静的ファイルを返すように変更したり、MySQLのパラメータを変えたりと細かなチューニングをしていきます。

とりあえずIPでの遮断の方を書き換えベンチを走らせると6000超えました。この調子でいけるか?ということでユーザロックのほうも実装開始。 これはいけるか?って思いましたがここからが... お昼も食べつつ13:30ぐらいに再度ベンチを走らせるものの/mypageがfailしまたreportとの付きあわせがうまく行かないらしく、スコアが送信されない状態... 送られれば100000越えてたのに...って感じでデバッグが開始されます。が、なかなかバグの原因がわからない。きっとmypageにアクセスできないはずのユーザがログインできているだろうと推測はできたのですが、手動でしらべるのは手間がかかる、またエラーログとしてページが予想されたものとことなりますだけでは情報がすくない... さらにPerlのデータ構造まわりの参照なのかスカラなのかハッシュあのかよくわからないというあれが発生し、さらに泥沼に... 改善したと思ったら今度はユーザロックをし続けているっぽい... 15:30頃一旦差し戻そうというはなしになり、スコアが3000に逆戻り... ソースコードをあらためて綺麗な心で書き換えはじめます。 うまくいかない...って感じですでに16:30。もう無理そうなので一旦諦めチューニングして別のところをチューニングし始めます。 ところでおなじBANなのになんでIPのほうはfailしてないのって話になりどうやらIPで遮断されたものは一回もないようなので、とりあえずそこのコードを単純にreturnするようにしました。これで6000程度に戻る。 あとはユーザのテーブルにインデックスをはったりして6500前後まで行きました。 もしかしてMySQLのデータを全部/tmp/shmにおけばいいのでは?とか考えて設定ファイル書き換えたらなんかMySQLが立ち上がらない... 設定ファイル差し戻してもダメ...結局これの解決をしていたら時間が来てしまいました...

反省点

  • 実装力低い...

これが大きかったです...とくにわたしがPerl読み書きできないので...また、コンテストの性質上コードを読んでいる時間が長くなるのですぐに実装できるより読みやすい言語のほうが良さそうです。次回参加する際はわたしもプログラミングまわりで力になれるようにしておきたいです。

*ダブルチェックをする

実は途中でわたしがsupervisordを再起動しとうとおもって、bashの履歴機能つかって再起動していたら実は複数回memcachedを再起動していてperlのエラーログがうまく出されないという事象がありまして、これは実サービスでやったらプロセスによってはとんでもないことになり非常に反省しております。また、今回でも余計に時間をかけさせてしまったというので申し訳ない。 再起動など影響のある作業するときはきちんとコマンドがあっているかチェックをする。声掛けだけではなく、ダブルチェックするなどを怠らないようにしないといけませんね。

*ダメそうだったら途中ですぐに諦める

loginまわりでかなり時間をとっていしまいました。 これは途中で方針変更できるはずなのに強行突破しとうとしたのは間違いでした。 MySQLのテーブル設計をきちんとする(一回でも成功しているかしていないかの判定があったのでそこのテーブルをわけるなど)、その上でクエリの改善をするなどで十分高速化できたはずで、その場合加点が0というわけではなく多少は加点があり、さらに別のポイントのチューニングにも時間をまわせました。

感想

今年が初参加でしたが、とてもおもしろかったです。 また、技術者として自分に足りない部分を再度確認できるよい機会でもありました。 問題自体は去年とはことなり、複数問題点が含まれているというより大きな問題がありそれを解決するって感じだったのかなって感じてます(もしかしたらたくさんある問題点をわたしたちがみつけられなかっただけなのかもしれませんが...)やっぱり計測大事ですね。 来年はもっとスコア伸ばしていきたいです。

参加者・運営の皆様お疲れ様でした!

追記

学生枠5位になんとか入り本戦出場できることになりました。 わたしは研究の関係で参加できないので残り二人に頑張ってもらいます。

MB-Systemのmbeditコマンドがセグフォで落ちてハマった話

地球科学 Linux

最近Qiitaはじめてそれとブログの使い分けを模索しております。ということでブログにはいろいろ試行錯誤した結果、Qiitaには完全に手順化されたり、検証された事実ベースで書いていこうかなと思います。ということで今日ははまったはなしとその対策。

MB-Systemというのは「Seafloor Mapping Software」ということらしいです。
研究で使うことになるツールの一つ。
これをFedora20にソースから入れたんだけどmbeditが起動せずにセグフォで落ちて困ってた。
configureの出力見てもちゃんと全部の機能Enabledになっているし、ldd mbeditしても特に共有ライブラリ解決できてないとか、変なの読み込んでいるとかなさそうだった...
しかたなくソースを読むことに。printfでどこでセグフォが起きているかの特定の作業。
幸いなことに起動時に落ちることからmainであたりをみていけば良い。do_mbedit_init関数を呼び出しているところでセグフォが起きているっぽいのでそちらをさらにしらべていく。どうやらフォント読み込んで適応しているところで落ちているっぽい。勘でロードのミスっていてないものを適応しようとして落ちているのかなーと思ってX Window Systemの登録されているフォント調べるためにxlsfontsで確認。案の定ない。yum searchしてそれっぽいパッケージあったのでインストール。ちゃんと動きました。
フォント関係もconfigureでチェックしてくれればいいと思うんだけど、難しいのかなぁ...

Fedora20でEMOBILEの無線LAN接続が不安定になった話

メモ Linux メモ

Fedora20でkernelをアップデートしたらEMOBILEのGL06Pの無線LAN接続が不安定になった。
原因はおそらくこれなので古いカーネルに差し戻したら(幸いカーネル自体は残っていたのでブートローダでkernelを変更するだけ)今までどおり使えるようになった。
他に困っている人がいるかもしれないのでメモ。
無線LANドライバが原因かなと思うけど他のルータにつないでもふつうに使えるのが謎い...