大数据之路 读书笔记 Day8 数据存储

回顾:
大数据之路 读书笔记 Day7 实时技术 简介及流式技术架构
大数据之路 读书笔记 Day6 离线数据开发之数据开发平台

数据存储

1 数据类型

实时任务在运行过程中,会计算很多维度和指标,这些数据需要放在一个存储系统中作为恢复或者关联使用。其中会涉及三种类型的数据:

  • 中间计算结果——在实时应用处理过程中,会有一些状态的保存(比如去重指标的明细数据),用于在发生故障时,使用数据库中的数据恢复内存现场。

  • 最终结果数据——指的是通过 ETL 处理后的实时结果数据,这些数据是实时更新的,写的频率非常高,可以被下游直接使用。

  • 维表数据——在离线计算系统中,通过同步工具导入到在线存储系统中,供实时任务来关联实时流数据。

维表数据在实时数据处理任务中扮演着关键角色,尤其是在构建实时数据仓库或实时分析系统时。维表,即Dimension Tables,是数据仓库架构中的重要组成部分,它们包含了描述性的信息,用来给事实表中的数据提供上下文。在实时任务中,维表数据的使用主要体现在以下几个方面:

  1. 上下文丰富
    维表提供了对事实数据的详细描述,如产品类别、客户信息、地理位置等,这些都是在事实表中通过外键引用的。当实时流数据到达时,通过与维表的关联,可以增加数据的维度,从而让数据更加丰富和有意义。

  2. 实时关联
    实时任务需要快速地将流数据与维表数据进行关联,以提供即时的分析结果。这通常涉及到高效的关联算法和存储结构,如内存中的哈希表,以减少延迟并提高处理速度。

  3. 数据更新
    维表数据可能随时间变化,如产品分类调整、客户地址变更等。实时任务必须能够及时反映这些更新,以确保分析结果的准确性。这通常要求维表具有良好的更新机制,如增量更新或全量更新策略。

  4. 存储选择
    为了满足实时关联的需求,维表数据往往存储在高性能的存储系统中,如内存数据库(如Redis)、列式存储数据库(如Druid)或关系型数据库(如MySQL)。选择合适的存储系统对于保证实时性能至关重要。

  5. 资源管理
    如果维表数据量较大,全量加载到内存可能不现实,这时可能需要采用部分加载、缓存策略或按需从后端存储系统查询数据的方法。

  6. 容错性
    实时任务中维表数据的使用还需要考虑系统的容错性,即在数据源不可用或数据损坏时,如何保证数据处理的连续性和正确性。

总之,维表数据在实时任务中提供了必要的上下文信息,使数据更具可解释性,并且需要通过高效的设计和实施策略来确保实时性和准确性。

2 数据库类型

数据库包括关系数据库、列式数据库、文档数据库等,在选择实时任务所用的数据库时,应该注意哪些特征呢?
前面的文章中提到过实时任务是多线程处理的,意味着使用的数据存储系统必须能较好的执行多并发读写,并且延时需要在毫秒级别
实践中用得较多的有HBase\Tair\MongoDB等列式存储系统,它们基本满足需求。

列式存储系统是一种专门设计用于优化数据分析工作负载的数据存储技术。与传统的行式存储不同,列式存储将数据按照列(属性)进行组织和存储,而不是按照行(记录)。这种存储方式尤其适用于数据仓库和大数据分析场景,因为在这种场景中,查询往往针对特定的列执行聚合或筛选操作,而不需要访问整行数据。
以下是列式存储的一些关键优势:

  1. 压缩效率高
    列式存储可以更有效地进行数据压缩,因为相同类型的数值存储在一起,压缩算法能更好地识别和消除冗余,从而节省存储空间。
  2. 查询性能
    在分析型查询中,由于只需要读取感兴趣的列,列式存储可以显著减少磁盘I/O操作,提高查询速度。例如,在计算所有用户的平均年龄时,只需要读取“年龄”这一列,而无需读取其他列的数据。
  3. 支持并发读取
    列式存储设计通常支持并发读取,这意味着多个查询可以同时运行而不会互相阻塞,提高了系统的吞吐量。
  4. 聚合和过滤操作优化
    对于常见的聚合和过滤操作,列式存储可以只处理相关的列,而忽略其他列,从而加快处理速度。
  5. 适合大数据处理
    列式存储系统,如Apache Parquet、Google BigQuery、Amazon Redshift等,专为大规模数据集设计,可以高效地处理PB级数据。

然而,列式存储也存在一些缺点:

  • 写入操作成本高
    更新或插入操作可能需要重写整个列,因此写入性能可能不如行式存储。
  • 不适合随机行访问
    如果应用程序需要频繁随机访问单个行,则列式存储可能不是最佳选择,因为这会涉及读取所有列才能重组一行数据。
  • 复杂性
    列式存储系统的实现和管理可能比行式存储系统更复杂,特别是在需要支持多种数据类型和复杂查询的情况下。
    总体而言,列式存储非常适合那些需要大量读取和分析操作的场景,而对写入操作的要求相对较低。

但是这些系统也有明显的缺点,以HBase为例,一张表必须有rowkey。rowkey是按照ASCII码来排序的,这种规则限制了数据读取的方式,如果业务方需要采用其他方式读取数据则需要重新输出rowkey,从这个角度看HBase甚至没有关系型数据库方便,但HBase一张表能存几到几十TB,而关系型数据库需要采用分库分表的处理(Day5讲过)才能做到。因此,对于海量数据的实时计算,一般会采用非关系型数据库,以应对大量的多并发读写。

HBase 是一个分布式、版本化的 NoSQL 数据库,它基于 Google 的 Bigtable 论文设计,主要用于处理海量的半结构化或非结构化数据。在 HBase 中,数据是以表格的形式存储的,每个表由一系列的行组成,而每一行都由一个唯一的行键(RowKey)来标识。

RowKey 的概念

RowKey 在 HBase 中起着至关重要的作用,它是数据的主键,用于唯一标识表中的每一条记录。HBase 不提供传统的 SQL 式的索引,所以所有的数据检索和查询都直接或间接依赖于 RowKey。

RowKey 的特点

  1. 唯一性:每个 RowKey 必须是唯一的,以便区分表中的不同行。
  2. 排序:RowKey 是按字典顺序排序的,这意味着 HBase 可以高效地进行范围查询,即查找介于两个 RowKey 值之间的所有行。
  3. 长度:RowKey 的最大长度可以达到 64KB,但实际上,为了性能考虑,RowKey 应该尽量短小。
  4. 二进制格式:RowKey 是以二进制格式存储的,这意味着它可以是任何二进制数据,包括数字、字符串或者更复杂的组合。

RowKey 的设计原则

设计 RowKey 时,应考虑到以下几点:

  • 查询模式:RowKey 应该反映最常见的查询模式,以优化查询性能。
  • 分布性:RowKey 的设计应该尽可能均匀分布,避免热点问题,确保数据在集群中均匀分布。
  • 时间戳:有时,RowKey 包含时间戳,这样可以方便地按照时间顺序检索数据。
  • 复合 RowKey:RowKey 可以由多个字段组成,称为复合 RowKey,以包含更多的信息和优化查询。

RowKey 的示例

假设有一个用户行为日志表,常见的查询是根据用户 ID 和日期来获取数据,那么 RowKey 可能设计为 <UserID>:<Date> 的形式,例如 12345:20230101

总结

RowKey 是 HBase 中最重要的概念之一,它的设计直接影响到数据的存储效率和查询性能。合理设计 RowKey 可以帮助最大化 HBase 的性能,满足特定的应用需求。

3 表名设计和rowkey设计

表名设计示例

设计规则:汇总层标识+数据域+主维度+时间维度
例如: dws_trd_slr_dtr
表示:汇总层交易数据,根据卖家(slr)主维度+0点截至当日(dtr)进行统计汇总
这样做的好处:

  • 减少表数量:将具有相同主维度的数据放在同一张物理表中,可以有效减少表的数量,使得数据库结构更加简洁,易于维护。
  • 直观易懂:通过表名可以直接看出存储的是什么类型的数据内容,这对于排查问题非常有帮助,因为开发者不需要花费太多的时间去理解表的结构和用途。

rowkey设计

设计规则:MD5 + 主维度 + 维度标识 + 子维度 1 + 时间维度 + 子维度 2

例如:卖家 ID 的 MD5 前四位 + 卖家 ID + app + 一级类目 ID + ddd + 二级类目 ID。

以 MD5 的前四位作为 rowkey 的第一部分,可以把数据散列,让服务器整体负载是均衡的,避免热点问题。在上面的例子中,卖家 ID 属于主维度,在查数据时是必传的。每个统计维度都会生成一个维度标识,以便在rowkey上做区分。

  • MD5: 这里指的是MD5哈希算法,它会将任意长度的数据转换成一个固定长度(通常是128位)的哈希值。MD5的前四位(通常是指哈希值的前几位字符)被用作rowkey的一部分,目的是为了散列数据,使得数据均匀地分布在多个服务器上,从而避免数据热点(即某些服务器上的数据访问远高于其他服务器)。

  • 主维度: 指的是数据中的主要分类或最重要的属性,比如这里的“卖家ID”。主维度在查询数据时通常是必填项,意味着大部分查询操作会基于这个维度进行。

  • 维度标识: 是对不同统计维度的标记,用于区分不同的统计数据类型或来源,确保即使主维度相同,不同的数据类型也能通过不同的维度标识进行区分。

  • 子维度: 子维度是对主维度的进一步细分,这里提到了“子维度1”和“子维度2”,例如“app”(应用程序)和“类目ID”(产品类别),它们可以提供更详细的分类信息。

  • 时间维度: 指的是与时间相关的部分,这可以是日期、时间戳或者特定的时间周期,例如“ddd”可能代表某一天或者某一时间段,这样可以方便进行时间范围内的数据查询。

按照上述规则设计的rowkey示例:“卖家ID的MD5前四位+卖家ID+app+一级类目ID+ddd+二级类目ID”。

这种设计的好处在于:

  1. 数据分散: MD5的前四位确保数据均匀分布在存储集群中,防止单点过载。
  2. 查询优化: 主维度和其他维度的组合可以帮助快速定位和检索特定的数据记录。
  3. 灵活性: 设计允许根据不同的查询需求进行扩展,同时保持数据的组织性和可读性。

总之,rowkey的设计应该考虑到数据的分布、查询模式以及可能的扩展需求,以确保数据库系统的高效运行。


今天的分享到这里就结束啦,点赞关注收藏,获取更多专业知识~

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

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

相关文章

微信小程序开发:DOM 相关 API 使用详解

在微信小程序开发中&#xff0c;与传统的网页开发相比&#xff0c;由于安全性和性能考虑&#xff0c;访问 DOM&#xff08;文档对象模型&#xff09;是受限的。然而&#xff0c;微信小程序提供了一些特定的 API&#xff0c;使开发者能够处理和操作视图层&#xff0c;实现丰富的…

Transformer之Vision Transformer结构解读

论文地址 代码地址 写在前面 什么是Transformer呢&#xff1f;就是把符号向量化为Token&#xff0c; 再和位置编码求和或者做阿达玛积&#xff0c;最后送入一定层数的Attention Block构成的Encoder和Decoder&#xff0c;就完成了Transformer的基础功能。 那么&#xff0c;把上…

C基础函数——内存分配(未完)

在C语言中&#xff0c;内存管理是非常重要的一部分。C语言提供了几种不同的函数用于动态内存分配和释放&#xff0c;这些函数允许程序在运行时根据需要分配和回收内存。以下是C语言中常用的几个内存管理函数&#xff1a; malloc() void malloc(size_t size); 这个函数用于请求…

C++中枚举(enum)的用法和限制

在C中&#xff0c;枚举&#xff08;enum&#xff09;是一种用户定义的类型&#xff0c;它允许程序员为整数常量指定易于阅读的名字。枚举类型是由一组命名的整型常量组成的类型&#xff0c;每个常量都表示该类型的一个有效值。枚举在编程中常用于表示一组固定的值&#xff0c;如…

MySQL:mysql的数据类型

MySQL 作为一个流行的关系型数据库管理系统&#xff0c;支持多种数据类型以满足不同的数据处理和存储需求。正确理解和使用这些数据类型对于提高数据库性能、确保数据完整性和准确性至关重要。 MySQL 数据类型 数据类型定义了列中可以存储什么数据以及该数据怎样存储的规则。…

idea2019版本创建JavaWeb项目并配置Tomcat步骤

一、创建JavaWeb项目 1.新建项目File->New->Project 2. 选择JavaWeb应用在New Project窗口中选择Java后勾选Java EE中的Web Application后点击next即可 3.设置项目名称后点击finish即可 4.至此项目创建完成&#xff0c;检查文件是否齐全&#xff0c;开始配置Tomcat 二、…

IDEA工具中Java语言写小工具遇到的问题

一&#xff1a;读取excel时遇到 org/apache/poi/ss/usermodel/WorkbookProvider 解决办法&#xff1a; 在pom.xml中把poi的引文包放在最前面即可&#xff08;目前就算放在最后面也不报错了&#xff0c;不知道为啥&#xff09; 二&#xff1a;本地maven打包时&#xff0c;没有…

base SAS programing学习笔记(read raw files2)

使用COLUMN input和FORMATTED input读入固定位置的外部文件&#xff1b;如下图所示&#xff0c; 1.COLUMN input &#xff08;按列数读入外部文件数据&#xff09; 使用column input 不需要按从左到右的顺序读取外部文件的数值&#xff0c;可以是任意读取&#xff0c;也可以重…

LeeCode Practice Journal | Day18_Binary Tree06

530.二叉搜索树的最小绝对差 题目&#xff1a;530. 二叉搜索树的最小绝对差 - 力扣&#xff08;LeetCode&#xff09; 题解&#xff1a;代码随想录 (programmercarl.com) 验证搜索树的进阶&#xff0c;二叉树中的双指针&#xff0c;思考过程中发现容易弄混递归向下传播和向上回…

STM32F103定时器中断详解

目录 目录 目录 前言 一.什么是定时器 1.1 STM32F103定时器概述 1.2基本定时器 1.2通用定时器 1.3高级定时器 1.4 三种定时器区别 基本定时器&#xff08;Basic Timer&#xff09; 通用定时器&#xff08;General-Purpose Timer&#xff09; 高级定时器&#xff08;Advanced Ti…

ubuntu2204配置anacondacuda4090nvidia驱动

背景 某个机房的几台机器前段时间通过dnat暴露至公网后被入侵挖矿&#xff0c;为避免一些安全隐患将这几台机器执行重装系统操作&#xff1b; 这里主要记录配置nvidia驱动及cuda&anaconda。 步骤 大概分为几个步骤 禁用nouveau配置grub显示菜单install nvidia-driveri…

基于Python+Django,开发的一个在线教育系统

一、项目简介 使用Python的web框架Django进行开发的一个在线教育系统&#xff01; 二、所需要的环境与组件 Python3.6 Django1.11.7 Pymysql Mysql pure_pagination DjangoUeditor captcha xadmin crispy_forms 三、安装 1. 下载项目后进入项目目录cd Online-educ…

【Rust光年纪】解锁Rust语言核心库奥秘:加密、数字签名和数据库操作全面解析

从加密到数据库&#xff1a;探索Rust语言丰富的工具库生态系统 前言 在Rust语言开发中&#xff0c;使用合适的库可以极大地提高代码的安全性和效率。本文将介绍一些用于加密、数字签名、数据库连接等功能的Rust语言库&#xff0c;帮助读者快速了解其核心功能、使用场景以及安…

Ubuntu2204搭建ceph17

Ceph 环境初始化搭建Ceph 本次实验基于VMware17 节点IPstorage01192.168.200.161storage01192.168.200.162storage01192.168.200.163 环境初始化 初始化基础环境&#xff0c;三节点执行 #!/bin/bash# 定义节点信息 NODES("192.168.200.161 storage01 root" "…

配置RIPv2的认证

目录 一、配置IP地址、默认网关、启用端口 1. 路由器R1 2. 路由器R2 3. 路由器R3 4. Server1 5. Server2 二、搭建RIPv2网络 1. R1配置RIPv2 2. R2配置RIPv2 3. Server1 ping Server2 4. Server2 ping Server1 三、模拟网络攻击&#xff0c;为R3配置RIPv2 四、在R…

Linux:Linux权限

目录 1. Linux权限的概念 2. Linux权限管理 2.1 文件访问者的分类 2.2 文件类型和访问权限 2.2.1 文件类型 2.2.2 基本权限 2.3 文件权限值的表示方法 2.4 文件访问权限的相关设置方法 2.4.1 chmod 2.4.2 chown 2.4.3 chgrp 2.4.4 umask 3. file指令 4. Linux目…

base SAS programming学习笔记13(Array)

1.Array array-name{dimension} <elements> array-name&#xff1a;向量名称 dimension&#xff1a;向量长度&#xff0c;默认为1&#xff1b; elements:列出变量名&#xff0c;变量名要么全是数值变量或者全是字符变量 array-name和variable不能相同&#xff1b;也不能和…

C++面试题之判断一个变量是不是指针

对于变量其实对应的就是内存&#xff0c;而内存并没有表明一定是什么数据类型&#xff0c;所以判断变量是否是一个指针其实是一个参数类型匹配问题&#xff0c;在C中支持函数的重载&#xff0c;那么不同的函数因为参数的不同从而匹配不同函数调用过程。 编译器在进行函数匹配调…

JAVA周总结(集合) 0721day

一.Collection集合 集合:可以存放多种类型数据的容器。 集合和数组的区别 数组的长度是固定的,集合的长度根据存储的数据发生改变。 数组只能存同一种类型的数组,而集合可以存多种类型。 1.2 单列集合常用类的继承体系 java.util.List: 添加的元素是有序、可重复 ; Lis…

欢迎来到 Mint Expedition:Web3 和 NFT 的新时代开始

7 月 15 日&#xff0c;Mint Expedition 正式开启&#xff0c;作为 Mint 生态系统的旗舰项目&#xff0c;将彻底变革 Web3 和 NFT 去中心化应用&#xff01; Mint Expedition 是 Mint 的最新航程&#xff0c;延续了 Mint Forest 的成功。Mint Forest 吸引了超过 41.4 万独立用…