2013年9月11日水曜日

iPhone 5s/5c LTE 各キャリア使える周波数まとめ

iPhone 5s/5c が発表されましたね!

まだ各キャリアでどの周波数をサポートするという話がないので、iPhone のスペック表から突き合わせてみました。また、ドコモはどのモデルを発売するか公式情報がありませんが、おそらくA1533(GSM)だと仮定して話を進めますドコモもA1453でした。 各キャリアの周波数割り当てはWikipediaのLTE記事他を参考にしました。

BandDocomoKDDISoftbank
1 (2100MHz)10MHz*220MHz*210MHz*2
3 (1800MHz)20MHz*2(東名阪)10MHz*2(emobile)
8 (900MHz)10MHz*2(2014年夏以降)
18 (800MHz)10MHz*2
19 (800MHz)10MHz*2

Docomo, KDDI が保有する 1.5GHz帯には対応しません。

以上からまとめてみますと...

ドコモは東名阪バンドの1800MHz帯が使用可能なので、特に周波数の逼迫する首都圏で高速通信が可能と推測。 800MHz帯はサービス開始間もないのでエリアはまだ狭そう。

KDDIは田中社長ご自慢の800MHz帯に対応したので、エリアの問題はおそらくクリアし、3キャリアで一番広くなりそう。ただし800MHz帯+1500MHz帯+2100MHz帯全体のエリアは公表しているけれど、800MHz帯+2100MHz帯のみのエリアは公表されていない。2100MHz帯の20MHzはまだ数局という感じなので、実質15MHzでのサービス。2100MHz帯での品質は皆様ご存知の通り。 VoLTE はまだ使えないので通話中のデータ通信はできないまま。

ソフトバンクは相変わらず厳しい。イーモバイルの1800MHz帯が今後も使えるとしても相変わらず逼迫したまま。特にプラチナバンドと呼ばれる900MHz帯でのサービスが来年夏以降なのが厳しい。2100MHz帯のみの比較ではKDDIよりも良いようですが、800MHz帯が加わった時にどうなるかは未知数。

現在KDDIでiPhone 5を使っているユーザーは、iPhone 5sに乗り換えると使える周波数が増えます。現在ソフトバンクでiPhone 5を使っているユーザーは、iPhone 5sに乗り換えても使える周波数は今のところ変わりません。

カタログスペックのみの比較なので、実際の通信速度や品質にはもちろんキャリアの基地局整備状況によります。ドコモは特にiPhone初めてなので、そこらへんも含めて注目です。

2013年9月8日日曜日

MySQL 5.6 の GTID のしくみ

MySQL 5.6 で GTID (Global Transaction ID)が導入されました。どうも使うと便利そうだ、というものの実際どんなものかイマイチ分からなかったので、調べてみました。

サーバーがUUIDを持つ

私は調べるまで誤解していたのですが、UUIDを持つのはサーバーであって、トランザクションではありません。それぞれのサーバーにUUIDが割り当てられ、トランザクションは連番が振られます。
例えば、4台のMySQLインスタンスで1台をマスターにした場合は以下のようににUUIDが振られます。
そして、トランザクションは次のようにIDが振られます。
UUID:トランザクション番号
例えば"40bbcf9b-e556-45b0-bdb3-e528f0041652"で実行された123番目のトランザクションは
40bbcf9b-e556-45b0-bdb3-e528f0041652:123
という感じになります。
そして、それぞれのサーバーで実行されたトランザクションは "GTID_Executed" に "uuid:最初-最後" というように記録されます。
この図の場合では、右端のスレーブのみ最後のトランザクションが実行されず、遅れていることがわかります。
ちなみに、途中のトランザクションだけ抜けた場合は、
40bbcf9b-e556-45b0-bdb3-e528f0041652:1-20:22-1021
という感じで、 : でつなげて記録されます。

マスターを切り替える

ではマスターが落ちた場合の動作を見てみましょう。
マスターが落ちました。右端のスレーブが遅れているので除外し、今回は左端のスレーブをマスターに昇格させます。
この場合、左側のスレーブは新マスターに追いついているので、新マスターの最新のログポジションに合わせれば良いことがわかります。右側のスレーブはひとつ遅れているので、新マスターの該当のログポジションに合わせます。これらが自動計算され CHANGE MASTER TO に MASTER_AUTO_POSITION=1 を指定するだけで良いのが GTID の売りです。

新マスターでのトランザクション

新マスターでトランザクションが実行された場合は、新マスターのUUID:1 から新しくトランザクションが数えられます。
GTID_Executed にはこれまで実行されたトランザクションがすべて記録されます。マスターが変更された場合は複数行記録されます。

新しくスレーブを追加

旧マスターに対するスナップショットから新しくスレーブを追加することもできます
右端に新しくスレーブを追加しました。旧マスターのトランザクションのみ実行され、新マスターのトランザクションが実行されていないことが GTID_Executed からわかりますので、新マスターに接続した時にポジションを新マスターの場所に自動的に設定します。

バイナリログの中身

GTIDを有効にした状態では、バイナリログに
SET @@SESSION.GTID_NEXT= 'a8679745-1864-11e3-a1ec-28924a2bea1c:14'
という行が現れます。これは、次に実行するトランザクションのIDを指定しています。
GTID_NEXT は通常であれば "AUTOMATIC" に設定されていて、その状態では "自分のuuid:次の番号" のIDを次のトランザクションに設定しますが、設定し直すと任意のIDのトランザクションを作成することができます。
# at 2621
#130908 21:05:04 server id 10  end_log_pos 2669 CRC32 0x20b2bc89        GTID [commit=yes]
SET @@SESSION.GTID_NEXT= 'a8679745-1864-11e3-a1ec-28924a2bea1c:14'/*!*/;
# at 2669
#130908 21:05:04 server id 10  end_log_pos 2737 CRC32 0x5e5fa3bb        Query   thread_id=10    exec_time=0     error_code=0
SET TIMESTAMP=1378641904/*!*/;
BEGIN
/*!*/;
# at 2737
#130908 21:05:04 server id 10  end_log_pos 2785 CRC32 0x757ca2c9        Table_map: `yuryu`.`test` mapped to number 70
# at 2785
#130908 21:05:04 server id 10  end_log_pos 2829 CRC32 0x4e043fe7        Write_rows: table id 70 flags: STMT_END_F

BINLOG '
8GcsUhMKAAAAMAAAAOEKAAAAAEYAAAAAAAEABXl1cnl1AAR0ZXN0AAEIAADJonx1
8GcsUh4KAAAALAAAAA0LAAAAAEYAAAAAAAEAAgAB//4RAAAAAAAAAOc/BE4=
'/*!*/;
# at 2829
#130908 21:05:04 server id 10  end_log_pos 2860 CRC32 0x3fbac367        Xid = 226
COMMIT/*!*/;
つまり、バイナリログがスレーブに転送されて実行されるのは
  1. GTID_NEXT を次に実行されるトランザクションID(マスターと同じもの)にセット
  2. BEGIN ~ COMMIT でトランザクションを実行
ということになります。

まとめ

  • サーバーごとにUUIDを付与
  • トランザクションIDは サーバーUUID:番号 として連番で生成
  • スレーブで実行するときは GTID_NEXT を指定して同じトランザクションを再生
  • 実行したトランザクションは GTID_EXECUTED に記録される
以上のような仕組みで GTID は自分がどこまでのトランザクションを実行したのか追跡しています。

参考資料

PerconaのMySQL 5.6 GTID in a nutshellというスライドが大変参考になりました。

2013年9月6日金曜日

CentOS / Debian 両方で使える memcached 複数インスタンス対応の init スクリプト

CentOS に標準で添付される memcached 用の init スクリプトは、単一のインスタンスを起動することしかできません。探していると memcached.conf を複数配置して実行するもの は存在するんですが、ほしいのは /etc/sysconfig/memcached を使う CentOS のやりかたと互換性を保ちながら複数インスタンスに拡張するものでした。

というわけで Debian 用の memcached.conf を複数配置するものをベースにして、CentOS / Debian 両対応するとともに環境変数を /etc/sysconfig/memcached から読み込んでインスタンスを起動するものを作成しました。

こちらです: https://github.com/yuryu/memcached-better-init-script/

使い方


もし1インスタンスしか使わない場合は、従来の init スクリプトと変わらず、 /etc/sysconfig/memcached がそのまま使えます。以下は複数インスタンスを起動するときのやりかたです(READMEを日本語にしたものです)。

/etc/sysconfig/memcached-server1
/etc/sysconfig/memcached-server2
        .
        .
        .
/etc/sysconfig/memcached-serverN
というふうに必要なだけサーバーを並べます。 server1 の部分は好きな名前が使えます。
service memcached start
とすると、すべてのサーバーを起動します。
service memcached start server3
とすると、指定したサーバーのみ起動します。 stop も同様です。 それぞれのファイルの中身は
PORT="11212"
USER="memcached"
MAXCONN="1024"
CACHESIZE="64"
OPTIONS=""
という感じで指定します。
CentOS 6.4 で動作確認しています。 LSB 準拠なので Debian でも動くはずですが確認はしていません。 CentOS では redhat-lsb-core パッケージが必要です。

2013年9月4日水曜日

MySQL 5.6.11でGTIDを有効にしFLUSH LOGSするとレプリケーションが止まる

タイトルのとおりです。 MySQL 5.6.11 (5.6.10までと5.6.12以降は大丈夫) において GTID を有効にした状態で、マスターで FLUSH LOGS すると、レプリケーションが停止します。

スレーブで SHOW SLAVE STATUS すると下記のようなエラーが出ています。

Last_IO_Error: Got fatal error 1236 from master when reading data from binary log: 'Found a Gtid_log_event or Previous_gtids_log_event when @@GLOBAL.GTID_MODE = OFF.; the first event 'mysql-bin.000013' at 404, the last event read from './mysql-bin.000013' at 452, the last byte read from './mysql-bin.000013' at 452.'
Last_SQL_Errno: 1778
Last_SQL_Error: Error 'Cannot execute statements with implicit commit inside a transaction when @@SESSION.GTID_NEXT != AUTOMATIC or @@SESSION.GTID_NEXT_LIST != NULL.' on query. Default database: ''. Query: 'FLUSH ERROR LOGS'

FLUSH ERROR LOGS でレプリケーションが止まってしまいます。これは logrotate するときに発行されていて、1日経つと(深夜に)レプリケーションが止まるという、とても困った状態になりました。

調べたところこれは 5.6.11 固有のバグでした。公式に MySQL Bugs: #69045: replication was broken while executing flush tables としてレポートされています。

gtid_next が automatic ではないときに、暗黙にトランザクションを発生させてコミットするようなステートメントを禁止した副作用で、FLUSH LOGSなどのステートメントがうまく動かなくなってしまったらしいのです。

5.6.12 以降ではこのパッチは差し戻されて、正常に戻っています。

tar は圧縮形式を指定しなくても展開できる

tar は最もよく使われるコマンドの一つですが、意外と知られていないことがあります。それは、展開するときに圧縮形式を指定しなくても展開できるということです。

よくtarを使ってファイルを展開するときに紹介されるコマンドは

tar xzvf archive.tar.gz
tar xjvf archive.tar.bz2
tar xJvf archive.tar.xz

というふうに、圧縮形式を指定しているものだと思います。ところが広く使われている GNU tar (Linux)も、BSD tar (OSX)も、展開するときは圧縮形式を自動判別します。つまり、

tar xvf archive.tar.gz
tar xvf archive.tar.bz2
tar xvf archive.tar.xz

とするだけで、すべての形式を自動判別して展開します。ちなみにファイルの一覧を出力してほしくない時は

tar xf archive.tar.gz
tar xf archive.tar.bz2
tar xf archive.tar.xz

とすると画面上には何も出力せず展開してくれます。

このことは、GNU tar であれば公式マニュアルBSD tar であればmanにかかれています。

GNU tar の場合
Reading compressed archive is even simpler: you don't need to specify any additional options as GNU tar recognizes its format automatically.
圧縮されたアーカイブを読むのはより簡単です。GNU tar が自動的に形式を認識するので、追加のオプションを指定する必要はありません。

BSD tar の場合
代表例として -z を抜粋しますが、他の形式のオプションのところにも同様のことが書かれています。
-z, --gunzip, --gzip
(c mode only) Compress the resulting archive with gzip(1). In extract or list modes, this option is ignored. Note that, unlike other tar implementations, this implementation recognizes gzip compression automatically when reading archives.
-z
 (cモードのみ) 生成されるアーカイブをgzip(1)で圧縮します。展開やリストモードでは、このオプションは無視されます。他のtarの実装と異なり、この実装ではアーカイブを読むときにgzip圧縮を自動的に認識します。

いかがでしょうか。特にBSD tarの場合は明確に「無視する」と書いています。

ちょっとしたトリビアですが、知ってるとだいぶ得した気分になれます。

2013年9月2日月曜日

各種圧縮ソフト 圧縮速度と圧縮率の比較(並列版含む)

Unix-like 環境でよく使われるアーカイバの圧縮速度、圧縮率を比較しました。

比較したツール

すべて CentOS 6.4 / EPEL のレポジトリのビルドを使用しました。

比較した環境

  • CPU: Intel Core i7 2600
  • SSD: Crucial m4
  • Memory: DDR3-1600 16GB

ベンチマーク内容

圧縮に使ったファイルは、数GBあるMySQL のダンプです。

cat original | command > original.compressed

という形でベンチマークしました。

下記の表は gzip の標準状態を 1 とした相対的な数値を示しています。 Software 欄の -1 や -9 は、コマンドに指定できる圧縮率です。 -1 が最低、 -9 が最高になっているコマンドが多いです。

並列に実行できるものに関してはすべて 8 スレッドで実行しています。

ベンチマーク結果

time real
実際の経過時間
time user
CPU user 時間
compression ratio
圧縮率の比。大きいほどファイルが大きい。
compression ratio (single/parallel)
並列版について、シングルスレッドに対する圧縮率の比
parallel overhead
シングルスレッド版と比較した CPU user時間の比


Softwaretime realtime usercompression ratiocompression ratio (single/parallel)parallel overhead
lzo0.220.191.55
lzo -94.914.931.25
gzip -10.500.491.15
gzip1.001.001.00
bzip2 -14.414.460.86
bzip25.875.940.79
xz -11.961.980.94
xz17.8618.140.72
pigz -10.100.771.151.001.56
pigz0.201.551.001.001.55
pbzip2 -10.957.600.861.001.70
pbzip21.5712.530.791.002.11
pxz -10.463.610.961.031.83
pxz4.1128.350.731.011.56

棒グラフが相対的な経過時間、緑の点が相対的な圧縮率です。


xz が飛び出てわかりづらいので、xz以外のシングルスレッド系圧縮ソフトを並べました。

lzo が極めて高速ですがgzipに比べ1.5倍程度のサイズになりました。 lzo の最大圧縮はとても速度が遅いにもかかわらず gzip -1 より圧縮率が悪くなりました。
bzip2 は -1..-9 は厳密には圧縮率ではないので、他のソフトに比べて差が小さかったです。圧縮速度と圧縮率のバランスが良いように思います。
xz はさすがの遅さでした。ただ、 xz -1 や(今回は測っていませんが) xz -2 であれば、bzip2 より高速にもかかわらず肉薄する圧縮率を出すので、かなり優秀だと思います。
gzip は圧縮速度と圧縮率のバランスが取れています。

次にマルチスレッド系圧縮ソフトです。棒グラフが相対的な経過時間、緑の点が並列化のオーバーヘッド(シングルスレッド版に対するCPU user timeの比)、赤い点がシングルスレッド版に対する圧縮率の比です。


ご覧のように、シングルスレッド版に対して圧縮率はほとんど変わりません。シングルスレッド版に対する実行時間は bzip2 が若干高く2倍を超えましたが、その他は1.5倍~1.8倍程度でした。

まとめ

圧縮速度と圧縮率のバランスが取れているのは gzip で、並列版の性能も優秀でした。速度をある程度要求される環境下においても、 lzo には並列版がないので、CPUをたくさん使えるのであればこれで決まりな気がします。

xz は最高の圧縮率でした。 ただ、時間をかけて圧縮する用途にしても、さすがに時間がかかりすぎの気もします... 今回は測っていませんが、bzip2 より展開は早い(らしい)ので、ファイルを配布するなどの用途には向いているのでしょう。

bzip2 は圧縮率こそ xz に叶いませんが、実行速度とのバランスは優れていると思います。展開に時間が掛かるのがデメリットですが、一応保存しておく系のログファイルなどには使えるのではないでしょうか。

lzo の高圧縮モードは今回の測定だと出番がないように見えますが、展開が gzip に比べてメモリや時間が少なくて済むので、組込み用途では活躍しそうです。

補足

xz のマルチスレッド版には pixz というのもありますが、これは圧縮アルゴリズムにも少し手を加えており、 xz とファイルの互換性がありません。 環境によってはビルドが失敗するなど、これからに期待です。 ファイルの互換性はあるようです。また、私の環境でビルドが失敗したのは単にSDKが古いから説が浮上したので、今度追試します。

pxz は xz を単純にマルチスレッドにしたもので、圧縮が終わってからファイルを連結するので、メモリとディスクの使用量がかなり大きくなります。

今回は展開速度に関しては測っていませんので、展開を頻繁に行う場合はそちらも考慮する必要があります。

2013年9月1日日曜日

Linux Kernel Updates の Kindle 版が出ました!

おまたせしました!

コミックマーケット83で頒布した Linux Kernel Updates 2012.12版と、コミックマーケット84で頒布した Linux Kernel Updates 2013.08版のKindle版を出版しました。

Linux Kernel Updates 2012.12


目次

  • What's New in Linux 3.7?
  • TCP Fast Open
  • Load Average の落とし穴
  • Completely Fair Scheduler
本文試し読み(冊子版のキャプチャです)。

Linux Kernel Updates 2013.08版

目次

  • What's New in Linux 3.8?
  • What's New in Linux 3.9?
  • What's New in Linux 3.10?
  • カーネルを更新するには
  • Modern Socket Progarmming
  • カーネルソース読書ガイド
  • マルチコアを使いこなす

本文試し読み(冊子版のキャプチャです)。