我在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()从根本上是不兼容的?
答案 0 :(得分:1)
由于igbinary
存储binary data as-is,因此无法保证任何字符可供使用:您可以序列化包含任何字节,任何字符的字符串或整数。
memcached
支持添加,删除和替换数据以及更新字符串。
在记住SQL查询之前,有两种方法可以将记录的数据保留在内存和memcached中:
'log1'
,...,'logN'
并跟踪N
。预订可以这样做:
str_replace( "\n", "\n1", $data ) . "\n0"
这将确保每次输出中都有\n
,
随后是0
或1
。
我不会将\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);