vm.swappinessの設定は本当に10でいいのだろうか

注意: この記事には特に数値やコードを提示したうえでの考察などは無いです。

Linuxにはディスクスワップのしやすさを調整する vm.swappiness というパラメータが有ります。
よく知られた設定としては以下のような物が有るかと思います。

vm.swappiness = 0 : かつて(Kernel 3.5 より前、RHELだとKernel 2.6.32-303 より前)はこれがスワップを極力させない設定だった。今これを使うとスワップが無効化されOOMが出まくるというような話を聞く。
vm.swappiness = 1 : 今の時代におけるvm.swappinessの最低値。
vm.swappiness = 10 : 一般(どこの?)に言われる現実的な下限値。RedHatの出しているOracle DataBase運用時の推奨値も10。
vm.swappiness = 60 : デフォルト値。

しかしまぁ極力スワップはするべきではないかと言われると、それもクライアントOSで言えば Windows 98~2000 位の頃の常識のようにも感じますし、サーバーという(一般的には)ピーク性能よりも安定稼働を目指す環境のうえではギリギリになってスワップを始めるよりはある程度事前にスワップを始めた方が安全のような気がします。カーネルのソースコードを読んだわけでもない完全な感覚値ですが、以下のような感じの方がいいのかもしれません。

実メモリ1GB以下: vm.swappiness = 40 くらい
実メモリ2GB以下: vm.swappiness = 30 くらい
実メモリ4GB以下: vm.swappiness = 20 くらい
実メモリが4GBより多い: vm.swappiness = 10 を使う

HDDならともかく、サーバーのストレージも(特にクラウドでは)SSDが普通という時代になり、以前よりも「極力スワップするべきではない!」という感じでもないかと思います。この辺アクセス数であったりどのようなシステム構成であるかであったりどのようなソフトウェアを動かしているかで全然変わってくる話ですが、全然変わってくる話ゆえに vm.swappiness = 1~10 以外の設定例を見かけないので、この辺誰か詳しい人に考察してほしいなぁという所。

5.5. 仮想メモリのチューニング – Red Hat Customer Portal
https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/6/html/performance_tuning_guide/s-memory-tunables

Linuxのswappinessは本当にスワップしにくさを設定できるのか
https://qiita.com/rarul/items/a96b61b1fb535dea5fe3
※本記事よりこちらを読んだ方がよっぽど詳しいです。

Swappiness – Wikipedia
https://en.wikipedia.org/wiki/Swappiness

Share this…

Zabbix 3.4が本当にphp-mysqlに依存していない事を確認してみた

CentOS上においてはphp-mysqlに依存してしまうzabbix-web-mysqlですが、実際の所は利用していないので何らかの方法で無視をする(※1)事で導入が出来ます。ただ、本当に依存していないのだろうか、という事を念のため確認してみました。

Zabbix WebフロントエンドはPHPで書かれているOSS(※2)なので、既に導入済みの環境であれば適当なエディタで開いて中身を確認する事が出来ます。公式サイトからソースをDLする事も出来ます。

まずはどこでDB関連の判断をしているのか。ファイル名の雰囲気から以下で設定ファイルを読み込んでいるものと思わます。

/usr/share/zabbix/include/classes/core/CConfigFile.php

         if (!isset($DB['TYPE'])) {
             self::exception('DB type is not set.');
         }

         if (!array_key_exists($DB['TYPE'], self::$supported_db_types)) {
             self::exception(
                 'Incorrect value "'.$DB['TYPE'].'" for DB type. Possible values '.
                 implode(', ', array_keys(self::$supported_db_types)).'.'
             );
         }

         $php_supported_db = array_keys(CFrontendSetup::getSupportedDatabases());

         if (!in_array($DB['TYPE'], $php_supported_db)) {
             self::exception('DB type "'.$DB['TYPE'].'" is not supported by current setup.'.
                 ($php_supported_db ? ' Possible values '.implode(', ', $php_supported_db).'.' : '')
             );
         }

設定ファイルで定義したDBのTYPEがCFrontendSetup::getSupportedDatabases()に含まれているかをチェックしていますね。ではそのCFrontendSetup::getSupportedDatabases()を確認します。

/usr/share/zabbix/include/classes/setup/CFrontendSetup.php

     /**
      * Get list of supported databases.
      *
      * @return array
      */
     public static function getSupportedDatabases() {
         $allowed_db = [];

         if (zbx_is_callable(['mysqli_close', 'mysqli_connect', 'mysqli_connect_error', 'mysqli_error',
                 'mysqli_fetch_assoc', 'mysqli_free_result', 'mysqli_query', 'mysqli_real_escape_string'])) {
             $allowed_db[ZBX_DB_MYSQL] = 'MySQL';
         }

         if (zbx_is_callable(['pg_close', 'pg_connect', 'pg_escape_bytea', 'pg_escape_string', 'pg_fetch_assoc',
                 'pg_free_result', 'pg_last_error', 'pg_parameter_status', 'pg_query', 'pg_unescape_bytea'])) {
             $allowed_db[ZBX_DB_POSTGRESQL] = 'PostgreSQL';
         }

         if (zbx_is_callable(['oci_bind_by_name', 'oci_close', 'oci_commit', 'oci_connect', 'oci_error', 'oci_execute',
                 'oci_fetch_assoc', 'oci_field_type', 'oci_free_statement', 'oci_new_descriptor', 'oci_parse',
                 'oci_rollback'])) {
             $allowed_db[ZBX_DB_ORACLE] = 'Oracle';
         }

         if (zbx_is_callable(['db2_autocommit', 'db2_bind_param', 'db2_close', 'db2_commit', 'db2_conn_errormsg',
                 'db2_connect', 'db2_escape_string', 'db2_execute', 'db2_fetch_assoc', 'db2_free_result', 'db2_prepare',
                 'db2_rollback', 'db2_set_option', 'db2_stmt_errormsg'])) {
            $allowed_db[ZBX_DB_DB2] = 'IBM DB2';
         }

         return $allowed_db;
     }

/usr/share/zabbix/include/func.inc.php

function zbx_is_callable(array $names) {
	foreach ($names as $name) {
		if (!is_callable($name)) {
			return false;
		}
	}

	return true;
}

mysqli_*コマンドが存在するかで確認しています。この事からZabbix 3.4ではMySQL = mysqli_* の利用となっており、旧来のmysql_*は利用していない事が分かります。ちなみにPDOは利用してないようです。

以下はもっとシンプルに接続関数 mysqli_connect と mysql_connect をgrepで探してみた結果です。

# find /usr/share/zabbix/ -type f -print | xargs grep mysql_co
→結果無し

# find /usr/share/zabbix/ -type f -print | xargs grep mysqli_co
/usr/share/zabbix/include/classes/setup/CFrontendSetup.php:             if (zbx_is_callable(['mysqli_close', 'mysqli_connect', 'mysqli_connect_error', 'mysqli_error',
/usr/share/zabbix/include/db.inc.php:                           $DB['DB'] = @mysqli_connect($DB['SERVER'], $DB['USER'], $DB['PASSWORD'], $DB['DATABASE'], $DB['PORT']);
/usr/share/zabbix/include/db.inc.php:                                   $error = 'Error connecting to database: '.trim(mysqli_connect_error());

mysql_connectの呼び出しが物理的に存在しない事が分かります。心置きなくphp-mysqlを葬り去れますね。

※1: 既に運用中のCentOS 7.x上のZabbix(Webフロントエンド)のPHPを5系から7系に入れ替える

※2:

/*
** Zabbix
** Copyright (C) 2001-2018 Zabbix SIA
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program; if not, write to the Free Software
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
**/

Share this…

既に運用中のCentOS 7.x上のZabbix(Webフロントエンド)のPHPを5系から7系に入れ替える

※2018/06/28 内容ブラッシュアップ

インストール時にCentOS 7.x系でPHP 7.xを使いつつZabbixを導入する方法はちょくちょく見かけるのですが、既に運用中で入れ替えて見る物は見かけなかったので残しておきます。PHP 5.6のサポート終了も年内となり、おそらくZabbix Webフロントエンドの動きもより快適になるであろう7.xに入れ替えていきましょう。

前提

  • CentOS Linux release 7.5
  • Zabbix 3.4.10
  • remiレポジトリから導入したPHP 5.6 → 同7.1
  • DBにはMySQLを利用

作業

・remiレポジトリの設定 /etc/yum.repos.d/remi.conf のPHP 5.6のenable設定を0に変更し、代わりに7.1を有効にします。

・このまま yum update php php-common を投げるとアップデート出来そうですが、実際には依存関係の絡みで失敗します。これはZabbix Webフロントエンドがphp-mysqlなるパッケージに依存している(事になっている)からなのですが、PHP 7.xにはもうそのようなパッケージはもう存在しません。本来php-mysqlndさえ存在していれば普通に動作します。

--skip-brokenオプションで回避できそうなメッセージも表示されますがそれを試しても結果はそう変わりません。yumでの導入を諦めてZabbixのパッケージをrpmで直接インストールするなどが可能なのですが、裏技的に以下のような対応で回避できます。

yum update php php-common --exclude=php-mysql

・上記コマンドを実行するとphp-mysql導入をスルーし、代わりにremiレポジトリ内にあるpecl拡張となったphp-pecl-mysqlがインストールされます。これはメンテナンスの終わったphp-mysqlモジュールをpecl拡張としたものですが、これでお茶を濁す事でphp 7.xもzabbix-webもyumを利用してインストールした状態にすることができます。

・もっとも実際には利用しないモジュールとはいえ、保守の終わったセキュリティフィックスも当たらない拡張を入れておくのも気持ちが悪いので設定で無効化しておきます。

/etc/php.d/50-mysql.ini 内でエクステンションを読み込んでいる部分をコメントアウトする事でphp-pecl-mysql拡張は読み込まれなくなります。これでyumでの導入状態を壊すことなく不要なエクステンションを無効化出来ます。

・zabbix-web-mysqlはmysqlモジュール(で提供されるmysql_* 関数)を利用していないので無効化してしまっても動作上全く問題は有りません(※1)。

なお、php.ini や /etc/httpd/conf.d/zabbix.conf 等の設定については今回触れませんので適宜調整してください。

※1: Zabbix 3.4が本当にphp-mysqlに依存していない事を確認してみた

Share this…