划分igbinary数据块

时间:2015-10-26 21:33:47

标签: php memcached igbinary

我在memcache中存储了大量的日志数据,以便稍后进入数据库。在每次向服务器发出请求时,我使用memcached :: append()保存数据数组,使用换行符分隔块。简化版本如下所示:

$myCache->append('log', serialize($myArray)."\n");

稍后当我想构建可能的查询时,我将所有行拉出数据库并对每个行进行反序列化:

$dataToInsert = explode("\n", $myCache->get('log'));
$dataToInsert = array_map(function($row) {
    return unserialize($row);
}, $dataToInsert);

这适用于内置的serialize()和unserialize(),但我想利用igbinary的明显优势 - 大小和速度。不幸的是,当我替换函数的igbinary版本时,我会遇到错误。

似乎igbinary-serialized数据可以包含“\ n”字符,因此当我分解隐藏数据时,它会创建当然失败的部分行。

我是否可以使用除换行符之外的分隔符来分隔igbinary数据块,或者igbinary和append()从根本上是不兼容的?

1 个答案:

答案 0 :(得分:1)

由于igbinary存储binary data as-is,因此无法保证任何字符可供使用:您可以序列化包含任何字节,任何字符的字符串或整数。

memcached支持添加,删除和替换数据以及更新字符串。

在记住SQL查询之前,有两种方法可以将记录的数据保留在内存和memcached中:

  • 使用多个密钥:'log1',...,'logN'并跟踪N
  • 通过转义序列化的二进制输出(并在反序列化之前进行转换)为自己保留一个字符。

预订可以这样做:

str_replace( "\n", "\n1", $data ) . "\n0"

这将确保每次输出中都有\n, 随后是01

我不会将\n替换为\n\n,因为如果$data\n开头或结尾,这将无效。

所以:

$myCache->append('log', str_replace("\n", "\n1", igbinary_serialize($myArray)."\n0");

然后使用\n0完成拆分数据,\n1未转义回\n

$dataToInsert = explode("\n0", $myCache->get('log'));
$dataToInsert = array_map(function($row) {
    return igbinary_unserialize(str_replace("\n1", "\n", $row));
}, $dataToInsert);