跳转到主要内容

KeyDB on FLASH (SSD 存储)

** 重要提示 - KeyDB FLASH 仍被视为 Beta 功能(实验性),应同样对待。请在使用时牢记这一点,并通过此处报告任何问题来帮助我们! **

KeyDB FLASH#

KeyDB FLASH 基于 RocksDB 构建,并会持久化到其写入的存储介质中。

FLASH 存储使您能够极大地扩展内存容量,而不会对性能造成巨大影响。最棒的是,您的数据在写入时会持久化到 FLASH 内存中,从而无需使用 AOF/RDB 文件。对于内存有限或应用成本过高的应用程序,KeyDB on FLASH 是一个很好的选择。对于经常接近或超过其 maxmemory 限制的数据库,它也是一个很好的选择。

本文档讨论 FLASH 的工作原理及其使用方法。

工作原理:#

启用 FLASH 选项后,所有数据都将写入 FLASH 并持久化,而热数据则同时保留在内存和 FLASH 中。通常,当数据库内存用完时,您会设置一个淘汰策略来开始删除键。使用 KeyDB on FLASH,这些数据会从内存中淘汰,但不会从 FLASH 中淘汰,并且仍然可以访问。

使用 KeyDB on FLASH,所有发送到数据库的内容都会持久化到 FLASH,类似于 AOF 的 fsync everysec 选项。如果您需要 fsync always 选项,建议设置 AOF 选项并将其设置为 fsync always。RDB 文件也不是必需的,但在创建和同步副本实例或更新 KeyDB 或迁移数据时是必需的。

Flash 存储基本上以两种方式工作:#

  • 针对较小值的缓存模式:不经常访问的较小值会保存在 FLASH 中,直到需要时才加载。KeyDB 会将最常用的值保留在 RAM 中以便更快地访问。这种缓存是透明进行的。
  • 针对较大值和流的 BLOB 模式:较大的值会被自动检测并视为二进制大对象(Binary Large Object)。这些对象保存在 Flash 中,并在需要时使用快速的顺序访问直接流式传输给客户端。这在提供出色性能的同时,确保了这些大对象不会对缓存中已有的对象产生负面影响。BLOB 阈值是完全可配置的,因此您可以为您的应用程序做出正确的权衡。

何时使用 KeyDB on FLASH:#

这实际上取决于您的设置、流量需求/模式以及延迟要求。显然,始终将所有数据保存在内存中会是最快的选项。然而,大多数用例中都有一部分数据的访问频率远高于其余数据。将这部分数据作为热数据保留在内存中,而其余数据则保留在 FLASH 上,这样可以在性能和最小化服务器需求之间取得良好的平衡。

对于那些希望获得额外容量、更便宜的容量或从 DRAM 备份溢出的人来说,FLASH 是一个很好的解决方案。

最好使用最接近 CPU 的 FLASH 存储介质,例如 NVMe。如果您使用的是 AWS 实例,I3 实例是 FLASH 选项的绝佳选择,因为它是附加存储,而不是像 EBS 卷那样的东西。带有“d”标识符的实例通常包含 FLASH(例如 m5d.xlarge)。如果您正在为实例添加 FLASH,最好进行基准测试以确保理想的设置。我们很快会发布一篇文章,比较不同的 FLASH 设置及其相关的性能统计数据。

使用 KeyDB on FLASH - 快速设置:#

指定存储介质,并配置 maxmemory 和淘汰策略。例如:

keydb-server --storage-provider flash [flash-storage路径] --maxmemory [DRAM最大内存... 例如 500mb 或 1G] --maxmemory-policy allkeys-lru

Docker 快速设置#

sudo docker run -d -it -p 6379:6379 --name mycontainername --mount type=bind,dst=/flash,src=/path/to/flash/ eqalpha/keydb keydb-server /etc/keydb/keydb.conf --storage-provider flash /flash --maxmemory [maxmemory-amount-ie. 500M] --maxmemory-policy [eviction-policy ie. allkeys-lfu]

请注意,KeyDB 在容器内以用户:组 keydb:keydb 的身份运行,因此根据您挂载卷到容器的方式,可能需要 keydb:keydb 的所有权。您可以在这里查看 Dockerfile 的详细信息。

使用 KeyDB on FLASH - 详细设置:#

挂载 FLASH 卷#

如果您不确定如何设置您的卷,可以查看 DigitalOcean 的这篇文章了解如何操作。完成后,您将指向希望 KeyDB 写入 FLASH 的目录。

在配置中指定#

设置好您的卷后,您可以使用参数 --storage-provider flash [location] 来指定您希望 KeyDB 写入的目录位置。

  • ‘flash’ 指定了要使用的存储介质(未来将提供多种类型)
  • [location] 是上面提到的 KeyDB FLASH 将要写入的目录

配置 maxmemory#

这决定了分配给 KeyDB 用于 DRAM 的内存量。这可以防止用尽所有内存,一旦超过限制,将 либо向客户端返回错误,或者如果设置了淘汰策略,将开始以指定的方式将数据移动到 FLASH。因此,maxmemory 通常设置得比较保守,具体取决于您对数据的重视程度。

使用 KeyDB on FLASH,您可以将 maxmemory 设置为您希望分配的 DRAM 量,而不必担心超过时会丢失数据。相反,数据会从 DRAM 中移除,但仍保留在 FLASH 中,不会丢失并且仍然可以提供服务。

将 maxmemory 设置为您愿意在服务器上分配给 KeyDB 的最大量,让 FLASH 处理其余部分。

使用指令 --maxmemory [max-memory-amount] 设置 maxmemory。默认单位是字节,但您也可以指定 mb、M、G 等,以避免输入长串字节。例如:--maxmemory 3G

设置淘汰策略#

有关设置 maxmemory 和淘汰策略的更多信息,请查看此文档。但请记住,使用 KeyDB on FLASH,数据不会被删除,它只是从 DRAM 中移除,但仍然在 FLASH 中可用。

摘录文档内容如下:

当达到 maxmemory 限制时,KeyDB 所遵循的确切行为是通过 maxmemory-policy 配置指令来配置的。

以下策略可用

  • noeviction: 当达到内存限制且客户端尝试执行可能导致使用更多内存的命令时(大多数写命令,但 DEL 和少数其他命令除外),返回错误。
  • allkeys-lru: 通过首先尝试移除最近最少使用 (LRU) 的键来淘汰键,以便为新添加的数据腾出空间。
  • volatile-lru: 通过首先尝试移除最近最少使用 (LRU) 的键来淘汰键,但仅限于设置了过期时间的键,以便为新添加的数据腾出空间。
  • allkeys-random: 随机淘汰键,以便为新添加的数据腾出空间。
  • volatile-random: 随机淘汰键,以便为新添加的数据腾出空间,但仅淘汰设置了过期时间的键。
  • volatile-ttl: 淘汰设置了过期时间的键,并尝试首先淘汰剩余生存时间 (TTL) 较短的键,以便为新添加的数据腾出空间。

如果没有符合先决条件的键可以淘汰,volatile-lru、volatile-random 和 volatile-ttl 策略的行为与 noeviction 相同。

建议使用像‘allkeys-lru’或‘allkeys-lfu’这样的策略,以确保您永远不会耗尽内存,并且数据总是可以移动到 FLASH 存储中。这些指令在大多数使用 FLASH 的场景中效果最好。

使用 --maxmemory-policy allkeys-lfu 进行指定