memcached設定 (Cent7,nginx,php7.2,php-fpm)

# 概要
- 仕事でElastiCacheとかマネージドサービス使えない状況だったので久しぶりに素のmemcachedを立てることに
- せっかくなので最新版1.5系を使ってみる
- 新しい分ハマった箇所もあるのでメモしておく
- 追記）memcached1.7も対応。2020/03やる機会が訪れたので以下の手順で問題なかった

# 事前準備
- remiとepelを有効にしておく。remiからphpやらmemcachedを使うので
- appサーバ(php,php-fpm,nginx)は動くようにしておく

# 詳細

#### インストール

* インストール類（memcachedサーバにて）

```
# yum install epel-release
# rpm -ivh http://rpms.famillecollet.com/enterprise/remi-release-7.rpm
```
```
$ sudo yum install memcached memcached-devel --enablerepo=epel,remi
```

* インストール類（appサーバにて）

```
$ sudo yum install php72-php-pecl-memcache libmemcached libmemcached-devel --enablerepo=remi,epel
$ sudo yum install php72-php-cli php72-php-devel php72-php-pdo php72-php-pecl-msgpack php72-php-pecl-msgpack-devel php72-php-pecl-memcached php72-php-pecl-redis php72-php-phpiredis php72-php-pecl-lua php72-php-pecl-apcu php72-php-pecl-apcu-bc php72-php-pecl-apcu-devel php72-php-xml --enablerepo=remi,epel
```

#### 設定

* memcached設定（memcachedサーバにて）
* http://blog.nomadscafe.jp/2013/12/memcached-2.html で確認
* キャッシュサイズはRAMサイズの8割程度
* 接続数はもっと増やせるがメモリが先に枯渇する恐れがあるのでほどほどにしておく
* オプションは適宜検討

```
$ sudo cp -p /etc/sysconfig/memcached /etc/sysconfig/memcached.org
$ vim /etc/sysconfig/memcached
PORT="11211"
USER="memcached"
CACHESIZE="3024"
MAXCONN="65536"
OPTIONS=""
 
$ sudo systemctl start memcached
```

* memcached-tool導入（memcachedサーバにて）
* memcached-toolダウンロード
* パスが通っているディレクトリに移動
* 動作確認をする

```
$ chmod 755 memcached-tool
$ sudo mv memcached-tool /usr/local/bin
$ which memcached-tool
$ memcached-tool localhost display
```

* カーネルパラメータ（app,memcachedサーバにて）
* カーネルパラメータも確認しておく
* ここ調整していないと死ぬ

```
$ cat /etc/sysctl.conf|grep net.core.somaxconn
net.core.somaxconn = 2147483647
```

* memcached単体で動作確認する（memcachedサーバにて）

```
$ telnet localhost 11211
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
set testkey 0 60 7
testvalue
STORED
get testkey
VALUE mykey 0 7
testvalue
END
delete testkey
DELETED
get testkey
END
flush_all
OK
quit
Connection closed by foreign host.
```


* appサーバからmemcachedサーバへ接続して動作確認する（appサーバにて）

```
$ telnet <memcached server private ip> 11211
Trying <memcached server private ip>...
Connected to <memcached server private ip>.
Escape character is '^]'.
get testkey
END
set testkey 0 60 7
myvalue
STORED
get mykey
VALUE testkey 0 7
myvalue
END
delete testkey
DELETED
flush_all
OK
quit
Connection closed by foreign host.
```

* appサーバのphpの設定を変更する（appサーバにて）

```
$ sudo vi /etc/php.ini
;; X-Powered-Byを隠す
expose_php = Off 
   
;; PHPタイムゾーン 
date.timezone = Asia/Tokyo 
   
;; デフォルト言語
mbstring.language = Japanese 
   
;; 内部文字エンコーディング 
mbstring.internal_encoding = UTF-8 

;; HTTP入力文字エンコーディング(auto:mgstring.languageの設定で展開) 
mbstring.http_input = auto 

;; HTTP出力文字エンコーディング（pass:変換しない） 
mbstring.http_output = pass 

;; HTTP入力変換有効
mbstring.encoding_translation = On 

;; デフォルト文字エンコーディング検出順序
mbstring.detect_order = auto

;; 無効な文字出力しない
mbstring.substitute_character = none; 
 
;; 動的ライブラリ格納パスをデフォルトからremi用に変更
extension_dir = "/opt/remi/php72/root/usr/lib64/php/modules"
```


* appサーバのphpの設定を変更する（appサーバにて）

```
$ sudo vi /etc/php-fpm.d/www.conf
：
;php_value[session.save_handler] = files
;php_value[session.save_path]    = /var/lib/php/session
php_value[session.save_handler] = memcached
php_value[session.save_path]    = "<memcached server private ip:11211>"
$ sudo systemctl restart php-fpm
```

* appサーバのphpの設定を変更する（appサーバにて）

```
$ sudo vim /etc/php-fpm.d/www.conf
：
php_value[session.save_handler] = memcached
php_value[session.save_path]    = "<memcached server private ip>:11211"
```



* 接続先となるmemcachedサーバをappサーバ上php-fpmに設定する（appサーバにて）

```

$ sudo vim /etc/php.d/30-memcached.ini
extension=memcached
php_value[session.save_handler] = memcached
php_value[session.save_path] = "<memcached server private ip>:11211"
 
$ sudo systemctl restart php-fpm
  
$ php --ini | grep memcached
/etc/php.d/30-memcached.ini
```

*  接続先となるmemcachedサーバをappサーバ上phpに設定する（appサーバにて）

```
# echo "extension=msgpack" > /etc/php.d/20-msgpack.ini
# echo "extension=igbinary" > /etc/php.d/20-igbinary.ini
 
# php -i | head
```

#### 設定確認
* 設定を確認する（appサーバにて）

```
# grep -v '^\s*;' /etc/php.ini |grep -v '^\s*$'
:
:
```

* ライブラリ確認
* memcachedライブラリが読み込めていることをブラウザから確認（appサーバにて）

![image.png](https://qiita-image-store.s3.amazonaws.com/0/57350/2955661d-a924-7dea-4dc6-2b1c5264f2c9.png)


* php経由で確認
* php-memcached間接続確認用ファイルを配置（appサーバにて）

```
$ vim /documentroot/conncheck.php
<?php
$memcache = new Memcached();
$memcache->addServer('<memcached server private ip>', 11211);
$data = 'memcached for col';
$memcache->set('key', $data, 1000);
echo $get_data = $memcache->get('key');
```

* ブラウザアクセスし問題ないことを確認

![image.png](https://qiita-image-store.s3.amazonaws.com/0/57350/332ef3d7-2fbc-b774-9908-26ab24840dca.png)

* エラーログが出ない事を確認

```
$ sudo tailf /var/log/nginx/app.error.log
$ sudo tailf /var/log/nginx/error.log
```


# 対処したエラー

* ライブラリが無いとのこと、extension_dirを変更する必要があった

```
2018/05/14 17:12:58 [error] 5024#5024: *6543 FastCGI sent in stderr: "PHP message: 
PHP Fatal error: Uncaught Error: 
Class 'Memcached' not found in /var/source/current/src/app/www/conncheck.php:2
Stack trace:
```

* extension=memcached.soと定義してしまうとsoがダブル

```
PHP Warning:  PHP Startup: Unable to load dynamic library 'memcached.so'
(tried: /opt/remi/php72/root/usr/lib64/php/modules/memcached.so 
(/opt/remi/php72/root/usr/lib64/php/modules/memcached.so: undefined symbol: php_json_decode_ex), 
/opt/remi/php72/root/usr/lib64/php/modules/memcached.so.so
(/opt/remi/php72/root/usr/lib64/php/modules/memcached.so.so: 
cannot open shared object file: No such file or directory)) in Unknown on line 0
```

* igbinaryライブラリをインストールしているが設定していない

```
PHP Warning: PHP Startup: Unable to load dynamic library 'memcached' 
(tried: /opt/remi/php72/root/usr/lib64/php/modules/memcached 
(/opt/remi/php72/root/usr/lib64/php/modules/memcached: cannot open shared object file: No such file or directory), 
/opt/remi/php72/root/usr/lib64/php/modules/memcached.so
(/opt/remi/php72/root/usr/lib64/php/modules/memcached.so: 
undefined symbol: igbinary_serialize)) in Unknown on line 0
```

* msgpackライブラリをインストールしているが設定していない

```
PHP Warning: PHP Startup: Unable to load dynamic library 'memcached' 
(tried: /opt/remi/php72/root/usr/lib64/php/modules/memcached 
(/opt/remi/php72/root/usr/lib64/php/modules/memcached: cannot open shared object file: No such file or directory), 
/opt/remi/php72/root/usr/lib64/php/modules/memcached.so 
(/opt/remi/php72/root/usr/lib64/php/modules/memcached.so:
undefined symbol: php_msgpack_serialize)) in Unknown on line 0
```