表格存储最佳实践:一种用于存储时间序列数据的表结构设计

本文主要是介绍表格存储最佳实践:一种用于存储时间序列数据的表结构设计,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在表格存储的数据模型这篇文章中提到:


在表格存储内部,一个表在创建的时候需要定义主键,主键会由多列组成,我们会选择主键的第一列作为分片键。当表的大小逐渐增大后,表会分裂,由原来的一个分区自动分裂成多个分区。触发分裂的因素会有很多,其中一个很关键的因素就是数据量。分裂后,每个分区会负责某个独立的分片键范围,每个分区管理的分片键范围都是无重合的,且范围是连续的。在后端会根据写入数据行的分片键的范围,来定位到是哪个分片。

 

表会以分区为单位,被均匀的分配到各个后端服务器上,提供分布式的服务。


 

        在表格存储的最佳实践中提出,一个设计良好的主键,需要避免访问压力集中在一个小范围的连续的分片键上,也就是说避免热点分片。设计良好的表结构,整张表的访问压力能够均匀的分散在各个分片上,这样才能充分利用后端服务器的能力。

 

        那在使用表格存储来存储时间序列数据时,我们应该如何设计表的结构,避免热点分片的问题?

 

        假设我们需要设计一张表,用于存储监控信息,监控信息包括:时间戳(timestamp)、监控指标名称(metric)、主机名(host)和监控指标值(value)。而我们的查询场景为,指定监控指标名称和时间范围,查询该监控指标的所有值。通常我们会这样设计我们的表结构:

 

 

表设计一:

 

 

c820f472b78acf84341a1312b75bcb1681d4afba

 


该设计以metric列为分片键,能够满足查询的场景,但是有很严重的分片热点问题。假设一个metric下每秒采集一个点,而我们有上百台设备,则该分片每秒需要能够提供上百的写入能力,这点也没有问题。但是由于使用了metric作为分片键,metric的值为常量,随着数据量的上涨,其无法再进行分裂,会导致该分片下的数据量不断膨胀,可能超过一台物理机所能承受的上限,存在分片数据量的热点。

 

 

为了解决这个问题,我们对分片键做一个调整:

 

表设计二:

b6cd2deec148f387ad46e143f56a88f12390f255

 

我们将第一列主键和第二列主键合并为一列主键作为分片键,在数据的分布模式上并没有什么变更,但是引入了时间这个维度后,我们避免了分片数据量的热点。但是当host规模变大,从上百膨胀到上万,则该张表需要每秒提供上万并发的写入能力。我们需要将该表的写入压力均匀的分散到各个分片上,但是由于其数据的特点,每次写入的数据都是最新时间的数据,其写入压力永远集中在最新时间戳所在的分片上。

 

为了将写入压力均匀的分散到分片上,我们再对表做一个重新设计:

 

表设计三:

4ff28d7fe2d852e218267c36a3e993fd99b643d0

 

我们引入一个新的列 - bucket,在每行数据写入前,为每行数据分配一个桶(可随机分配),以桶的编号为分片键(HBase中有类似的解决方案,称为salted key)。桶的个数任意,可扩张,在写入之前将数据预分桶之后,也就解决了写入压力热点的问题,因为写入压力永远是均匀分配在各个桶上的。可根据具体的写入压力,决定桶的个数。

 

数据分桶后,如果需要读取完整的数据,需要在每个桶内都分别执行一遍查询后将数据进行汇总,可以使用我们SDK提供的异步接口,来并行的查询每个桶,提高查询的效率。

 

总结

在时间序列存储的场景,例如监控数据或者日志数据,通常比较难解决的是写入的问题,传统的数据库难以承载如此大数据量、高并发的写入压力。

 

表格存储能够提供非常优秀的写入能力,在阿里内部得到到了正好的实践和证明。但是若要发挥其强度的写入能力,需要有一个良好的表结构设计。

 

本篇文章给出了一个存储时间序列数据库的最佳实践,供参考。但表结构设计并不是千篇一律的,需要根据不同的业务场景设计做灵活的调整,欢迎一起探讨。

 

转:https://yq.aliyun.com/articles/54644?spm=a2c4e.11153940.blogcont54785.11.7fef7f4bdqjlWp

这篇关于表格存储最佳实践:一种用于存储时间序列数据的表结构设计的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/880595

相关文章

Spring Boot集成/输出/日志级别控制/持久化开发实践

《SpringBoot集成/输出/日志级别控制/持久化开发实践》SpringBoot默认集成Logback,支持灵活日志级别配置(INFO/DEBUG等),输出包含时间戳、级别、类名等信息,并可通过... 目录一、日志概述1.1、Spring Boot日志简介1.2、日志框架与默认配置1.3、日志的核心作用

破茧 JDBC:MyBatis 在 Spring Boot 中的轻量实践指南

《破茧JDBC:MyBatis在SpringBoot中的轻量实践指南》MyBatis是持久层框架,简化JDBC开发,通过接口+XML/注解实现数据访问,动态代理生成实现类,支持增删改查及参数... 目录一、什么是 MyBATis二、 MyBatis 入门2.1、创建项目2.2、配置数据库连接字符串2.3、入

SpringBoot多环境配置数据读取方式

《SpringBoot多环境配置数据读取方式》SpringBoot通过环境隔离机制,支持properties/yaml/yml多格式配置,结合@Value、Environment和@Configura... 目录一、多环境配置的核心思路二、3种配置文件格式详解2.1 properties格式(传统格式)1.

解决pandas无法读取csv文件数据的问题

《解决pandas无法读取csv文件数据的问题》本文讲述作者用Pandas读取CSV文件时因参数设置不当导致数据错位,通过调整delimiter和on_bad_lines参数最终解决问题,并强调正确参... 目录一、前言二、问题复现1. 问题2. 通过 on_bad_lines=‘warn’ 跳过异常数据3

Android Paging 分页加载库使用实践

《AndroidPaging分页加载库使用实践》AndroidPaging库是Jetpack组件的一部分,它提供了一套完整的解决方案来处理大型数据集的分页加载,本文将深入探讨Paging库... 目录前言一、Paging 库概述二、Paging 3 核心组件1. PagingSource2. Pager3.

Java获取当前时间String类型和Date类型方式

《Java获取当前时间String类型和Date类型方式》:本文主要介绍Java获取当前时间String类型和Date类型方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,... 目录Java获取当前时间String和Date类型String类型和Date类型输出结果总结Java获取

Python实现批量提取BLF文件时间戳

《Python实现批量提取BLF文件时间戳》BLF(BinaryLoggingFormat)作为Vector公司推出的CAN总线数据记录格式,被广泛用于存储车辆通信数据,本文将使用Python轻松提取... 目录一、为什么需要批量处理 BLF 文件二、核心代码解析:从文件遍历到数据导出1. 环境准备与依赖库

在Java中使用OpenCV实践

《在Java中使用OpenCV实践》用户分享了在Java项目中集成OpenCV4.10.0的实践经验,涵盖库简介、Windows安装、依赖配置及灰度图测试,强调其在图像处理领域的多功能性,并计划后续探... 目录前言一 、OpenCV1.简介2.下载与安装3.目录说明二、在Java项目中使用三 、测试1.测

MyBatis-Plus 自动赋值实体字段最佳实践指南

《MyBatis-Plus自动赋值实体字段最佳实践指南》MyBatis-Plus通过@TableField注解与填充策略,实现时间戳、用户信息、逻辑删除等字段的自动填充,减少手动赋值,提升开发效率与... 目录1. MyBATis-Plus 自动赋值概述1.1 适用场景1.2 自动填充的原理1.3 填充策略

C#监听txt文档获取新数据方式

《C#监听txt文档获取新数据方式》文章介绍通过监听txt文件获取最新数据,并实现开机自启动、禁用窗口关闭按钮、阻止Ctrl+C中断及防止程序退出等功能,代码整合于主函数中,供参考学习... 目录前言一、监听txt文档增加数据二、其他功能1. 设置开机自启动2. 禁止控制台窗口关闭按钮3. 阻止Ctrl +