对于每一个关注于用户体验的web与移动应用程序来说,诸如开源的Redis与Memcached等基于内存的NoSQL存储系统正在成为事实上的标准。但是,近几年间,大型企业对于这些数据库的使用仍发展缓慢,其原因主要归结于性能、可伸缩性及可用性等方面的挑战。
幸运的是,现代编程语言(Ruby,Node.js和Python等)以及开发平台(Rails,Sinatra和Django等)已经直接创建好了一系列的工具和类库,它们能够充分利用基于内存的数据存储系统(Redis体现得尤为明显)的高性能以及各种操作命令类型,实现了一系列常见的用例。
这些开源软件项目的用例包括了任务管理、论坛、实时分析、twitter clone,地理位置搜索及缓存高级应用。
不过,对于每一个应用程序来说,数据库的可用性、可伸缩性以及性能对于整个应用的成败都有着莫大的影响。
本文概括介绍了为了将你的内存NoSQL数据库为企业应用做好准备所需的各种知识,以及在云端管理这些数据库时,如何克服七项最大挑战的提示与建议。
无论你进行何种操作,你的数据集对应用程序来说应该是始终可用的。这对内存数据库来说尤其重要,因为如果没有应用正确的策略,当以下状况发生时,你就会丢失你的数据集的部分或全部内容:
对于状况1与状况2的情形(本文稍后会讨论状况3的内容),你必须应用两种主要的机制:
网络分裂(network splits)在云端频繁发生,它或许是世界上任何一个分布式数据库系统中最复杂的部分。一旦发生分裂,你的应用程序也许只能见到你的全部内存NoSQL结点中的一部分,并且你的任意一个内存NoSQL结点也只能见到其它内存NoSQL结点的一部分。
为什么说这是一个很大的问题呢?如果你的数据库隐含着某些方面的设计缺陷的话,那么当网络分裂发生时,你或许你发现你的应用程序将数据写入了错误的结点。这就意味着,一旦分裂状况恢复时,在此阶段你的应用程序所发出的数据写入请求都将消失。这对于内存NoSQL数据库来说是个极大的问题,因为它每秒钟所产生的“写”操作远远大于其它任何NoSQL数据库系统。
那么如果你的内存NoSQL数据库设计正确呢?很不幸,你将不得不在两种非常糟糕的替代方案(实际上是一种……)中进行选择,如下所示:
请注意:由于目前市面上还没有任何一种最终一致的内存NoSQL数据库存在,实际上你只能选择第1个选项。
即使你的内存NoSQL解决方案允许多种分发方案,你仍应该考虑数据持久化与备份问题,出于以下几个原因:
希望我已经使你了解到数据持久化是必要的,在多数云端环境中,你应该为你的云端实例附加一个存储设备(例如AWS的EBS和Azure的Cloud Drive等等),如果你依然使用本地磁盘保存数据,那么下次节点故障时数据就会丢失。
一旦你启用了数据持久化机制之后,你的头号挑战就是如何在实时地将数据写入你的持久化存储介质时,保持你的内存NoSQL数据库依然高速运作。
诸如Redis与Memcached等内存NoSQL数据库在设计时的指标是:每秒能够处理超过10万次请求,并保证延迟小于毫秒级。但如果你不按照以下方法去做的话,你在云端环境中的速度是达不到这些值的:
多数云端实例都配置了一块独立的1G网卡。在内存NoSQL数据库的情况下,这1G需要处理以下内容:
这1G流量会很容易成为各种操作的瓶颈,以下是解决该问题的一些建议:
对于简单的键/值缓存解决方案来说(例如Memcached或者Redis的简单应用),一般而言都不会把扩展当作一个大问题,因为在多数情况下,只需将一台服务器加入服务器列表(或从列表中移除),并修改哈希方法即可。不过,富有经验的用户会意识到,扩展仍然可能成为一项令人头疼的任务。以下是处理此问题的一些建议:
在处理复杂的命令,例如Redis的UNION或者INTERSECT时,扩展会成为一个真正的难题。这些命令的作用相当于SQL语句中的JOIN命令,在对一个多分片(multi-shard)的架构进行操作时,必然需要加入一定量的延迟以及复杂性。如果在应用程序级别进行分片则能够部分解决此问题,因为它允许你在分片级别运行一些复杂的命令。但这意味着,你的应用程序设计会与内存NoSQL节点的配置紧密相关,使整个设计变得非常复杂。比方说,支持分片的应用程序必需了解每个键存储在哪一个节点上。并且像重新分片等扩展事件将导致大量的代码变更,并消耗运维部门的大量精力。
作为替代方案,有些用户声称新一代的超高性能RAM,例如AWS的High Memory Cluster Eight Extra Large 244GB内存(cr1.8*large)能够通过纵向扩展实例的方式解决多数复杂数据类型的扩展问题。但现实稍有不同,因为像Redis这样的内存NoSQL数据库,当它的数据集大小达到了25GB到30GB的规模后,会有许多其它操作上的难题出现,它们会使你执行纵向扩展的计划受阻。这些难题与本文之前描述的诸多挑战密切相关,例如分发、存储介质I/O、单核的单线程架构,网络开销等等。
处理内存NoSQL数据库的各种运维操作会消耗巨大的精力。它需要你对这些技术的所有细节都有深入的了解,以保证在各种紧要关头作出正确的决定。它同时要求你紧跟这些系统的最新变化与发展趋势,因为技术的变化是非常频繁的(或许太频繁了些)。
正如我以上所阐述的一样,为了充分利用Redis和Memcached这些开源技术的各种优点,充分了解它们的各种问题也是非常关键的。对企业级IT团队来说,了解如何在企业级环境下以最佳的方式克服这些挑战,以最大程度发挥内存NoSQL数据库的作用,这一点是尤其重要的。我对开源项目并没有偏见,但我依然建议寻求一些能够克服可伸缩性及高可用性的种种限制,同时保证在功能与性能方面不会作出任何妥协的商业解决方案。因为执行内存NoSQL数据库运维操作需要尖端的领域专家,而这种专家是数量很少的。
当前市面上已经有一些基于Redis和Memcached的内存NoSQL即服务(NoSQL-as-a-service)解决方案存在了。我建议你对这些服务以及自己动手打造解决方案的方式做一个全面的对比,然后再决定对你的应用程序来说,怎样克服这些在云端管理内存NoSQL时所面临的挑战才是最佳的方式。对你心仪的解决方案最好能建立一些基于真实项目的经验,这也是为什么很多服务商会提供一个免费试用阶段的原因之一。
Yiftach Schoolman是Garantia Data的联合创始人之一,并担任CTO,他是一位经验丰富的技术专家,在多个领域担任过软件开发与产品设计的领导者,包括了应用程序加速、云计算、软件即服务(Saas)、Broadband Networks与Metro Networks。Yiftach也是Crescendo Networks公司(后被F5 – NASDAQ代码FFIV收购)的创始人、主席以及CTO,Native Networks公司(后被Alcatel – NASDAQ代码ALU收购)的VP软件工程师,并且是ECI电信宽带业务部门的创始团队成员之一,担任VP软件工程师。Yiftach拥有数学及计算机科学专业的学士学位,并且修完了Tel-Aviv大学的计算机科学专业的硕士学位。
查看英文原文:How to Make Your In-memory NoSQL Datastores Enterprise-Ready