勤務先の Wi-Fi 環境を改善した

2.4 GHz 帯はもう諦めている。

前提

駅前のガラス張りのオフィスビル

やったこと

周波数帯の調整

W53 (5250 - 5350 MHz), W56 (5470 - 5725 MHz) は気象レーダーなどにも使用されており、それらを検出した場合、レーダー波を優先するために一時的な停波やチャネルの変更を行う必要がある1。恐らく事前の調査 (サイトサーベイ) は行われておらず、レーダー波の影響がないことを保証できないため、W52 (5150 - 5250 MHz) のみを使用することにした。

基本的には W53, W56 の使用は避けたほうが無難である。特に W56 は屋外利用が可能であり、公衆 Wi-Fi にも利用されているため遠方飛来も多い。

帯域幅の調整

調整前は 80 MHz に設定されていたのだが、今回のように外的要因の多い環境でボンディングを安定して運用することは非常に難しい。また、それ以前の問題として社内の AP 同士で干渉を起こしていた。そこで、帯域幅を 20 MHz にしたところかなりの改善がみられた。

大抵の場合、帯域幅は 20 MHz で十分に思える。確かにスループットは上がるかもしれないが、それよりも安定して通信できることをを優先したほうがストレスが少ない。

RSSI (信号強度) で足切り2

Wi-Fi のデータレートは RSSI に応じてリアルタイムに変化する。つまり、電波状況が悪くなると伝送速度が落ちるということだ。また、Wi-Fi は遅いクライアントがいると全体が遅くなるため3、RSSI で足切りをして遅いデータレートで通信させないようにする4。様子を見ながら -74 dB で足切り (ちょっと甘め)。これもかなり改善に寄与した。

パワーレベルの調整

調整前はパワーレベルが最大に設定されていた 。これはクライアントが (設計者の) 意図しない AP に接続してしまう原因にもなるためパワーレベルを落とす。

今回はパワーレベルを最弱にしたが、それでも時折クライアントが遠方の AP に接続しにいってしまうことがある。これ以上の改善を図るには、AP の配置の見直しや指向性アンテナの導入が必要になる。

チャネルの調整

自動設定になっていたがあまりかしこくなかったため、隣接する AP 同士でチャネルが被らないように手動で設定しなおした。

結果

SNR がかなり改善され、ルーターへの ping が 1 ms 台で返ってくるようになった。自分でもちょっとびっくりするくらい快適になっている。

Wi-Fi は目に見えない電波を扱うため非常に扱いが難しい。今回は既存の設備での調整となったが、本来は予めサイトサーベイを行いそれに基づいて設計を行うことが望ましい。


  1. DFS (Dynamic Frequency Selection)

  2. MCS Index を指定する機能はなかった

  3. 無線通信は空間が伝送媒体となるため複数のクライアントが同時に通信することができず 、ある瞬間は特定のクライアントが時空間を占有している (CPU のタイムシェアリングに近い考え方)。遅いクライアントがいるとそのクライアントが長時間にわたり時空間を占有してしまうため、全体の速度が低下する。

  4. 電波状況が悪い遠方の AP に接続してしまうことを防ぎ、近隣の AP に接続するようにする

Rails + CircleCI で MySQL の utf8mb4 をつかう

前提

ActiveRecordをutf8mb4で動かす - Qiita

気合でコンテナ上の MySQL の設定を変更する

circle.yml
database:
  override:
    - mysql -u root -e 'set global innodb_file_format = Barracuda'
    - mysql -u root -e 'set global innodb_file_per_table = 1'
    - mysql -u root -e 'set global innodb_large_prefix = 1'
    - bundle exec rake db:create db:schema:load --trace

本当は怖い less

tl;dr

パイプから大きいデータを less に渡すとメモリ死する。

パイプから読むとき

必要に応じて動的にバッファが確保される。起動直後に G とか押すと全部メモリにのる。GB オーダーのファイルでそういうことすると死ぬ。

どうしたらいいの

-B オプションをつかうと、動的にメモリを確保せず 64 KB(Amazon Linux 64bit の場合)または -b オプションで指定されたサイズのみをバッファに使用する。

そもそも

less で GB オーダーのファイル開く意味が分からない。grep とかでしぼってから less に渡そう。

jpmobile - タブレットは PC のテンプレートをつかうようにする

app/controllers/application_controller.rb
include Jpmobile::ViewSelector

before_filter :disable_mobile_view_if_tablet

private

def disable_mobile_view_if_tablet
  if request.mobile.try(:tablet?)
    disable_mobile_view!
  end
end

R3/I2 ファミリーで instance store をつかう

tl;dr

起動時にフォーマットしてマウントする。

Amazon Linux のデフォルト

cloud-init によって ephemeral0 が起動時にマウントされる。

$ grep mounts -A1 /etc/cloud/cloud.cfg
mounts:
 - [ ephemeral0, /media/ephemeral0 ]
$ tail -1 /etc/fstab
/dev/sdb        /media/ephemeral0       auto    defaults,nofail,comment=cloudconfig     0       2

R3/I2 ファミリー

SSD をいい感じに使うための TRIM という仕組みに対応していて、その関係で instance store が起動時にフォーマットされない。ので、起動時にマウントされない。 http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/InstanceStorage.html#InstanceStoreTrimSupport

どうするよ

/etc/rc.d/rc.local に以下を追加(cloud-init とかでもいいとおもう)。

if mount | grep '/dev/xvdb' &> /dev/null || [[ $(cat /sys/block/xvdb/queue/discard_max_bytes) -ne 0 ]]; then
  mkfs.ext4 -E nodiscard /dev/xvdb && mount -o discard /dev/xvdb /media/ephemeral0
fi

instance store がマウントされていない且つ TRIM に対応している場合は、instance store をフォーマットしてマウントする。デバイス名はよしなに。

困ったこと

instance store を複数つかう場合に対応していない。