由NoSQL数据建模错误导致的性能问题
引言
您可能没有注意到,数据建模错误往往是导致系统性能出现问题的根本原因之一。人们往往简单地认为,只需根据应用的访问模式,对NoSQL 数据建模即可。事实上,在真正处理对于性能极其敏感的工作负载时,应用就很容易出现性能瓶颈。
未处理大分区
在您的开发团队着手扩展分布式数据库时,大分区通常会随之出现。此处的大分区是指:那些可能会在整个集群的副本中,产生性能问题的过大分区。
具体而言,它往往取决于:
- 分区键的选择
- 聚类键的数量
- 工作负载模式
鉴于上述方面,下表展示了大分区在不同载荷大小(如 1、2 和 4KB)下的影响。
行数 | 载荷大小 | 分区大小 |
---|---|---|
10000 | 1KB | 10MB |
10000 | 2KB | 20MB |
10000 | 4KB | 40MB |
可以看出,在相同行数的情况下,负载越高,分区就越大。不过,如果您的应用需要经常扫描整体分区的话,那么请注意对数据库予以限制,以防止内存被无限制地消耗。
例如,ScyllaDB 在每隔 1MB 就会切分开不同页面。这正是为了防止系统内存的耗尽。其他数据库(甚至是关系型数据库)也有类似的保护机制,以防止无限制的查询,导致数据库资源的枯竭。
若要使用 ScyllaDB 检索大小为 4KB 和 1 万行数的负载,您需要检索至少 40 页,才能通过单次查询扫描完整个分区。起初,这似乎不是什么大问题。但是,随着时间的推移,客户端的整体延迟会逐渐受到影响。
另一个值得考虑的因素是:在 ScyllaDB 和 Cassandra 等数据库中,写入数据库的数据往往会被存储在提交日志(commitlog)和名为 memtable 的内存数据结构中。
如上图所示,提交日志是一个提前写入的日志,除非服务器崩溃或服务中断,否则它不会被真正地读取到。由于 memtable 存在于内存中,因此最终它会被填满。因此,为了释放内存空间,数据库会将内存表刷到磁盘上。这一过程会产生排序字符串表(SortedStringsTables,SSTables),这就是数据被持久化的过程。
那么这些又与大分区有何关系呢?实际上,SSTables 有着一些需要在数据库启动时,保存在内存中的特定组件。它们可以确保读取效率,并在查找数据时尽量减少存储磁盘 I/O 的浪费。
因此,当您拥有超大分区时(例如,2.5Terabyte 的分区),这些 SSTable 组件就需要减少沉重的内存压力,从而缩小数据库的缓存空间,进一步限制延迟。
如何解决大分区问题?
具体而言,我们该如何通过数据建模,来解决大分区问题呢?通常,我们可以从主键入手。毕竟主键决定了数据在集群中的分布方式,可以被用来提高性能和资源利用率。
如您所知,一个好的分区键应该具有基数性(Cardinality)且能够大致均匀地分布。例如,UserName、UserID 或 SensorID 等基数性较高的属性,都可能是很好的分区键。而像 State(州)这样的属性则不太合适,毕竟像加利福尼亚州和德克萨斯州这样的州,可能会比怀俄明州和佛蒙特州之类人口较少的州,拥有更多的数据。
让我们来看一个例子。下表可被用于带有多个传感器的分布式空气质量监测系统:
CREATETABLE r_quality_data(
sensor_id text,
time timestamp,
co_ppm int,
PRIMARY KEY (sensor_id, time)
);
由于 time 是该表格的聚类键(clustering key),因此不难想象,每个传感器的分区可能会变得非常大,尤其是在每几毫秒就收集一次数据的情况下。长此以往,这个看似无害的表最终会变得大到无法使用。而在本例中,我们只需要约 50 天。
一个标准的解决方案是修改数据模型,以减少每个分区键的聚类键数量。下面,让我们来看看更新后的模式:
CREATETABLE r_quality_data(
sensor_id text,
location text,
time timestamp,
co_ppm int,
PRIMARY KEY ((sensor_id, location), time)
);
未处理热点数据
热点数据是指经常被访问的特定数据点。在 NoSQL 数据建模中,未处理热点数据可能会对性能产生重大影响。
这可以通过两个方面来解释:
- 缓存效率低下:热点数据可能会使缓存效率低下,因为它会不断地驱逐其他数据点。
- 资源争用:热点数据会造成资源争用,因为它会使多个线程和进程同时访问同一个数据点。
为了解决热点数据问题,可以使用以下技术:
- 分区:通过将热点数据分布在多个分区中,可以减少对单个分区的压力。
- 复制:通过在多个节点上复制热点数据,可以确保即使一个节点发生故障,数据仍然可用。
- 缓存:通过将热点数据缓存到本地内存,可以减少对数据库的访问。
未考虑数据局部性
数据局部性是指将相关数据存储在同一位置的原则。在 NoSQL 数据建模中,未考虑数据局部性会导致频繁的跨分区访问,从而降低性能。
为了解决未考虑数据局部性问题,可以使用以下技术:
- 数据建模:通过将相关数据存储在同一分区中,可以提高数据局部性。
- 查询优化:通过优化查询以访问同一分区中的数据,可以提高性能。
- 数据分区:通过将数据分区到不同的节点上,可以减少跨分区访问。
结论
通过避免或解决这些常见的数据建模错误,您可以显著提高 NoSQL 数据库的性能。通过遵循这些最佳实践,您可以确保您的应用在扩展到更大的工作负载时,能够保持最佳性能。
nosql数据库是什么 具有代表性以key-value的形式存储的
什么是NoSQL大家有没有听说过“NoSQL”呢?近年,这个词极受关注。 看到“NoSQL”这个词,大家可能会误以为是“No!SQL”的缩写,并深感愤怒:“SQL怎么会没有必要了呢?”但实际上,它是“Not Only SQL”的缩写。 它的意义是:适用关系型数据库的时候就使用关系型数据库,不适用的时候也没有必要非使用关系型数据库不可,可以考虑使用更加合适的数据存储。 为弥补关系型数据库的不足,各种各样的NoSQL数据库应运而生。 为了更好地了解本书所介绍的NoSQL数据库,对关系型数据库的理解是必不可少的。 那么,就让我们先来看一看关系型数据库的历史、分类和特征吧。 关系型数据库简史1969年,埃德加?6?1弗兰克?6?1科德(Edgar Frank Codd)发表了划时代的论文,首次提出了关系数据模型的概念。 但可惜的是,刊登论文的《IBM Research Report》只是IBM公司的内部刊物,因此论文反响平平。 1970年,他再次在刊物《Communication of the ACM》上发表了题为“A Relational Model of Data for Large Shared Data banks”(大型共享数据库的关系模型)的论文,终于引起了大家的关注。 科德所提出的关系数据模型的概念成为了现今关系型数据库的基础。 当时的关系型数据库由于硬件性能低劣、处理速度过慢而迟迟没有得到实际应用。 但之后随着硬件性能的提升,加之使用简单、性能优越等优点,关系型数据库得到了广泛的应用。 通用性及高性能虽然本书是讲解NoSQL数据库的,但有一个重要的大前提,请大家一定不要误解。 这个大前提就是“关系型数据库的性能绝对不低,它具有非常好的通用性和非常高的性能”。 毫无疑问,对于绝大多数的应用来说它都是最有效的解决方案。 突出的优势关系型数据库作为应用广泛的通用型数据库,它的突出优势主要有以下几点:保持数据的一致性(事务处理)由于以标准化为前提,数据更新的开销很小(相同的字段基本上都只有一处)可以进行JOIN等复杂查询存在很多实际成果和专业技术信息(成熟的技术)这其中,能够保持数据的一致性是关系型数据库的最大优势。 在需要严格保证数据一致性和处理完整性的情况下,用关系型数据库是肯定没有错的。 但是有些情况不需要JOIN,对上述关系型数据库的优点也没有什么特别需要,这时似乎也就没有必要拘泥于关系型数据库了。 关系型数据库的不足不擅长的处理就像之前提到的那样,关系型数据库的性能非常高。 但是它毕竟是一个通用型的数据库,并不能完全适应所有的用途。 具体来说它并不擅长以下处理:大量数据的写入处理为有数据更新的表做索引或表结构(schema)变更字段不固定时应用对简单查询需要快速返回结果的处理。 。 。 。 。 。 NoSQL数据库为了弥补关系型数据库的不足(特别是最近几年),NoSQL数据库出现了。 关系型数据库应用广泛,能进行事务处理和JOIN等复杂处理。 相对地,NoSQL数据库只应用在特定领域,基本上不进行复杂的处理,但它恰恰弥补了之前所列举的关系型数据库的不足之处。 易于数据的分散如前所述,关系型数据库并不擅长大量数据的写入处理。 原本关系型数据库就是以JOIN为前提的,就是说,各个数据之间存在关联是关系型数据库得名的主要原因。 为了进行JOIN处理,关系型数据库不得不把数据存储在同一个服务器内,这不利于数据的分散。 相反,NoSQL数据库原本就不支持JOIN处理,各个数据都是独立设计的,很容易把数据分散到多个服务器上。 由于数据被分散到了多个服务器上,减少了每个服务器上的数据量,即使要进行大量数据的写入操作,处理起来也更加容易。 同理,数据的读入操作当然也同样容易。 提升性能和增大规模下面说一点题外话,如果想要使服务器能够轻松地处理更大量的数据,那么只有两个选择:一是提升性能,二是增大规模。 下面我们来整理一下这两者的不同。 首先,提升性能指的就是通过提升现行服务器自身的性能来提高处理能力。 这是非常简单的方法,程序方面也不需要进行变更,但需要一些费用。 若要购买性能翻倍的服务器,需要花费的资金往往不只是原来的2倍,可能需要多达5到10倍。 这种方法虽然简单,但是成本较高。 另一方面,增大规模指的是使用多台廉价的服务器来提高处理能力。 它需要对程序进行变更,但由于使用廉价的服务器,可以控制成本。 另外,以后只要依葫芦画瓢增加廉价服务器的数量就可以了。 不对大量数据进行处理的话就没有使用的必要吗?NoSQL数据库基本上来说为了“使大量数据的写入处理更加容易(让增加服务器数量更容易)”而设计的。 但如果不是对大量数据进行操作的话,NoSQL数据库的应用就没有意义吗?答案是否定的。 的确,它在处理大量数据方面很有优势。 但实际上NoSQL数据库还有各种各样的特点,如果能够恰当地利用这些特点将会是非常有帮助。 具体的例子将会在第2章和第3章进行介绍,这些用途将会让你感受到利用NoSQL的好处。 希望顺畅地对数据进行缓存(Cache)处理希望对数组类型的数据进行高速处理希望进行全部保存多样的NoSQL数据库NoSQL数据库存在着“key-value存储”、“文档型数据库”、“列存储数据库”等各种各样的种类,每种数据库又包含各自的特点。 下一节让我们一起来了解一下NoSQL数据库的种类和特点。 NoSQL数据库是什么NoSQL说起来简单,但实际上到底有多少种呢?我在提笔的时候,到NoSQL的官方网站上确认了一下,竟然已经有122种了。 另外官方网站上也介绍了本书没有涉及到的图形数据库和对象数据库等各个类别。 不知不觉间,原来已经出现了这么多的NoSQL数据库啊。 本节将为大家介绍具有代表性的NoSQL数据库。 key-value存储这是最常见的NoSQL数据库,它的数据是以key-value的形式存储的。 虽然它的处理速度非常快,但是基本上只能通过key的完全一致查询获取数据。 根据数据的保存方式可以分为临时性、永久性和两者兼具三种。 临时性memcached属于这种类型。 所谓临时性就是 “数据有可能丢失”的意思。 memcached把所有数据都保存在内存中,这样保存和读取的速度非常快,但是当memcached停止的时候,数据就不存在了。 由于数据保存在内存中,所以无法操作超出内存容量的数据(旧数据会丢失)。 在内存中保存数据可以进行非常快速的保存和读取处理数据有可能丢失永久性Tokyo Tyrant、Flare、ROMA等属于这种类型。 和临时性相反,所谓永久性就是“数据不会丢失”的意思。 这里的key-value存储不像memcached那样在内存中保存数据,而是把数据保存在硬盘上。 与memcached在内存中处理数据比起来,由于必然要发生对硬盘的IO操作,所以性能上还是有差距的。 但数据不会丢失是它最大的优势。 在硬盘上保存数据可以进行非常快速的保存和读取处理(但无法与memcached相比)数据不会丢失两者兼具Redis属于这种类型。 Redis有些特殊,临时性和永久性兼具,且集合了临时性key-value存储和永久性key-value存储的优点。 Redis首先把数据保存到内存中,在满足特定条件(默认是15分钟一次以上,5分钟内10个以上,1分钟内个以上的key发生变更)的时候将数据写入到硬盘中。 这样既确保了内存中数据的处理速度,又可以通过写入硬盘来保证数据的永久性。 这种类型的数据库特别适合于处理数组类型的数据。 同时在内存和硬盘上保存数据可以进行非常快速的保存和读取处理保存在硬盘上的数据不会消失(可以恢复)适合于处理数组类型的数据面向文档的数据库MongoDB、CouchDB属于这种类型。 它们属于NoSQL数据库,但与key-value存储相异。 不定义表结构面向文档的数据库具有以下特征:即使不定义表结构,也可以像定义了表结构一样使用。 关系型数据库在变更表结构时比较费事,而且为了保持一致性还需修改程序。 然而NoSQL数据库则可省去这些麻烦(通常程序都是正确的),确实是方便快捷。 可以使用复杂的查询条件跟key-value存储不同的是,面向文档的数据库可以通过复杂的查询条件来获取数据。 虽然不具备事务处理和JOIN这些关系型数据库所具有的处理能力,但除此以外的其他处理基本上都能实现。 这是非常容易使用的NoSQL数据库。 不需要定义表结构可以利用复杂的查询条件面向列的数据库Cassandra、Hbase、HyperTable属于这种类型。 由于近年来数据量出现爆发性增长,这种类型的NoSQL数据库尤其引人注目。 面向行的数据库和面向列的数据库普通的关系型数据库都是以行为单位来存储数据的,擅长进行以行为单位的读入处理,比如特定条件数据的获取。 因此,关系型数据库也被称为面向行的数据库。 相反,面向列的数据库是以列为单位来存储数据的,擅长以列为单位读入数据。 高扩展性面向列的数据库具有高扩展性,即使数据增加也不会降低相应的处理速度(特别是写入速度),所以它主要应用于需要处理大量数据的情况。 另外,利用面向列的数据库的优势,把它作为批处理程序的存储器来对大量数据进行更新也是非常有用的。 但由于面向列的数据库跟现行数据库存储的思维方式有很大不同,应用起来十分困难。 高扩展性(特别是写入处理)应用十分困难最近,像Twitter和Facebook这样需要对大量数据进行更新和查询的网络服务不断增加,面向列的数据库的优势对其中一些服务是非常有用的,但是由于这与本书所要介绍的内容关系不大,就不进行详细介绍了。 总结:NoSQL并不是No-SQL,而是指Not Only SQL。 NoSQL的出现是为了弥补SQL数据库因为事务等机制带来的对海量数据、高并发请求的处理的性能上的欠缺。 NoSQL不是为了替代SQL而出现的,它是一种替补方案,而不是解决方案的首选。 绝大多数的NoSQL产品都是基于大内存和高性能随机读写的(比如具有更高性能的固态硬盘阵列),一般的小型企业在选择NoSQL时一定要慎重!不要为了NoSQL而NoSQL,可能会导致花了冤枉钱又耽搁了项目进程。 NoSQL不是万能的,但在大型项目中,你往往需要它!
nosql数据库的五大优势
关系数据库模型已经流行了几十年了,但是一种新类型的数据库——被称为NoSQL,正在引起企业的注意。下面是关于它的优势和劣势的一个概述。二十多年以来,对数据库管理来说,关系数据库(RDBMS)模型一直是一个占统治地位的数据库模型。但是,今天,非关系数据库,“云”数据库,或“NoSQL”数据库作为关系数据库以外的一些选择,正在引起大家的广泛关注。在这篇文章里,我们将主要关注那些非关系的NoSQL数据库的十大利弊:包括五大优势和五大挑战。
NoSQL的五大优势
1,灵活的可扩展性
多年以来,数据库管理员们都是通过“纵向扩展”的方式(当数据库的负载增加的时候,购买更大型的服务器来承载增加的负载)来进行扩展的,而不是通过“横向扩展”的方式(当数据库负载增加的时候,在多台主机上分配增加的负载)来进行扩展。但是,随着交易率和可用性需求的增加,数据库也正在迁移到云端或虚拟化环境中,“横向扩展”在commodity hardware方面的经济优势变得更加明显了,对各大企业来说,这种“诱惑”是无法抗拒的。
在commodity clusters上,要对RDBMS做“横向扩展”,并不是很容易,但是各种新类型的NoSQL数据库主要是为了进行透明的扩展,来利用新节点而设计的,而且,它们通常都是为了低成本的commodity hardware而设计的。
2,大数据
在过去的十年里,正如交易率发生了翻天覆地的增长一样,需要存储的数据量也发生了急剧地膨胀。O’Reilly把这种现象称为:“数据的工业革命”。为了满足数据量增长的需要,RDBMS的容量也在日益增加,但是,对一些企业来说,随着交易率的增加,单一数据库需要管理的数据约束的数量也变得越来越让人无法忍受了。现在,大量的“大数据”可以通过NoSQL系统(例如:Hadoop)来处理,它们能够处理的数据量远远超出了最大型的RDBMS所能处理的极限。
3,“永别了”!DBA们!(再见?)
在过去的几年里,虽然一些RDBMS供应商们声称在可管理性方面做出了很多的改进,但是高端的RDBMS系统维护起来仍然十分昂贵,而且还需要训练有素的DBA们的协助。DBA们需要亲自参与高端的RDBMS系统的设计,安装和调优。
NoSQL数据库从一开始就是为了降低管理方面的要求而设计的:从理论上来说,自动修复,数据分配和简单的数据模型的确可以让管理和调优方面的要求降低很多。但是,DBA的死期将至的谣言未免有些过于夸张了。总是需要有人对关键性的数据库的性能和可用性负责的。
免责声明:本文转载或采集自网络,版权归原作者所有。本网站刊发此文旨在传递更多信息,并不代表本网赞同其观点和对其真实性负责。如涉及版权、内容等问题,请联系本网,我们将在第一时间删除。同时,本网站不对所刊发内容的准确性、真实性、完整性、及时性、原创性等进行保证,请读者仅作参考,并请自行核实相关内容。对于因使用或依赖本文内容所产生的任何直接或间接损失,本网站不承担任何责任。