【问题标题】:delimiting blocks of igbinary data分隔 igbinary 数据块
【发布时间】:2015-10-26 21:33:47
【问题描述】:

我将日志数据块存储在内存缓存中,以便稍后放入数据库。在对服务器的每个请求中,我使用 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() 根本不兼容?

【问题讨论】:

  • 您可以尝试使用下划线_,因为它自然不是分隔符,因此可能会起作用...未经测试,之前未做过,但值得一试。
  • 当我说二进制数据包含换行符时,我有点不精确;因为它是二进制的,所以它根本没有字符。但是explode() 会将任何0A 解释为换行符。我想我的问题归结为,'是否有任何字节组合不会出现在我可以爆炸的 igbinary 数据中?或者也许是除了explode() 之外的方法来检索离散数据块?

标签: php memcached igbinary


【解决方案1】:

由于igbinary 存储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 完成数据拆分,并将@​​987654339@ 转义回\n

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

【讨论】:

  • 完美。谢谢!我已经开始编写代码来为每个二进制数据块添加长度前缀,但这感觉更好。
  • 那可能会更快更高效。我认为你的解决方案是最好的答案:-)
猜你喜欢
  • 2010-09-22
  • 2019-01-27
  • 1970-01-01
  • 2023-03-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-27
  • 2019-09-23
相关资源
最近更新 更多