CloudWatchのモニタリングスクリプトでハマった話

CloudWatchのモニタリングスクリプト設定してあるのに、該当のインスタンスIDのデータがCloudWatchにputDataされていなくてハマった話。

ハマったインスタンスは、すでにクラウドウォッチが設定してあるAMIから立ち上げたインスタンスで、 AMIに配置されている、CloudWatchにputDataするスクリプト自体は、インスタンスIDに依存していないから、 そのまま問題なく正しいインスタンスIDでputDataされるはず。             

だが、実際はAMI作成ものインスタンスIDでメトリクスが登録されてしまう。。

インスタンスIDを確認

# curl -s http://169.254.169.254/latest/meta-data/instance-id
i-xxxxxxxx

で紹介したスクリプトを利用している。

# /usr/bin/check_cw_stats

MemoryUtilization: 12.86724312544 (Percent)
DiskSpaceUtilization [/]: 6.65698036312681 (Percent)
Using AWS credentials file </etc/aws/awscreds.conf>
Endpoint: https://monitoring.ap-northeast-1.amazonaws.com
Payload: {"MetricData":[{"Timestamp":1460957603,"Dimensions":[{"Value":"i-yyyyyyyy","Name":"InstanceId"}],"Value":12.86724312544,"Unit":"Percent","MetricName":"MemoryUtilization"},{"Timestamp":1460957603,"Dimensions":[{"Value":"/dev/xvda1","Name":"Filesystem"},{"Value":"i-yyyyyyyy","Name":"InstanceId"},{"Value":"/","Name":"MountPath"}],"Value":6.65698036312681,"Unit":"Percent","MetricName":"DiskSpaceUtilization"}],"Namespace":"System/Linux","__type":"com.amazonaws.cloudwatch.v2010_08_01#PutMetricDataInput"}
Received HTTP status 200 on attempt 1


Successfully reported metrics to CloudWatch. Reference Id: 1038cd0d-0527-11e6-b8f3-fbed7fa60205

あきらかに、PayloadのインスタンスIDが実際にインスタンスメタデータで取得したInstanceIdと異なっている。 ちなみにi-yyyyyyyyのインスタンスIDはAMIのインスタンスIDになる。

AWSから提供されているCloudWatch登録のスクリプトをおってみる。

  • /usr/local/src/CloudWatch-1.0.20.0/aws-scripts-mon/mon-put-instance-data.pl
338: my $instance_id = CloudWatchClient::get_instance_id();
  • /usr/local/src/CloudWatch-1.0.20/aws-script-mon
sub get_instance_id
...
{
  if (!$instance_id) {
    $instance_id = get_meta_data('/instance-id', USE_CACHE);
  }
  return $instance_id;
}
...

USE_CACHEだと!!というわけで、キャッシュをするようです。

インスタンスIDを取得しているようなメソッドが。

よくよくAmazon EC2 Linux インスタンスのメモリとディスクのメトリックスのモニタリングを読んでみると以下のようにキャシュに関する文章が。

スクリプトパッケージに含まれる CloudWatchClient.pm モジュールは、インスタンスメタデータをローカルでキャッシュします。スクリプトを実行しているインスタンスから AMI を作成すると、キャッシュ TTL(デフォルト: 6 時間、Auto Scaling グループでは 24 時間)以内にこの AMI から起動したすべてのインスタンスは、元のインスタンスの ID を使用してメトリックスを出力します。キャッシュ TTL 期間が経過した後は、スクリプトは新しいデータを取得し、スクリプトは現在のインスタンスの ID を使用します。これをすぐに修正するには、$ rm /var/tmp/aws-mon/instance-id を使用してキャッシュされたデータを削除します

気を取り直し、キャッシュを削除

rm -rf /var/tmp/aws-mon/*

再度メトリクススクリプトの実行。

# /usr/bin/check_cw_stats

MemoryUtilization: 13.8519340228981 (Percent)
DiskSpaceUtilization [/]: 6.65734560054434 (Percent)
Using AWS credentials file </etc/aws/awscreds.conf>
Endpoint: https://monitoring.ap-northeast-1.amazonaws.com
Payload: {"MetricData":[{"Timestamp":1460958577,"Dimensions":[{"Value":"i-xxxxxxxx","Name":"InstanceId"}],"Value":13.8519340228981,"Unit":"Percent","MetricName":"MemoryUtilization"},{"Timestamp":1460958577,"Dimensions":[{"Value":"/dev/xvda1","Name":"Filesystem"},{"Value":"i-xxxxxxxx","Name":"InstanceId"},{"Value":"/","Name":"MountPath"}],"Value":6.65734560054434,"Unit":"Percent","MetricName":"DiskSpaceUtilization"}],"Namespace":"System/Linux","__type":"com.amazonaws.cloudwatch.v2010_08_01#PutMetricDataInput"}
Received HTTP status 200 on attempt 1

となり、正しいインスタンスIDでputDataができました。

ということで、AMIなどから新しいインスタンス、オートスケールなどを実行する際には、

ユーザーデータで

#!/bin/bash
rm -rf /var/tmp/aws-mon/*

と設定しておけば安心です。

AMIからのインスタンス作成し、CloudWatchモニタリングスクリプトではまってしまった お話でした。

_| ̄|○

AWSのCentOS6.7のインスタンスでボリュームが8GBしか認識しない

AWSでCentOS6.7のコミュニティAMIを利用してHVMインスタンスを作成して、ディスクがなぜか8GBしか認識されなかったので、解決した話。

インスタンス起動後、EBSは50GBで割り当てたはずなのに、dfでみてみると認識されていない??

# df -h
Filesystem      Size  Used Avail Use% Mounted on
/dev/xvda1      7.8G  3.2G  4.3G  43% /
tmpfs           3.9G     0  3.9G   0% /dev/shm

パーティションサイズが8GBでしか認識されていないので、resize2fsをつかっても8GBしか割り当てられない。

fdiskではディスクは50GB認識しているが、パーティションはブロックをみると8387584しか認識していない模様。

# fdisk -l

ディスク /dev/xvda: 53.7 GB, 53687091200 バイト
ヘッド 255, セクタ 63, シリンダ 6527
Units = シリンダ数 of 16065 * 512 = 8225280 バイト
セクタサイズ (論理 / 物理): 512 バイト / 512 バイト
I/O size (minimum/optimal): 512 bytes / 512 bytes
ディスク識別子: 0x00098461

デバイス ブート      始点        終点     ブロック   Id  システム
/dev/xvda1   *           1        1045     8387584   83  Linux

調べてみると、CentOS6のAMIはAmazon Linuxなどと異なりCloud-initなどがインストールされていないことが原因のよう。

そこで、実際にCloud-initをインストールする。Cloud-initはEPELのリポジトリからインストールできるので、EPELのリポジトリをインストールし、

/etc/yum.repos.d/epel.repoのenabled=0に変更しておく。

# rpm -Uvh http://ftp-srv2.kddilabs.jp/Linux/distributions/fedora/epel/6/x86_64/epel-release-6-8.noarch.rpm

つぎに、Cloud-initなどをインストールする。

# yum -y --enablerepo=epel install cloud-init.noarch cloud-utils-growpart

インストール後、拡張前にパーティションを確認しておく。

# parted -l
モデル: Xen Virtual Block Device (xvd)
ディスク /dev/xvda: 53.7GB
セクタサイズ (論理/物理): 512B/512B
パーティションテーブル: msdos

番号  開始    終了    サイズ  タイプ   ファイルシステム  フラグ
 1    1049kB  8590MB  8589MB  primary  ext4              boot → 8GBしか認識していない。

Cloud-InitモジュールのgrowpartコマンドでEBSのサイズにあわせて、ボリュームを拡張できる。 早速実行。

# growpart /dev/xvda 1
/usr/bin/growpart: line 170: シリンダ数*255、63*: syntax error: operand expected (error token is "シリンダ数*255、63*")

うまくいかない、またまた調べてみるとロケールが悪さしているよう。

ロケールを変更して、

# export LANG="en_US.UTF-8"
# locale
LANG=en_US.UTF-8
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHONE="en_US.UTF-8"
LC_MEASUREMENT="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=

再度実行。

# growpart /dev/xvda 1
CHANGED: partition=1 start=2048 old: size=16775168 end=16777216 new: size=104854207,end=104856255

忘れないうちにロケールを戻し、

export LANG="ja_JP.UTF-8"

パーティションが拡張されているか、確認してみる。

# parted -l
モデル: Xen Virtual Block Device (xvd)
ディスク /dev/xvda: 53.7GB
セクタサイズ (論理/物理): 512B/512B
パーティションテーブル: msdos

番号  開始    終了    サイズ  タイプ   ファイルシステム  フラグ
 1    1049kB  53.7GB  53.7GB  primary  ext4              boot → 50GB認識した。

パーティションは無事拡張されているので、ファイルシステムも確認。

# df -h
Filesystem      Size  Used Avail Use% Mounted on
/dev/xvda1      7.8G  3.2G  4.3G  43% /
tmpfs           3.9G     0  3.9G   0% /dev/shm

ファイルシステムは拡張されていない。これで、再起動すれば認識するのだが、 その前にCloud-initの最低限の設定をしておかないと

  • rootログイン不可

など困った状況になってしまうので、最低限Cloud-Init設定を行っておく。

# cp -p /etc/cloud/cloud.cfg /etc/cloud/cloud.cfg.org
# diff /etc/cloud/cloud.cfg /etc/cloud/cloud.cfg.org
4c4
< disable_root: 0 → rootを許可する。
---
> disable_root: 1
13,14d12
< locale: ja_JP.UTF-8 ロケール
< timezone: Asia/Tokyo タイムゾーン

上の設定が終わったら気持よく

# reboot

ファイルシステムをdfで確認。

# df -h
Filesystem      Size  Used Avail Use% Mounted on
/dev/xvda1       50G  3.2G   44G   7% /
tmpfs           3.9G     0  3.9G   0% /dev/shm

無事にファイルシステムが50GBに拡張されている。

といわけで、色々罠にハマりましたが。 無事に割り当てたボリュームを認識させることができました。

それでは。 (・∀・)イイネ!!

CentOS6.6にCloudWatchを設定する。

CloudWatchデフォルトで監視できる項目は、CPU使用率、ネットワーク帯域などOSに依存しない項目のみとなっていて、Memory、DISK、SWAP、プロセスなどOSに依存する項目は、インスタンスにCloudWatchCommandLineTool / CloudWatchモニタリングスクリプトをインストールしてメトリクスを取得する必要があります。

CloudWatchCommandLineToolのインストール

CloudWatchCommandLineToolの前提としてJavaがインストールされていることを確認します。 インストールディレクトリは/usr/local/srcとしています。

# /usr/java/latest/bin/java -version
java version "1.8.0_45"
Java(TM) SE Runtime Environment (build 1.8.0_45-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.45-b02, mixed mode)

CloudWatchCommandLineTool SDKをダウンロードする。

# cd /usr/local/src
# curl -O curl -O http://ec2-downloads.s3.amazonaws.com/CloudWatch-2010-08-01.zip
# unzip CloudWatch-2010-08-01.zip

CloudWatchモニタリングスクリプトのインストール

依存パッケージをインストールします。

# yum -y install perl-DateTime perl-Sys-Syslog perl-LWP-Protocol-https perl-Digest-SHA
# yum -y install perl-CPAN perl-libwww-perl openssl-devel
# yum -y install libyaml

足りないモジュールをCPANを使ってインストールする。色々聞かれますが、とりあえずすべてyesで。

# perl -MCPAN -e shell
cpan[1]> install Bundle::LWP6 LWP
cpan[2]> install YAML
cpan[3]> install Crypt::SSLeay

CloudWatchモニタリングスクリプトをインストールします。

# cd /usr/local/src/CloudWatch-1.0.20.0/
# curl -O http://aws-cloudwatch.s3.amazonaws.com/downloads/CloudWatchMonitoringScripts-1.2.1.zip
# unzip ./CloudWatchMonitoringScripts-1.2.1.zip
Archive:  ./CloudWatchMonitoringScripts-1.2.1.zip
 extracting: aws-scripts-mon/awscreds.template
  inflating: aws-scripts-mon/AwsSignatureV4.pm
  inflating: aws-scripts-mon/CloudWatchClient.pm
  inflating: aws-scripts-mon/LICENSE.txt
  inflating: aws-scripts-mon/mon-get-instance-stats.pl
  inflating: aws-scripts-mon/mon-put-instance-data.pl
  inflating: aws-scripts-mon/NOTICE.txt

/usr/local/src/CloudWatch-1.0.20.0/aws-scripts-monにインストールされました。

Aws Credentialを設定する

AWS CLIで利用するクレデンシャルを設定します。インスタンスにiamを設定している場合は、そちらの方法を優先させます。

クレデンシャル記述のテンプレートを確認。CLIツールと同じですね。

# cat CloudWatch-1.0.20.0/credential-file-path.template
AWSAccessKeyId=<Write your AWS access ID>
AWSSecretKey=<Write your AWS secret key>

クレデンシャルを設定します。

# mkdir -p /etc/aws
# cp -p  ./CloudWatch-1.0.20.0/credential-file-path.template /etc/aws/awscreds.conf
# vim /etc/aws/awscreds.conf

監視スクリプトを設置する

プロセスの存在性、リソースをClowdWatchに登録するスクリプトを設置します。

# vim /usr/bin/check_cw_stats
----
#!/bin/bash
# Parameter
    export AWS_CLOUDWATCH_HOME=/usr/local/src/CloudWatch-1.0.20.0
    export AWS_CREDENTIAL_FILE=/etc/aws/awscreds.conf
    export AWS_MONITOR_PROCESSLIST=/etc/aws/mon_pro_list
    export AWS_CLOUDWATCH_URL=https://monitoring.amazonaws.com
    export PATH=$AWS_CLOUDWATCH_HOME/bin:$PATH
    export JAVA_HOME=/usr/java/default
    export INSTANCE_ID=$(curl -s http://169.254.169.254/latest/meta-data/instance-id)
    InstanceId=$INSTANCE_ID

### Memory & Disk util Check
 perl ${AWS_CLOUDWATCH_HOME}/aws-scripts-mon/mon-put-instance-data.pl --mem-util --disk-space-util --disk-path=/ --aws-credential-file=${AWS_CREDENTIAL_FILE}

  if [ $? != 0 ]; then
     logger -p user.err -t "batch[${$}][Error]" "${0##*/} Memory & Disk util Check execution failed."
  fi

### Process Check
 while read line
  do
     PRO_NAME=`echo $line |awk -F"," '{print $1}'`
     PRO_GREP_STRINGS=`echo $line |awk -F"," '{print $2}'`
     PRO_COUNT=`ps ax| grep "${PRO_GREP_STRINGS}" | grep -v grep | wc -l`
     mon-put-data --metric-name "${PRO_NAME}" --namespace "System/Linux" --dimensions "InstanceId=$InstanceId" --value "$PRO_COUNT" --unit "Count" --region ap-northeast-1
  done < ${AWS_MONITOR_PROCESSLIST}
---

監視対象のプロセスを定義します。

vim /etc/aws/mon_pro_list
----
crond,crond
sshd,/usr/sbin/ssh
httpd,/usr/sbin/httpd
postfix,/usr/libexec/postfix/master

スクリプトに権限設定する。

# chmod +x /usr/bin/check_cw_stats

スクリプトを実行してみる。

# /usr/bin/check_cw_stats

Successfully reported metrics to CloudWatch. Reference Id: fba01c9f-e4d1-11e5-843f-87deeeda5ed9

成功。ClowdWatchコンソールから登録されていることを確認する。

f:id:youshjp:20160308111253p:plain

最後にスクリプトをcronで設定して、定期的にCloudWatchに登録するようにしたらおしまい。

# crontab -e
----
*/5 * * * * /usr/bin/check_cw_stats

それでは。m(__)m

大量データが入ったMySQLのテーブルになんとかカラムを追加する

オンラインのMySQLで、案件数100万件のレコードが入っていてかつWRITEが頻繁に発生しているテーブルに 新たにカラムを追加する必要があり、なんとか解決した話。

Alterでのカラム変更の場合、テーブルにWriteロックがかかってしまう。また、Alterでカラム変更を行うと、 レコードの数に比例した時間が必要となってしまう。そのため、数100万規模のレコードがすでに存在する既存の テーブルの場合、結構な時間Writeロックがかかってしまい、その間オンラインから発生する更新操作ができなくなってしまう。

ということで、Alterクエリ以外でオンラインへの影響が少ないカラム追加を次のような方法で行いました。

・既存のテーブル〜<table>

・カラムを追加した新しいテーブル〜<newtable>

  1. 新たなテーブル定義の<newtable> ( <table> に新たにカラムを追加したテーブル)を作成する。
  2. から特定の登録日時までのレコードを<newtable>に移行する。

    具体的にはinsert 〜 select 〜 クエリを利用した。

    insert into <newtable> (c1, c2, ...) select c1, c2, ... from <table> where created_at < '2016-01-10 00:00:00';
    1. 2つのテーブル1トランザクションで一度にリネームを行うことで、一貫性を保つ。<table><oldtable><newtable><table> このタイミングから、カラムが追加されている新しいテーブルにレコードが登録されるようになる。

    参照 MySQL :: MySQL 5.6 リファレンスマニュアル :: 13.1.32 RENAME TABLE 構文

    rename table <table> to <oldtable>, <newtable> to <table>;

    あとはのんびり古いテーブルに残っているレコードを移行するだけ。

    1. <oldtable>から 2で移行していない残りのレコードをRename後の<table>に移行する。

    というわけで、無事にオンラインに影響なくカラム追加ができました。

    めでたし、それではm(__)m

    VarnishでS3をオリジンとするキャッシュの構築

    Varnish 4.0を使ってCentOS6.7(x64)に、S3をオリジンとしたキャッシュサーバーを設定した話。 S3に対してキャッシュ作らなくてもいいということもあるけど、オリジンはS3に限らず応用が効くのでそのときの手順をまとめてみました。

    前提の環境

    • CentOS6.7 (x64)
    • Varnish 4.0.3

    下準備

    Varnishはjemallocを利用するため、下準備としてEPELのリポジトリを追加する。 また、Varnishもyumでインストールしたいのでリポジトリを追加。

    # rpm --nosignature -i https://repo.varnish-cache.org/redhat/varnish-4.0.el6.rpm
    # rpm --nosignature -i http://ftp-srv2.kddilabs.jp/Linux/distributions/fedora/epel/6/x86_64/epel-release-6-8.noarch.rpm

    インストール

    jemallocとVarnishをインストールする。

    # yum -y install --enablrepo=epel jemalloc
    インストール:
      jemalloc.x86_64 0:3.6.0-1.el6
    完了しました!
    # yum -y install --enablerepo=varnish-4.0 varnish
    ...
    インストール:
      varnish.x86_64 0:4.0.3-1.el6
    
    依存性関連をインストールしました:
      varnish-libs.x86_64 0:4.0.3-1.el6

    設定

    待受ポートの変更

    Varnishの待ち受けポートを変更する。

    # /etc/sysconfig/varnish
    
    VARNISH_LISTEN_PORT=80

    オリジンの設定

    次にキャッシュするコンテンツが配置されているオリジンサーバに関する設定。 今回は、static web hosting が有効になっているS3をオリジンとする場合の設定をする。

    オリジンのドメイン{your s3 bucket}.s3-website-ap-northeast-1.amazonaws.com とする。

    ^/contents へアクセスされた場合に、S3のオリジンサーバーへコンテンツを取りに行く設定をする。 (Varnishのキャッシュにヒットしなかった場合。)

    # diff /etc/varnish/default.vcl /etc/varnish/default.vcl.org
    backend s3 {
        .host = "{your s3 bucket}.s3-website-ap-northeast-1.amazonaws.com";
        .port = "80";
    }
    
    sub vcl_recv {
        # Happens before we check if we have this in cache already.
        #
        # Typically you clean up the request here, removing cookies you don't need,
        # rewriting the request, etc.
        if (req.url ~ "^/contents/.*") {
            set req.http.host = "{your s3 bucket}.s3-website-ap-northeast-1.amazonaws.com";
            set req.backend_hint = s3;
        } else {
            return (synth(403, "Forbidden!!"));
        }
    }

    オリジンサーバーからのレスポンスで、S3に特有のヘッダーを削除してレスポンスをする設定。

    sub vcl_backend_response {
        # Happens after we have read the response headers from the backend.
        #
        # Here you clean the response headers, removing silly Set-Cookie headers
        # and other mistakes your backend does.
        unset beresp.http.x-amz-id-2;
        unset beresp.http.x-amz-request-id;
        set beresp.ttl = 1w;
    }

    設定ファイルが正しいか確認。

    # varnishd -C -f /etc/varnish/default.vcl

    起動

    # /etc/init.d/varnish start
    Starting Varnish Cache:                                    [  OK  ]
    # /etc/init.d/varnishncsa start
    Starting varnish ncsa logging daemon:                      [  OK  ]
    # /etc/init.d/varnishlog start
    Starting varnish logging daemon:                           [  OK  ]

    うまく設定できているか確認するために、s3のオリジンにあるコンテンツ {content}を取得する。

    # curl -O http://{Your Varnish host}/contents/{content}

    無事取得確認できたら、Cheome develop ment toolでも、同様のコンテンツを取得。

    f:id:youshjp:20151128130805p:plain

    無事に、S3特有のヘッダーも削除されて、コンテンツも取得されていることがわかる。

    というわけで、無事にS3をオリジンとするキャッシュサーバーが構築できたので、次はVarnishの設定パラメータを細かく見ていこうと思います。

    それではm(__)m

    参照

    Using Varnish in front of your Amazon S3 static content - MDLog:/sysadmin

    AWSソリューションアーキテクト アソシエイト試験を受けた所感

    AWSソリューションアーキテクトの試験を受けてきて、なんとか合格しました。

    受験までにした内容と所感をまとめてみました。

    筆者は業務上 EC2/Autoscaling/SQS/RDSなどを主に利用していて、それぞれの特徴などは 感覚的に掴んでいたものの、試験ではEC2/VPC/EBS/S3/Autosceleに関してがよく問われていた感想です。

    試験要項 AWS 認定ソリューションアーキテクト – アソシエイト にあるように以下のような設問の配分となっているようです。

    • 高可用性、コスト効率、対障害性、スケーラブルなシステムの設計 60%
    • 実装/デプロイ 10%
    • データセキュリティ 20%
    • トラブルシューティング 10%

    受験までの準備

    筆者のばあい業務上利用していることもあり、まずは模擬試験をオンライン上で受けてみて、感覚を掴んでVPC周りがよくわからなかったので、 そこを中心に勉強しました。

    主に勉強したもの

    各分野のホワイトペーパーは読むのですが、文字が多く読みづらいということもあり、以下にリンクを貼ったスライドなどを参考にしました。

    試験を受けた感想

    ちまたの噂通りに、

    • EC2
    • VPC
    • EBS
    • S3
    • Autoscale

    が沢山出題されていました。

    その他細かい話としては、

    • SQSの適切な使い方
    • EBSスナップショット時の挙動
    • EBSの暗号化
    • RDS MultiAZの障害時の挙動
    • CloudFrontのOAIに関する問題
    • IAM/LDAPの連携
    • Dynamoのアクセス権限周りの話
    • プレイスメントグループの話
    • Snapshot時の挙動
    • Elastic Network Interfaceの話
    • ペネトレーションテストに関する話

    など。

    筆者としては、EBSは結構細かいことが効かれていたので、もう少し きちんとホワイトペーパーも読んでおけばよかったと思っています。

    あと、設問の日本語がわかりづらい(T_T) ので、言いまわしが慣れない。。その意味でも 事前の模擬試験は必須だと思います。すぐに答えられる問題も多いため、余った時間で読み直すのも いいでしょう。

    それでは (・∀・)

    Mac OS X YosemiteでToo many open filesが発生したときの対処法

    Mac上でPHP Laravelを組み込みサーバー

    $ php artisan serve

    で開発をやっているときしばらくするとたまに、

    [Thu Nov 26 17:16:02 2015] PHP Warning: Unknown: failed to open stream: Too many open files in Unknown on line 0

    がでるので、Linuxなんかであるファイルディスクリプタを超えてしまったようなエラー内容なので、そこにあたりをつけ確認した記録。

    現状の設定確認

    環境は

    Mac OS X 10.10.5 Yosemite

    まずは、現状の設定状況の確認。

    $ sudo launchctl limit
    
    Password:
    cpu unlimited unlimited
    filesize unlimited unlimited
    data unlimited unlimited
    stack 8388608 67104768
    core 0 unlimited
    rss unlimited unlimited
    memlock unlimited unlimited
    maxproc 709 1064
    maxfiles 256 unlimited

    maxfilesがファイルディスクリプタの設定。256なんて設定だと開発しているとき、たくさんのアプリケーションを開き、サーバーを起動させなんてやっていたらあっという間に超えてしまいそう。

    一時的にファイルディスクリプタの設定を変更する

    一時的な変更 ファイルディスクリプタの設定前に現場の設定値を確認する。

    $ ulimit -n 256

    次にファイルディスクリプタを設定する。

    $ ulimit -n 2028

    設定されているか確認する。

    $ ulimit -n 2028

    というわけで設定が反映されているがめ、一時的な設定はOK。 再起動なしで設定が反映されます。

    恒久的にファイルディスクリプタの設定を変更する

    まずは確認

    $ sudo launchctl limit
    Password:
        cpu         unlimited      unlimited
        filesize    unlimited      unlimited
        data        unlimited      unlimited
        stack       8388608        67104768
        core        0              unlimited
        rss         unlimited      unlimited
        memlock     unlimited      unlimited
        maxproc     709            1064
        maxfiles    unlimited         256

    以下のファイルを作成して、記述。

    $ sudo vi /etc/launchctl.conf

    limit maxfiles 65536 65536

    そして再起動。。

    $ ulimit -n

    256

    反映されていない。。 ちまたに溢れている情報だとこのやり方なのですが、新しMacのOSだとうまくいかないのかも。

    気を取り直して、英文のWebを読み進め、

    /Library/LaunchDaemons/limit.maxfiles.plist

    を設定する方法があることを発見。

    ファイルがない場合は以下を作成して、記述。

    $ sudo vim /Library/LaunchDaemons/limit.maxfiles.plist

    <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    <plist version="1.0">
      <dict>
        <key>Label</key>
        <string>limit.maxfiles</string>
        <key>ProgramArguments</key>
        <array>
          <string>launchctl</string>
          <string>limit</string>
          <string>maxfiles</string>
          <string>524288</string>
          <string>524288</string>
        </array>
        <key>RunAtLoad</key>
        <true/>
        <key>ServiceIPC</key>
        <false/>
      </dict>
    </plist>

    再起動。。。。

    おもむろに設定値を確認する。。

    $ ulimit -n

    524288

    反映されている。。

    恒久的に反映する方法で、なんだか疲れたけど。 なんとかうまくいきました。

    それではm(__)m