KyotoTycoonのmemcachedプラグインにPHP(PECL)からアクセスする

 メモ書きにつき。
 PECLのMemcacheクラスを使ってKyotoTycoonにアクセスしていたが、あるデータサイズを超えた時、突然データが「壊れる」という現象に遭遇。原因を究明するため、以下のようなコードで試してみた。

<?php
$str_1k = '';
foreach(range(1, 1024) as $i) {
    $str_1k .= 'a';
}
$str_5k = '';
foreach(range(1, 5) as $i) {
    $str_5k .= $str_1k;
}
$str_10k = '';
foreach(range(1, 2) as $i) {
    $str_10k .= $str_5k;
}
$str_15k = '';
foreach(range(1, 3) as $i) {
    $str_15k .= $str_5k;
}
$str_20k = '';
foreach(range(1, 2) as $i) {
    $str_20k .= $str_10k;
}
$str_30k = '';
foreach(range(1, 3) as $i) {
    $str_30k .= $str_10k;
}

$m = new Memcache;
$m->addServer('kt-domain', 1975);

$m->set('test-1k', $str_1k);
$m->set('test-5k', $str_5k);
$m->set('test-10k', $str_10k);
$m->set('test-15k', $str_15k);
$m->set('test-20k', $str_20k);
$m->set('test-30k', $str_30k);

echo "test-1k: " . mb_strlen($m->get('test-1k')) ."\n";
echo "test-5k: " . mb_strlen($m->get('test-5k')) ."\n";
echo "test-10k: " . mb_strlen($m->get('test-10k')) ."\n";
echo "test-15k: " . mb_strlen($m->get('test-15k')) ."\n";
echo "test-20k: " . mb_strlen($m->get('test-20k')) ."\n";
echo "test-30k: " . mb_strlen($m->get('test-30k')) ."\n";

$m->delete('test-1k');
$m->delete('test-5k');
$m->delete('test-10k');
$m->delete('test-15k');
$m->delete('test-20k');
$m->delete('test-30k');

 念のためmb_strlen関数を使ってるが、これで格納されてるデータのサイズを取得できるはず。そう思って実行したら、こんな結果が出てきた。

test-1k: 1024
test-5k: 5120
test-10k: 10240
test-15k: 15360
test-20k: 44
test-30k: 53

 上記を起点にもう少し詰めてみると、どうも20kbを超えたところから極端にデータサイズが落ちてる。実際に中身を見てみると、アルファベットしか入ってないはずなのに化ける。
 最初はKyotoTycoonのデータサイズの上限かと勘ぐってしまったが、どうもそんな記述はない。となると、Memcacheクラスのどこかに何かがある。
 そう思ってMemcacheのドキュメントを漁ってみると、これが出てきた。
PHP: Memcache::setCompressThreshold - Manual
 キャッシュするデータ量を抑えるために、ある一定以上のデータサイズについては圧縮をする設定のことだ。特にディフォルト値の記述はないが、サンプルコードにある「20000」という指定が怪しい。試しに、上記スクリプトのaddServerの直後に、以下のコードを入れてみた。

$m->setCompressThreshold(0, 0);

 多分これならどんなデータサイズでも無圧縮で入れてくれるはず、と思って、再度スクリプトを実行。その結果は

test-1k: 1024
test-5k: 5120
test-10k: 10240
test-15k: 15360
test-20k: 20480
test-30k: 30720

 20kb以上のデータもちゃんと取れるようになった。と、ここで、そもそも何故このご時世にMemcachedクラスの方ではなくMemcacheクラスを採用していたかを思い出した。Memcachedクラスを使用したとき、何を入れてもデータが「壊れて」しまっていたので、てっきりKyotoTycoon(のmemcachedプラグイン)とは相性が悪いんだと思ってたけど、実際には圧縮して格納していたため、参照時に解凍できてないだけなのかも。
 と思ったので、Memcacheの定義部分を以下に変更。

$m = new Memcached;
$m->addServer('kt-domain', 1975);
$m->setOption(Memcached::OPT_COMPRESSION, false);

 これを実行してみたら、全く問題がなくなった。ということで、問題の本質は圧縮の設定だったということですね。となると、KyotoTycoonにデータを圧縮して入れるには、どうしたらいいんだ。。。?