分隔 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
,
它后面跟着 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);
我将大块的日志数据存储在内存缓存中,以便稍后放入数据库。在对服务器的每个请求中,我使用 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
,
它后面跟着 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);