当前位置: 首页 > 后端技术 > Java

全球最快内存数据库横空出世,速度比Redis快25倍,Star数飙升,疯狂杀戮!

时间:2023-04-02 01:10:52 Java

出处|资讯,整理|玉莹和蒂娜反击了,那岂不是输了?!今年年中,一位前谷歌和亚马逊工程师推出了Dragonfly,这是他创建的开源内存数据缓存系统,用C/C++编写,并在BSL许可证(商业源许可证)下分发。根据过去的基准测试结果,Dragonfly可能是世界上最快的内存存储系统。它提供了对Memcached和Redis协议的支持,但可以在运行时以更高的性能查询并消耗更少的内存。与Redis相比,Dragonfly在典型工作负载下实现了25倍的性能提升;单个Dragonfly服务器每秒可以处理数百万个请求;在5GB存储测试中,Dragonfly需要的内存比Redis少30%。作为一款开源软件,Dragonfly在短短两个月内获得了9.2KGitHubstar和177个fork分支。虽然这些年出现了很多类似的兼容Redis的内存数据存储系统,比如KeyDB和Skytable,但都没有像这次这样“轰动”过。毕竟Redis诞生已经十多年了。这时候,从头设计一个缓存系统,可以摒弃历史包袱,更好地利用资源。Redis反击针对新崛起的Dragonfly,Redis联合创始人兼CTOYiftachShoolman、RedisLabs首席架构师YossiGottlieb和RedisLabs性能工程师FilipeOliveira联合发表了一篇名为《13 年后,Redis 是否需要新的架构》的文章。在文章中,他们专门给出了Redis7.0vsDragonfly的benchmark测试结果,他们认为比较公平:Redis的吞吐量比Dragonfly高出18%-40%,以及对Redis架构的一些看法和思考证明“为什么Redis仍然是内存中实时数据存储(缓存、数据库以及介于两者之间的一切)的最佳架构”。尽管他们强调Redis架构仍然是同类中最好的,但他们不能忽视Dragonfly等这些新软件提供的一些新鲜有趣的想法和技术,更现代的词典,更多的线程使用等)。此外,Redis指出Dragonfly基准测试的比较方法“并不代表Redis在现实世界中的运作方式。”对此,Reddit上有网友反驳道:这绝对代表了普通用户在现实世界中运行Redis的方式。“在一台机器上运行集群,只是为了能够使用超过1个核心”是额外的复杂性,只有在别无选择的情况下才会这样做,如果竞争对手能够“正常工作”,那就太好了有一个更容易的设置。另外最近面试整理了Java最新最全的面试题:https://www.javastack.cn/mst/也有人说这篇文章是Redis团队委婉否认“Dragonfly是最快的缓存系统”,但更多网友表示,Redis发文“反击”已经代表他们市场部输了:“Redis投入了如此多的工程精力写了这样一篇文章,还对标了Reids/Dragonfly,这是对蜻蜓的巨大赞美。”“我很高兴Redis发布了这个,所以我不得不去看看Dragonfly,它看起来很棒。”Redis博文翻译:作为一项基础技术,每隔一段时间就会有人跳出来,想用新的架构来取代Redis。KeyDB几年前就提出了这样的方案,最近Dragonfly号称是最快的兼容Redis的内存数据存储系统。是的,这类解决方案的出现当然带来了很多值得关注和讨论的有趣技术/想法。在Redis,我们也喜欢接受重新审视Redis原始架构设计原则的挑战。当然,我们一直在为Redis寻找提高性能和扩展功能的创新方向,但在这里我们想谈谈我们的看法和思考,并解释为什么Redis仍然是最好的实时内存数据存储(包括缓存,数据库和调解)。以及介于两者之间的所有内容)选项。接下来,我们将重点关注Redis对速度和架构差异的看法,然后将其作为比较的基础。在文末,我们还将提供基准测试结果以及与Dragonfly项目的详细性能对比信息。欢迎大家自行比较参考。速度问题Dragonfly基准测试实际上是将独立的单进程Redis实例(只能使用单个内核)与多线程Dragonfly实例(可以使用VM/服务器上的所有可用内核)进行比较。显然,这样粗略的对比并不能代表Redis在真实场景下的运行状态。作为技术建设者,我们希望更准确地把握自己的技术与其他解决方案的差异,所以这里做一个公平的调整:40个分片(可以使用大部分实例核)的Redis7.0集群与Dragonfly团队在基准测试中使用的最大实例类型(AWSc4gn.16xlarge)。在这一轮测试中,我们看到Redis的吞吐量比Dragonfly高出18%到40%,而这仅使用了总共??64个vCore中的40个。架构差异的背景信息在我们看来,每一个多线程项目的开发人员在项目被批准之前,都会根据之前工作中经历的痛点来指导架构决策。我们也承认,在多核设备上运行单个Redis进程(此类设备通常提供数十个内核和数百GB的内存)确实存在资源利用不足的问题。但是Redis在设计之初并没有考虑到这一点,很多Redis服务商都想出了相应的解决方案来在市场上占有一席之地。Redis通过运行多个进程(使用Redis集群)进行横向扩展,包括在单个云实例的上下文中。在TheRedisCompany,我们将这一概念更进一步,构建了RedisEnterprise。RedisEnterprise提供管理层,允许用户大规模运行Redis,默认情况下启用高可用性、即时故障转移、数据持久性和备份等功能。下面,我们打算分享一些幕后使用的原则,向您展示我们如何为Redis的生产应用设计良好的工程实践。架构设计原则在每个虚拟机上运行多个Redis实例通过在每个虚拟机上运行多个Redis实例,我们可以:使用完全无共享的架构来实现垂直和水平的线性扩展。这种方法始终提供比纯粹向上扩展的多线程架构更好的架构灵活性。提高复制速度,因为复制操作是跨多个进程同时完成的。从虚拟机故障中快速恢复。因为新虚拟机的Redis实例会同时填充来自多个外部Redis实例的数据。将每个Redis进程限制在合理的大小我们不允许单个Redis进程的大小超过25GB(在闪存上运行Redis时最大为50GB)。这样,我们在执行Redisfork复制、快照保存、AOF重写等操作时,就可以享受边写边复制的好处,而不会产生沉重的内存开销。否则,我们(或客户端)将不得不付出昂贵的资源成本。为了便于管理整个集群,我们希望每个Redis实例保持较小的规模,从而加快迁移分片、重新分片、缩放和重新平衡等操作的执行速度。水平扩展是灵活运行的最重要方式——内存数据以水平扩展的方式存储,这是Redis成功的关键。原因如下:更好的弹性——我们在集群中使用的节点越多,整个集群就越健壮。例如,如果您在三节点集群上运行数据集,并且其中一个节点降级,则集群的三分之一无法运行;但是,如果您在九个节点降级上运行数据集,则只有九分之一的集群无法运行。易于扩展——在横向扩展系统中,向集群添加一个额外的节点并将部分数据集迁移到它要容易得多。相比之下,在扩容系统中,我们只能直接引入更大的节点,复制整个数据集……这是一个漫长的过程,过程中随时可能出问题。逐步向上扩展更具成本效益——向上扩展,尤其是在云环境中,通常需要付出代价。在大多数情况下,即使只是向数据集添加几千兆字节,也需要将实例大小加倍。高吞吐量——在Redis,我们看到许多客户在小型数据集上运行高吞吐量工作负载,即具有极高的网络带宽和/或每秒数据包(PPS)要求。我们以每秒100万次以上操作的1GB数据集为例。与使用单节点c6gn.16xlarge集群(128GB内存、64个CPU和100Gbps传输带宽,每小时成本为2.7684美元)相比,三个c6gb.xlarge节点(8GB内存、4个CPU及以上)的集群到25Gbps的传输带宽,每小时0.1786美元)将运营成本降低了20%,而且更加稳健。由于性价比极佳,弹性更强,吞吐量超限,横向扩容无疑是比纵向扩容更好的选择。接近NUMA架构——垂直扩展也需要使用双路服务器,可以容纳更多核心和大容量DRAM;相比之下,Redis等多处理架构实际上更适合NUMA架构,因为它们的行为特征接近于较小节点的A网络。但必须承认,NUMA与多线程架构之间也存在着天然的冲突。根据我们在其他多线程项目中的经验,NUMA最多可使内存数据存储的性能降低80%。存储吞吐量限制——AWSEBS等外部磁盘的扩展速度显然不如内存和CPU。事实上,云服务提供商会根据使用的设备类型增加存储吞吐量限制。因此,避免吞吐量限制并满足高数据持久性要求的唯一方法是使用横向扩展——即添加更多节点和更多伴随的网络连接磁盘。临时磁盘-临时磁盘是在SSD上运行Redis的好方法(其中SSD用于替代DRAM,而不是作为持久性存储),在保持Redis非常高的速度等级水平的同时,将数据库成本保持在磁盘上。但临时磁盘也有上限。一旦接近这个上限,我们就需要进一步扩容——这个时候,更好的办法还是增加更多的节点,引入更多的临时磁盘。因此,横向扩展继续取胜。商品硬件——最后,我们的许多客户在本地数据中心、私有云甚至小型边缘数据中心运行Redis。在这些环境中,大多数设备的内存不超过64GB,CPU不超过8个,因此唯一可行的扩展方式是横向扩展。结论我们还是很欣赏社区提出的各种有趣的想法和技术方案。其中一些有望在未来进入Redis(我们已经开始研究io_uring、更现代的词典、更丰富的线程使用策略等)。但在可预见的未来,我们不会放弃Redis所坚持的sharednothing、multi-process等基本架构原则。这种设计不仅具有最佳的性能、可扩展性和弹性,而且可以支持内存实时数据平台所需的各种部署架构。附:Redis7.0forDraonflybenchmarkdetailsRedis教程推荐在这里:https://www.javastack.cn/database/redis/结果概览版本:我们使用Redis7.0.0直接从源码搭建Dragonfly。来自https://github.com/Dragonfly/...6月3日源码(hash=e806e6ccd8c79e002f721a1a5ecb847bd7a06489)目标:验证Dragonfly发布的结果是否可重现,确定检索结果的完整条件(给定memtier_benchmark,操作系统版本等)缺少)确定AWSc6gn.16xlarge实例上可实现的最佳OSSRedis7.0.0集群性能,并与Dragonfly的基准测试结果进行比较客户端配置:OSSRedis7.0解决方案需要大量访问打开与Redis集群的连接,因为每个memtier_benchmark线程都需要连接到所有碎片。OSSRedis7.0方案在客户端虚拟机上运行两个memtier_benchmark进程时效果最好资源利用和配置优化:OSSRedis集群在40个primaryshard的配置下表现最好,对应虚拟机上24个备用vCPU。虽然设备资源还没有得到充分利用,但我们发现继续增加分片数量是没有意义的,反而会降低整体性能。我们仍在调查确切原因。另一方面,Dragonfly解决方案完全耗尽了虚拟机性能,所有64个vCPU都达到了100%的利用率。在这两种解决方案中,我们都调整了客户端配置以达到最佳效果。如下图,我们成功复现了大部分Dragonflybenchmark数据,甚至在30通道条件下取得了比项目方更高的测试成绩。本次测试强调与Dragonfly测试环境的一致性。如果调整测试环境,Redis的性能有望进一步提升。最后,我们还发现Redis和Dragonfly都不受每秒网络数据包或传输带宽的限制。我们已经确认,在2台虚拟机(分别作为client和server,均使用c6gn.16xlarge实例)之间使用TCP传输约300B的数据包负载时,每秒的数据包传输量可达1000万以上,传输带宽超过30Gbps。分析结果显示,单个GET通道的延迟小于1毫秒:OSSRedis:443万次/秒,平均延迟和50%的值均达到亚毫秒级别。平均客户端延迟为0.383毫秒。Dragonfly声称每秒400万次操作:-我们成功地重现了每秒380万次操作,平均客户端延迟为0.390毫秒-Redis与Dragonfly-Redis吞吐量比Dragonfly声称的结果高10%,比我们的更快成功重现Dragonfly结果高出18%。30个GET通道:OSSRedis:每秒2290万次操作,平均客户端延迟为2.239毫秒Dragonfly声称每秒操作高达1500万次:-我们设法重现了每秒1590万次操作,平均客户端延迟为3.99毫秒-Redis与Dragonfly-Redis比Dragonfly的可重现和声称的结果分别高出43%和52%。单个SET通道延迟低于1毫秒:OSSRedis:每秒474万次操作,平均延迟值和第50个百分位数都在亚毫秒范围内。平均客户端延迟为0.391毫秒Dragonfly声称每秒可进行400万次操作:-我们成功地再现了每秒400万次操作,平均客户端延迟为0.500毫秒-Redis与Dragonfly-可重现的结果和DragonflyRedis的声明在两者中均优于19%与30个SET通道比较的结果:OSSRedis:每秒1985万次操作,平均客户端延迟为2.879毫秒Dragonfly声称每秒1000万次操作:-我们设法重现了每秒1400万次操作,平均客户端延迟为4.203毫秒-RedisvsDragonfly-Redis比Dragonfly的可重现性和声称的结果分别高出42%和99%变体的Memtier_benchmark命令:单GET通道低延迟1msRedis:2X:memtier_benchmark–ratio0:1-t24-c1–test-time180–distinct-client-seed-d256–cluster-mode-s10.3.1.88–port30001–key-maximum1000000–hide-histogramDragonfly:memtier_benchmark–ratio0:1-t55-c30-n200000–distinct-client-seed-d256-s10.3.1.6–key-maximum1000000–hide-histogram30GETchannelsRedis:2X:memtier_benchmark–ratio0:1-t24-c1–test-time180–distinct-client-seed-d256–cluster-mode-s10.3.1.88–port30001–key-maximum1000000–hide-histogram–pipeline30Dragonfly:memtier_benchmark–ratio0:1-t55-c30-n200000–distinct-client-seed-d256-s10.3.1.6–key-maximum1000000–hide-histogram–pipeline30单个SET通道延迟低于1毫秒Redis:2X:memtier_benchmark–ratio1:0-t24-c1–test-time180–distinct-client-seed-d256–cluster-mode-s10.3.1.88–port30001–key-maximum1000000–hide-histogramDragonfly:memtier_benchmark–ratio1:0-t55-c30-n200000–distinct-client-seed-d256-s10.3.1.6–key-maximum1000000–hide-histogram30SETchannelsRedis:2X:memtier_benchmark–ratio1:0-t24-c1–test-time180–distinct-client-seed-d256–cluster-mode-s10.3.1.88–port30001–key-maximum1000000–hide-histogram–pipeline30Dragonfly:memtier_benchmark–ratio1:0-t55-c30-n200000–distinct-client-seed-d256-s10.3.1.6–key-maximum1000000–hide-histogram–pipeline30测试设施详情本次对比测试,我们在客户端(用于运行memtier_benchmark)和服务器(用于运行Redis和Dragonfly)使用相同的虚拟机类型,具体规格:虚拟机:AWSc6gn.16xlargeaarch64ARMNeoverse-N1每个插槽的核心数:64每个核心的线程数:1NUMA节点:1核心版本:Arm64内核5.10安装内存:126GB参考链接:https://redis。com/博客/redis-...https://www.reddit.com/r/prog...近期热点文章推荐:1.1,000+Java面试题及答案(2022最新版)2.厉害了!Java协程来了。.3.SpringBoot2.x教程,太全面了!4.不要用爆破爆满画面,试试装饰者模式,这才是优雅的方式!!5.《Java开发手册(嵩山版)》最新发布,赶快下载吧!感觉不错,别忘了点赞+转发!