今天许多应用程序仍然依赖于传统的SQL数据库,如MySQL,MariaDB或PostgreSQL,用于数据存储和数据处理。随着使用此数据库系统进行的越来越多的数据和新的工作负载,我们经常在我们需要考虑缩放此类系统的情况下找到自己。
数据存储,如果我们存储越来越多的数据,它变得昂贵或与他们一起工作
使选择查询更快,因为它们的复杂性或因为它们需要查询大量数据
在本文中,我将在缩放传统SQL数据库上展示一些基本想法和起点。
MySQL,PostgreSQL和其他传统SQL数据库的较新版本通常会有性能改进。即使较新的数据库系统与直接替换不快,也可能有新功能,我们可以利用。保持我们的数据库系统最新延迟扩展我们的选项对我们的数据可以执行的操作,并为我们提供最佳盒式性能。它是一个用于缩放的基本启动器。
缩放最直观的想法是使用更好的硬件垂直缩放(在一个数据库服务器上)。谈到硬件时,我们通常会查看CPU,磁盘和RAM:
CPU的数量会影响数据库可以运行的查询数量,因此可以提供多少客户端
RAM的大小为我们提供了索引,临时表和缓存的空间,数据库可以存储在快速内存中,这使得我们的系统更快地使IO访问磁盘。
磁盘IO速度高度影响查询时间,特别是对于全扫描读取(当不能使用索引时)或写入重型系统
如果应用程序的代码在我们的控制中,我们可以缓存在Redis或Memcached等内存存储中的数据,以避免查询数据库。我们不必只是缓存数据库读取,但我们也可以使用这样的系统作为写入的缓冲区,例如,当我们收集分析数据并且可能的延迟不是问题。
涉及数据时,它全部以数据类型开头,换句话说,单个信息如何物理存储在内存中。选择合适的数据类型始终是效率和功能之间的平衡,影响我们可以使用特定数据类型执行所需的内存,查询性能和操作数。
逻辑:如何存储一般信息,如电话号码或IP地址;例如,我们可以将颜色存储为字符串,枚举或作为RGB整数的集合,我们可以将IP地址存储为字符串或作为字节
物理:我们选择字符串,整数或时间的特定数据类型,因为我们通常具有多个选项;例如日期和时间通常可以存储为时间戳(更快但具有有限的日期范围和功能)或作为更复杂的DateTime,更多的开发人员友好且灵活,允许存储时区等。
使用适当的类型为数据库列尤其重要,当我们想要索引列时尤为重要,在where子句中使用它,使用它以便加入或当我们有很多数据时。
我们经常接受培训以规范关系数据库的数据,以减少数据冗余并提高数据完整性。虽然这通常是有用的,但我们可能希望在缩放方面重新考虑我们的一些数据。
一般而言,我们使我们能够检索或保存的数据更简单,我们可以拥有的更多信息。
通过在已请求的表单中具有已优化的数据,可以优化许多选择查询。这可以方便地分析大量数据。例如,而不是每次聚合数据,而不是预先聚合它们。当然,这并不总是可能的,例如,我们不能汇总其他平均聚合,因为我们会失去精确度。
物化视图是连续更新的数据,这些数据在写操作或计划时间上更新,并且可以被视为前一点的扩展。与经典视图不同,物理化视图是物理存储的,并且在需要时不需要计算。这对于Select查询需要很长时间才能产生结果的情况非常有用。
例如,查看PostgreSQL的PopelIneyB扩展,它在实时数据上产生聚合,允许我们在写入重系统中保留聚合统计数据。
使用正确的表索引可以是一个巨大的性能更换器。通常,我们应该索引我们要查询数据的列,或者我们要用于执行连接。但是,添加索引也可以降低写入重型工作负载的性能,因为必须在每个插入和更新时更新索引。在某些数据类型上使用索引也没有意义。所以这一切都是关于找到合适的平衡。
为了优化读取,我们需要知道数据库查询策划器如何执行我们的查询。我们可以使用Explate语句来获取SQL Server将用于我们查询的执行计划。
在这里,我们应该了解数据库计划在表中使用任何现有索引或计划进行全表扫描。它可以给我们提示是否应该更改数据的结构,以不同的方式添加索引或重写查询。但请注意,对于某些查询,完整的表扫描也可以更快或必要,因此它不是黑白情况。
最常见的关系数据库使用多版本并发控制并使锁定非常粒度(而不是锁定整个表,如Myisam存储引擎)。但是,我们仍然需要告诉数据库,并发控制行为究竟是如何通过设置适当的交易隔离级别来实现。 SQL:1992标准中有4个基本隔离级别,它们将极大地影响我们的数据库系统的行为方式。
在表中编写或更新单个行是不高效的,但数据库如MySQL或PostgreSQL等数据库有方法可以在批量中插入或修改数据。我们每次都应该利用这一点。
多次我们不需要通过表中的所有列查询数据。如果是这种情况,我们可以通过将一些列以压缩形式存储一些列来进一步优化存储大小。这对字符串或某些类型的二进制数据特别有用。
某些数据库或其扩展可能已经在引擎盖下压缩数据,以便首先了解存储数据以及是否在应用层上添加压缩会带来所需的益处。
当数据量或工作量增加时,我们将体验到较慢,更慢的改变表到其中一些可能在合理的时间内可能无法完成。最重要的是要知道的是通常有两种改变数据库表的结构的方法。一个是否定,修改原始表,另一个是复制,创建一个新表并之后移动数据。数据库通常会尝试在可能的情况下修改表,但有时会明确要求复制操作可能有意义。
添加新列时,最好将其添加在表的末尾,因为在特定位置插入列是慢的。
更改现有列后,首先创建新列可能是一个好主意,然后复制数据并之后删除列。
如果表上的写入操作使得难以执行更改表,则使客户端首先从写入表格写入表格是有意义的。这并不总是可能的,但是如此。分析数据的集合可以在数据库前面的摄取缓冲区推迟,或者我们可以暂时暂停与表一起使用的ETL作业。
最后的度假胜地是根本没有在大型和重写尺寸表上进行任何改变表,选择创建一个新表来存储新数据。
每个数据库服务器都有一些基本配置,最大并发连接数。当我们需要更多时,我们通常需要重新配置此值。虽然越来越大,但是 - 我们需要确保我们的系统实际上可以使用所需数量的连接运行。
传统的SQL数据库通常不能通过添加更多服务器来水平扩展为写操作,但我们仍然可以以只读副本的形式添加其他计算机。这项工作的方式是所有写入操作都在主服务器上完成,并使用写入前瞻日志传播到其他机器。因此,所有副本将以与主要服务器的底层存储相同的顺序应用相同的操作。这可确保数据将同步。
然后,可以将副本用于缩放读取查询数和连接客户端的数量,如果它们只需要读取操作。
分区允许我们在文件系统上分发一个单个表,并根据某些特定规则存储单个分区。 When such rules are chosen well, SQL queries don’t have to query all partitions but can limit their search only to a subset of them.这将切割查询运行的时间,因为不需要查看整个数据库表。
当我们需要存储和处理地理空间,时间序列和其他专业数据时,我们有时可以使用像时间尺寸或后智能的数据库扩展,以使数据处理和存储更高效。
分片是在类固醇上分配,并允许我们将数据库表(分片)的部分存储在不同的服务器上。分布式数据库通常使用碎片的概念构建,但传统的SQL服务器无法自动分析数据,因为它们只能使用一个主服务器和副本。所以,我们能做些什么?
我们可以调查一些MySQL群组或Vitess for MySQL或PictgreSQL等群集解决方案是否可以解决我们的缩放问题。构建此解决方案以提供“水平可扩展的SQL数据库”,但它们并非没有限制。例如,MySQL Cluster不适用于Classic InnoDB引擎,因此我们不能只需编写我们曾经的应用程序。
另一种选择是在应用层上手动分离数据。这为应用程序提供了额外的复杂性,我们需要管理与不同服务器的多个连接并适当地查询数据库,但它是考虑的解决方案。
如果数据量是我们的主要问题,我们的表格变得太大,我们应该考虑我们是否可以将此数据放在其他地方。
如果我们偶尔需要数据,我们在整个表中不需要任何唯一索引,我们可以简单地将数据划分为多个表。例如,我们可以将来自不同客户的数据分开或存储旧数据表中的旧数据。这样我们就可以让我们的表格较小,更加性能。
在某些情况下,我们甚至可以决定在我们的主数据库中存储一些数据,并且只需删除它们或将它们移动到另一个存储系统中。
有时关系SQL数据库是不够的。例如,我们可能希望创建不适合此类系统的数据工作流程,或者我们可能无法对模式进行更改或更改现有程序与数据库交互方式。也许我们在缩放当前数据处理方面达到了极限,我们需要更多。所以现在怎么办?
在许多情况下,最好的方法是将数据移动到另一个系统并在那里进行处理。幸运的是,我们可以利用写入前瞻性日志(WAL),该日志(WAL)存储数据库应该执行的所有更改(插入,更新,更改表)。我们可以以编程方式读取此日志并将其传输到另一个系统中。例如,我们可以使用现有的数据库连接器将数据传输到Kafka,并允许其他应用程序读取它。或者我们可以直接将此数据发送给专用数据库,例如,到分析数据库点击房或像Hadoop这样的数据湖泊并在那里处理它们。我们还可以通过其他方式移动数据:拍摄数据库的副本,用SQL提取数据等。
如果我们只想在不使用不同的数据库系统的情况下扩展数据计算,从多个数据源的过程数据一次或只是想更好地组织我们的数据处理,我们可以使用Apache Spark等分布式群集计算软件。
许多人从AWS或Azure等云提供商支付托管的SQL数据库,以便他们不必担心维护它们。但是,当我们需要扩展我们的传统SQL商店时,许多缩放选项实际上将无法使用。
这可能包括有限的更改数据库配置的能力,有限的硬件选项可供选择,有限的副本,更高的延迟,写入前瞻性日志可能无法访问,我们可能无法将数据库版本更新到当前,现代版本我们想。我们可能无法安装将提高系统性能的扩展。此外,调试此类远程系统上的性能问题可能是困难或不可能的,因为我们可能无法正确访问操作系统。
因此,在购买永不担心SQL商店的梦想之前,我们应该调查选项是什么,如果托管数据库提供实际上是足够的。
呈现的选项只是可能的起点,为我们提供一些思考的领域。由于缩放SQL数据库不是直接的操作,我不想进入额外的细节。我们总是需要考虑我们的系统和我们拥有的选项,使每个解决方案都是独一无二的。