如何让NoSQL内存数据库适合企业级应用

本文涉及的产品
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
简介: 如何让NoSQL内存数据库适合企业级应用作者:chszs,转载需注明。博客主页:http://blog.csdn.net/chszs英文原文:How to Make Your In-memory NoSQL Datastores Enterprise-Ready对于每一个关注用户体验的Web应用或移动应用而言,NoSQL内存数据库(例如开源的 Redis和Memcached)正逐步成为事实上的标准。

如何让NoSQL内存数据库适合企业级应用

作者:chszs,转载需注明。博客主页:http://blog.csdn.net/chszs

英文原文:How to Make Your In-memory NoSQL Datastores Enterprise-Ready


对于每一个关注用户体验的Web应用或移动应用而言,NoSQL内存数据库(例如开源的 Redis和Memcached)正逐步成为事实上的标准。但是,近几年来,大型企业在采用这些数据库方面还面临着诸多挑战,主要是由于性能、可扩展性和可用性方面的问题。

非常幸运的是,现代编程语言(例如Ruby、Node.js、Python等)和开发平台(例如Rails、Sinatra、Django等)已经内置了很多工具和开发库。这些工具和开发库能够有效利用内存数据库的高性能和各种操作命令,能够实现当前流行的多种应用项目。

这些开源项目的案例包括作业管理、论坛、实时分析、Twitter克隆、地理位置搜索以及高级缓存等等。

但是,对于这些项目成功至关重要的是数据库系统的可用性(Availability)、可扩展性(Scalability)和性能(Performance)。

本文粗略的介绍如何利用内存数据库构建企业级应用,包括一些技巧和建议;这些技巧和建议能够解决云端NoSQL数据库管理面临的七大挑战。

一、可用性(Availability)


无论你在做什么,对于你的应用来说数据必须是时刻可用的。这对于内存数据库来说尤为重要;因为,如果没有适当的措施,当下面的情形发生时你的数据将会部分或全部丢失:
1) 节点失效(在云中经常发生)
2) 进程重启(你可能需要不时的进行重启)
3) 按需要扩展(我们假设你可能需要这个)

对于情形1和情形2有两种方式来解决;情形3将在稍后讨论。

1、复制:你要确保将你的数据集保存一份到集群的另一节点,如果是另一数据中心则更为可靠,以便应付数据中心发生故障(亚马逊AWS在2012年至少发生了4次故障)。不幸的是事情并非如此简单。随便就能举一个复制非常困难的例子:

一旦程序的写频率增加,你会发现应用服务器写入速度远大于复制的速度,尤其是在主节点和复制节点存在网络拥堵的情形下。一旦发生这种情况,如果数据集非常大,节点的复制同步很有可能永远也完不成。

2、自动切换:为什么需要这个?内存数据库每秒处理的请求比一般数据库通常多100倍,这就意味着每增加一秒宕机时间就会延迟更多的请求处理并给用户带来不好的用户体验。在实现自动切换时一定要遵循下面的原则:

(1) 确保主存储节点一旦失效就立刻切换到备用复制节点。这一般基于成熟健壮的看门狗技术 (Watch Dog),看门狗持续的监控节点,一旦发现失效就切换到健康的复制节点。
(2) 对于你的应用程序而言切换过程应尽可能透明;最理想的情况是无需更改任何配置。更高级的解决方案是仅仅修改DNS中存储节点的IP地址,确保修复过程在几秒钟之内完成。
(3) 自动切换应当基于Quorum并且是完全一致(Fully Consistent)或最终一致(Eventually Consistent)的。讨论下面继续:

二、网络分割过程中和完成后的一致性


网络分割(Network Split)在云中频繁发生,对地球上的分布式存储系统而言也是最复杂的问题。一旦发生分割,应用程序可能只会找到内存数据库的部分节点;同时,每个NoSQL内存数据库节点也可能只能找到其他部分NoSQL数据库节点。

为什么说这是一个非常严重的问题呢?如果你的数据库包含一些隐蔽的设计缺陷,当网络分割发生时,应用程序很可能会把数据写入错误的节点。这意味着,当网络分割的情况恢复时,应用程序之前的写请求操作的数据就会丢失。这对NoSQL内存数据库来说这是一个非常重要的话题,因为NoSQL内存数据库每秒的写操作数量远大于其他NoSQL数据库系统。 

一个设计得当的NoSQL内存数据库是什么样子的呢?很不幸,你只能从下面两个非常糟糕的候选中进行选择:
(1) 如果NoSQL内存数据库是完全一致的,在某些情况下你是不允许写入任何内容的,除非网络分割恢复。
(2) 如果NoSQL内存数据库是最终一致的,应用程序可以对“读”请求采用quorum方法——返回一个值或者阻塞。 

注意:到目前为止,业界并不存在最终一致的NoSQL内存数据库产品,所以只有选项1是可以实际应用的方案。

三、数据的耐久性(Durability)


尽管NoSQL内存数据库解决方案提供了多种复制选择,你还是需要着重考虑数据的持久化和备份,原因如下:

(1) 或许你不想为内存复制支付额外的费用,但是仍希望将数据集保存在某个地方,以便在遇到节点故障时能够将数据恢复(即使恢复速度很慢)。
(2) 你肯定希望在遇到任何故障时(比如节点故障、多节点故障、数据中心故障等)都能将数据恢复并且希望保留另外一个选择——将数据保存在另外一个安全的地方,即使数据不能与最新的修改同步。
(3) 还有其他一些采用数据持久化的理由,比如导入产品数据集到阶段环境,以便于测试。

现在你已经确信数据持久化是必要的,在大多数云环境中你应当使用附属在云主机上的存储设备(像AWS的EBS、Azure的Cloud Derive等)。如果你将数据保存在本地硬盘,当遇到节点故障时你就会丢失数据。

一旦数据得到持久化保存,你最大的挑战将变成:在更新数据持久化存储的同时保证NoSQL内存数据库的速度。 

四、稳定的性能


NoSQL内存数据库(例如Redis或Memcached)的设计目标是:在毫秒延迟内,每秒钟能够处理超过10万个请求。但是,这个数字在云环境下是很难达到的,除非你遵循以下原则:

1、确保你的解决方案使用的是功能强大的云主机(Cloud Instance),比如AWS的 m2.2xlarge/m2.4xlarge云主机或者是Azure的A6/A7云主机,而且还有一个专用环境。

另外,可以实现一种预防跨不同云账户的“吵闹的邻居”现象的机制。此机制应该能监控你的数据集的性能,可实时监控、按命令监控、基于一定的规则去监控、或根据一套机制去监控,比如当发现延迟超过阈值就自动迁移数据集到另一个节点。

2、避免存储的I/O瓶颈,确保解决方案使用了功能强大的存储设备,最好是配置了RAID。其次,要确保在“请求数突然暴增”的情况下也不会阻塞你的应用。例如,使用开源Redis方案,你可以配置slave节点执行持久化存储操作;master节点专注于处理用户请求,在“请求数突然暴增”的情况下避免超时现象。

3、测试云厂商提供的各种关于存储I/O优化的建议,例如AWS的PIOPS。大多数情况下,这些建议对随机访问(读或写)来说很有用;但是,对于NoSQL内存数据库经常采用的像顺序写之类的情况来说就没什么优化价值。
AWS的PIOPS

4、 如果内存数据库基于单线程架构(例如Redis),要确保不要在同一个线程中运行多个数据库。不然,某个数据库在执行命令的过程中很有可能会阻塞另外一个数据库。 
 

五、网速


大多数云主机都配置了一块千兆(1Gbps)网卡。在NoSQL内存数据库上下文中,此千兆网卡需要处理:

1、应用程序的请求
2、集群内部的通信
3、复制
4、存储访问

这很容易造成运行瓶颈。因此,下面提供一些建议可解决此问题:

(1) 为每一台云主机配置万兆网卡(10Gbps,但是要有心理准备,它非常昂贵)
(2) 选择能够为一些特殊应用在VPC内部配置多块千兆网卡的云服务商,例如AWS
(3) 采用能够在NoSQL内存数据库节点之间高效分配资源的解决方案以便让网络阻塞最小 

六、可扩展性(Scalability)


对于简单的键值(Key / Value)缓存解决方案(例如Memcached或者Redis的简单应用),其扩展不会被认为是严重问题;因为在大多数情况下,它只需在服务器列表中增加或删除节点并修改哈希函数。但是,对于实际遭遇过此问题的人就会意识到它仍然是一个令人痛苦的问题。

对于此问题我们有一些建议:

1、采用一致性哈希(Hashing)。
用简单的哈希函数(例如求模)做扩展时,意味着遇到扩展事件会丢失所有的键数据。另一方面,很多人不知道的是:即使采用一致性哈希函数,在扩展的时候你仍然会丢失部分数据。例如,在扩展的时候你会丢失1/N的键数据,N是你扩展后的节点数目。所以,如果N比较小,它就是一个很痛苦的过程(比如对2个节点的集群采用一致性哈希函数进行扩展,就意味着会丢失1/3的数据)。

2、建立一种机制,用扩展事件同步所有的NoSQL内存数据库的客户端,以预防这样的事件发生——在扩展过程中不同的应用服务器写入到不同的节点。
当进行某些复杂操作时,例如Redis的UNION和INTERSECT操作,扩展就会成为非常实际的问题。这些命令等同于SQL中的JOIN命令,在多线程架构下,如果不增加一定的延迟和复杂性,这些操作就不能实现。应用程序级的分片(Sharding)能够解决一定的问题,因为它允许在分片级运行一些复杂命令。但是,这需要很复杂的设计,并且与NoSQL内存数据库的配置有一定的关联。比如,分片的应用必须注意节点上存储的每一个主键;扩展事件(如重分片)需要修改大量代码和额外的执行开销。

另外,一些人声称,新一代的超高速RAM,比如亚马逊AWS的HIgh Memory Cluster Eight Extra Large 244GB内存(cr1.8xlarge),能够解决节点扩展中遇到的大多数问题。
但现实是有所不同的,对于25GB-30GB数据集规模,对于像Redis之类的内存数据库,还有一些其他的操作问题会阻止扩展的执行。这些问题与本文前面提到的挑战密切相关,像复制、存储I/O、单核的单线程架构限制、网络带宽开销等。

七、巨大的运维开销


NoSQL内存数据库在处理所有的操作方面会产生巨大的额外开销。你需要对这些技术进行深入了解,以便在紧要关头能做出正确的决策。同时,因为这些技术更新频率很快(可能是非常快),你还要时刻关注这些系统的趋势和最新变化。

八、结论


正如我们上面所说的一样,为了更好的利用Redis、Memcached等开源技术带给我们的优势,我们需要对这些技术进行深入了解和掌握。对于企业IT团队来说,为了能够在企业环境中使用NoSQL内存数据库,了解如何更好的应对这些挑战就显得尤为重要。不是我持有偏见,我强烈建议寻找一些能够攻克可扩展性和高可用性限制而不损害功能和性能的商业解决方案;因为执行这些内部操作需要该领域的高级专家,而这是非常稀少的。

在市场上有一些关于Redis和Memcached的NoSQL服务(NoSQL-as-a-service);我建议你对每一个可用的服务进行深入的比对(就像DIY),以便挑选一个最佳的解决方案。能够实际体验一下这些服务就更好了,很多服务商为这个目的都提供了免费体验。 
相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
相关文章
|
3天前
|
存储 开发工具 Android开发
构建高效的Android应用:从内存管理到用户界面
【5月更文挑战第29天】 随着智能手机的普及,Android应用的开发变得日益重要。然而,许多开发者在开发过程中忽视了性能优化,导致应用运行缓慢,用户体验差。本文将深入探讨如何通过有效的内存管理和用户界面优化,提升Android应用的性能。我们将详细介绍内存泄漏的原因和解决方案,以及如何使用Android的新特性来创建流畅的用户界面。无论你是新手还是经验丰富的开发者,都可以从本文中获得有用的技巧和建议。
|
3天前
|
存储 算法 C语言
C语言指针与二维数组在函数参数传递和动态内存管理中的应用
C语言指针与二维数组在函数参数传递和动态内存管理中的应用
12 0
|
3天前
|
NoSQL MongoDB 数据库
使用MongoDB进行NoSQL数据库管理
【5月更文挑战第29天】MongoDB是流行的NoSQL数据库,以其文档存储、动态模式、高性能和丰富查询功能著称。它采用BSON格式,支持灵活的数据结构。基本操作包括安装、连接、创建数据库和集合、插入/查询/更新/删除文档。最佳实践涉及合理设计数据模型、使用索引、监控调优、备份恢复及确保安全性。MongoDB为复杂应用提供了高效的数据管理解决方案。
|
3天前
|
移动开发 安全 Android开发
构建高效Android应用:采用Kotlin进行内存优化
【5月更文挑战第29天】 在移动开发领域,性能优化一直是开发者关注的焦点。特别是对于Android应用而言,内存管理是影响应用性能和用户体验的关键因素之一。近年来,Kotlin作为官方推荐的开发语言,以其简洁的语法和强大的功能受到广大开发者的青睐。本文将深入探讨如何通过Kotlin语言的特性来优化Android应用的内存使用,从而提升应用的性能表现。我们将从内存泄露检测、对象创建与销毁策略,以及数据结构的合理选择等方面入手,为读者提供一系列实用的优化建议。
|
3天前
|
JSON 数据管理 测试技术
自动化测试工具Selenium Grid的深度应用分析深入理解操作系统的内存管理
【5月更文挑战第28天】随着互联网技术的飞速发展,软件测试工作日益复杂化,传统的手工测试已无法满足快速迭代的需求。自动化测试工具Selenium Grid因其分布式执行特性而受到广泛关注。本文旨在深入剖析Selenium Grid的工作原理、配置方法及其在复杂测试场景中的应用优势,为测试工程师提供高效测试解决方案的参考。
|
3天前
|
机器学习/深度学习 传感器 自动驾驶
基于深度学习的图像识别技术在自动驾驶系统中的应用深入理解操作系统内存管理:原理与实践
【5月更文挑战第28天】 随着人工智能技术的飞速发展,图像识别作为其重要分支之一,在多个领域展现出了广泛的应用潜力。尤其是在自动驾驶系统中,基于深度学习的图像识别技术已成为实现车辆环境感知和决策的关键。本文将深入探讨深度学习算法在自动驾驶图像识别中的作用,分析其面临的挑战以及未来的发展趋势,并以此为基础,展望该技术对自动驾驶安全性和效率的影响。
|
3天前
|
移动开发 监控 Android开发
构建高效Android应用:从内存优化到电池寿命代码之美:从功能实现到艺术创作
【5月更文挑战第28天】 在移动开发领域,特别是针对Android系统,性能优化始终是关键议题之一。本文深入探讨了如何通过细致的内存管理和电池使用策略,提升Android应用的运行效率和用户体验。文章不仅涵盖了现代Android设备上常见的内存泄漏问题,还提出了有效的解决方案,包括代码级优化和使用工具进行诊断。同时,文中也详细阐述了如何通过减少不必要的后台服务、合理管理设备唤醒锁以及优化网络调用等手段延长应用的电池续航时间。这些方法和技术旨在帮助开发者构建更加健壮、高效的Android应用程序。
|
4天前
|
监控 Android开发 UED
构建高效的Android应用:从内存管理到用户体验
【5月更文挑战第28天】 在移动开发的世界中,打造一个既快速又高效的Android应用是每个开发者追求的目标。本文将深入探讨如何通过合理的内存管理策略、优化的代码实践和用户界面设计的提升来增强应用性能。我们将剖析内存泄漏的根源,提供解决方案,探索Kotlin与Java在性能上的差异,并分析如何利用Android系统提供的工具监控和改善应用表现。此外,我们还将讨论Material Design的应用以及其对用户体验的影响。通过这些技术的综合运用,你将能够为用户提供更流畅、响应更快的使用体验。
|
4天前
|
监控 安全 网络安全
网络安全与信息安全:防护之道与加密技术构建高效Android应用:从基础到高级的内存优化策略
【5月更文挑战第27天】在数字化时代,数据成为了新的货币。然而,随着信息技术的蓬勃发展,网络安全漏洞和信息泄露事件层出不穷,对个人隐私和企业安全构成了严重威胁。本文将深入探讨网络安全的重要性,分析当前常见的网络攻击方式,并重点分享关于加密技术和提升安全意识的知识。通过阅读本文,读者将获得如何有效防御网络威胁、保护个人和企业信息安全的策略。
|
4天前
|
存储 缓存 算法
深入理解操作系统内存管理:分页系统的优势与挑战构建高效Android应用:探究Kotlin协程的优势与实践
【5月更文挑战第27天】 在现代计算机系统中,内存管理是操作系统的核心功能之一。分页系统作为一种内存管理技术,通过将物理内存划分为固定大小的单元——页面,为每个运行的程序提供独立的虚拟地址空间。这种机制不仅提高了内存的使用效率,还为多任务环境提供了必要的隔离性。然而,分页系统的实现也带来了一系列的挑战,包括页面置换算法的选择、内存抖动问题以及TLB(Translation Lookaside Buffer)的管理等。本文旨在探讨分页系统的原理、优势及其面临的挑战,并通过分析现有解决方案,提出可能的改进措施。