Raspberry Pi

コンピュータ関連のことを、出来る時に、出来ることだけ。
上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。
前回Raspberry piにHDDを接続して高速化を図りましたが、iowaitは減ったもののやっぱり遅いので、チューニングをしてみます。
現在は、画面表示中(リクエスト応答中)にCPUが100%に張り付いている状態です。

どれだけ早くなったか定量的に確認したいので、チューニング前の速度を計測してみます。
インターネット側から接続できるようにルータを設定して、google PageSpeed Insightsで計測しました。

1.チューニング前
3回平均:10.73秒(10.8秒、10.5秒、10.9秒)

試験項目の「モバイル」はパソコンとほぼ同速度だったので、無視します。安定の遅さ(笑)です。ムラがあるよりはやりやすいと自分に言い聞かせます。
37-01.png

2.lighttpdを使用する
軽いWebサーバとしてlighttpdなるものがあるらしいと知ったので、使用してみたのですが、いくら設定してもPHPが上手く動いてくれませんでした。ダラダラと調べつつ半年経ってしまったので、pidoraでlighttpdを動かすことをあきらめて、OSをraspbianに変えて試したところあっさり成功。既にチューニングというレベルではないです(笑)

やったことはこちらのサイトそのまま+/varディレクトリのhdd化です。
http://denshikousaku.net/raspberry-pi-wordpress-and-power-consumption

3回平均:3.1秒(3.0秒、3.0秒、3.1秒)
なんだか劇的に早くなりました♪これくらいなら実用に耐えれそうです。

3.GPUで使用するメモリを削減する
先ほどのブログにも記載のあるメモリ節約(GPU割り当て分を減らす)も実施してみました。
3回平均:3.1秒(3.2秒、3.0秒、3.0秒)
メモリがボトルネックになっている状況ではなかったので、速度は変わりませんでした。

4.オーバークロックする
raspberry piでは簡単にオーバークロックができるので、それも実施してみます。

raspi-configコマンドを実行し「Raspberry Pi Software Configuration Tool」メニューを表示させます。
"8"のOverclockを開くと、警告文が表示されます。「オーバークロックするとラズパイの寿命が短くなるかもしれないから気を付けろ」的なことが書いてあります。ようするに自己責任でということですね。
37-02.png

選択できる項目は以下の通りです。
None→Modest→Medium→High→Turbo≒Pi2
Noneはオーバークロックなしで、右側(画面だと下側)ほど強くオーバークロックするようです。最上位はTurboですが、SDRAM周波数とOvervoltを下げたPi2もあります。おそらくPi2はRaspberry Pi2と同等という意味かと。

Mediumに設定
3回平均:2.7秒(2.7秒、2.7秒、2.7秒)

Pi2に設定
3回平均:1.9秒(2.0秒、1.9秒、1.9秒)

Pi2までやると、結構な効果が出ています。が、負荷がかかりすぎて壊れてしまうのも怖いので、Medium程度にしておきます。

5.w3c total chashの導入と設定
「もしすばやい修正が今すぐ必要なら、まっすぐキャッシングページへ向かってください。最低限の努力で最大の効果を得られるでしょう。」とWordpressの公式サイトにも書いてあるので、その通りにしてみます。
ただし、キャッシュの導入はサイトによっては動作に影響を与える場合があるので、注意が必要です。具体的には頻繁に動的な更新が行われるサイト、例えば掲示板を主とするようなサイトでは、正しく表示できなくなる可能性があるようです。

w3c total chashをインストールし、このサイトを参考に以下の項目を設定しました。

キャッシングを実施するとgoogle PageSpeed Insightsでは応答速度が表示されなくなりました。google PageSpeed Insightsはあくまで「問題」に対する解決案を提示するというツールなので、「問題」でないレベルまで応答速度が上がれば、表示されないようです。

これでようやく実用レベルになりました!
この記事を書いた時点で稼働中ですので、よかったらご覧ください。次の記事から引っ越し先に書くようにします。
また、今回のセットアップのansible-playbookも引越先に載せる予定です♪

どうかよろしくお願いします!!
スポンサーサイト
Ansibleを使っていてトラブルが起きたのでメモ。

raspberry piをAnsibleで諸々操作していたところ、ある時から鍵認証のパスフレーズを何回も聞かれるようになりました。
以下のような感じです。正しいパスフレーズを入力している(コピペしているので間違いない)のに、必ず3回入力を求められます。

[user@vagrant-centos65 ~]$ ansible -m ping 192.168.x.x
Enter passphrase for key '/home/user/.ssh/id_rsa':
Enter passphrase for key '/home/user/.ssh/id_rsa':
Enter passphrase for key '/home/user/.ssh/id_rsa':
192.168.x.x | success >> {
"changed": false,
"ping": "pong"
}


しかも、playbookを使うとタスク毎に3回パスワードの入力を求められてしまい、面倒な事この上ありません。
Raspberry piのOS(Raspbian)再インストールまで実施したのですが、解消せず。ただし、別のユーザーを作成してそちらでAnsibleコマンドを実行すると、発生しません。

Ansibleではないですが、sshを使用する際に、sshクライアント側のパーミッション設定により、同様の事象が発生している方がいらっしゃいました
http://ts-engine.net/wp/archives/583

■原因と対策
結論としては、Ansibleサーバ側=sshクライアント側が原因でした。使用していたユーザーのホームディレクトリの以下ファイルを削除すると、次回ansibleコマンド実行時に再作成され、解消しました。

~/.ansible/cp/ansible-ssh-192.168.x.x-22-user


ファイルの種類ha「socket」とのこと
ansible-ssh-192.168.x.x-22-user: socket

正常な状態だと、1分も経たないうちに削除されるのですが、何らかの理由で削除されずに残ってしまっていたようです。私の場合1月13日から残っていました。

もう少し詳しく確認してみると、ansibleコマンドを実行してから1分ほど、Ansibleサーバ側でLISTENINGしているようです。本来その間のみ存在しているはずなのに、残って悪さしていた様子。

[user@vagrant-centos65 .ansible]$ netstat -ane|grep ansible;ls -la cp
unix 2 [ ACC ] STREAM LISTENING 26749 /home/user/.ansible/cp/ansible-ssh-192.168.x.x-22-user.CpQMvTQe8yJUppPZ
total 8
drwx------ 2 user users 4096 Feb 2 15:53 .
drwx------ 4 user users 4096 Jan 17 15:02 ..
srw------- 1 user users 0 Feb 2 15:53 ansible-ssh-192.168.x.x-22-user
[user@vagrant-centos65 .ansible]$
[user@vagrant-centos65 .ansible]$
[user@vagrant-centos65 .ansible]$ netstat -ane|grep ansible;ls -la cp
total 8
drwx------ 2 user users 4096 Feb 2 15:54 .
drwx------ 4 user users 4096 Jan 17 15:02 ..
[user@vagrant-centos65 .ansible]$



よくわからず使っているとハマりますね。勉強が足りませんでした。
前回Raspberry Piにwordpressをインストールしましたが、パフォーマンスが非常に悪いので、改善を試みます。

wordpress使用中にtopを表示させると、ページ更新するたびにiowaitが100%近くまで上昇していて、ディスクIOがボトルネックになっているようです。さすがにSDカードでDBMSのIOを処理するのは辛そうなので、USBハードディスクドライブを接続し、データベースのデータファイルをそこに置くようにしてみました。

mariadbの設定(/etc/my.cnf)を確認すると、データ関連のファイルはデフォルトで/var/配下に保存される設定になっていました。
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid

wordpressも/var/www/wordpress配下に配置していますし、各種ログも/var/log配下に出力されることを考えて、USBハードディスクを/varにマウントすることにします。

Ansibleのplaybookを以下のように修正します。

1:---
2:- hosts: <ホスト名>
3: sudo: yes
4: vars_files:
5: - vars/vars.yml
6: tasks:
7:
8: - name: ls /dev/disk/by-uuid
9: command: ls -la /dev/disk/by-uuid
10: register: ls_result
11:
12: - debug: var=ls_result.stdout_lines
13: when: ls_result
14:
15: - pause: prompt="Device UUID?"
16: register: devuuid
17:
18: - name: Mount the New Device
19: shell: mount -t ext4 "UUID={{ devuuid.user_input }}" /media
20: when: devuuid.user_input != ""
21:
22: - name: Copy /var Data
23: shell: creates=/media/log/messages cp -rf /var/* /media/
24: when: devuuid.user_input != ""
25:
26: - name: Unmount the New Device
27: shell: umount /media
28: when: devuuid.user_input != ""
29:
30: - name: Mount the new device, add the fstab configuration
31: mount: name=/var src='UUID="{{ devuuid.user_input }}"' fstype=ext4 state=mounted
32: when: devuuid.user_input != ""
33:
34: - name: Install the relevant package yum
35: yum: pkg={{ item }} state=present
36: with_items:
37: - httpd
38: - php
39: - mariadb
40: - mariadb-server
41: - php-mysql
42: - MySQL-python
43:
44: - name: Enable the relevant services
45: service: name={{ item }} state=started enabled=yes
46: with_items:
47: - httpd
48: - mariadb
49:
50: - name: Root user password setting
51: mysql_user: name=root password={{ db_root_password }} state=present
52:
53: - name: Place a my.cnf
54: template: src=my.cnf.j2 dest=/root/.my.cnf mode=0600
55:
56: - name: Remove a test database
57: mysql_db: name=test state=absent
58:
59: - name: Remove anonymous user
60: mysql_user: name='' state=absent
61:
62: - name: Remove remote users
63: mysql_user: name='' host=pidora.local state=absent
64: mysql_user: name=root host=pidora.local state=absent
65:
66: - name: Create a new database
67: mysql_db: name=wordpress state=present
68:
69: - name: Create User for Wordpress
70: mysql_user: name=wordpress password={{ db_wpuser_password }} priv=wordpress.*:ALL,GRANT state=present
71:
72: - name: Expand the wordpressarchive file
73: unarchive: copy=yes src=wordpress-4.2.2-ja.zip dest=/var/www/html/
74:
75: - name: Copy the configuration file
76: copy: src=wp-config.php dest=/var/www/html/wordpress/



前回から8行~32行を追加しました。その他の変更はありません。USBハードディスクは予めext4でフォーマットしています。

[8-13行目]
USBデバイスを複数接続した場合、起動ごとにデバイス名が変わってしまうことがあるため、デバイスはUUIDで指定するようにしました。リモートホスト上でコマンド「ls」を実行させて、その結果を表示します。

9行目→command:でlsコマンド実行。UUIDを確認するため/dev/disk/by-uuidを表示します。
10行目→register:で変数に結果を保存
12行目→debug:で表示

[15-16行目]
プロンプトを表示してユーザーからの入力をまちます。ユーザがUUIDを入力してEnterキーを押すと、register:の変数に入力値を保存します。

[18-20行目]
shell:でリモートホスト上でmountコマンドを実行して、/mediaにUSBハードディスクをマウントします。

ポイントは16行目のregister:で保存されるのは単純に入力した値ではなく、変数名、保存時間などの各種パラメータを含むオブジェクトであることです。入力した値そのものを取得したい場合は、変数名のdevuuidだけでなく、devuuid.user_inputを指定する必要があります。

また、このあたりの処理は2回目以降は実行する必要がないので、when:でdevuuidの値が空白ならコマンドを実行させないようにしました。

[22-24行目]
/var配下のファイルを/mediaにコピーします。コピー済みの場合は実行しないよう、念のためcreate=/media/log/messagesを追加しました。この場合/media/log/messagesが存在する場合は、コマンドは実行されません。
また、command:ではなくshell:を使っているのは、commandではワイルドカード(*)が使用できなかったためです。

[26-28行目]
/mediaをアンマウントします。

[30-32行目]
mount:で/varにUSBハードディスクをマウントします。これが便利で、マウントしたうえ、/etc/fstabに追記してくれる優れものです。

一旦SDカードをwordpressインストール前の状態に戻してからRaspberry Piを起動し、Playbookを実行すると、無事にUSBハードディスクが/varにマウントされて、そこにデータファイルが配置されました。

さっそくWordpressの管理画面を開いてみると、若干パフォーマンスが上昇しましたが、まだ遅い..
topを見ると、iowaitは上がらなくなりましたが、userの使用率が100%近くまで上がっていて、httpdプロセスが主に使用していました。次はapacheのチューニングを行ってみます。
せっかくRaspberry Piを常時稼働させているので、サーバとして動かしたい!ので、このブログを移行すべくWordPressをインストールしてみます。前回の最後にServerSpecをやってみると書きましたが、ハマったので断念(泣)。

インストール自体はそんなに難しくなかったですが、引き続きAnsibleを使って導入できるようPlayBookを作ったので、ちょっと手間取りました。PlayBookは以下の通り。公式サイトの「WordPress 日本語版のインストール」をそのままPlayBookにしたつもりです。

■ファイル構成
wordpress
├vars
│└vars.yml
├my.cnf.j2
├wordpress-4.2.2-ja.zip
├wordpress_setup.yml
└wp-config.php

※「wordpress-4.2.2-ja.zip」はWordPressの公式サイトからダウンロードしたものです。zipファイルのまま置きます。

■各ファイルの内容
・wordpress_setup.yml
WordPressをインストールするPlayBookです。

1:---
2:- hosts: <対象ホスト名>
3: sudo: yes
4: vars_files:
5: - vars/vars.yml
6: tasks:
7:
8: - name: Install the relevant package yum
9: yum: pkg={{ item }} state=present
10: with_items:
11: - httpd
12: - php
13: - mariadb
14: - mariadb-server
15: - php-mysql
16: - MySQL-python
17:
18: - name: Enable the relevant services
19: service: name={{ item }} state=started enabled=yes
20: with_items:
21: - httpd
22: - mariadb
23:
24: - name: Root user password setting
25: mysql_user: name=root password={{ db_root_password }} state=present
26:
27: - name: Place a my.cnf
28: template: src=my.cnf.j2 dest=/root/.my.cnf mode=0600
29:
30: - name: Remove a test database
31: mysql_db: name=test state=absent
32:
33: - name: Remove anonymous user
34: mysql_user: name='' state=absent
35:
36: - name: Remove remote users
37: mysql_user: name='' host=pidora.local state=absent
38: mysql_user: name=root host=pidora.local state=absent
39:
40: - name: Create a new database
41: mysql_db: name=wordpress state=present
42:
43: - name: Create User for Wordpress
44: mysql_user: name=wordpress password={{ db_wpuser_password }} priv=wordpress.*:ALL,GRANT state=present
45:
46: - name: Expand the wordpressarchive file
47: unarchive: copy=yes src=wordpress-4.2.2-ja.zip dest=/var/www/html/
48:
49: - name: Copy the configuration file
50: copy: src=wp-config.php dest=/var/www/html/wordpress/



[4-5行目]
パスワードをPlayBook内に書き込むのはどうかと思ったので、「vars_files」を使って外部ファイルから読み取るようにしています。vars.ymlの内容は後述します。

[8-16行]
Apache、MySQL、PHPと関連パッケージをインストールします。Pidora(Fedora)ではMySQLではなくて、MySQLの互換DBのMariaDBが標準になっていたので、MariaDBをインストールしています。使用する分には違いは無いようですね。
php-MySQLはphpからMySQL(MariaDB)を使用するために入れます。MySQL-pythonはAnsibleがMySQLを使用するために必要なものなので、Ansibleを使わずにインストールする場合は不要です。

with-items句を使って、ループ処理をさせてみました。

[18-22行]
httpd(Apache)とmariadbサービスを起動し、自動起動するよう設定しています。

[24-38行]
通常MySQL(MariaDB)をインストールした後は対話式のコマンド「mysql_secure_installation」を実行してセキュアな設定にします。Ansibleで対話式のコマンドやスクリプトを実行させることもできるようですが、ここではmysql_secure_installationと同じことをPlayBookで直に実行しています。

24-25行では、rootユーザのパスワードを設定しています。インストール直後はrootユーザのパスワードが設定されておらず、パスワードなしでログインできてしまうためです。

27-28行では、my.cnfファイルを配置しています。AnsibleのMySQLモジュールは、デフォルトで~/.my.cnfから認証情報を読み取るため、これ以降はmy.cnfに記載されているユーザ名とパスワードでmysql_userやmysql_dbが実行されます。全てsudoで実行しているため、rootユーザのホームディレクトリに配置しました。

mysql_userやmysql_dbなどのMySQL関連のAnsibleモジュールでは、login_userやlogin_passwordオプションを使用することで、モジュール実行時の認証情報を渡すこともできますが、実行毎に指定する必要があることと、PlayBook内にパスワードを記載することになります。また、25行のようにrootユーザのパスワードを変更すると、1回目は「①パスワードなしでrootユーザでログイン(PlayBook上は省略)して、②rootユーザのパスワードを設定する」ことができますが、再度Playbookを実行した時は、既にrootユーザーのパスワードが設定されているため、①のログイン自体ができません。それでは「冪等性」が維持できないため、このようにしています。というか、なぜわざわざmy.cnfを使っているのか分からず、1週間ほどハマってしまいました...

mysql_userやmysql_dbの使い方は↓に書いてあります。
http://docs.ansible.com/mysql_db_module.html
http://docs.ansible.com/mysql_user_module.html

[40-44行]
WordPress用のデータベースとユーザーを作成しています。ユーザーには全ての権限を付与しました。

[46-47行]
WordPressの圧縮ファイルを、対象サーバ上で展開します。

[49-50行]
WordPressの設定ファイルwp-config.phpを配置します。

・vars.yml
パスワードを変数として別出しにしたファイルです。

1:---
2:db_root_password: <パスワード>
3:db_wpuser_password: <パスワード>



・my.cnf.j2
AnsibleのMySQLモジュールが読み取る~/.my.cnfのテンプレートです。変数部分は配置時に置き換えられます。

1:[client]
2:user = root
3:password = {{ db_root_password }}



・wp-config.php
「wordpress-4.2.2-ja.zip」内に含まれている「wp-config-sample.php」を公式サイト「wp-config.php の編集」に沿って編集したものです。

1: 2:
3:define('DB_NAME', 'wordpress');
4:define('DB_USER', 'wordpress');
5:define('DB_PASSWORD', '<パスワード>');
6:define('DB_HOST', 'localhost');
7:define('DB_CHARSET', 'utf8mb4');
8:
9:define('DB_COLLATE', '');
10:
11:define('AUTH_KEY', '<認証用ユニークキー>');
12:define('SECURE_AUTH_KEY', '<認証用ユニークキー>');
13:define('LOGGED_IN_KEY', '<認証用ユニークキー>');
14:define('NONCE_KEY', '<認証用ユニークキー>');
15:define('AUTH_SALT', '<認証用ユニークキー>');
16:define('SECURE_AUTH_SALT', '<認証用ユニークキー>');
17:define('LOGGED_IN_SALT', '<認証用ユニークキー>');
18:define('NONCE_SALT', '<認証用ユニークキー>');
19:
20:$table_prefix = 'wp_';
21:
22:define('WP_DEBUG', false);
23:
24:if ( !defined('ABSPATH') )
25: define('ABSPATH', dirname(__FILE__) . '/');
26:
27:require_once(ABSPATH . 'wp-settings.php');



インストール後「http://<URL>/wordpress/」でWordPressにアクセスできます。最初にサイト名やパスワードを設定すれば、もう使用できる状態になりました。

使用感としては、残念ながらレスポンスが遅すぎでした。パフォーマンスを何とか上げれるよう、チューニングしてみます。
前回のAnsibleのplaybookを書きましたが、パッケージをインストールするだけでは特に便利になった感は少ないので、もうちょっとやってみます。

以下のplaybookを実行します。

01:---
02:- hosts: 192.168.1.5
03: sudo: yes
04: tasks:
05:
06: - name: Install net-tools
07: yum: pkg=net-tools state=latest
08:
09: - name: Install net-snmp
10: yum: pkg=net-snmp state=latest
11: - name: Install net-snmp-utils
12: yum: pkg=net-snmp-utils state=latest
13: - name: Copy ConfFile snmpd.conf
14: template: src=/vagrant/pi/etc/snmp/snmpd.conf dest=/etc/snmp/snmpd.conf
15: - name: Enable snmpd
16: service: name=snmpd state=started enabled=yes
17:
18: - name: Install ntp
19: yum: pkg=ntp state=latest
20: - name: Enable ntpd
21: service: name=ntpd state=started enabled=yes


・09-10行
 net-snmpをインストール
・11-12行
 net-snmp-utilをインストール
・13-14行
 snmpdの設定ファイルをコピー。
・15-16行
 snmpdを起動(state=started)し、自動起動するよう設定(enabled=yes)
・18-19行
 ntpをインストール
・20-21行
 ntpdを起動(state=started)し、自動起動するよう設定(enabled=yes)

snmpdの設定ファイルは、Ansibleサーバ上に予め準備しておきます。

$ cat /vagrant/pi/etc/snmp/snmpd.conf
com2sec notConfigUser default xxxxx

group notConfigGroup v1 notConfigUser
group notConfigGroup v2c notConfigUser

view systemview included .1.3.6.1.2.1.1
view systemview included .1.3.6.1.2.1.25.1.1

access notConfigGroup "" any noauth exact systemview none none

syslocation raspberry_pi
syscontact Root xxxxx@example.com

dontLogTCPWrappersConnects yes



playbookを実行します。

$ ansible-playbook raspberrypi_setup.yml -k -K
SSH password:
sudo password [defaults to SSH password]:

PLAY [192.168.1.5] ************************************************************

GATHERING FACTS ***************************************************************
ok: [192.168.1.5]

TASK: [Install net-tools] *****************************************************
ok: [192.168.1.5]

TASK: [Install net-snmp] ******************************************************
changed: [192.168.1.5]

TASK: [Install net-snmp-utils] ************************************************
changed: [192.168.1.5]

TASK: [Copy ConfFile snmpd.conf] **********************************************
changed: [192.168.1.5]

TASK: [Enable snmpd] **********************************************************
changed: [192.168.1.5]

TASK: [Install ntp] ***********************************************************
changed: [192.168.1.5]

TASK: [Enable ntpd] ***********************************************************
changed: [192.168.1.5]

PLAY RECAP ********************************************************************
192.168.1.5 : ok=8 changed=6 unreachable=0 failed=0


問題なく完了しました。
Raspberry piにログインして、意図通りに設定できているか確認します。

snmpdの設定ファイルは正しく配置されていました。

[root@pidora ~]# ls -l /etc/snmp/snmpd.conf
-rw------- 1 root root 421 Mar 25 23:43 /etc/snmp/snmpd.conf
[root@pidora ~]# cat /etc/snmp/snmpd.conf
com2sec notConfigUser default xxxxx

group notConfigGroup v1 notConfigUser
group notConfigGroup v2c notConfigUser

view systemview included .1.3.6.1.2.1.1
view systemview included .1.3.6.1.2.1.25.1.1

access notConfigGroup "" any noauth exact systemview none none

syslocation raspberry_pi
syscontact Root xxxxx@example.com

dontLogTCPWrappersConnects yes
[root@pidora ~]#



ntpdとsnmpdは、enable(自動起動)になっています。

[root@pidora ~]# systemctl list-unit-files | egrep "ntpd.service|snmpd.service"
ntpd.service enabled
snmpd.service enabled
[root@pidora ~]#



ntpdとsnmpdのプロセスも稼働しています。

[root@pidora ~]# ps -wef|egrep "ntp|snmp" | grep -v grep
root 31600 1 0 01:21 ? 00:00:02 /usr/sbin/snmpd -LS0-6d -f
ntp 31745 1 0 01:24 ? 00:00:00 /usr/sbin/ntpd -u ntp:ntp -g
[root@pidora ~]#



これくらいやってみると、便利さが実感できてきました。よく「実行できる手順書」と表現されますが、まさしくその通り。playbookがあれば設定ができて、何をやろうとしたかも分かる。しかも対象にログインしなくてよい。これは…良いものだ。

ただ、結局稼働確認で管理対象にログインしているので、そこも何とかしたい。次はserverspecをやってみます。

 | Copyright © ふたごパパのサーバ構築日記 All rights reserved. |  Next

 / Template by 無料ブログ テンプレート カスタマイズ
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。