虽然缓存和数据库是不同的,但数据库始终可以缓存数据,而缓存也开始使用磁盘。它们的性能会随着时间的推移而趋于一致吗?
内存缓存一直被认为是速度最快的基础设施组件之一。而且,缓存解决方案开始涉足闪存领域也已经有几年了。这些举措提出了一个有意思的问题:如果内存缓存可以依赖闪存存储,那么为什么持久性数据库不能用作缓存呢?
为了量化各自的优势和利弊,ScyllaDB 与 memcached 的维护者联合在不同场景中对两者进行了比较。
我们将解释进行这些测试的动机,提供测试场景和结果的摘要,然后为可能在 ScyllaDB 和 memcached 之间做出选择的人提供建议。
在此过程中,我们分析了这两种解决方案背后的架构差异,并讨论了每种解决方案所涉及的权衡结果。
剧透:结果显示:
memcached 和 ScyllaDB 在类似条件下承受压力时都最大化了磁盘和网络带宽,并且整体上保持了类似的性能。
虽然 ScyllaDB 需要数据模型更改,才能完全满足网络吞吐量,但 memcached 需要额外的 IO 线程来满足磁盘 I/O。
尽管与 memcached 流水线磁盘请求,相对ScyllaDB 表现出更好的延迟,但 memcached 对于单个请求的延迟效果更好。
该项目还有一本详细的 Gitbook,其中更详细地介绍了测试和结果,并提供了可用于自己执行测试的特定配置的链接。
ScyllaDB 感谢 memcached 维护者 Alan Kasindorf(又名dormando)和Danny Kopping对此项目的贡献,并感谢他们的支持和耐心。
内存级别缓存效率
内存中可以容纳的项目越多,缓存命中的几率就越大。当缓存命中越多,访问速度就会比访问磁盘快得多。最终的结果便是改善延迟。
以下的项目首先测量了我们可以将多少个项目存储到每个数据存储中。在整个测试过程中,memcached 的密钥介于 4 到 12 个字节(key0 .. keyN)之间,ScyllaDB 的密钥介于 12 个字节之间。该值固定为 1,000 个字节。
Memcached
在运行结果表明,Memcached 能够存储大约 1.01 亿个项目。它非常节省内存。在 memcached 分配的 114 GB 内存中,这大约相当于 101G 的值,未考虑密钥大小和其他标志:
Memcached 在内存中存储了 1.01 亿个项目
ScyllaDB
在运行之前,ScyllaDB 存储了 6000 万到 6100 万个项目。这并不奇怪,因为它的协议要求在写入过程中存储更多数据(例如自公元纪元以来的写入时间戳、行活跃度等)。
ScyllaDB 还会在执行过程中将数据持久保存到磁盘,这意味着过滤器(以及可选的索引)需要存储在内存中,以供后续进行磁盘查找。
使用 ScyllaDB,当尝试加载 6100 万行数据时,由于内存压力而开始过载。
总结
Memcached 存储的内存项目比 ScyllaDB 多约 65%。
ScyllaDB 行具有更高的每项开销,以便支持宽列方向。
在 ScyllaDB 中,布隆过滤器、索引缓存和其他组件也存储在内存中,以支持高效的磁盘查找,这又增加了一层开销。
只读内存工作负载
缓存的理想工作负载是所有数据都适合内存,这样读取就不需要访问磁盘,也不会发生驱逐或未命中。
ScyllaDB 和 memcached 都采用 LRU(最近最少使用算法)的逻辑来释放内存:当系统在压力下运行时,项目会从 LRU 的尾部被驱逐;这些通常是最不活跃的项目。
消除驱逐和缓存未命中有助于衡量和设置两个数据存储的性能基准。它将重点放在这些类型的工作负载最重要的方面:读取吞吐量和请求延迟。
在本次测试中,我们首先使用与上一次测试中相同的有效负载大小对两个存储进行预热。然后,我们针对各自的范围启动读取,持续 30 分钟。
Memcached
在负载运行中,Memcached 实现了令人印象深刻的每秒 300 万次 Get(获取),充分利用了 AWS 网络接口卡 (NIC) 带宽 (25 Gbps)!
Memcached 保持稳定的 3M rps,充分发挥 NIC 吞吐量
解析结果显示p99.999响应在1毫秒内完成:
stat:cmd_get:totalhits:5503513496tax:3060908/s === counter mg === 1-10us 0 0.000% 10-99us 343504394 6.238% 100-999us 5163057634 93.762% 1-2ms 11500 0.00021%
ScyllaDB
为了在 ScyllaDB 中读取更多行,我们要为客户端请求设计一个更好的数据模型,因为协议特性(特别是没有流水线)。使用聚类键,我们可以充分利用 ScyllaDB 的缓存,从而显著提高缓存行数。
我们提取了 500 万个分区,每个分区有 16 个聚类键,总共 8000 万个缓存行。
结果,与之前显示的键值数字相比,缓存中的记录数量显著提高。
虽然 memcached 工作负载始终命中单个键值对,但 ScyllaDB 中的单个请求会导致返回多行。值得注意的是,使用 memcached 可以通过将整个有效负载作为单个键下的值来获得相同的结果,结果会相应地缩放。
经过这些调整,加载工具在 30 分钟内总共运行了 187,000 次读取操作/秒。每次操作都会检索 16 行。
与 memcached 类似,ScyllaDB 也最大化了网卡吞吐量。它仅从内存数据中每秒就能处理大约 300 万行:
node_exporter 报告的 ScyllaDB 服务器网络流量:
练习期间的读取操作数(左)和从缓存中命中的行数(右)
ScyllaDB 公开了服务器端延迟信息,这对于在没有网络的情况下分析延迟非常有用。在测试期间,ScyllaDB 的服务器端 p99 延迟保持在 1ms 范围内:
ScyllaDB 的延迟和网络流量与完成的调整相匹配
不出所料,客户端百分位数高于服务器端延迟,读取 P99为 0.9 毫秒。
Cassandra-stress P99 延迟直方图
总结
memcached 和 ScyllaDB 都完全占满了网络;为了防止达到每秒最大网络数据包数的饱和,memcached 依赖于请求流水线,而 ScyllaDB 则切换到宽列方向。
ScyllaDB 的缓存采用宽列模式后显示出了显著的增益,与之前简单的键值导向相比能够存储更多的项目。
在协议层面,memcached 的协议更简单、轻量级,而 ScyllaDB 的 CQL 提供的功能更丰富,但处理也更重。
将磁盘添加到镜像中
测量闪存性能本身就带来了一系列挑战,这使得几乎不可能全面地真实地描述给定的工作负载。
对于与磁盘相关的测试,我们决定衡量最悲观的情况:比较两种解决方案,它们主要从块存储提供数据,同时了解:
实际工作量发生这种情况的可能性接近于零。
在实践中,用户应该预期之前的乐观缓存工作负载和悲观的磁盘绑定工作负载之间的数字。
Memcached 扩展存储
维基百科Extstore页面详细介绍了该解决方案的内部工作原理。从高层次上讲,它允许 memcached 将其哈希表和键保存在内存中,但将值存储在外部存储中。
在测试用例中,我们在 memcached 中填充了 12.5 亿个项目,这些项目的值大小为 1KB,密钥大小最多为 14 个字节:
尽管磁盘空间充足,但当我们达到约 12.5 亿个项目时,就会开始驱逐
使用 Extstore,我们存储的项目数量是之前内存工作负载的 11 倍左右,直到开始出现驱逐(如上图右侧面板所示)。尽管 11 倍已经是一个令人印象深刻的数字,但闪存上存储的总数据量仅为 AWS 实例提供的 3.5 TB 中的 1.25 TB。
只读性能
对于实际性能测试,针对 1KB 和 8KB 的项目大小对 Extstore 进行了强调。下表总结了结果:
测试类型 | 每次 GET 的内容 | 有效载荷大小 | IO 线程 | 获取率 | P99 |
perfrun_metaget_pipe | 16 | 1KB | 32 | 188K/秒 | 4~5毫秒 |
perfrun_metaget | 1 | 1KB | 32 | 182K/秒 | <1毫秒 |
perfrun_metaget_pipe | 16 | 1KB | 64 | 261千/秒 | 5~6毫秒 |
perfrun_metaget | 1 | 1KB | 64 | 256K/秒 | 1~2毫秒 |
perfrun_metaget_pipe | 16 | 8 千字节 | 16 | 92K/秒 | 5~6毫秒 |
perfrun_metaget | 1 | 8 千字节 | 16 | 90K/秒 | <1毫秒 |
perfrun_metaget_pipe | 16 | 8 千字节 | 32 | 110K/秒 | 3~4毫秒 |
perfrun_metaget | 1 | 8 千字节 | 32 | 105K/秒 | <1毫秒 |
ScyllaDB
我们向 ScyllaDB 填充了与 memcached 相同数量的项目。尽管 ScyllaDB 的 GET 速率高于 memcached,但与 memcached 的非流水线工作负载相比,它的尾部延迟略高。总结如下:
测试类型 | 每次 GET 的内容 | 有效载荷大小 | 获取率 | 服务器端 P99 | 客户端 P99 |
1KB读取 | 1 | 1KB | 268.8K/秒 | 2毫秒 | 2.4毫秒 |
8KB读取 | 1 | 8 千字节 | 156.8K/秒 | 1.54毫秒 | 1.9毫秒 |
总结
Extstore 需要对其设置进行大量调整,以完全满足闪存存储 I/O 的要求。
由于 memcached 架构,较小的有效负载无法充分利用可用的磁盘空间,与 ScyllaDB 相比,收益较小。
在键值导向方面,ScyllaDB 的速率总体上高于 memcached,尤其是在负载较大的情况下。延迟优于流水线请求,但略高于 memcached 中的单个 GET。
覆盖工作负载
根据之前的磁盘结果,我们在以相同吞吐量(250K ops/sec)为目标的读取为主的工作负载中比较了这两种解决方案。所涉及的工作负载是 memcached针对 Extstore 的“基本”测试的轻微修改,具有 10% 的随机覆盖。它被认为是“半最坏情况”。
Memcached
Memcached 在测试期间的速率略低于 249,000。尽管写入速率在测试期间保持稳定,但我们观察到读取速率在整个运行过程中略有波动:
Memcached:主要读取工作负载指标
尽管读取率降低了,但我们仍观察到指标略高,但延迟仍然很低。这些结果总结如下:extstore_io_queue
方法 | IO 线程 | 速度 | P99 延迟 |
获取cmd | 64 | 224千/秒 | 1~2毫秒 |
命令集 | 64 | 24.8K/秒 | <1毫秒 |
ScyllaDB
ScyllaDB 测试使用两个加载器运行,每个加载器的速度为目标速度的一半。尽管 ScyllaDB 实现了稍高的吞吐量(259.5K),但在整个运行过程中写入延迟保持较低水平,而读取延迟较高(与 memcached 类似):
ScyllaDB:主要读取工作负载指标
下表总结了两个加载器的客户端运行结果:
装载器 | 速度 | 写入 P99 | 阅读 P99 |
装载器1 | 124.9K/秒 | 1.4毫秒 | 2.6 毫秒 |
加载器2 | 124.6K/秒 | 1.3毫秒 | 2.6 毫秒 |
memcached 和 ScyllaDB 的写入率都很稳定,而读取率在整个运行过程中略有波动。
ScyllaDB 写入仍然占提交日志开销,位于热写入路径中。
ScyllaDB 服务器端延迟与 memcached 结果中观察到的延迟相似,尽管客户端延迟略高。
在 Gitbook 中阅读有关该项目的更详细分析。
总结
memcached 和 ScyllaDB 在所有测试中都实现了底层硬件利用率的最大化,并将延迟保持在可预测的低水平。
那么你应该选择哪一个呢?真正的答案是:视情况而定。
如果你现有的工作负载可以容纳简单的键值模型,并且受益于流水线,那么 memcached 应该更适合您的需求。另一方面,如果工作负载需要支持复杂的数据模型,那么 ScyllaDB 可能更适合。
坚持使用 memcached 的另一个原因是:它可以轻松传输远远超出网卡所能承受的流量。事实上,在Hacknews的帖子中,dormando 提到他可以为一个服务器将其扩展到超过 5500 万次读取操作/秒。
有鉴于此,可以使用较小和/或更便宜的实例类型来维持类似的工作负载,前提是可用内存和磁盘占用空间足以满足你的工作负载需求。
需要考虑的另一个角度是数据集大小。
虽然 Extstore 允许用户存储超出内存的项目,从而节省大量成本,但每 GB 内存可容纳的键数量是有限的。与包含较大项目的工作负载相比,包含小项目的工作负载会有较小的收益。但 ScyllaDB 可允许开发者存储数十亿个项目,而不管其大小如何。
考虑是否需要数据持久性也很重要。
如果需要,那么将 ScyllaDB 作为复制的分布式缓存运行,可以为你提供更大的弹性和不间断的操作,但代价是(正如memcached 正确指出的那样)复制会使你的有效缓存大小减半。
不幸的是,Extstore 不支持热重启,因此单个节点的故障或维护很容易提高你的缓存未命中率。这是否可以接受,取决于你的应用程序语义:如果缓存未命中对应于数据库的往返,则端到端延迟将暂时更高。
关于一致性哈希,memcached 客户端负责在分布式服务器之间分发密钥。这可能会带来一些问题,因为不同的客户端配置会导致密钥分配不同,并且某些实现可能彼此不兼容。这些详细信息已经在Mmemcached 的 ConfiguringClient wiki中概述。ScyllaDB 采用不同的方法:一致性哈希在服务器级别完成,并在首次建立连接时传播到客户端。这可确保所有连接的客户端在扩展时始终遵循相同的拓扑结构。
那么,是谁赢了或者谁输了?
这并不是一场比赛,而且也不是一个详尽的清单,只是概述每个解决方案的相关考虑因素而已。ScyllaDB 和 memcached 使用了不同的方法来高效地使用底层基础设施。如果配置正确,两者都有可能帮助我们节省系统的大量成本。
我们应该很高兴看到 ScyllaDB 的数据与业界公认的 memcached 相当。当然,我们并不指望数据库会“更快”。在事实上,当我们大规模接近微秒级延迟时,“更快”的定义就会变得相当主观。
优网科技秉承"专业团队、品质服务" 的经营理念,诚信务实的服务了近万家客户,成为众多世界500强、集团和上市公司的长期合作伙伴!
优网科技成立于2001年,擅长网站建设、网站与各类业务系统深度整合,致力于提供完善的企业互联网解决方案。优网科技提供PC端网站建设(品牌展示型、官方门户型、营销商务型、电子商务型、信息门户型、DIY体验、720全景展厅及3D虚拟仿真)、移动端应用(手机站、APP开发)、微信定制开发(微信官网、微信商城、企业微信)、微信小程序定制开发等一系列互联网应用服务。