建模杂谈系列236 Block Manager

说明

很久没有写了,总是写一半就没空往下写。这次正好有个单独的主题,可以写一下。

内容

1 块的分配

数据应该怎么切分和管理?这没有一个固定的答案,在我的实践中,我觉得一个块(Block)一万条记录是比较合理的。然后按照片(Shard)、区(Partition)进行拆分和管理。

我稍微重新定义了片区块的概念。

片 Shard: 可以理解一个片就是一个物理存储位置,A主机存一个片,B主机存一个片。片是集群管理的单位。

区 Partition: 区对应于表级的概念。一个项目或主题有一个库名,下面会分为若干表,也就是分区。库名是项目名称。

块 Block: 对应于表内的一个索引字段,按照顺序进行编号。块有两种类型,一种是时间型的,按时隙进行顺序编号;另一种是空间型的,只是按照入库的顺序进行编号。

片的意义是,当数据真的非常大,需要集群来进行分担时采用的存储单元。当然,有的时候是因为并发太大,将记录均匀映射到多个分片,从而让集群中的每台机器来均匀的处理请求。

区的意义是,当进行查询时,仅需对相对较小的部分进行查询。

块的意义是,既满足并行处理的效率需求,也满足存储,特别是内存的限制。效率问题主要是指:当我们逐条处理数据时,CPU的性能大部分是处在停等状态的。显然我们可以批量执行来提高处理效率,以目前我接触到的处理来看,一万条应该是一个比较合适的量级:吞吐量是一条的约一万倍,同时对于大部分数据而言,内存都不会占用太多。

2 块的编号

按照上面设计的层级,一个块可以由 project_nameshard_idpart_idblock_id构成。按照物理的级别,实际上层级的顺序应该是 shard_id ~ 物理机、project_name ~ 库名、part_id ~ 表名 和block_id ~ 筛选字段。block_id又可以分为时间和空间两部分id。

一个样例名称是: myproject.0.0.0.0,其意义为:
myproject : 项目名称
第一个0 : shard, 0~999, 0 通常也意味着没有启动集群
第二个0 : part, 0~999 ,0 也意味着初始表,如果一个project只有一个sub_project, 那么一个part容纳1000个block,也就是一千万条记录
第三个0: 0 时隙,意味着时隙无关数据,时隙顺着统一时间轴编号,这个可以是默认的轴。
第四个0: block, 0~999 ,这个是通过sub_project的rec_id计算出来的,每个sub_project的rec_id是唯一的。

因此,假设project只有一个sub_project时,每个数据库服务(对应某块硬盘)的存储的数据大约是10万(1000*1000)个block,也就是10亿条数据。要扩充这个设计上线只要改变编号数就可以,我是觉得这个尺寸刚好。因为数据库服务是微服务,如果主机够强,可以支撑多个shard(1000),那么就是1万亿条数据。我可以假定一个项目不会超过这个数据上限(至少目前没有碰到如此夸张的数据)。

3 Worker

worker是实现逻辑的核心单元,通过player进行调度,每个worker每次处理的数据单位就是block。 worker会按照块编号提出自己的数据请求。

在某一次处理中,worker将锁定某一个时空的block(通过编号),发起数据请求。当数据请求被满足时,worker将执行任务。这里有几方面内容:从时间序列的角度来说,先取时间块,再取空间块。例如,某个worker要处理某个标的的数据,先获取时间块(例如对应2020年1月数据),再从时间块中获取某个标的的数据(空间块)。有时候,问题可能会简化为时间无关的空间块需求(例如对全量进行处理)

每时每刻都会有大量的worker分别在完成不同的任务,这会带来很多挑战。

首先,是计算资源,如CPU或者GPU。这个一般可以通过worker的数量进行简单的控制:每个worker处理的基础单位是block(n>=1),因此在设计时就天然的限制了内存的使用,以及CPU/GPU的使用(毕竟数据少,计算时间短)。所以,在多个worker下,每个项目总有机会得到轮替执行。由于分布式网络的存在,以及现在很流行的算力租用,启动更多的worker变的容易。所以计算资源暂时可以认为是容易解决的。

其次,是存储资源,或者说是IO资源。在极端情况下,假设只有一个worker,那么显然,worker可以直接从数据库调取数据;当有多个worker,这些worker可能会反复的对某些块发出需求,此时数据库就会濒临崩溃。由于内外存的数据存储速度还是存在巨大的差异,并且反复执行数据库查询操作会占用大量的CPU时间,连接数等,这会导致服务器的能力急剧下降。关键是从道理上来说,每个worker都没错,但是从整体上来看,这些独立的worker造成了大量的浪费。比如1000个worker,就对某个块读取了1000次。特别是,当算力拓展到租用机时,如何确保这些租用机能获取到相应的数据?

4 Block Manager

所以,Worker不能直接从数据库(Mongo)取数,而是要从内存(Redis)里取数;另外,如何对于数据减少反复读取,以及分发到扩展主机上,需要有一个管理者。这就是Block Manager。

worker在一次运行中(通常是半个时隙,或者说一个节拍)会执行元数据计算,或者是数据计算。

在元数据计算阶段,主要需要计算状态,以及对应的数据请求。状态会决定是否可计算,以及具体的计算方法。并根据据此提供所需求的数据需求(数据块名称)。

在计算阶段,worker尝试读取数据块进行工作,并将结果(无论是顺利执行,数据缺失或者逻辑错误)写入元数据,然后结束。

因此,Block Manager需要接受来自不同worker的块请求,去数据库取数,存在内存里。其管理作用体现在:

  • 1 预取数 Pre-Fetch。
  • 2 动态删除数据 Dynamic-Delete。
  • 3 避免重复取数 Read Once

我觉得chat归纳的比我清晰。
在这里插入图片描述

4.1 预取数

worker有两种方式:一种空间型的,通过player可以做全盘的规划,然后并行执行;还有一种是时间型的,下一次worker的执行必须依赖本次worker执行的结果。

空间型的预取数主要是根据计划表按“通道”来执行提前取数。首先player会生成一张待执行表,表里有一个通道字段,供不同的worker进行并行。一般任务数不会超过10万个(每个任务的block是一万)。worker所在的服务器在执行任务时,会被分配一个任务通道,然后按顺序执行任务。这个顺序会按通道删选,可能还会按照优先级排序(可动态),然后再按照所使用的block顺序排序。

worker的元信息中会包含所属任务表,这样Block Manager就知道当前worker的需求,同时可以较为准确的知道接下来worker需要哪些数据。这是属于通过任务(计划)表进行的预取数,还有一种是通过模型/算法进行取数预测,这是后话。

取数分为两种,历史的和最新的。如果是历史取数,那么只要block存在,就不必再读取。如果是最新(次新)的block,就需要反复读取。预取数可以提前准备好n个block,这样如果worker处理的时间足够长,那么在下一次时隙到来时,其运行总是不用停等的。由于BM将数据取到了内存,worker只是在内存中取数。

4.2 动态删除数据

BM每次获取block时都会设置失效时间,一般是一天。这种被动式的删除数据方法显然太慢,如果worker请求的block很多,那么内存将很快被撑爆。

BM应当接受一些参数来采取更主动的数据管理,这些参数包括:最大的块限制、最大的内存使用限制。

这要求BM对存储块保持跟踪对每个块的追踪(block_tracking_table),包括某个块的载入次数,大小等,这样就可以接受参数来进行控制。

4.3 避免重复取数

通常worker会发送task_table的信息给到BM,BM会读取并比较这些task_table是否是取相同的数据源等。

5 Class BlockManager

用一些粗糙的方法来展示BM的一些功能

class BlockManager:
	state = 'I' # 初始化
	def __init__(self,name):
		pass
	def _set_max_blocks(): # 最大的块
		pass
	def _set_max_mem(): # 最大内存
		pass
	def _mongo_connect(): # 数据库连接
		pass
	def _redis_connect(): # redis连接
		pass
	def pre_fetch():  # 预取数
		pass
	def flip(): # 元数据计算
		pass
	def flop(): # 数据计算
		pass
	def gc(): # 内存回收
		pass
	def ikeep(): # 适当的保存数据避免重复读取
		pass
	def _merge_task_table(): # 读取新的任务表,来进行块的估计
		pass

先写到这吧,假期快结束了。

一句话总结:数据的IO与数据的流转是两个完全不同的领域。之前的ADBS已经完成了流转部分功能,在IO方面需要BM及规范来确保大量的计算是自由的。

最后再补充一点,片、区、块的设计是UCS的一部分,在拓展计算(租用算力上),可以通过rsync方式将块以文件方式同步到算力机上,这样就实现了数据的全局同步。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

PostGIS学习教程十八:维数扩展的9交集模型

PostGIS学习教程十八:维数扩展的9交集模型 文章目录 PostGIS学习教程十八:维数扩展的9交集模型一、什么是维数扩展的9交集模型二、查找具有特定关系的几何图形三、数据质量测试四、本文涉及的函数五、更多相关资料 一、什么是维数扩展的9交集模型 “维数…

计算机基础知识——数据的表示概述

目录 1 进制转换 1.1 二进制、十进制和十六进制等常用数制及其相互转换 1.2 十进制和二进制之间转换 1.3 二进制数与八进制数、十六进制数之间的转换 2 码值:原码、反码、补码 2.1 原码 2.2 反码 2.3 补码 3 浮点数表示 3.1 浮点数的运算 1 进制转换 1…

Chinese-llama-2部署踩坑记录

Chinese-llama-2部署踩坑记录 1. Chinese-LLaMA-Alpaca-2A. 部署a. inference_with_transformers_zhb. text generation webui_zhc. api_calls_zhd. llamacpp_zhe. privategpt_zhf. langchain_zh Tool Github 1. Chinese-LLaMA-Alpaca-2 A. 部署 a. inference_with_transform…

【UnityShader入门精要学习笔记】(2)GPU流水线

本系列为作者学习UnityShader入门精要而作的笔记,内容将包括: 书本中句子照抄 个人批注项目源码一堆新手会犯的错误潜在的太监断更,有始无终 总之适用于同样开始学习Shader的同学们进行有取舍的参考。 文章目录 上节复习GPU流水线顶点着色…

【git使用】一个非常适合新手的代码管理方法——master/develop模型

生产/开发模型【支持master/develop 类型分支】 1.gitee、github创建仓库2.使用sourcetree拉取仓库3. 检出develop分支,并初始化工作流4.模拟日常开发流程5.具备发布条件,进行发布6.将master和develop分支的版本都推送到远程仓库7.继续循环4-5-6进行开发…

Python 面向对象之多态和鸭子类型

Python 面向对象之多态和鸭子类型 【一】多态 【1】概念 多态是面向对象的三大特征之一多态:允许不同的对象对同一操作做出不同的反应多态可以提高代码的灵活性,可扩展性,简化代码逻辑 【2】代码解释 在植物大战僵尸中,有寒冰…

数据结构和算法-希尔排序(增量序列 算法实现 性能分析 稳定性)

文章目录 希尔排序过程小结增量序列不是固定的 算法实现算法性能分析稳定性小结 希尔排序 基本有序,就是存在有序的子序列 通过增量4得到各个子表 对各个子表分别进行插入排序 缩小增量,再除2,此时的子表 对各个子表插入排序 缩小增量&…

STC进阶开发(四)SPI协议、矩阵键盘、EEPROM

前言 这一期我们简单介绍一下SPI协议,然后我们学习一下矩阵键盘,了解EEPROM是干什么用的,话不多说,开整! SPI协议 SPI(Serial Peripheral Interface)是一种同步串行通信协议,用于在…

OJ刷题 第十七篇()

34005 - 汽水瓶(有意思) 时间限制 : 1 秒 内存限制 : 128 MB 有这样一道智力题:“某商店规定:三个空汽水瓶可以换一瓶汽水。小张手上有十个空汽水瓶,她最多可以换多少瓶汽水喝?”答案是5瓶,方…

Python 测试框架 Pytest 入门

简介 pytest 是一个功能强大而易于使用的 Python 测试框架。它提供了简单的语法和灵活的功能,用于编写和组织测试代码。 1、简单易用:pytest 的语法简洁明了,使得编写测试用例更加直观和易于理解。它使用 assert 语句来验证预期结果&#x…

SpringBoot内嵌的Tomcat启动过程以及请求

1.springboot内嵌的tomcat的pom坐标 启动后可以看到tomcat版本为9.0.46 2.springboot 内嵌tomcat启动流程 点击进入SpringApplication.run()方法里面 看这次tomcat启动相关的核心代码refreshContext(context);刷新上下文方法 public ConfigurableApplicationContext run(Stri…

银行卡号识别

导入库 from typing import Any, Union, Sequencefrom cv2.mat_wrapper import Mat from imutils import contours import numpy as np import argparse import imutils import cv2 import myutils设置参数 # 设置参数 from numpy import dtype, ndarray, genericap argpars…

“巴渝工匠杯”2022年重庆市职业院校技能大赛(高职组)云计算样题

“巴渝工匠杯”2022年重庆市职业院校技能大赛(高职组)云计算样题 需要软件包环境可私信博主 【赛程名称】云计算赛项第一场次-私有云 某企业拟使用OpenStack搭建一个企业云平台,以实现资源池化弹性管理、企业应用集中管理、统一安全认证和授…

Visual Studio 2022进行文件差异比较

前言 Visual Studio 2022在版本17.7.4中发布在解决方案资源管理器中比较文件的功能,通过使用此功能,可以轻松地查看两个文件之间的差异,包括添加、删除和修改的代码行。可以逐行查看差异,并根据需要手动调整和编辑文件内容以进行…

易图讯便携式三维电子沙盘实战应用系统

便携式三维电子沙盘采用军工加固三防高性能笔记本,具有IP65级防尘防水防摔性能,以大数据、云计算、虚拟现实、物联网、AI等先进技术为支撑,支持高清卫星影像、DEM高程数据、矢量数据、三维模型、倾斜摄像、BIM、点云、城市白模、等高线、标高…

数据结构学习 jz56数组中数字出现的次数

关键词:位运算 异或性质 虽然有两道题,但是其实应该分成三个级别的题目。 题目一: 一个整型数组 sockets 里除 一个 数字之外,其他数字都出现了两次。 思路:异或的性质 复杂度计算: 时间复杂度O(n) 空…

在Go语言中处理HTTP请求中的Cookie

在Web开发中,Cookie是一种常用的技术,用于在客户端存储数据,并在随后的请求中发送回服务器。Go语言的标准库提供了强大的支持来处理HTTP请求中的Cookie。 首先,让我们了解如何在Go语言中设置Cookie。以下是一个简单的示例&#x…

three.js场景设计器-小地图的视角参考功能

three.js实现场景方向的左上角小地图 思路 1&#xff1a;创建单独场景 2.添加辅助线 3.添加坐标轴的XYZ文字-使用sprite实现 4.旋转主视图时同步相机位置到小地图。 <template> <div ref"miniMapContainer" class"mini-map"></div>…

Apache Commons Email在邮件发送中的应用

第1章&#xff1a;简介 大家好&#xff0c;我是小黑&#xff0c;今天咱们聊聊Apache Commons Email这个库&#xff0c;它在发送邮件方面可谓是小而美的利器。Apache Commons Email基于JavaMail API&#xff0c;但它提供了更简洁、更易用的接口&#xff0c;让咱们在处理电子邮件…

如果PostgreSQL有两层nginx代理,会发生什么事?

转载说明&#xff1a;如果您喜欢这篇文章并打算转载它&#xff0c;请私信作者取得授权。感谢您喜爱本文&#xff0c;请文明转载&#xff0c;谢谢。 1. 前言 PostgreSQL默认只能本机连接&#xff0c;若要在别的客户端远程连接pgsql&#xff0c;则需要修改配置文件pg_hba.conf&a…