APCU の apc.ttl の動き

## まとめ

- メモリがいっぱいになると TTL が切れてるエントリが全部クリアされる
    - `apc.ttl=0` だと TTL が無限なのでクリアされることはない
- それでもメモリが足りなければキャッシュがすべてクリアされる
- TTL が切れていてもメモリがいっぱいにならない限りエントリは有効なまま

## 詳細

```php
// 100KB ぐらいの文字列をキャッシュしつつ apcu のステータスを表示
$str = str_repeat('x', 1024*100);
for ($i=0; $i<10; $i++) {
    apcu_store("a.$i", $str);
    print_r([$i => apcu_sma_info(true) + apcu_cache_info(true)]);
}
```

CLI で apcu を有効に、TTL に Request time は使わずに現在時刻を使う、サイズ 1M、TTL 1秒で実行。

```sh
php -d apc.enable_cli=1 -d apc.use_request_time=0 -d apc.shm_size=1M -d apc.ttl=1 z.php
```

メモリがいっぱいになった時点でキャッシュのすべてのエントリがクリアされる（出力を見やすくするために抜粋）。

```
    [8] => Array
            [seg_size] => 1048440
            [avail_mem] => 82488
            [num_slots] => 4099
            [ttl] => 1
            [num_entries] => 9
            [expunges] => 0

    [9] => Array
            [seg_size] => 1048440
            [avail_mem] => 911800
            [num_slots] => 4099
            [ttl] => 1
            [num_entries] => 1
            [expunges] => 1
```

----

```php
$str = str_repeat('x', 1024*100);

// 500 KB ぐらいキャッシュする
for ($i=0; $i<5; $i++) {
    apcu_store("a.$i", $str);
}

// apc.ttl=1 なので TTL 切れになる
sleep(3);

// エントリをフェッチ
for ($j=0; $j<$i; $j++) {
    apcu_fetch("a.$j");
}

// さらに 400 KB ぐらいキャッシュしつつステータス表示
for (; $i<9; $i++) {
    apcu_store("a.$i", $str);
    print_r([$i => apcu_sma_info(true) + apcu_cache_info(true)]);
}

// エントリをフェッチ
for ($j=0; $j<$i; $j++) {
    apcu_fetch("a.$j");
}

// さらに 100 KB ぐらいキャッシュしつつステータス表示
for (; $i<10; $i++) {
    apcu_store("a.$i", $str);
    print_r([$i => apcu_sma_info(true) + apcu_cache_info(true)]);
}

// エントリをフェッチ
for ($j=0; $j<$i; $j++) {
    apcu_fetch("a.$j");
}

// 最後にステータス表示
print_r([$i => apcu_sma_info(true) + apcu_cache_info(true)]);
```

↑と同じように実行する。

```sh
php -d apc.enable_cli=1 -d apc.use_request_time=0 -d apc.shm_size=1M -d apc.ttl=1 z.php
```

メモリがいっぱいになったときに TTL が切れてるエントリがザクッと消えている。

TTL が切れていてもメモリがいっぱいになるまでは有効なキャッシュとして残ったまま（途中で TTL が切れたキャッシュを fetch しているのにそのときは num_misses が増えていない）。


```
    [5] => Array
            [seg_size] => 1048440
            [avail_mem] => 393480
            [ttl] => 1
            [num_hits] => 5
            [num_misses] => 0
            [num_inserts] => 6
            [num_entries] => 6
            [expunges] => 0

    [6] => Array
            [seg_size] => 1048440
            [avail_mem] => 289816
            [ttl] => 1
            [num_hits] => 5
            [num_misses] => 0
            [num_inserts] => 7
            [num_entries] => 7
            [expunges] => 0

    [7] => Array
            [seg_size] => 1048440
            [avail_mem] => 186152
            [ttl] => 1
            [num_hits] => 5
            [num_misses] => 0
            [num_inserts] => 8
            [num_entries] => 8
            [expunges] => 0

    [8] => Array
            [seg_size] => 1048440
            [avail_mem] => 82488
            [ttl] => 1
            [num_hits] => 5
            [num_misses] => 0
            [num_inserts] => 9
            [num_entries] => 9
            [expunges] => 0

    [9] => Array
            [seg_size] => 1048440
            [avail_mem] => 497144
            [ttl] => 1
            [num_hits] => 14
            [num_misses] => 0
            [num_inserts] => 10
            [num_entries] => 5
            [expunges] => 0

    [10] => Array
            [seg_size] => 1048440
            [avail_mem] => 497144
            [ttl] => 1
            [num_hits] => 19
            [num_misses] => 5
            [num_inserts] => 10
            [num_entries] => 5
            [expunges] => 0
```

## おまけ

単位をつけるとき m だと分じゃなくてメガ。

```sh
php -d apc.enable_cli=1 -d apc.ttl=1s -r 'print_r(apcu_cache_info(true));' | grep ttl
#=>     [ttl] => 1

php -d apc.enable_cli=1 -d apc.ttl=1m -r 'print_r(apcu_cache_info(true));' | grep ttl
#=>     [ttl] => 1048576

php -d apc.enable_cli=1 -d apc.ttl=1h -r 'print_r(apcu_cache_info(true));' | grep ttl
#=>     [ttl] => 1

php -d apc.enable_cli=1 -d apc.ttl=1k -r 'print_r(apcu_cache_info(true));' | grep ttl
#=>     [ttl] => 1024

php -d apc.enable_cli=1 -d apc.ttl=1g -r 'print_r(apcu_cache_info(true));' | grep ttl
#=>     [ttl] => 1073741824
```