NoSQL 数据建模错误会降低性能

数据建模错误是破坏性能的最简单方法之一。当您使用 NoSQL 时,特别容易搞砸,(讽刺的是)NoSQL 往往用于对性能最敏感的工作负载。NoSQL 数据建模最初可能看起来非常简单:只需对数据进行建模以适应应用程序的访问模式。但实际上,说起来容易做起来难。

修复数据建模并不有趣,但它通常是一种不可避免的罪恶。如果您的数据建模从根本上来说效率低下,那么一旦扩展到某个临界点(根据您的特定工作负载和部署而变化),您的性能就会受到影响。即使您在最强大的基础设施上采用最快的数据库,除非您的数据建模正确,否则您将无法充分发挥其潜力。

本文探讨了破坏 NoSQL 数据库性能的三种最常见方法,以及有关如何避免或解决这些问题的提示。

不处理大分区

当团队扩展其分布式数据库时,通常会出现大型分区。大型分区是指变得太大以至于开始在集群副本中引入性能问题的分区。

我们经常听到的问题之一(至少每月一次)是“什么构成了大分区?” 这得看情况。需要考虑的一些事项:

  • 延迟预期:分区越大,检索所需的时间就越长。考虑页面大小以及完全扫描分区所需的客户端-服务器往返次数。

  • 平均有效负载大小:较大的有效负载通常会导致较高的延迟。它们需要更多的服务器端处理时间来进行序列化和反序列化,并且还会产生更高的网络数据传输开销。

  • 工作负载需求:某些工作负载自然需要比其他工作负载更大的负载。例如,我曾与一家 Web3 区块链公司合作,该公司将多个交易存储为单个密钥下的 BLOB,并且每个密钥的大小很容易超过 1 MB。

  • 如何从这些分区中读取:例如,时间序列用例通常具有时间戳集群组件。在这种情况下,从特定时间窗口读取将检索到的数据比扫描整个分区要少得多。

下表说明了大分区在不同负载大小(例如 1、2 和 4 KB)下的影响。

正如您所看到的,在相同的行数下,您的有效负载越高,您的分区就越大。但是,如果您的用例经常需要扫描整个分区,那么请注意数据库有限制以防止无限制的内存消耗。例如,ScyllaDB 每 1MB 就切断页面,以防止系统可能耗尽内存。其他数据库(甚至是关系数据库)也有类似的保护机制,以防止无限的错误查询导致数据库资源匮乏。要使用 ScyllaDB 检索 4KB 的负载大小和 10K 行,您需要检索至少 40 个页面才能使用单个查询扫描分区。乍一看这似乎没什么大不了的。但是,随着时间的推移进行扩展,它可能会影响整体客户端尾部延迟。

另一个考虑因素:对于 ScyllaDB 和 Cassandra 等数据库,写入数据库的数据存储在提交日志中和称为“memtable”的内存数据结构下。

提交日志是一种预写日志,除非服务器崩溃或服务中断,否则永远不会真正读取它。由于内存表存在于内存中,因此它最终会变满。为了释放内存空间,数据库将内存表刷新到磁盘。该过程会产生 SSTable(排序字符串表),这就是数据持久化的方式。

这一切与大分区有什么关系?嗯,SSTables 有特定的组件,需要在数据库启动时保存在内存中。这可确保读取始终高效,并最大限度地减少查找数据时存储磁盘 I/O 的浪费。当您拥有非常大的分区时(例如,我们最近有一个用户在 ScyllaDB 中拥有 2.5 TB 的分区),这些 SSTable 组件会带来沉重的内存压力,从而缩小数据库的缓存空间并进一步限制延迟。

如何通过数据建模解决大型分区问题?基本上,是时候重新考虑你的主键了。主键决定数据如何在集群中分布,从而提高性能和资源利用率。一个好的分区键应该具有高基数和大致均匀的分布。例如,用户名、用户 ID 或传感器 ID 等高基数属性可能是一个很好的分区键。像“州”这样的州将是一个糟糕的选择,因为加利福尼亚州和德克萨斯州等州可能比怀俄明州和佛蒙特州等人口较少的州拥有更多的数据。

或者考虑这个例子。下表可用于具有多个传感器的分布式空气质量监测系统:

CREATE TABLE air_quality_data (   sensor_id text,   time timestamp,   co_ppm int,   PRIMARY KEY (sensor_id, time));

由于时间 是我们表的聚类键,因此很容易想象每个传感器的分区可能会变得非常大,特别是如果每几毫秒收集一次数据。这张看似无辜的桌子最终可能会变得无法使用。在此示例中,仅需要大约 50 天。

标准解决方案是修改数据模型以减少每个分区键的集群键数量。在这种情况下,我们来看看更新后的`air_quality_data`表:

CREATE TABLE air_quality_data (   sensor_id text,   date text,   time timestamp,   co_ppm int,   PRIMARY KEY ((sensor_id, date), time));

更改后,一个分区保存一天收集的值,这使得它不太可能溢出。这种技术称为分桶,因为它允许我们控制分区中存储的数据量。

热点介绍

热点可能是大分区的副作用。如果您有一个大分区(存储大部分数据集),那么您的应用程序访问模式很可能会比其他分区更频繁地访问该分区。既然如此,它也成为热点。

只要有问题的数据访问模式导致集群中的数据访问方式不平衡,就会出现热点。罪魁祸首之一是应用程序未能对客户端施加任何限制,并允许租户潜在地向给定的密钥发送垃圾邮件。例如,考虑一下消息应用程序中的机器人经常在频道中发送垃圾邮件。不稳定的客户端配置也可能以重试风暴的形式引入热点。也就是说,客户端尝试查询特定数据,在数据库超时之前超时,并在数据库仍在处理前一个查询时重试查询。

监控仪表板应该可以让您轻松找到集群中的热点。例如,此仪表板显示分片 20 因读取而不堪重负。

再举一个例子,下图显示了三个利用率较高的分片,这与为相关键空间配置的三个分片的复制因子相关。

在这里,由于垃圾邮件,分片七引入了更高的负载。

如何解决热点问题?首先,在受影响的节点之一上使用供应商实用程序来对采样期间最常点击的键进行采样。您还可以使用跟踪(例如概率跟踪)来分析哪些查询正在命中哪些分片,然后从那里采取行动。

如果您发现热点,请考虑:

  • 检查您的应用程序访问模式。您可能会发现需要更改数据建模,例如前面提到的分桶技术。如果需要排序,可以使用单调递增组件,例如 Snowflake。或者,也许最好应用并发限制器并限制潜在的不良行为者。

  • 指定每个分区的速率限制,之后数据库将拒绝命中同一分区的任何查询。

  • 确保客户端超时 高于服务器端超时,以防止客户端在服务器有机会处理查询之前重试查询(“重试风暴”)。

滥用集合

团队并不总是使用集合,但当他们使用集合时,他们经常会错误地使用它们。集合用于存储/反规范化相对少量的数据。它们本质上存储在单个单元中,这会使序列化/反序列化变得极其昂贵。

使用集合时,您可以定义相关字段是冻结还是非冻结。冻结集合只能作为一个整体来写;您不能从中添加或删除元素。可以附加非冻结集合,而这正是人们最常误用的集合类型。更糟糕的是,您甚至可以拥有嵌套集合,例如一个地图包含另一个地图,其中包含一个列表,等等。

例如,误用的集合会比大分区更快地引入性能问题。如果您关心性能,集合根本不能太大。例如,如果我们创建一个简单的键:值表,其中键是` sensor_id`,值是随时间记录的样本集合,那么一旦开始提取数据,我们的性能将不是最佳的。

         CREATE TABLE IF NOT EXISTS {table} (               sensor_id uuid PRIMARY KEY,               events map<timestamp, FROZEN<map<text, int>>>,            )

以下监视快照显示了当您尝试一次将多个项目追加到集合时会发生什么情况。

您可以看到,虽然吞吐量下降,但 p99 延迟却增加。为什么会出现这种情况?

  • 集合单元作为排序向量存储在内存中。

  • 添加元素需要合并两个集合(旧的和新的)。

  • 添加元素的成本与整个集合的大小成正比。

  • 树(而不是向量)会提高性能,但是......

  • 树会降低小集合的效率!

返回同一示例,解决方案是将时间戳移动到聚类键并将映射转换为 FROZEN 集合(因为您不再需要向其中附加数据)。这些非常简单的更改将极大地提高用例的性能。

    CREATE TABLE IF NOT EXISTS {table} (               sensor_id uuid,        record_time timestamp,               events FROZEN<map<text, int>>,     PRIMARY KEY(sensor_id, record_time)            )

作者:Felipe Mendes

更多技术干货请关注公号【云原生数据库

squids.cn,云数据库RDS,迁移工具DBMotion,云备份DBTwin等数据库生态工具。

irds.cn,多数据库管理平台(私有云)。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/186104.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【C++】异常处理 ② ( 异常捕获类型 | 异常捕获机制 - 严格匹配异常类型 | 未知异常捕获 - 不知道异常类型 )

文章目录 一、异常捕获机制 - 严格匹配异常类型1、异常捕获机制 - 严格匹配异常类型2、代码示例 - 异常捕获严格匹配异常类型 二、异常捕获机制 - 未知异常捕获1、未知异常捕获 - 不知道异常类型2、代码示例 - 未知异常捕获 一、异常捕获机制 - 严格匹配异常类型 1、异常捕获机…

Echarts大屏-数据可视化

使用原生htmljavascript实现大屏展示,较为麻烦的为边框的四个小角使用伪元素生成,其余echarts使用如下快速上手 - Handbook - Apache ECharts 效果如下:

java论坛数据以及搜索接口实现

一. 内容简介 java论坛数据以及搜索接口实现 二. 软件环境 2.1 java 1.8 2.2 mysql Ver 8.0.13 for Win64 on x86_64 (MySQL Community Server - GPL) 2.3 IDEA ULTIMATE 2019.3 2.4d代码地址 三.主要流程 3.1 创建数据库,创建数据表 3.2 开始编写接口&#xff0c;并测…

键盘打字盲打练习系列之刻意练习——1

一.欢迎来到我的酒馆 盲打&#xff0c;刻意练习! 目录 一.欢迎来到我的酒馆二.选择一款工具三.刻意练习第一步&#xff1a;基准键位练习第二步&#xff1a;字母键位练习第三步&#xff1a;数字符号键位练习 四.矫正坐姿 二.选择一款工具 工欲善其事必先利其器。在开始之前&…

井盖位移报警器安装,智能化井盖厂家推荐

当井盖发生位移或倾斜时&#xff0c;通常会引起所处道路的安全隐患&#xff0c;给过往的车辆和行人带来许多潜在的危险。为了避免潜在的安全事故频繁出现&#xff0c;及时发现并处理井盖位移或倾斜才能更好的保障人民的安全。因此安装井盖位移报警器是满足政府和市民需求的。 单…

vue项目npm install报错Failed at the fibersa4.0.3 install script

报错如下 解决&#xff1a;降低node版本 降到12.16.0 参考链接

Linux下删除当前目录下的所有目录

Linux下删除当前目录下的所有目录 Linux下删除当前目录下的所有目录&#xff0c;可以使用命令&#xff1a;rm -rf ./* rm -rf ./*可以得知rm -rf ./命令是删除当前目录下的所有文件和文件夹&#xff0c;但不会删除根目录下的文件。其中&#xff0c;".“代表当前目录&…

Pycharm新手开发指南

文章目录 前言一、常用功能介绍二、常用高效pycharm使用方法关于Python技术储备一、Python所有方向的学习路线二、Python基础学习视频三、精品Python学习书籍四、Python工具包项目源码合集①Python工具包②Python实战案例③Python小游戏源码五、面试资料六、Python兼职渠道 前言…

武汉芯源半导体首款车规级MCU,CW32A030C8T7通过AEC-Q100测试考核

近日&#xff0c;武汉芯源半导体正式发布首款基于Cortex-M0内核的CW32A030C8T7车规级MCU&#xff0c;这是武汉芯源半导体首款通过AEC-Q100 (Grade 2)车规标准的主流通用型车规MCU产品。 CW32A030C8T7通过AEC-Q100车规可靠性测试 作为武汉芯源半导体首款车规级MCU产品&#xff0…

Spring整合web环境

目录 Javaweb三大组件及环境特点 Spring整合web环境的思路及实现 Spring的web开发组件spring-web MVC框架思想及其设计思路 Javaweb三大组件及环境特点 Spring整合web环境的思路及实现 package com.xfy.listener;import com.xfy.config.SpringConfig; import org.springfra…

Linux中的fork()函数的面试题目

1.面试题目1 (1)fork 以后&#xff0c;父进程打开的文件指针位置在子进程里面是否一样&#xff1f;(先open再fork) (2)能否用代码简单的验证一下? (3)先fork再打开文件父子进程是否共享偏移量?父进程打开的文件指针位置在子进程里面是否一样&#xff1f;能否用代码简单验证一…

代理模式 1、静态代理 2、动态代理 jdk自带动态代理 3、Cglib代理

文章目录 代理模式1、静态代理2、动态代理jdk自带动态代理 3、Cglib代理 来和大家聊聊代理模式 代理模式 代理模式&#xff1a;即通过代理对象访问目标对象&#xff0c;实现目标对象的方法。这样做的好处是&#xff1a;可以在目标对象实现的基础上&#xff0c;增强额外的功能操…

【Openstack Train安装】八、placement安装

Placement 肩负着这样的历史使命&#xff0c;最早在 Newton 版本被引入到 openstack/nova repo&#xff0c;以 API 的形式进行孵化&#xff0c;所以也经常被称呼为 Placement API。它参与到 nova-scheduler 选择目标主机的调度流程中&#xff0c;负责跟踪记录 Resource Provide…

java学校高校运动会报名信息管理系统springboot+jsp

课题研究方案&#xff1a; 结合用户的使用需求&#xff0c;本系统采用运用较为广泛的Java语言&#xff0c;springboot框架&#xff0c;HTML语言等关键技术&#xff0c;并在idea开发平台上设计与研发创业学院运动会管理系统。同时&#xff0c;使用MySQL数据库&#xff0c;设计实…

五种多目标优化算法(MOPSO、MOAHA、NSGA2、NSGA3、MOGWO)求解微电网多目标优化调度(MATLAB)

一、多目标优化算法简介 &#xff08;1&#xff09;多目标粒子群优化算法MOPSO 多目标应用&#xff1a;基于多目标粒子群优化算法MOPSO求解微电网多目标优化调度&#xff08;MATLAB代码&#xff09;-CSDN博客 &#xff08;2&#xff09;多目标人工蜂鸟算法&#xff08;MOAHA…

nexus制品库的介绍及详细部署使用

一、nexus 介绍 Nexus 是一个强大的仓库管理工具&#xff0c;用于管理和分发 Maven、npm、Docker 等软件包。它提供了一个集中的存储库&#xff0c;用于存储和管理软件包&#xff0c;并提供了版本控制、访问控制、构建和部署等功能。 Nexus 可以帮助开发团队提高软件包管理的效…

【Linux】cd 命令使用

cd&#xff08;英文全拼&#xff1a;change directory&#xff09;命令用于改变当前工作目录的命令&#xff0c;切换到指定的路径。 ~ 也表示为 home 目录 的意思。. 则是表示目前所在的目录。.. 则表示目前目录位置的上一层目录。 语法 cd [目录] 命令选项及作用 执行令 …

C++——AVL树

作者&#xff1a;几冬雪来 时间&#xff1a;2023年11月30日 内容&#xff1a;C板块AVL树讲解 目录 前言&#xff1a; AVL树与搜索二叉树之间的关系&#xff1a; AVL树概念&#xff1a; 插入结点&#xff1a; 平衡因子&#xff1a; 旋转&#xff1a; 双旋&#xff1a; …

基于SpringBoot母婴商城

摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本母婴商城系统就是在这样的大环境下诞生&#xff0c;其可以帮助管理者在短时间内处理完毕庞大的数据信息&am…

网络基础『发展 ‖ 协议 ‖ 传输 ‖ 地址』

&#x1f52d;个人主页&#xff1a; 北 海 &#x1f6dc;所属专栏&#xff1a; 神奇的网络世界 &#x1f4bb;操作环境&#xff1a; CentOS 7.6 阿里云远程服务器 文章目录 &#x1f324;️前言&#x1f326;️正文1.网络发展1.1.背景1.2.类型 2.网络协议2.1.什么是协议2.2.协议…