本文选自 HighScalability上的一篇博客文章,作者系 Tokutek公司(Tokutek能够提升MongoDB, MySQL以及MariaDB的性能20倍)的一位工程师,该公司研究的主要方向是存储引擎。CSDN编译整理如下:
作为一名软件开发者,我们非常看重那些抽象化的东西。API越简单,对我们越有吸引力。辩证地讲,MongoDB最大的优势就是“优雅”的API和它的敏捷性,这让开发者的编码过程变得异常的简单。
但是,当MongoDB涉及到大数据可扩展性问题时,开发者还是需要了解一下它的底层,弄明白那些潜在的问题,然后才能快速地进行解决。如果不理解,最终可能会选择一个低效的解决方案,而且浪费了时间和金钱。本文重点介绍了,如何为大数据的扩展性问题找个一个高效的解决方案。
定义问题
首先,我们要确定应用的上下文,本文主要讨论的是MongoDB的应用程序。这意味着,我们将研究一个分布式文档存储数据库,而且它还支持二级索引和分片集群。如果是针对其他的NoSQL产品,像Riak或者Cassandra,我们可能会讨论I/O瓶颈问题,而本文主要关注MongoDB的一些特性。
其次,这些应用能够做什么?是做联机事务处理( OLTP)还是做联机分析处理( OLAP)?本文主要讨论的是OLTP,因为对MongoDB而言,OLAP还是一个不小的挑战,或者说基本不能够进行处理。
第三,大数据是什么?通过大数据,我们能够处理和使用更多的数据,不再局限于单机RAM中的那些部分。这样的话,有些数据保留在服务器上,而更多的数据则是存放在磁盘中,这就需要I/O的访问。但是请注意,我们不是在讨论数据库够不够大,而是关注那些经常被存取和使用的数据(有时称之为“工作集”)是不是很小。比如说,磁盘上虽然存储了好几年的数据,但是应用可能经常访问的只有最后一天的数据。
第四,OLTP应用的限制性因素有哪些?简而言之,就是I/O。硬盘驱动每秒钟只可以启动上百次的I/O,而另一方面,RAM每秒可以实现数百万次的存取,这个限制性因素就是导致大数据应用I/O瓶颈的原因所在。
最后,我们应该如何解决I/O瓶颈?通过分析思维,公式和直接指令给我们提供了很多种方式,但是一个持久性的解决方案就需要“理解”。用户必须着眼于应用程序的I/O特性,然后才能做出最好的设计决策。
开销模型
未来解决I/O瓶颈,第一步需要掌握哪些数据库操作会包括I/O。 无论MongoDB,还是其他的数据库类型,都有三种基本的操作:
Point Query:查找一个独立的文件。在一个给定的位置的文件夹(磁盘或者内存上),检索该文档。对于大数据来说,该文件可能不在内存中。此操作可能会导致一次I/O。
Range Query:在索引中,查找大量的连续性文件,对比Point Query而言,它是一个更高效的查询操作。这是因为我们查找的这些数据都是打包存放在磁盘上,可以通过极少的I/O操作来直接读入内存。Range Query一般检索100个文件才会启动一次I/O,相对比,100个Point Query检索100个文件可能就需要100次I/O操作。
Write:写文件到数据库中。类似MongoDB这样的数据库,都会产生I/O。而对那些“写优化”数据结构的数据库而言,比如 TokuMX,仅仅需要很少的I/O。不像MongDB,“写优化”的数据结构能够通过执行多次插入来分摊I/O。
在了解三个基本操作对I/O的影响之后,还需要理解MongoDB数据库语句对I/O的影响。MongoDB包含了这三个基本操作,同时还构建了四个用户级别的操作:
- 插入:将一个新文件写到数据库中。
- 查询:在集合上使用索引,这样做一个Range Queries和Point Query的整合。如果该索引是一个覆盖索引或者是集群索引,那么接下来基本上只需要做范围查询。否则的话,整合的范围查询和点查询就会被启用。
- 修改和删除:这是一个查询和写操作的整合。查询操作用于发现那些需要更新和删除的文件,然后写操作再对这些文件进行修改或者是删除。
现在,我们理解了开销模型。不过为了解决I/O的瓶颈问题,用户还需要知道哪些应用启动了I/O操作。这就需要我们了解数据库的行为。I/O启动是源于查询操作吗?如果是这样的话,查询行为是如何影响I/O的?还是源于修改操作?如果是因为修改导致的影响,那么是因为修改过程中的查询操作还是插入操作?一旦用户掌握了哪些因素会影响 I/O,接下来就可以逐步来解决瓶颈的问题了。
假设我们明白了某个应用的I/O特性,我们就可以探讨几种途径来解决这一问题。我最喜欢的方式是这样的:首先尝试使用软件来解决该问题,如果不能完美的解决,那么再考虑硬件。毕竟软件的成本更低且易于维护。
可行的软件解决方案
一个可行的软件解决方案,就是需要减少软件或者应用的I/O启动次数。针对不同的瓶颈,下面列举了对应可行的解决方案:
问题:插入操作导致过多的I/O
可行方案:使用一个写优化的数据库,比如说TokuMX,使用TokuMX的一项优势就是它能够大幅度减少对写操作的I/O请求,而索引方式使用的是Fractal Trees( TokuDB实际上还对Fractal Trees做了改进,将插入的IO数量级从log(N)提高到了logB(N))
问题:查询操作导致过多的I/O
可行方案:使用一个更好的索引,减少点查询,尽量使用范围查询替代。在我看来,还是需要“理解索引”。我解释了索引能够减少查询操作的I/O请求。当然这不是用一两段话就可以说得清的,但是要点如下:减少应用的I/O请求首先要避免独立的点查询来检索每个文件夹,为了实现这点,我们要使用覆盖或者集群索引,这样可以智能地过滤掉在查询过程中已经分析过的文件,然后再使用范围查询报告结果。
诚然,一个好的索引方式还不足够,如果是一个OLTP应用,那么所有的查询从本质上讲都是点查询(因为他们只是检索极少的文件),即使使用一个完全适合的索引,用户还是会出现I/O的瓶颈问题。在这种情况下,硬件的解决方案就是必要的。
当然,增加索引也意味着增加插入的成本,因为每个插入操作都要保证索引的及时更新,但是写优化的数据库可以减少一定的成本。这也是我一直强调我们需要理解应用的原因所在,对于某些应用来说,一个可行的解决方案,并不代表也适用于其他的应用。
问题:修改或者删除导致过多的I/O
解决方案:整合以上所有的解决方案
修改和删除之所以复杂是因为这是查询和插入的一个整合。提升它们的性能要求对操作开销有一个很好的理解。哪部分操作会涉及到I/O?是查询?如果这样,我们就提升索引。是写操作?还是兼而有之?简单来讲,就是哪部分操作牵涉到I/O问题,我们就应用对应的解决方案。
一个很常见的错误就是:当我们使用一个写优化的数据库(像TokuMX),在不改变任何索引的情况下,就希望它能够消除修改或者删除的I/O瓶颈问题。毕竟,写优化的数据库还是不足够的,在修改/删除过程中的隐含的查询也必须进行处理。
可行的硬件解决方案
就像上文提到的那样,当软件解决方案不能够解决问题的时候,我们就需要寻求硬件的解决方案。我们先分析一下硬件的优势和劣势:
- 购买尽可能多的内存,即使难以做到,也要把工作集放到内存中
- 使用SSD来增加IOPS
- 购买更多的服务器,并使用一个可扩展的解决方案,其中包括
- 通过副本进行读扩展
- 分片
购买更多的内存
RAM是很昂贵的,而且在一台机器上可扩展的内存也是有限的。如果数据太大,都保存在RAM中也不是一个可行的选择。这种解决方案可能适于用大多数的应用,但我们更关注那些这种方案解决不了的应用。
使用SSD存储
不可否认,如果存储设备使用SSD提升吞吐量,这绝对是一个很实用的解决方案。如果I/O成为应用的限制性因素,那么增加IOPS(每秒的I/O操作)理所当然地能够增加吞吐量,简单且使用。
然而,SSD的成本和硬盘的成本也不一样,SSD绝对可以显著地提升I/O的吞吐量,虽然成本也不便宜,但是更轻、容量更大,速率也更快。那么为了降低成本,数据压缩就是一个关键。 其实,虽然硬件成本增加了,但这并不意味着管理成本也会增加:
通过副本进行读扩展
当查询操作成为应用的瓶颈,那么通过副本进行读扩展就是一个非常有效的解决方案。想法如下:
- 使用备份功能,将多个数据拷贝到相互独立的机器上
- 分布地在不同的机器上进行读取,这样将会提升读的吞吐量
如果是插入、修改或者是删除过程存在瓶颈,那么副本可能就不会那么的高效。这是因为写操作需要将数据备份到所有的服务器的副本集上,机器在数据的输入过程中也面临同样的瓶颈问题。
分片
基于shard key,分片片将数据切分到不同的副本集,集群中不同副本集负责相应范围的值。所以,可以通过将写操作分配给集群中不同的副本集来提升应用程序的写吞吐量。对于写负载高的应用,分片可以非常有效的。
在shard key空间中将数据按范围划分,使用shard key横跨多个副本做范围查询可以非常有效。如果将shard key哈希,那么所有范围查询必须运行在集群中的所有分片,但是在shard key上的点查询只运行在一个分片上。shard key哈希,据结构模型并且不支持join,分片用起来非常的高效且简单。如果上述的方案都不足以解决应用的瓶颈问,那么你可以在分片上多下工夫了。
无论如何,分片都是一个重量级的解决方案,而且成本非常之高。对初入者来说,你的硬件投入预算需要增加好几倍。不仅仅需要为分片设置增加服务器,还需要增加一整套副本集。你还需要增加和管理配置服务器,考虑到成本问题,用户需要慎重考虑分片是不是很必要。通常来讲,上面所有方案都比这个节省成本。
另外一个很大的挑战就是选择一个shard key,一个好的shard key有以下特点:
- 大多数(如果不是全部)的查询都使用shard key,任何查询(没有使用shard key)必须运行在所有的分片上。这点可能比较麻烦。
- shard key应该非常有利于集群不同副本及上的分布写操作,如果所有的写操作都对应到集群上同一个副本集,那么该副本集对于写操作来讲,就会成为一个瓶颈,就好像处在一个非分片的设置中,这样的话,这种情况糟糕到就像使用时间戳作为shard key。
这些要求并不是很容易实现。有时,一个好的shard key并不存在,这让分片变得极不高效。
总结
很多解决方案都行得通,但是没有一个能百分百得到保障的,甚至包括分片。这也是作者强调的:理解应用的特性是至关重要的。工具可以解决问题,但是如何更好地使用工具,这就取决于用户了。(文/王鹏,审校/仲浩)
背景资料:
TokuDB是一个高性能、支持事务处理的MySQL和MariaDB的存储引擎。TokuDB的主要特点则是对高写压力的支持。在今年4月份,TokuDB v7发布了,项目托管在GitHub上,宣布开源。TokuDB V7主要特点有:快速Trickle负载,快速批量负载,快速通过聚集索引范围查询,无碎片化,完全兼容MySQL/ MariaDB,易于安装。(信息源于 CSDN)
相关推荐
这可能涉及到扩展网络带宽、增加并发连接数、优化数据库查询效率等方面。 总结来说,优化输入输出是通过多种技术和策略来提升系统处理数据的速度和能力,这不仅关乎硬件升级,也包括软件层面的改进,如使用高效的...
### 数据库I/O系统知识点详解 #### 一、存储设备与磁盘存储技术 数据库I/O系统的性能在很大程度上取决于其存储设备的选择和技术的应用。在本章节中,我们将重点介绍几种常见的存储设备及其特点。 **1.1 存储层次*...
在优化数据库磁盘IO时,需要监控数据库的性能,检查系统的I/O问题,使用V$FILESTAT确定oracle文件I/O的进程,分布I/O减少磁盘竞争,避免动态空间管理,确定动态扩展,分配分区,避免回滚段的动态空间管理,减少迁移...
Oracle数据库系统中输入输出(I/O)的设计和分析是确保数据库性能和响应速度的关键。本文将从I/O需求、数据文件I/O性能、I/O优化策略以及如何调整数据文件I/O等方面进行深入探讨。 首先,我们需要了解I/O设计在...
Mellanox 横向扩展数据库解决方案 Mellanox 横向扩展数据库解决方案是基于 Mellanox 56Gb/s InfiniBand 适配器和交换机的数据库服务器集群,通过统一的连接(可容错)与存储互连,可以实现超高的 CPU 效率和存储...
磁盘I/O是数据库性能的关键因素。优化磁盘I/O可以通过以下方式实现: 1. **检查系统的I/O问题**:通过监控I/O等待事件,识别是否存在高I/O延迟或争用。 2. **使用分布I/O**:通过RAID配置、I/O子系统优化和多路径I/O...
数据库的扩展能力提升,特别是对于非结构化数据处理中的I/O吞吐能力,成为了数据库技术研究中的核心问题。 Sharding碎片技术是一种水平扩展方案,主要用于解决单节点数据库服务器在I/O上的扩展瓶颈。它通过分散同一...
本篇将详细探讨如何在不同的操作系统环境下扩展Oracle数据库的内存,包括HP-UX、AIX 5、AIX 6以及Windows和SuseLinux等。 首先,内存扩展对于Oracle数据库至关重要,因为内存是数据库执行查询、缓存数据和执行其他...
由于省去了操作系统层,读写速度显著提升,特别适用于高I/O负载的数据库应用。在某些情况下,使用裸分区可提升超过30%的性能。然而,这也意味着失去了操作系统提供的缓存和故障防护功能,因此需要更谨慎地管理和监控...
本文将深入探讨Oracle数据库性能优化的多个关键方面,包括监控数据库性能、优化磁盘I/O、回滚段管理以及RED日志的优化。 首先,**监控数据库性能**是性能优化的基础。通过收集和分析数据库的运行数据,可以发现性能...
磁盘I/O效率直接影响到Oracle数据库的性能。为了提高磁盘I/O效率,可以从以下几个方面入手: 1. **使用分布I/O减少磁盘竞争** - 将数据文件和重做日志文件(Redo Log Files)放置在不同的物理磁盘上,以分散I/O...
4. 配置优化:合理调整MySQL服务器的配置参数,如内存分配、I/O调度策略、网络设置等,可以提高数据库的处理性能和稳定性。 此外,在进行高性能可扩展数据库架构优化时,还需要注意数据库的高可用性和灾难恢复能力...
本文将详细介绍一种全面的Oracle数据库优化方案,涵盖监控、磁盘I/O优化、回滚段优化、Redo日志优化、系统全局区(SGA)优化等多个方面。 #### 二、监控数据库性能 监控是优化的基础。为了准确了解Oracle数据库的...
总结一下,I/O完成端口模式是Windows系统中一种强大的多线程I/O管理机制,通过`CreateIoCompletionPort`、`AddToCompletionPort`(可能的用法)和`GetQueuedCompletionStatus`等API,能够高效地处理大量并发的异步I/...
数据库优化是提升系统性能的关键环节,旨在避免磁盘I/O瓶颈、减少CPU利用率和降低资源竞争。本文将深入探讨基于第三范式的基本表设计、扩展设计以及数据库表对象放置等方面,旨在为实际开发提供指导。 **一、基于第...
数据库性能的评价指标主要包括响应时间、命中率、吞吐量、内存使用情况以及磁盘I/O量。 1. **系统吞吐量**:衡量数据库在单位时间内处理SQL语句的能力,高吞吐量意味着系统资源得到有效利用。通过优化SQL执行时间和...
1. 性能监控:定期检查数据库性能指标,如CPU利用率、内存使用、I/O等待等。 2. 调优工具:利用数据库自带的工具或第三方工具进行性能分析和调优。 九、云数据库选择 1. 云服务提供商:考虑AWS的RDS、Azure的SQL ...
**IOCP(I/O完成端口)是Windows操作系统中一种高效处理I/O操作的机制,尤其适用于高并发的网络服务器。本篇文章将深入探讨IOCP的创建及其在入门级学习中的重要性。** 首先,我们需要了解IOCP的基本概念。IOCP,即I...
本文将深入探讨Oracle数据库性能优化的策略与实践,涵盖数据库磁盘I/O优化、回滚段优化、Redo日志优化、系统全局区(SGA)调整以及数据库对象优化等关键领域。 #### 数据库磁盘I/O优化 磁盘I/O效率直接影响数据库...
它通过集中处理来自多个套接字的I/O请求,提供了高并发、非阻塞的I/O模型,尤其适用于服务器应用,如网络服务器、数据库服务器等。IOCP的原理是将I/O操作从线程执行转移到内核,当I/O操作完成后,系统会将结果放入一...