Amazon Linux 2のPHP 7.4環境に、APCuを導入する

# What's？

PHP 7.4に、APCuを導入したいなと。

PHPの動作環境は、Amazon Linux 2で。

# APCu

APCuについては、こちら。

https://www.php.net/manual/ja/book.apcu.php

用途がシンプルに書かれています。

> APCu は、PHP で動くインメモリの key-value ストアです。 キーは文字列型で、値は任意のPHPの変数を保存できます。

https://www.php.net/manual/ja/intro.apcu.php

# 環境

今回の環境。

```shell
$ cat /etc/os-release
NAME="Amazon Linux"
VERSION="2"
ID="amzn"
ID_LIKE="centos rhel fedora"
VERSION_ID="2"
PRETTY_NAME="Amazon Linux 2"
ANSI_COLOR="0;33"
CPE_NAME="cpe:2.3:o:amazon:amazon_linux:2"
HOME_URL="https://amazonlinux.com/"


$ uname -srmvpio
Linux 4.14.256-197.484.amzn2.x86_64 #1 SMP Tue Nov 30 00:17:50 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
```

PHPのインストールと

```shell
$ sudo amazon-linux-extras install php7.4
```

バージョン確認。

```shell
$ php --version
PHP 7.4.21 (cli) (built: Jul  7 2021 17:35:08) ( NTS )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies
```

PHP-FPMの有効化と起動。

```shell
$ sudo systemctl enable php-fpm
$ sudo systemctl start php-fpm
```

Webサーバーは、Apacheにします。

```shell
$ sudo yum install httpd
```

バージョン。

```shell
$ httpd -V
Server version: Apache/2.4.51 ()
Server built:   Oct  8 2021 22:03:47
Server's Module Magic Number: 20120211:118
Server loaded:  APR 1.7.0, APR-UTIL 1.6.1
Compiled using: APR 1.7.0, APR-UTIL 1.6.1
Architecture:   64-bit
Server MPM:     prefork
  threaded:     no
    forked:     yes (variable process count)
Server compiled with....
 -D APR_HAS_SENDFILE
 -D APR_HAS_MMAP
 -D APR_HAVE_IPV6 (IPv4-mapped addresses enabled)
 -D APR_USE_PROC_PTHREAD_SERIALIZE
 -D APR_USE_PTHREAD_SERIALIZE
 -D SINGLE_LISTEN_UNSERIALIZED_ACCEPT
 -D APR_HAS_OTHER_CHILD
 -D AP_HAVE_RELIABLE_PIPED_LOGS
 -D DYNAMIC_MODULE_LIMIT=256
 -D HTTPD_ROOT="/etc/httpd"
 -D SUEXEC_BIN="/usr/sbin/suexec"
 -D DEFAULT_PIDLOG="/run/httpd/httpd.pid"
 -D DEFAULT_SCOREBOARD="logs/apache_runtime_status"
 -D DEFAULT_ERRORLOG="logs/error_log"
 -D AP_TYPES_CONFIG_FILE="conf/mime.types"
 -D SERVER_CONFIG_FILE="conf/httpd.conf"
```

有効化と起動。

```shell
$ sudo systemctl enable httpd
$ sudo systemctl start httpd
```

# APCuをインストールする

インストール方法はこちらで、PECLでインストールできると書かれています。

https://www.php.net/manual/ja/apcu.installation.php

https://pecl.php.net/package/apcu

ですが、Amazon Linux 2だと`yum`でインストールできそうだったので、こちらを使うことにします。

```shell
$ yum info php-pecl-apcu
読み込んだプラグイン:langpacks, priorities, update-motd
利用可能なパッケージ
名前                : php-pecl-apcu
アーキテクチャー    : x86_64
バージョン          : 5.1.18
リリース            : 1.amzn2
容量                : 53 k
リポジトリー        : amzn2extra-php7.4/2/x86_64
要約                : APCu - APC User Cache
URL                 : http://pecl.php.net/package/apcu
ライセンス          : PHP
説明                : APC User Caching

```

インストール。

```shell
$ sudo yum install php-pecl-apcu
```

インストールされるファイルは、こちらですね。

```shell
$ rpm -ql php-pecl-apcu
/etc/php.d/40-apcu.ini
/usr/lib64/php/modules/apcu.so
/usr/share/doc/pecl/apcu
/usr/share/doc/pecl/apcu/INSTALL
/usr/share/doc/pecl/apcu/NOTICE
/usr/share/doc/pecl/apcu/README.md
/usr/share/doc/pecl/apcu/TECHNOTES.txt
/usr/share/licenses/php-pecl-apcu-5.1.18
/usr/share/licenses/php-pecl-apcu-5.1.18/LICENSE
/var/lib/php/peclxml/php-pecl-apcu.xml
```

インストールされた状態での設定ファイル。

```ini:$ grep -vE '^;|^$' /etc/php.d/40-apcu.ini
extension = apcu.so
apc.enabled=1
apc.mmap_file_mask=/tmp/apc.XXXXXX
```

PHP-FPMを再起動して、組み込んだAPCuを反映します。

```shell
$ sudo systemctl restart php-fpm
```

確認用のPHPソースコードを作成して

```php:/var/www/html/phpinfo.php
<?php

phpinfo();
```

確認。APCuを認識しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309669/6b99f877-628b-d2c5-a0fc-2186f49efc73.png)

設定を変更する場合は、こちらですね。

https://www.php.net/manual/ja/apcu.configuration.php

# APCuを使ってみる

では、APCuを使ってみましょう。


こちらを参考に

https://www.php.net/manual/ja/book.apcu.php

APCuに値を保存、取得するソースコードを作成。

```php:/var/www/html/apcu-example.php
<?php

if (!apcu_exists('key1')) {
    $value = getMessage();
    apcu_store('key1', $value, 10);
}

$value = apcu_fetch('key1');

echo $value;

function getMessage() {
    sleep(5);

    return 'Hello World - ' . date('Y-m-d H:i:s');
}
```

APCuの関数は、`apcu_store`と`apcu_fetch`を使用しています。キャッシュの有効期限は、10秒にしました。

キャッシュに登録する値は、作成するのに5秒かかるようにしています。つまり、キャッシュに登録後の有効期限内は高速に動作し、有効期限が切れた後は再び時間がかかることを想定した使い方です、と。

確認。

初回は遅いですが

```shell
$ time curl localhost/apcu-example.php
Hello World - 2021-12-15 04:00:16
real    0m5.008s
user    0m0.003s
sys     0m0.003s
```

2回目以降は速くなり

```shell
$ time curl localhost/apcu-example.php
Hello World - 2021-12-15 04:00:16
real    0m0.009s
user    0m0.003s
sys     0m0.005s
```

有効期限が切れた後は、キャッシュに値がなくなるので再び遅くなります。

```shell
$ time curl localhost/apcu-example.php
Hello World - 2021-12-15 04:00:27
real    0m5.008s
user    0m0.000s
sys     0m0.006s
```

こんなところでしょう。