Hammerspace

类似哈希表的持久化、并发、堆外存储接口
331
作者Jon Tai

什么是Hammerspace?

Hammerspace……在虚构作品中,它是一个粉丝们设想的额外维度空间,可以瞬间访问存储区域,用于解释动画、漫画和游戏角色如何凭空变出物品。

这个 gem 提供了持久化、并发访问的堆外字符串存储,并具有熟悉的类似哈希表的接口。它针对批量写入和随机读取进行了优化。

动机

应用程序经常使用从不更改或很少更改的数据。在许多情况下,访问此数据时可以接受一定的延迟。例如,用户的个人资料可以从 Web 服务、数据库或外部共享缓存(如 memcache)加载。在其他情况下,延迟更为敏感。例如,翻译可能被多次使用,即使从外部缓存访问它们需要 ~2ms 的延迟也慢得无法接受。

为了解决性能问题,此类型的数据通常在应用程序启动时加载。不幸的是,这意味着数据存储在堆上,垃圾收集器必须在每次运行时扫描所有对象(至少在 Ruby MRI 的情况下是这样)。此外,对于使用多个进程的应用程序服务器,每个进程都有自己的一份数据副本,这是对内存的低效使用。

Hammerspace 通过将数据从堆移动到磁盘来解决这些问题。利用针对批量写入和随机读取优化的库和数据结构,可以保持可接受的性能水平。由于数据是持久化的,因此除非数据已更改,否则无需在应用程序启动时从外部缓存或服务重新加载。

不幸的是,这些底层库并不总是支持并发写入。Hammerspace 添加了并发控制,允许多个进程安全地更新和读取单个共享数据副本。最后,Hammerspace 的接口旨在模仿 Ruby 的 Hash,以便轻松直接地与现有应用程序集成。可以通过实现使用该库的新后端来使用不同的底层库。(目前,仅支持Sparkey。)后端只需要实现少量方法([][]=closedeleteeachuid),但如果底层库支持更高效的实现,则可以覆盖其他方法的默认实现。