背景
在数字化转型浪潮中,企业和组织越来越依赖数据驱动的决策。这些决策往往需要实时或近实时的数据支持,尤其在面向客户的应用场景(例如,电商平台、社交媒体、金融应用等)中,响应时效至关重要。用户和业务运营团队期待能够通过实时查询迅速获得所需的信息和见解。因此,高并发查询场景在保证良好用户体验和提供即时数据支持方面变得尤为关键。
高并发查询需求的实现往往存在以下挑战:
- 负载压力: 高并发意味着数据库同时处理大量查询,给系统带来极大压力,可能涉及到磁盘 I/O、CPU 性能 以及网络带宽的瓶颈。
- 数据一致性: 在分布式数据库中,保障数据同步和一致性。
- 资源调度: 有效地调度和分配数据库资源,保证高优先级的查询能够获得更多资源,提高响应速度。
- 查询优化: 在多用户并发场景下,如何优化查询,减少不必要的计算和数据传输,提高效率。
ArgoDB 作为一款分布式分析型数据库,具备强大的数据存储和计算能力,通过其特有的技术架构和分布式计算能力,支持企业在处理大规模数据的同时,满足复杂查询的需求。
常见场景
在实际业务中,高并发查询场景常常涉及到多种不同的查询模式,而不同的查询模式各自有着独特的性能挑战和优化机会。
总之,无论是简单的点查询,还是复杂的聚合和 Join 操作,在高并发环境中都可能面临着性能和资源的挑战。接下来,我们将转变视角,探讨一些通用的查询优化手段,这些手段不仅仅局限于特定的查询模式,更可以作为提升 ArgoDB 整体查询性能的策略和方法。
查询模式 |
场景说明 |
潜在优化点 |
点查询 |
根据某一或多个特定属性检索一条或多条记录,例如根据订单号快速查询到一个订单的所有相关信息。 |
查询可能聚焦在一些特定的行,可能导致某些节点压力过大,可结合行存表、表分区分区、索引、倾斜优化等方法进行优化。 |
范围查询 |
选择一个特定的值范围来获取数据,例如查询某个时间范围内的所有交易记录。 |
范围查询涵盖范围较大时,查询性能可能会下降,可结合分区、索引等方法进行优化。 |
聚合查询 |
对数据进行汇总和分析,例如分析一段时间内每个商品类别的销售总额。 |
当需要聚合大量数据时,网络 I/O 可能成为瓶颈,可结合局部预聚合等方式进行优化。 |
复杂Join |
通常涉及多表关联查询,例如根据客户信息表和购买历史表,查询特定客户的购买历史记录。 |
Join 操作可能需要大量的网络数据传输,可基于不同场景来选择 Join 类型(如 Map Join)来优化。 |
常见并发优化方法
接下来,我们将结合 ArgoDB 的特性,从数据存储、查询任务分配、SQL 优化、参数调整等方面详细探讨如何优化高并发查询的性能。
1、增加机器规格
对于数据库性能的提升,硬件升级通常是最直接的手段。增加 CPU 核数、内存和磁盘存储速度能够提供更多的计算、存储和 I/O 能力,直接提高查询和数据处理的能力,此外,我们还需要结合数据库软件的优化技术来最大化发挥硬件能力。
- 垂直扩展: 增加单个节点的硬件能力,例如CPU、内存和存储。
- 水平扩展: 通过增加数据库节点数,平行提高数据库集群的整体处理能力。
2、优化数据分布
优化数据的物理布局对于数据库查询性能有着深远的影响。当数据量持续增长,如何有效地组织和管理这些数据就显得至关重要。在 ArgoDB 中,常见的优化方法如下:
a.数据分区
表分区是一种在数据库中组织和存储数据的技术,可用于处理大量数据并提高查询性能,其核心思想是将数据按照某个特定的标准分成多个物理块,每个物理块即为一个分区,从而使数据的存储和管理更加高效,可帮助我们我们实现稳定的存储增长、高性能和易维护。这种方法的好处在于:
- 有针对性的查询:如果查询模式相对固定,例如经常根据某一业务部门进行查询,选择适当的分区键可以显著地减少需要扫描的数据规模,从而提高查询效率。
- 时间序列数据管理:对于按时间排序的数据,如日志,使用时间作为分区键不仅提高了按时间范围查询的效率,还方便了旧数据的管理和归档。
b.数据分桶
为了更细粒度地管理和优化数据存储与访问,数据分桶(Bucketing)技术逐渐受到了关注,即对指定列的哈希值将其分配到固定数量的子集中(桶),保障数据的均匀分布,从而为复杂查询提供了更高效的处理方式。选择分桶的主要考虑因素包括:
- 高频的连接操作:当两大表经常基于某个列进行连接,并且连接过程中产生了大量的数据移动和 Shuffle 操作,采用数据分桶可以显著减少这种开销,从而加快查询速度。
- 频繁的聚合操作:对于常见的聚合查询,如果数据按照聚合的键分桶,可以大幅提升性能。因为这允许每个数据节点独立地、并行地完成其桶内的聚合操作。
3、均衡查询请求
在处理用户业务的并发接入时,连接的处理任务分配管理服务可能随着并发量的加大而逐步达到性能瓶颈,而任务的均衡分配处理可以协助任务分配管理服务更好地分配调度待执行任务,均衡分配业务处理,充分调动分布式数据库并发处理能力,从而实现并发业务处理响应。
不同于传统解决方案,在 ArgoDB 中,您只需简单修改配置文件,即可在 Quark Gateway 的 Session 层面,将客户端的连接分摊给多个可用的 Quark Server ,从而平衡业务流量以应对高并发场景。
在配置时,我们首先进入 Quark Gateway 的配置文件路径:
# 根据环境替换服务 ID,例如 cd/etc/quarkgateway1/conf/
cd /etc/quarkgateway{服务 ID}/conf/
随后通过 vim 修改配置文件 servers.data,示例如下:
NAME IS001
URI host1:10000
TAG primary
NAME IS002
URI host2:10000
TAG primary
NAME IS003
URI host3:10000
TAG primary
- NAME:取值唯一的名称。
- URI:Quark Server 的连接信息,包含主机名和端口号。
- TAG:标签,Quark Gateway 将依据标签进行路由,本案例中,我们将 3 个 Quark Server 都设置相同的标签,即可将它们组成了一个群组,实现负载均衡。
4、缓存查询结果
为进一步提升查询性能,您可以登录 Transwarp Manager,开启 Quark Gateway 服务的结果集缓存能力,将缓存存放至内存中,即设置 inceptor.gateway.cache.result.enabled 为 true,配置示例如下:
设置完成后下方配置并重启,随后即可访问 http:// Quark Gateway 登录地址:6066/v1/resultcache 页面,查看缓存使用情况。
5、启用新计算引擎
计算引擎的效率直接影响到查询性能和系统的响应速度,而 ArgoDB 的全新计算引擎 Linac 是基于 C++ 编写的 Native 引擎,拥有高效的计算性能、内存管理和并行计算等一系列优势,为数据处理和查询带来显著的性能提升。
在实际使用时,需要创建的 Holodesk 的表为 Performance 表(默认),同时还需要在 Beeline 命令行中执行 set use.linac =true; 来开启该功能,如果遇到某些新引擎不支持的数据类型或 UDF,ArgoDB 将自动回退采用 WindRunner 计算引擎来执行任务。
6、增加细粒度索引
细粒度索引可用于提升数据库的点查性能,尤其是针对除 blob 和 clob 类型以外的数据。通过在主表上创建 K-V 索引,其中“Key”负责存储索引键值,而“Value”则维护了与索引键相关联的所有行信息,该技术确保了即使在数据体量庞大的情况下,我们也能迅速定位并检索到所需数据。
考虑到索引表本身也可以涵盖大量数据,此外,为了进一步提升查找速度,索引表还实行分桶策略。在每个桶内,数据按 Key 值进行排序,进而在实际查询过程中能够显著提升索引表的检索速度。这一策略不仅优化了点查的效率,同时也间接减轻了全表扫描的性能负担,实现了在保证查询精度的同时,提升查询响应速度的目标。
细粒度索引创建示例如下:
-- 为 acc_num 和 trans_time 字段添加细粒度索引
ALTER TABLE demo_table ADD FINE-GRAINED INDEX (acc_num, trans_time);
完成索引配置后,您可以通过 EXPLAIN 命令来确认查询语句的执行计划是否通过索引来响应。
7、优化关联查询
在数据库查询过程中,尤其是涉及多表查询的场景,Join 操作是不可避免的。但是,未经优化的 Common Join 可能会在复杂的查询场景中成为性能瓶颈,尤其是当处理大规模数据集或实时查询时。因此,对 Join 进行合理优化不仅是提高查询性能的关键,也是保证数据库资源高效利用的重要手段,通常考虑如下:
- 合理安排 Join 顺序:在多表进行连接时,Join 之间的连接顺序将极大影响 SQL 的执行效,优化的主要思路包括减少 Inner Join 的中间量和先 Inner Join 之后再 Outer Join。
- 手动增加过滤规则:在执行关联查询时,尤其是小表与大表的连接,先过滤小表并识别连接字段的范围,仅比对大表中此范围的记录,能减少不必要的数据匹配,显著提升查询效率。
- 选择合适的 Join 类型:
- MapJoin:当一张表的大小远小于另一张表时,使用 MapJoin 可以将小表加载到内存中,从而加速与大表的关联操作。
- Bucketed Join:当两张大表关联时,Bucketed Join 可以通过分桶数据来提高 Join 效率。
- Lookup Join:当小表与大表关联时,可以先在大表中为小表的每个键值进行查找,从而避免全表扫描。
- Skew Join:数据倾斜是指某些键值在表中的出现频率远高于其他键值,这会导致某些 Join 操作比其他操作处理更多的数据,通过 Skew Join 能够识别并针对这种数据倾斜进行优化。
8、预存查询结果
物化视图(Materialized View)在性能优化中充当一个十分重要的角色,特别是在数据分析和报表生成等业务中,其通过预存计算结果,能够显著减轻重复计算带来的系统压力,加速相同或相似查询的响应速度。物化视图一个与普通视图类似但将结果集持久化存储的数据库对象。简而言之,它将查询结果保存下来,以便下次有相同或相似的查询请求时直接读取已经存储的结果,而非重新计算,从而节省系统资源,提高查询响应速度。物化视图使用策略如下 :
- 预存计算结果
- 汇总与聚合:将经常用到的汇总和聚合运算的结果预存到物化视图中,避免了每次查询都进行重复的计算。
- 频繁的 JOIN 操作:预存常用的表连接操作结果,减少在实际查询中的计算量。
- 选择刷新策略
- 定期刷新:根据数据变更的频率和查询的需求,定时刷新物化视图中的数据。
- 基于事件的刷新:当源表数据变动后,物化视图自动重建,保证其数据的时效性。
9、优化参数设置
在数据库的运行过程中,适当的参数调整往往能实现并发性能的显著提升,具体如下:
- 日志级别:登录 DBA Service,将 Quark 执行器的日志级别调整为 ERROR 来降低日志级别(动态生效),减少日志生成和 I/O 的压力,遇到问题需要诊断时可重新调整日志级别(如 INFO)。
- 安全特性:在确保符合合规要求的前提下,可通过 Manager 平台关闭 Quark 的安全认证,适度减轻或优化安全相关的运算和验证过程,以减轻数据库的运算负载。
- 其他参数调整:通过 Beeline 连接数据库进行调整,也可以通过 Manager 来设置以实现服务级生效。