填充你的日志! - 保罗·黄:一些 Lisp

主要观点:九个月前,Backtrace服务器开始将可变长度字符串(如符号化调用栈)的持久化(磁盘上)表示格式迁移为一种自同步的一致开销字节填充(COBS)变体,这种选择提高了软件对本地文件数据损坏的恢复能力,并行数据水化使启动时间缩短了 10 倍,且无需从旧格式到当前格式的硬迁移。本文将解释为何二进制日志的首选表示形式应为自同步的,并介绍用于服务器软件的特定算法。
关键信息:

  • 自同步代码在符号流中能明确检测有效码字的起始位置,UTF-8 编码是自同步的,COBS 是字节流的自同步编码,空间开销最坏情况为一个字节加 0.4%。
  • 对二进制日志,自同步编码能以简单且健壮的方式定界记录,减少数据损坏的影响,如 COBS 编码通过保留字节分离记录,解码器状态在每个分隔符后重置。
  • 在[Backtrace]的日志编码中,采用混合字/字节填充方案,使用不太可能出现在数据中的两字节保留序列0xfe 0xfd,编码第一个块时特殊处理,后续块用两字节大小前缀,提高了编码和解码速度,渐近空间开销为 0.0031%。
  • 日志编码可从坏字节中恢复,处理逻辑能处理重复的有效记录,还能利用这种鲁棒性实现新功能,如定期处理日志尾部、并行处理日志、随机访问等,且在文件系统支持稀疏文件时也能良好处理。
  • [Backtrace]的日志格式使用预填充记录,带有crc32c校验和和generation字段,写操作可输出到缓冲FILE流或文件描述符,读操作可从缓冲区或内存映射文件中读取,还可选择接收原始数据或解码后的 protobuf 消息。
    重要细节:
  • COBS 编码器在遇到保留 0 字节或 254 字节缓冲数据时停止缓冲,输出块大小和内容;解码器根据块大小前缀解码。
  • [Backtrace]的混合方案中,第一个块大小前缀为单字节[0, 252],后续块用小端基数 253 的两字节大小前缀,最大可编码 64008 字节。
  • 编码短记录时,通常只需添加一个uint8_t长度前缀;编码算法比原始 COBS 稍复杂,需处理保留序列。
  • 日志格式在过去九个月中用于存储元数据记录,通过逐步添加和并行化加载元数据,实现了从长度前缀数据格式到自同步记录流的过渡,目前性能良好且有提升空间,正在为分布式数据库做准备。
阅读 276
0 条评论