SOSP 19′ 文件系统是否适合做分布式文件系统的后端——Ceph 的十年经验总结

过去十年里,Ceph 一直是在本地文件系统的基础上实现。这个是目前大部分分布式文件系统的选择,因为这样可以利用这些实际环境验证过的代码。然而,Ceph 的经验告诉我们这么做也是有代价的——首先,实现一个零开销的事务机制会很困难;其次,本地的元数据性能会极大影响分布式系统;第三支持新的存储硬件会变得很慢。 Ceph 通过一个新存储后端 BlueStore 来解决这些问题,BlueStore 设计为直接在块设备上运行。在其面世的短短两年里,BlueStore 已经被 70% 的生产客户所采用。通过运行在用户态和对 IO 栈的完全控制,BlueStore 实现了高效的元数据空间和数据校验、EC 数据快速覆写、在线压缩、减少了性能的波动而且避免了一系列本地文件系统的隐患(pitfalls)。最后,通过 BlueStore 还让支持一些原本不支持的存储硬件成为可能。 介绍 后端存储采用文件系统的好处: 无需自行解决数据持久和块分配的问题 提供熟悉的 POSIX 接口和抽象(文件、目录) 可以使用ls、find这些常用工具来管理 Ceph 开发 BlueStore 几个主要原因: 难以在现有文件系统上实现高效的事务操作。 现有的实现要么有很高的性能损失、要么功能有限、要么接口或实现过于复杂,总之都没有直接集成到文件系统里。 Ceph 使用用户态的 WAL 来实现,或者一个支持事务的 KV 存储,但性能都不能满意 本地文件系统的元数据性能极大影响分布式层。具体来说,Ceph 需要快速枚举(enumerate)有几百万条目的目录,但 Btrfs 和 XFS 都支持的不够好;如果拆分目录(directory splitting )来减小一个目录内的文件数量,这个操作在文件系统上有成本极大,会拖垮整个系统的性能 因为文件系统本身的过于成熟,会导致它对新存储硬件的支持非常慢。例如用来解决 HDD 容量问题的 SMR,用来解决 SSD 的 FTL 层性能损失的 ZSS SSD 都难以支持 […]

devconf 19′: virtio 硬件加速

前言 devconf 也是我比较关注的一个 summit,devconf 的内容当然比较偏实践,但有一些东西还是比较前沿的。 很多人会认为 virtio 是一套实现(virtio-net, virtio-blk 等等),但实际上 virtio 是一套标准(或者说抽象层),因为 virtio 通过半虚拟化的方式来加速虚拟化的性能,那么就需要 hypervisor 和 guest 的协作来达到目的,其中 hypervisor 端我们称为 backend driver,guest 端称为 frontend driver。 virtio 的具体介绍在 developer works 有一篇很好的文章,如果对 virtio 不了解的话可以参考这篇: https://www.ibm.com/developerworks/cn/linux/l-virtio/index.html,进一步的,还可以阅读 Rusty 写的原论文:https://www.ozlabs.org/~rusty/virtio-spec/virtio-paper.pdf 这里简单介绍一下 virtio 的基本架构,就是下面这张图: 可以看到 IO 的核心就是 virtqueue,virtqueue 定义了 add_buf、get_buf、kick 等几个关键 IO 接口。 virtio 刚提出时其实是很先进的,因为通过共享内存替代了完整的 trap/模拟过程,大大提升了性能,但是随着底层 IO 设备性能的越来越强,大家对 virtio 也逐渐提出了更高的要求,例如通过 vhost […]

Eurosys 19′ Notes:Ursa: Hybrid Block Storage for Cloud-Scale Virtual Disks

Ursa 是美团云 16 就发布过的面向 IaaS 云主机的块存储系统,目前 Ursa 主要有几篇公开文章讨论其架构: 最早:https://tech.meituan.com/2016/03/11/block-store.html 介绍了 motivation、和其他块存储的比较 17 年在知乎专栏发表了基于混合存储的效率优化,和这次 Eurosys 19′ 内容相关:https://zhuanlan.zhihu.com/p/27695512 17 年还有一篇 USENIX 17′ 的文章:https://tech.meituan.com/2017/05/19/speculative-partial-writes-erasure-coded-systems.html 介绍了对 EC 的优化 下面介绍这篇文章,原文地址:https://www.cs.jhu.edu/~huang/paper/ursa-eurosys19.pdf or https://dl.acm.org/citation.cfm?id=3303967 简介 通过追踪块存储的 IO pattern 可以发现其 IO 的 locality 很差,因此相对于使用 SSD 作为 cache layer,Ursa 选择了底层直接使用 SSD-HDD 混布方案,将主副本放在 SSD 上,备副本放在 HDD 上,通过 Journal 来弥补 SSD 和 HDD 之间的性能差距。实验显示之中模式在大部分情况下可以达到与全 SSD 相同的性能,与全 […]

NSDI 2019 Notes

前言 NSDI 2019 里有两篇容器网络相关的话题,这篇还是比较有意思的,the morning paper 也谈到了这篇文章:https://blog.acolyer.org/2019/03/22/slim-os-kernel-support-for-a-low-overhead-container-overlay-network/。原版的视频、Slides、文章在 NSDI 官网都可以看:https://www.usenix.org/conference/nsdi19/presentation/zhuo。同时作者在 Github 上开源了实现:https://github.com/danyangz/Slim 大致思路是容器里的应用的流量送到另一个容器里的应用需要经过四次协议栈。 除了底层物理机的协议栈之外,主要是有一层 network namespace: 因此主要思路就是绕过这一层 stack,其效果还是不错的: memcached 吞吐提高 71%,延迟降低 42%,CPU 占用减少 56% Nginx CPU 占用减少 22-24% PostgreSQL CPU 占用介绍 22% Kafka CPU 占用减少 10% 介绍 容器网络往往使用 overlay 网络,但是 overlay 网络会带来显著地性能影响。测试显示 overlay 网络和 host 网络相比的吞吐会下降 23~48%,每个报文的延迟会增长 34~85%,CPU 占用会提高 93%,现有的加速技术往往是针对虚拟化的,对容器支持不够。 这里的核心问题就是一个包要在一个物理机上穿越两次协议栈,来回就是四次。这种设计显示受虚拟化的影响,因为虚拟机是有自己的协议栈的,宿主机不知道任何 Guest 的协议栈知识,但是容器不然,宿主机知道每个网络连接的完整信息。 因此作者设计了一种容器网络,核心思想就是让一个物理机上报文只经过一次协议栈。 这个设计有几个挑战: 网络虚拟化不能要求应用作出修改 […]

The design of a practical system for fault-tolerant virtual machines

这篇文章是 MIT 6.824 课程安排的一篇阅读材料。 我 Fork 了别人整理的 MIT 6.824 的课程材料,关于这篇文章的内容可以在这里找到:https://github.com/MatheMatrix/MIT-6.824-Distributed-Systems/tree/master/Lectures/LEC04 下面是笔记。 摘要 VMware 在 2010 年发布了这篇文章,主要描述它们在 vShpere 4.0 上实现的虚拟机高可用方案,这是一个商用的、企业级的方案,虚拟机性能下降在 10% 以内,虚拟机同步需要 20M 左右带宽。文章提到让这样一个系统支撑企业应用除了复制虚拟机的指令外,还有很多其他问题。 介绍 实现高可用的基本思路是主备,主备最简单的想法就是复制主的所有状态,包括 CPU、内存、IO。但是这个方案无疑需要非常大的带宽。 另一种方法是复制状态机思路,简单的说,这个思路就是把虚拟机当作一个确定状态机,两边先保持一个一致的初始状态,然后保证它们能够一样的顺序接收一样的指令。因为总有一些操作造成的结果不是确定性的,因此还需要额外的工作来保持同步(主要是内存)。 这个思路在物理机上无疑很难实现,但是在虚拟机上就好做很多,因为虚拟机就是一个定义的很完善的状态机,其所有操作、设备都是虚拟化的。但是相比物理机,虚拟机自己也有一些非确定性操作,例如读取时间和发送中断,这就是为什么我们刚才说需要额外操作来保持同步。 VMware vSphere FT 基于确定性重放(deterministic replay),但是增加了必要的额外协议和功能来保证系统功能完整。到写这篇文章时,FT 生产版本还只能支持单 CPU 虚拟机,因为对多 CPU 来说,几乎每次读写共享内存都是非确定性操作,由此带来巨大的性能损失。 这个系统的设计目标只处理 fail-stop 错误,也就是系统一旦出错则立即 stop,而且正确的服务器立刻知道它 stop 了。(分布式系统中的各种错误可以参考:http://alvaro-videla.com/2013/12/failure-modes-in-distributed-systems.html, fail-stop 几乎是最简单的错误类型) FT 设计 首先我们将备份虚拟机运行在一个和主虚拟机不同的物理机上,备份虚拟机与主虚拟机保持同步和一致但有一个很小的时间差,这时我们称这两个虚拟机处于 virtual lockstep。 两个虚拟机的虚拟磁盘位于共享存储上(例如 FC 或 iSCSI,后面会讨论非共享存储的场景),只有主虚拟机会在网络上对外通告,所以所有网络输入只会进入主 […]