分隔 igbinary 数据块

delimiting blocks of igbinary data

我将大块的日志数据存储在内存缓存中,以便稍后放入数据库。在对服务器的每个请求中,我使用 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 序列化数据似乎可以包含“\n”字符,所以当我分解隐藏的数据时,它会创建部分行,当然会失败。

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

igbinary stores binary data as-is 起,无法保证任何字符都可用:您可以序列化包含任何字节、任何字符的字符串或整数。

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

在想到 SQL 查询之前,将记录的数据保存在内存之外和内存缓存中的两种方法:

  • 使用多个键:'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);