Tag Archives: linux

[sh] オレオレ証明書作成シェルスクリプト

Pocket

すぐに作り方を忘れるので、シェルスクリプトを記録しておく。
変数OPENSSLにopensslをフルパスで与えること。
あとはchmod 755して実行すればカレントディレクトリにserver.crtとserver.keyができる。
おまけでDHパラメータ、dhparam.pemもできる。

#!/bin/sh

# Generates a self-signed certificate.

OPENSSL=/usr/bin/openssl
KEYFILE=server.key
CERTFILE=server.crt
SIGNREQ=server.csr
DHPARAM=dhparam.pem

if [ -f $CERTFILE ]; then
  echo "$CERTFILE already exists, won't overwrite"
  exit 1
fi

if [ -f $KEYFILE ]; then
  echo "$KEYFILE already exists, won't overwrite"
  exit 1
fi

if [ -f $SIGNREQ ]; then
  echo "$SIGNREQ already exists, won't overwrite"
  exit 1
fi

echo
echo "Generating key file, $KEYFILE"
echo "============================"
$OPENSSL genrsa 2048 > $KEYFILE || exit 2
chmod 0600 $KEYFILE
echo "============================"
echo
echo "Generating sign request file, $SIGNREQ"
echo "============================"
$OPENSSL req -new -key $KEYFILE > $SIGNREQ || exit2
echo "============================"
echo
echo "Generating cert file, $CERTFILE"
echo "============================"
$OPENSSL x509 -days 3650 -req -signkey $KEYFILE < $SIGNREQ > $CERTFILE || exit2
echo "============================"
echo
echo "Generating DH key, $DHPARAM"
echo "============================"
$OPENSSL dhparam -out $DHPARAM 2048
echo "============================"
echo
echo "Now you have $CERTFILE, $KEYFILE and $DHPARAM"
echo

参考
http://d.hatena.ne.jp/rikunora/20120514/p1
http://qiita.com/kunichiko/items/12cbccaadcbf41c72735

[メモ][Vagrant] Ubuntuのboxを作る

Pocket

Vagrantは便利だが、boxの初回ダウンロードがウンザリするくらい長い。
torrentに流してくれればいいのに…。
しかたないので自分でUbuntuのboxを作る。

参照ドキュメントは公式の以下のもの。
https://docs.vagrantup.com/v2/boxes/base.html

VirtualBox上でUbuntu14.04をインストール後、apt-get update && apt-get upgrade && apt-get dist-upgradeまで済ませた前提。
providerはVirtualBox。
まずVirtualBox特有の注意点を先に。

VirtualBox向けにBoxを作るときの注意点

https://docs.vagrantup.com/v2/virtualbox/boxes.html

  1. ネットワークインタフェースはNATにしておくこと。
  2. MACアドレスをメモしておくこと。
  3. VirtualBox Guest Additionsをインストールしてあること。

一つ目の理由は、VirtualBoxが決め打ちで接続してくるから。
二つ目の理由は、Vagrantfileのconfig.vm.base_macに書く必要があるから。
MACアドレスはVirtualBoxのGUIから確認できる。
三つめの条件を満たすには、あらかじめlinux kernel headersとbasic developer toolsをインストールしておく必要がある。
手順は後述。
ではさっそく。

不要なハードウェアの無効化

USB, オーディオなどを無効化する。
特にUSBが有効になっていると、無用なバグを引いたりするので、無効化しておくことを強く勧める。

デフォルトユーザ(vagrant)の作成

Vagrantの作業用アカウントを作る。
Vagrantはデフォルトでユーザ”vagrant”として仮想マシンにSSH接続する。
vagrantというユーザのいることが明らかだと、それはそれでセキュリティ上のリスクになるのだが、それはVagrantに慣れてから考える。

vagratを追加し、パスワードもvagrantに。
パスワードを設定しておくのは、万が一、手動で仮想マシンに接続する必要が生まれたときのため。

# useradd -m vagrant
# passwd vagrant

SSH接続用に鍵を作成する。
鍵はインターネットからダウンロードする。そんな鍵なんて危ないように見えるが、これはあくまでも初回ブート用。Vagrantが自動的に書き換えてくれる。

# mkdir -p /home/vagrant/.ssh
# cd /home/vagrant/.ssh 
# curl -k -L -o authorized_keys 'https://raw.github.com/mitchellh/vagrant/master/keys/vagrant.pub'
# chmod 700 /home/vagrant/.ssh
# chmod 600 /home/vagrant/.ssh/authorized_keys
# chown -R vagrant:vagrant /home/vagrant/

ユーザvagrant向けsudo設定

ユーザvagrantがパスワードなしでsudoできるように。
visudoで以下の行を追加。

# visudo
vagrant ALL=(ALL)       NOPASSWD: ALL

さらにrequirettyという記述があればコメントアウト

# requiretty # コメントアウトでttyなくsudoできる。

rootのパスワードも変える。

rootのパスワードも”vagrant”に。

# passwd

sshd設定

sshdがなければインストール。

# apt-get install openssh-server

sshdの設定ファイルを書き換え

# vi /etc/ssh/sshd_config

以下の行があることを確認。なければ書く。

    Port 22
    PubKeyAuthentication yes
    AuthorizedKeysFile %h/.ssh/authorized_keys
    PermitEmptyPasswords no
    UseDNS no

VirtualBox Guest Additionsのインストール

再掲だが以下のドキュメントに沿って。
https://docs.vagrantup.com/v2/virtualbox/boxes.html

# apt-get install dkms
# /etc/init.d/vboxadd setup
# apt-get install -y build-essential linux-headers-server

その後、VirtualBox Guest Additionsのインストール
VitualBoxのGUIからCDを挿入し、以下を実行。

# mount /dev/cdrom /media/cdrom
# sh /media/cdrom/VBoxLinuxAdditions.run
# umount /media/cdrom
# apt-get clean

後はこちらの通り。

rsyncのディレクトリ指定でエスケープの必要な文字を含めるには

Pocket

先に結論:ダブルクオーテーションで括ればよい。

rsyncの対象ディレクトリでカッコ「()」など、エスケープの必要な文字の含まれているケースがある。
たとえば、Sambaでサービスしている共有フォルダとか。
そのままディレクトリ名をrsyncに与えてしまうと、とても面倒なことになる。

どうするか。
ダブルクオーテーションで括ればよい。
ふむ。よろしい。
ではディレクトリがリモートにある場合、どこからどこまでを括ればよいの?
以下の通りである。
192.168.1.1にsomeoneでログインした先のディレクトリを手元にsyncする場合。

rsync -avz someone@192.168.1.1:"/work/fileshare/file\(20141022\)" /home/someone/fileshare/backup

参考
http://serverfault.com/questions/234876/escaping-spaces-in-a-remote-path-when-using-rsync-over-a-remote-ssh-connection

以上。

[メモ] sambaのパスワードファイルに登録されているユーザ一覧を表示するには

Pocket

smbpasswdにはそういった機能がない。
pdbedit -Lを使う。

pdbeditとは

manによれば「SAM database(sambaユーザデータベース)を管理するコマンド」

pdbedit -L

ユーザデータベースに登録されているユーザアカウントをすべて表示する。
「ユーザ名:uid:フルネーム」という書式で表示。
以下、実行例はすべてmanから。

$ pdbedit -L
sorce:500:Simo Sorce
samba:45:Test User

-vを付けると詳細に。

$ pdbedit -L -v
---------------
username:       sorce
user ID/Group:  500/500
user RID/GRID:  2000/2001
Full Name:      Simo Sorce
Home Directory: ¥¥BERSERKER¥sorce
HomeDir Drive:  H:
Logon Script:   ¥¥BERSERKER¥netlogon¥sorce.bat
Profile Path:   ¥¥BERSERKER¥profile
---------------
username:       samba
user ID/Group:  45/45
user RID/GRID:  1090/1091
Full Name:      Test User
Home Directory: ¥¥BERSERKER¥samba
HomeDir Drive:
Logon Script:
Profile Path:   ¥¥BERSERKER¥profile

そのほかのオプションはpdbedit –helpあるいは、もちろんman。

Pythonがあればwebサーバを動かせる件について

Pocket

Pythonがあれば、webサーバソフトウェアを追加することなくwebサーバを立ち上げることができる。
たいへん便利なのでメモしておく。

書式

Python 2.xの場合、以下のようにすると、「カレントディレクトリ」をwebサーバとして公開する。
ポートは8000。
つまりアドレスはhttp://<当該ホスト>:8000/となる。
なお、8000なので起動はスーパーユーザじゃなくても平気。

python -m SimpleHTTPServer

Python 3.xの場合。

python -m http.server

 

実行例

下記のようなindex.htmlを用意する。

$ cat ./index.html
it works!

pythonでwebサーバ起動。
2.7.6なので、python2の書式ですな。

$ python -V
Python 2.7.6

$ python -m SimpleHTTPServer
Serving HTTP on 0.0.0.0 port 8000 ...

w3mで繋いでみると。

$ w3m -no-proxy http://127.0.0.1:8000/
it works!

おお。
sockstatの結果は以下の通り。

$ sockstat -l4
USER     COMMAND    PID   FD PROTO  LOCAL ADDRESS         FOREIGN ADDRESS
vanilla  python2.7  69678 3  tcp4   *:8000                *:*
root     sshd       980   4  tcp4   *:22                  *:*

 

[UNIX tips] 復活祭(イースター)の日付に神代の遊び心を見た(2014年のイースターは4/20です)

Pocket

cal/ncalにはイースター(復活祭)を表示するオプションがある。
私はキリスト教徒ではないのですが、コマンドにこういったオプションが自然に入っていることに感銘したので記録する。

結論

ncal -e (西方教会向け)
ncal -o (東方教会向け)

* Linux(GNU cal)ならcal -e/cal -oでOK。

calコマンド

UNIXにはcalコマンドという、カレンダーを表示するコマンドがある。
手許のMacにもきちんと入っていて(MacなのでFreeBSD由来です)、実行してみると以下のように表示される。

$ cal

2月 2014
日 月 火 水 木 金 土
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28

 

復活祭とは

wikiがこちら。
http://ja.wikipedia.org/wiki/復活祭

「復活祭は基本的に「春分の日の後の最初の満月の次の日曜日」に祝われるため、年によって日付が変わる移動祝日である。」ということなので、コンピュータに計算させるニーズは、それなりにあるというわけですな。

コマンド実行例

OS XやFreeBSDで復活祭の日付を表示させるには、calコマンドではできず、ncalコマンドを使う必要がある。
GNU calなら問題なし、つまり大半のLinuxでも問題なし。
ncalコマンドは、calコマンドにさらにレイアウトやオプションを追加したもの。

-e、つまりeaster、で復活祭の日付を表示する。
-o、つまりOrthodox(正教)での復活祭の日付を表示する。

$ ncal -e
4月 20 2014

$ ncal -o
4月 20 2014

東方、西方、同じようですな。

おわりに

マニュアルを見ると、calコマンドはAT&T UNIXのVersion 5で現れたとのこと。
1975年ごろ。
まさに神代である。

そして、そんな時代でターミナル上にカレンダーを豪快に表示させるという、ロックなコマンドが生まれてるんである。
「真面目にやれよ」とか怒られなかったんですかね。
そしていつごろか、そこに復活祭のような移動祝祭日を計算するオプションが入ってくる。
のびのびしているというか、融通無碍というか。
気持ちよくて、駄文を記した次第でございます。

zfs snapshotの差分send/recvについて

Pocket

 

zfs snapshotの差分send/recvについて

zfsのバックアップは、snapshotを撮っておいて、自ホストの別zpool、あるいは他ホストの別zpoolに移すことで行われる。
バックアップは定期的に行われるものであるが、ではそのsnapshotを移す際、毎回毎回まるまる送っていたんでは帯域も時間もディスク寿命も無駄である。
zfsはそこも考慮していて、差分だけを送ればいいようにincrementalオプションがきちんと用意されている。

書式は以下の通りsendに-iオプションを与えるだけ。
(recv側にはsnapshotAがすでに転送済みの前提)

zfs send -i <snapshotA> <snapshotB> | zfs recv <target pool>

 

よろしい。では次回からは…?

ふむ。
では二回目以降はどうするのだろう?
上記の書式例でsnapshotCが出来たらどうするのだろう?
まさかsnapshotA, B, Cを全部並べるのか?と思ったけどそれは間違いで、snapshotB, Cだけでよい。

recv側にはsnapshotAがすでにあるとき。
zfs send -i snapshotA snapshotBでAとBの差分のみが送られる。
つぎにzfs send -i snapshotB snapshotCでBとCの差分のみが送られる、というわけ。

では早速試してみる。が。

「転送先が更新されているため差分を転送できません」

こんなエラーがでる。

cannot receive incremental stream: destination warehouse/dir has been modified
since most recent snapshot

まあ文字通りなんですが。
バックアップ用の転送先が更新されるのはなぜか分からないが(atimeだろうか?)。

こういう場合には、recv側で-Fオプションを与えればよい。
-Fオプションによりrecv側は最新snapshotに強制rollbackして、それからsnapshotを受け取る。

下記の例だと、recv側は@20131226にいったんrollbackしてから受け取る。

$ sudo sh -c "zfs send -i vault/chamber@20131226 vault/chamber@2014010
2 | zfs recv -F warehouse/chamber"

 

atimeのoff

recv側がなぜ更新されてるのか、atimeが怪しいのでoffにしておく。
recv側のzpoolに対してzfs set atime=offするだけ。
(zpoolから切り出されたzfsすべてに適用される)

$ zfs get atime warehouse
NAME       PROPERTY  VALUE  SOURCE
warehouse  atime     on     default
$ sudo zfs set atime=off warehouse
$ zfs get atime warehouse
NAME       PROPERTY  VALUE  SOURCE
warehouse  atime     off    local
$ zfs get atime warehouse/chamber
NAME               PROPERTY  VALUE  SOURCE
warehouse/chamber  atime     off    inherited from warehouse

 

Windows7でsambaのファイルがうまく開けない件について(oplocks死すべし)

Pocket

昨年あたりからWindows XPのサポート終了にともない、Windows 7へクライアントOSを移す企業が多い。
私の仕事PCも過日、ついに7に変更された。
さすがに色んなところが改善されていて使いやすくなっているのだが、なぜかSambaに置いてあるファイルが壊れたり、誰も開いていないはずなのに読み取り専用でしか開けない事象が頻発した。
特に共有設定したOfficeドキュメントで顕著。

しばらく悩んでいたのだが、Sambaのログにoplocks failedという記録を見つけて(おそらく)対処方法が分かった。
以下に示す。
Sambaのバージョンは3.6.22である。

結論

smb.confのglobalセクションに以下を書け。

oplocks = No
blocking locks = No

 

ネタ元

ネットを渉猟したところ、やはりOplocksの評判はあまりよくない。

以下のホワイトペーパーが分かりやすかった。
Oplocksとread cachingが原因と断定している。

Opportunistic Locking and Read Caching on Microsoft Windows Networks
http://www.dataaccess.com/whitepapers/opportunlockingreadcaching.html

先に進む前にプロトコルとしてのSMBでいくつか確認を。

 

SMB(プロトコル)のバージョンについて

Windowsファイル共有で使われるプロトコルSMBは、Vistaでバージョン2, 7でバージョン2.1になった。
Oplocksとread cachingもバージョン2以降で追加、あるいは強化されている。
詳細は以下。

SMB の新機能
http://technet.microsoft.com/ja-jp/library/ff625695.aspx
SMB1⇒2⇒2.1への変化と新機能
http://blog.goo.ne.jp/mito_and_tanu/e/10c47629fbb7e7d3d73cbd54a1a9f28d


Oplocksとは

ネットワークの効率化を狙う、Windows固有の機能。
複数のプロセスが同じファイルをロックでき、なおかつクライアントがデータをキャッシュできる。

Chapter 17. File and Record Locking
http://www.samba.org/samba/docs/man/Samba-HOWTO-Collection/locking.html
http://www.samba.gr.jp/project/translation/Samba3-HOWTO/locking.html

Read Cachingとは

Oplocksの一機能。クライアント側でのデータキャッシュ。
クライアントがローカルでデータをキャッシュする目的は、ネットワーク越しの書き込み回数を減らすこと、ひいてはネットワークの効率化のため。
ファイルの同じ部分(the same region)に対する書き込みをまとめて、一回で済ませる。

Oplocksの危険性

Oplocksが狙い通りに動けば、目的通りネットワークの効率化が図られる。
問題なのはネットワークに何か問題が起こり、キャッシュが適切にフラッシュされない場合。ともするとファイルの破壊を引き起こす。
とくにデータベースが危険。
以下のリンクに詳細が。
本記事の末尾に私訳を付す。

Locks and Oplocks
http://www.samba.org/samba/docs/using_samba/ch08.html

対策:Oplocksを無効にしろ

ここまで分かれば、対策は簡単。
Oplocksを無効にすればよい。
無効にする方法には、サーバ側での方法、クライアント側での方法がある。
クライアントと言っても、たいていはWindowsであろうが、Windowsで対処しようとするとレジストリの変更が必要になる。
さすがにそれは面倒だ。
そこでサーバ側、Sambaの設定でOplocksを無効にする。

smb.confでOplocksを無効にする

oplocks = noとすればよい。
デフォルト無効にしたければ[global]セクションに、共有ごとに無効にしたければ共有のところに書けばよい。
smb.confのmanは一見、共有ごとにしか指定できないように見えるかもしれないが[global]にも使える。
また、oplocksはbooleanなのでnoでもfalseでも、はたまた0でも理解してもらえる。

なお、ファイルごとに有効無効を指定したければveto oplock filesで指定できる。

smb.confのmanより抜粋

oplocks (S)

This boolean option tells smbd whether to issue oplocks
(opportunistic locks) to file open requests on this share.
(略)

Default: oplocks = yes

smb.confのmanよりPARAMETERS抜粋

PARAMETERS
(略)
The letter G in parentheses indicates that a
parameter is specific to the [global] section. The letter S indicates
that a parameter can be specified in a service specific section. All S
parameters can also be specified in the [global] section - in which
case they will define the default behavior for all services.

 

blocking locks

Sambaはロックの方法を指定できる。
blocking locksというものである。
これは、ファイルをロックするときに、特定部分だけをロック(range lock)するか、ファイル全体をロックするか、というものである。
デフォルトで有効。
WindowsのRead Cachingに対応してそうな機能である。
加えてmanを見ると、「range lockに失敗すると、タイムアウトするまで何回かrange lockを再試行する」などと書いてある。
これも無効にしよう。

blocking locks (S)

This parameter controls the behavior of smbd(8) when given a
request by a client to obtain a byte range lock on a region of an
open file, and the request has a time limit associated with it.

If this parameter is set and the lock range requested cannot be
immediately satisfied, samba will internally queue the lock
request, and periodically attempt to obtain the lock until the
timeout period expires.

If this parameter is set to no, then samba will behave as previous
versions of Samba would and will fail the lock request immediately
if the lock range cannot be obtained.

Default: blocking locks = yes

 

設定例

以上を踏まえて、以下のように設定
しょぼい英文は勘弁しておくれ。

[global]
(略)
#
# Disable oplock
# It's supposed to improve network performance but causes problems
#
# See:
# Opportunistic Locking and Read Caching on Microsoft Windows Networks
# http://www.dataaccess.com/whitepapers/opportunlockingreadcaching.html
#
oplocks = no
blocking locks = no

 

再起動しておしまい。

$ sudo service samba restart
Performing sanity check on Samba configuration: OK
Stopping winbindd.
Waiting for PIDS: 667.
Stopping smbd.
Waiting for PIDS: 664, 664.
Stopping nmbd.
Waiting for PIDS: 661.
Removing stale Samba tdb files: .. done
Starting nmbd.
Starting smbd.
Starting winbindd.

 

(参考)Locks and Oplocks 私訳

http://www.samba.org/samba/docs/using_samba/ch08.html
Locks and Oplocks

oplocksの使用によって得られるパフォーマンス増は、大変に望ましいことがほとんどだ。
しかしながら、クライアントやネットワークのハードウェアの信頼性が怪しいような状況では、クライアントにデータをキャッシュさせることは大きなリスクになり得る。
クライアントが書き込みのためにファイルを開き、oplockを行う場合を考えてみよう。
そして他のクライアントが同じファイルを開こうとしたとき、”oplock break”要求が最初のクライアントに送られる。
もしこの要求が何らかの理由により失敗し、二番目のクライアントがファイルの書き込みをしたとする。
二つのプロセスが同時に書き込みをするわけだから、ファイルは簡単に壊れてしまうだろう。
残念なことに上記のケースは現実に起こりうる。
SMBネットワークにおける複数のWindowsクライアント環境では、このようなおかしな動きは頻繁にみられる。
たくさんのクライアントが同時に書き込みを行うデータベースファイルは特に影響を受けてしまう。

oplocksの失敗するもっと具体的な例を挙げると、それはデータベースファイルが大変に大きい場合である。
クライアントがこのようなファイルを開き、oplockを許可されると、非常に大きな遅延が発生する。
その一部を修正するためだけであっても、クライアントがファイル全部をキャッシュするからである。
このファイルを別のクライアントが開こうとしたとき、状況はさらに悪くなる。
二番目のクライアントがファイルを開くためには、最初のクライアントがキャッシュをすべてサーバに書き戻す必要があるからだ。
このために、また別の遅延が発生する(しかも双方のクライアントで)。
結果として、タイムアウトにより二番目のクライアントがファイルオープンに失敗し、たぶんデータが壊れた旨のWarning messageも併せて表示されるだろう。

In most cases, the extra performance resulting from the use of oplocks is highly desirable. However, allowing the client to cache data can be a big risk if either the client or network hardware are unreliable. Suppose a client opens a file for writing, creating an oplock on it. When another client also tries to open the file, an oplock break request is sent to the first client. If this request goes unfulfilled for any reason and the second client starts writing to the file, the file can be easily corrupted as a result of the two processes writing to it concurrently. Unfortunately, this scenario is very real. Uncoordinated behavior such as this has been observed many times among Windows clients in SMB networks (with files served by Windows NT/2000 or Samba). Typically, the affected files are database files, which multiple clients open concurrently for writing.

A more concrete example of oplock failure occurs when database files are very large. If a client is allowed to oplock this kind of file, there can be a huge delay while the client copies the entire file from the server to cache it, even though it might need to update only one record. The situation goes from bad to worse when another client tries to open the oplocked file. The first client might need to write the entire file back to the server before the second client’s file open request can succeed. This results in another huge delay (for both clients), which in practice often results in a failed open due to a timeout on the second client, perhaps along with a message warning of possible database corruption!

Hadoopフレンドリーなデータとは

Pocket

 

ログは1行1イベントに

何を言っとるんだお前はという感じであるが、つまりこういう事である。

通常、ログは1行が1イベントである。
たとえばapacheのログやらなにやら、みんなそうである。
少なくともUNIX系のシステムであれば、これは常識である。
しかし、この世の中、UNIX系の常識が通用しないログだって山ほどあるのである。

1イベントが複数行にわたるログがなぜいけないか。

たとえば以下の様な擬似ログを考えてみよう。

まったく関係のない話だが、以下のデータは手元にあるLIFEのノートから適当にでっち上げた。
冒頭にタイムスタンプがあり、イベントの内容が記される、典型的なログである。

2013/12/16 17:55:05.6582 N28 [499016804864] Noble note section B6 5m/m

しかしこれが、以下のように複数行にわたって記録(あるいは表示)される、こういうログを相手にすることだってあるのだ。

2013/12/16 17:55:05.6582 N28
4990 1680
4864
Noble note section
B6 5m/m

 

これは主に可読性を意識したせいであろうが、こういったログをHadoopで扱うのは難しい。

Hadoopのデータの扱い方

というのも、Hadoopは分散処理のためにログを分割するからだ(デフォルトでは64MBごと)。

しかもその分割は、単純にサイズのみで判断され、文脈は考慮されない。
上のログで言えば、Nobleの手前で切られてしまってログとして意味がなくなってしまうことだってある。

これを避けるには、Hadoopにファイルそのものではなくて、ファイルリストを与える手があるけれども、それではHadoopの長所を活かせない。
ファイルリストは綺麗に分割されるけど、ファイルの大きさはまちまちだから。

ログの整形

というわけで、こういったログを扱う前に、下準備として1行1イベントにまとめてしまおう。

まとめ自体もHadoopで処理してしまえば楽である。
Hadoopの象本Appendix Cに良い例があるのでこれを使う。
ここでfiles.txtは処理するログファイルをリストしたものとする。
また、concat.shは1行1イベントにまとめるスクリプトとする。

$ hadoop jar $HADOOP_INSTALL/contrib/streaming/hadoop-*-streaming.jar \
-D mapred.reduce.tasks=0 \
-D mapred.map.tasks.speculative.execution=false \
-D mapred.task.timeout=12000000 \
-input files.txt \
-inputformat org.apache.hadoop.mapred.lib.NLineInputFormat \
-output output \
-mapper concat.sh \
-file concat.sh

 

reduceは必要ないのでmapred.reduce.tasks=0。
重複して書き込んでほしくないのでmapred.map.tasks.speculative.execution=false。
タイムアウトは長めに。
mapが一回に処理するファイルはひとつにしたいので、-inputformat org.apache.hadoop.mapred.lib.NLineInputFormat 。

以上

NginxでのFastCGI PHP設定

Pocket

 

タイトル通り、FreeBSDでnginx、FastCGIでPHPを動かす場合。
lighttpd + phpの場合はこちら

必要なもの。

  • nginx
  • spawn-fcgi
  • php(fastCGI)

 

概要

nginxは静的コンテンツ向けのwebサーバ。
そのままでは動的コンテンツは扱えない。
どうしても必要なら、よそで動的コンテンツを生成してもらわなければならない。

その仕組みの一つにFastCGIがある。
FastCGIは動的コンテンツの受け渡しのためのインタフェースである。
spawn-fcgiはFastCGIプロセスの管理を行う。

ここで、PHPにはFastCGIサーバモードというのがある。
指定されたポートで待ち受けてリクエストに応えるというもの。
spawn-fcgiとPHPのFastCGIサーバモードを組み合わせれば、PHPのFastCGIインタフェースができあがる。

nginxはPHPコンテンツのリクエストを受けたら、FastCGIを通してphp-cgiにコンテンツを生成してもらう、というわけ。

参考。まあwikipediaなんですけどね。

nginx
http://ja.wikipedia.org/wiki/Nginx
CGI
http://ja.wikipedia.org/wiki/Common_Gateway_Interface
FastCGI
http://ja.wikipedia.org/wiki/FastCGI

インストール

FreeBSDなら、pkgで前章の三つをインストールする。
特に難しいこともないので割愛。
phpはpkgそのままでfastCGI対応になっているので意識する必要なし。

PHPの確認

FastCGI対応かどうかを念のため確認。
/usr/local/bin/php-cgiというのがインストールされていればよい。
念のため-vで確認。

$ php-cgi -v
PHP 5.4.23 (cgi-fcgi) (built: Dec 19 2013 21:06:30)
Copyright (c) 1997-2013 The PHP Group
Zend Engine v2.4.0, Copyright (c) 1998-2013 Zend Technologies

 

spawn-fcgiの設定

spawn_fcgiには特定の設定ファイルがないのでrc.confに直接書き込む。
起動スクリプト/usr/local/rc.d/spawn-fcgiの中身を見るとどういったオプションがあるかが分かる。

nginx、spawn-fcgiの起動設定と一緒にやってしまおう。
下記を/etc/rc.confにひとまず貼りつける。

コメントアウトしてあるのはデフォルト設定。
変えたい箇所があれば#を外して設定する。

注意!
spawn-fcgiのspawnとfcgiの間はハイフン(ダッシュ)”-“であるが、/etc/rc.confでの記載にはアンダースコア”_”にすること。
言い方を変えると、spawn-fcgi_enableなどと書かないこと。

#
# nginx, with PHP FastCGI
#
nginx_enable="YES"
spawn_fcgi_enable="YES"
##spawn_fcgi_app="/usr/local/bin/php-cgi"
##spawn_fcgi_pidfile="/var/run/spawn-fcgi.pid"
##spawn_fcgi_username="www"
##spawn_fcgi_groupname="www"
##spawn_fcgi_bindaddr="127.0.0.1"
##spawn_fcgi_bindport="9000"
##spawn_fcgi_bindsocket_mode="0777"
##spawn_fcgi_children="5"
##spawn_fcgi_max_requests="1000"
##spawn_fcgi_path_env="/sbin:/bin:/usr/sbin:/usr/bin:/usr/games:/usr/local/sbin:/usr/local/bin"

最終的に以下のようにした。
個人用のサーバなのでささやかに。
(冗長なので一部のコメント部分は除く)

#
# nginx, with PHP FastCGI
#
nginx_enable="YES"
spawn_fcgi_enable="YES"
spawn_fcgi_bindport="8000"
spawn_fcgi_children="3"
spawn_fcgi_max_requests="100"

 

spawn-fcgiの起動確認

serviceコマンドで起動。

$ sudo service spawn-fcgi start
Starting spawn_fcgi.
spawn-fcgi: child spawned successfully: PID: 7486

sockstatで待ち受けポートを確認

$ sockstat -l4
USER     COMMAND    PID   FD PROTO  LOCAL ADDRESS         FOREIGN ADDRESS
www      php-cgi    7489  0  tcp4   127.0.0.1:8000        *:*
www      php-cgi    7488  0  tcp4   127.0.0.1:8000        *:*
www      php-cgi    7487  0  tcp4   127.0.0.1:8000        *:*
www      php-cgi    7486  0  tcp4   127.0.0.1:8000        *:*
(略)

 

phpの動作確認

nginxにはサンプルの設定ファイルがついてくる。
それをベースに、たとえば以下のような設定ファイルを作る。
location ~ \.php$のブロックが重要。
fastcgi_pass 127.0.0.1:8000;のポートを先のswawn-fcgiと合わせること。

worker_processes  1;
events {
    worker_connections  1024;
}
http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;
    server {
        listen 80;
        root /usr/local/www/php-test;
        index   index.html;
        fastcgi_index   index.php;
        location ~ \.php$ {
                include fastcgi_params;
                fastcgi_param   SCRIPT_FILENAME  $document_root$fastcgi_script_name;
                fastcgi_pass    127.0.0.1:8000;
        }
    }
}

/usr/local/www/php-testにindex.htmlをつくる。また、test.phpを作る。
index.html

It works!

test.php

<?php
phpinfo();
?>

nginxをスタートしておき;

$ sudo service nginx restart
Performing sanity check on nginx configuration:
nginx: the configuration file /usr/local/etc/nginx/nginx.conf syntax is ok
nginx: configuration file /usr/local/etc/nginx/nginx.conf test is successful
Stopping nginx.
Performing sanity check on nginx configuration:
nginx: the configuration file /usr/local/etc/nginx/nginx.conf syntax is ok
nginx: configuration file /usr/local/etc/nginx/nginx.conf test is successful
Starting nginx.

ブラウザで繋ぐ。
スクリーンショット撮るのが面倒なのでw3mで。
下記の通り/usr/local/www/nginx/index.htmlの内容が表示される。

$ w3m 127.0.0.1
It works!

index.htmlの内容が表示された。
これで通常のwebサーバとしては問題なく動作していることが確認できた。

ではphpの動作確認
PHP infoの結果が表示される。
内部的には、nginxが127.0.0.1:8000で待っているphp-cgiにtest.phpを実行させて、その結果を返している。

$ w3m 127.0.0.1/test.php

PHP Logo

PHP Version 5.4.23

              FreeBSD copper 10.0-RC2 FreeBSD 10.0-RC2 #0 r259404: Sun Dec
System        15 08:18:20 UTC 2013 root@snap.freebsd.org:/usr/obj/usr/src/
              sys/GENERIC amd64

Build Date    Dec 19 2013 21:05:25
(略)

以上