从 Hadoop 到云原生,大数据平台如何做存算分离
本文的理论思想来源于 JuiceFs 社区的一篇文章《从 Hadoop 到云原生,大数据平台如何做存算分离》,本文分为理论+实践两个部分,理论部分是对社区文章的总结、实践部分则是对理论的落地探索企业对 hadoop 生态的改造
一、大数据平台如何做存算分离
1.1 hadoop 存算耦合架构回顾
hadoop 作为大数据时代的开山组件,作为一个 all-in-one 套件有三个核心组件:MapReduce负责计算、Yarn负责资源调度、HDFS负责存储。在这三个组件中,发展最迅速和多元的是计算组件这一层,最早只有一个 MapReduce,但业界很快在计算层上面各显神通,造出了一大堆的轮子,包括有 MapReduce,Tez,Spark 这样的计算框架,Hive 这类数据仓库,还有 Presto、Impala 查询引擎,各种各样的组件。配合这些组件的,还有像 scoop 这样的数据流转采集的组件也很丰富,一共有几十款。
但底层存储经过了大概 10 年左右的时间,一直是 HDFS 一枝独秀,带来的一个结果就是它会成为所有计算组件默认的设计选择。上面提到的这些大数据生态里发展出来的各种组件,都是面向HDFS API 去做设计的。有些组件也会非常深入的利用 HDFS 的一些能力,比如深入看 Hbase,在写 WAL log 的时候就直接利用了HDFS 的一些很内核的能力,才能达到一个低时延的写入;比如说像最早的 MapReduce 和 Spark 也提供了数据亲和性(Data Locality)的能力,这些都是HDFS 提供的一些特殊的 API。这些大数据组件面向 HDFS API 设计的做法, 为后续数据平台上云带来了潜在的挑战。MapReduce等计算框架针对海量数据还提出了“移动计算”的计算模型和本地读取的设计思想,其主要原因就是网络带宽是一个瓶颈。这些都促使 hadoop 在设计之初就是一个存算耦合的架构。
1.2 存算分离需求的出现
从企业需求来看,2006年到2016年的十年发展。企业数据增长很快,但算力的需求其实长得没那么快,这些计算任务不会发生一天一倍的去涨的情况,但是产生的数据的速度是是非常快的,有可能是指数型的;而且有些数据产生出来,也不一定马上知道怎么用,但未来会用,所以企业都会先把数据尽可能全量的去存起来,再去挖掘它的价值。在这个背景下,存算耦合的硬件的拓扑的架构就给扩容带来了一个影响,当存储不够,就要去加机器。但是不能只加机器,不能只有硬盘,因为在存算耦合的架构上,数据的节点还需要负责计算,所以 CPU 和内存也不能太差。因此配置的机器都是计算与存储配置非常平衡的机器,在提供足够存储容量的同时,也提供了等量的算力。但实际场景中算力的需求没涨。这样扩出来的算力对企业来说造成了更大的浪费,整个集群在存储和 I/O 上的资源利用率可能是非常不平衡的,**当集群越大,这种不平衡就越严重。而且另外买机器也挺难的,购买的机器必须是计算与存储平衡的。**在这个过程中硬件也发生了翻天覆地的变化,带宽将不在是限制,这给存算分离架构带来了可行性。
1.3 如何实现存算分离
1. 最初的尝试:云上部署 hdfs
最初的方案比较简单,就是独立部署 HDFS,不再和负责计算 worker 去混合部署。这个方案在 Hadoop 生态里,没有引入任何的新组件。即 DataNode 节点上不再部署 NodeManager,存储成为独立的集群,计算需要用到的数据都会通过网络来传输,端到端的万兆网卡去支持。在这个改变里,尽管 HDFS 最巧妙的数据本地性这个设计被舍弃了,但由于网络通讯速度的提高,给集群的配置带来更大的便利。但是这个架构没有得到进一步发展,是什么原因呢?最大的一个原因,当在机房做这样的改造是可行的,但当我们去使用云上资源的时候,这个方案的弊端就显露了。
首先,源自于 HDFS 的多副本机制在云上会增加企业的成本。过去为了避免裸硬盘的损坏 HDFS 设计了多副本机制来保证数据的安全性,同时多副本机制还承担数据的可用性,因为除了磁盘的损坏还存在 DataNode 宕机的情况。当 HDFS 被迁移到云上,云厂商提供的云盘也是经过多副本机制,企业用云盘搭建 HDFS 再去配置软件层面的多副本,如果都是三倍冗余那么企业数据在云上就要存 9 份,成本飙升好几倍。后来云厂商也提供一些裸硬盘机型,但这类机型往往非常少且型号不一定符合企业要求。
其次,这个方案依然是需要企业去云上部署 HDFS 集群,需要自己创建机器、监控和维护。企业并没有得到云上的独特优势,对于如开箱即用、弹性伸缩、按量付费等。
最后,由于 HDFS 本身的限制,当集群存储文件过多时 NameNode 的内存将是集群的瓶颈,负载高容易触发 FullGC 影响集群的可用性,这就需要引入 HDFS 的 Federation 机制,但它就增加了运维和管理的成本。
2. 公有云+对象存储
随着云计算技术的成熟,企业存储又多了一个选项————对象存储。最早从 AWS 开始,后来所有的云厂商其实都在往这个方向发展,开始推动用对象存储去替代 HDFS。这些方案首先带来了两个 HDFS 无法实现的最明显的好处:
- 对象存储是服务化的,开箱即用,不用做任何的部署监控运维这些工作
- 弹性伸缩,企业可以按量付费,不用考虑任何的容量规划,开一个对象存储的 bucket ,有多少数据写多少数据,不用担心写满(只要你付得起账单就是无限存储)
这些方案相比在云上独立部署 HDFS , 运维方面是有了很大的简化。但当对象存储被用来去支持复杂的 Hadoop 这样的数据系统,就会发现如下的一些问题。
- 文件 Listing 的性能比较弱。对象存储的元数据结构是扁平的,当用户需要存储成千上万,甚至数亿个对象,对象存储需要做的是用 Key 去建立一份索引,Key 可以理解为文件名是该对象唯一标识符。如果用户要执行 Listing,只能在这个索引里面去搜索,搜索的性能相比文件系统树形结构的查找弱很多。
- 对象存储没有原子 Rename, 影响任务的稳定性和性能。在 ETL 的计算模型中,每个子任务完成会将结果写入临时目录,等到整个任务完成后,把临时目录改名为正式目录名即可。但由于对象存储没有原生目录结构,处理 rename 操作是一个模拟过程,会包含大量系统内部的数据拷贝,会耗时很多,而且没有事务保证。
- 对象存储数据最终一致性的机制,会降低计算过程的稳定性和正确性。举个例子,比如多个客户端在一个路径下并发创建文件,这是调用 List API 得到的文件列表可能并不能包含所有创建好的文件列表,而是要等一段时间让对象存储的内部系统完成数据一致性同步。这样的访问模式在 ETL 数据处理中经常用到,最终一致性可能会影响到数据的正确性和任务的稳定性。
3. 对象存储+Juicefs
下面是 Juicefs 的部署架构图
YARN 管理的这些执行节点上,都带一个 JuiceFS Hadoop SDK, 这个 SDK 可以保证完整兼容 HDFS。图片下方可以看到, SDK 它需要访问两个部分,左侧是 JuiceFS Meta Engine,右侧是 S3 bucket。Metadata engine 就相当于 HDFS里的 NameNode,整个文件系统的元数据信息会存储在这里,元数据信息包括目录数、文件名,权限时间戳这些信息,并且相应的解决掉了 HDFS NameNode 扩展性 、GC 这些的痛点。相较于直接使用对象存储, JuiceFS 还有哪些优势呢?
- HDFS 100% 兼容。可以和 HDFS 一块使用,在 Hadoop 集群中可以配置多个文件系统。可以结合着业务,结合着集群的情况,分步分批的去做融合。
- 元数据性能强大。JuiceFS 将元数据引擎独立出来不再依赖于 S3 里面的原数据性能,保证了元数据的性能。
- 原子 rename。因为有独立的原数据引擎,JuiceFS 也可以支持原子 rename。
- 缓存。为了复现数据本地化特性,提高热数据访问性能,Juicefs 支持将反复读取的热数据缓存在 worker 节点的本地磁盘。
- 兼容 POSIX 协议。
二、Juicefs 实战
2.1 Juicefs + oss 部署
Juicefs支持市面上几乎所有的对象存储,这里则使用 minio 作为对象存储的实现,下面演示 docker 部署,其他部署模式可参考这个。
mkdir -p ~/minio/datadocker run -d\-p 9000:9000 \-p 9090:9090 \--name minio \-v ~/minio/data:/data \-e "MINIO_ROOT_USER=ROOTNAME" \-e "MINIO_ROOT_PASSWORD=NIXIANGBUDAODEMIMA" \quay.io/minio/minio server /data --console-address ":9090"
注:9000 为 API 端口,9090 为 web 端口
创建一个用于测试的 bucket
创建一个用于测试的 access key(默认自动生成,可以根据自己喜好自定义)
因为 juicefs 的元数据系统是独立于对象存储之外的,需要我们自己部署元数据系统。允许多个用户通过网络同时访问的数据库,从这个角度出发,可以简单的把数据库分成:
- 单机数据库:数据库是单个文件,通常只能单机访问,如 SQLite,Microsoft Access 等;
- 基于网络的数据库:数据库通常是复杂的多文件结构,提供基于网络的访问接口,支持多用户同时访问,如 Redis、PostgreSQL 等。
JuiceFS 目前支持的基于网络的数据库有:
- 键值数据库:Redis、TiKV
- 关系型数据库:PostgreSQL、MySQL、MariaDB
不同的数据库性能和稳定性表现也各不相同,比如 Redis 是内存型键值数据库,性能极为出色,但可靠性相对较弱。PostgreSQL 是关系型数据库,相比之下性能没有内存型强悍,但它的可靠性要更强。
这里使用 Redis 作为元数据引擎,同样是用 docker 部署,个人比较喜欢 bitnami 的开源镜像。
docker run -d \-p 6379:6379 \-e ALLOW_EMPTY_PASSWORD=no \-e REDIS_PASSWORD=NIXIANGBUDAODEMIMA \-e REDIS_AOF_ENABLED=no \--name redis \-v ~/redis/data:/bitnami/redis/data \bitnami/redis:latest
到这里准备环境就做好了,首先需要明白一点 juicefs 本质上就是一个客户端,哪个节点、哪个服务想要将数据存储到对象存储中就需要安装 juicefs 客户端或者依赖包。幸运的是 juicefs 提供一键安装脚本
curl -sSL https://d.juicefs.com/install | sh -
Downloading juicefs-1.0.3-linux-amd64.tar.gz% Total % Received % Xferd Average Speed Time Time Time CurrentDload Upload Total Spent Left Speed
100 24.0M 100 24.0M 0 0 1545k 0 0:00:15 0:00:15 --:--:-- 701k
Install juicefs to /usr/local/bin/juicefs successfully!# 校验
juicefs --version
juicefs version 1.0.3+2022-12-27.e4bf15a
类似 NameNode 的安装首先需要初始化
juicefs format \--storage minio \--bucket http://xxx.xxx.xxx.xxx:9000/juicefs \--access-key gu2iEV10yWTIHIWx \--secret-key Vt5WdZ9ct1yY7hHnKN0DSzm9W05A3ZQd \redis://:NIXIANGBUDAODEMIMA@xxx.xxx.xxx.xxx:6379/1 \juicefs
- storage: 对象存储的类型,更多对象存储实现的类型参考这个
- bucket: 桶的 endpoint,不同对象存储的 endpoint 不一致,参考上面的链接
- juicefs:juicefs 的文件系统名称(任意,后续使用 JFS_NAME 泛指)
结果如下:
此时 redis 已经存在若干个 key
后续只要 juicefs 可以访问到这个 redis 元数据系统就可以操作同一个对象存储
2.2 fuse
juicefs 支持 fuse 模式,将对象存储挂载到本地,像操作本地磁盘一样操作对象存储。fuse 模式可以支撑很多有趣的玩法,如各类数据库的热温冷数据的分离,例如将 clickhouse 的热数据存储在本地磁盘,通过配置存储策略和TTL,将温数据自动下沉到由 juicefs 挂载在本地的目录中实现冷热数据分离。其 fuse 也超简单
juicefs mount \--background \--cache-dir ~/mycache \--cache-size 512000 \redis://:NIXIANGBUDAODEMIMA@115.231.162.10:6379/1 \~/jfs
缓存机制可以让 juicefs 高效的处理海量数据的读写任务,通过 cache-dir 配置本地缓存路径,并通过 cache-size 指定缓存空间大小
例如将对象存储挂载到 ~/jfs 下
当然肯定没有 1P 的容量,毕竟我的 minio 也是部署在单节点,这里只是体现 juicefs 的一种设计思想,juicefs 只需要做好中间层的 API 就好无需考虑实际存储,因为只要你付得起账单,对象存储就是一个无限的。
下面操作对象存储就和操作本地文件一样,你可以在 ~/jfs 下任意进行文件操作,例如进行一下压测
卸载文件系统
juicefs umount ~/jfs
如若存在 Device or resource busy 异常表名此时本地进程正有 ~/jfs 的读写操作,尝试等待或终止这个读写进程
注:如在使用过程中发现本地文件系统文件已经删除,但是通过对象存储查看 bucket 容量没有变化,是因为 juicefs 存在回收站机制文件已经从元数据层面被删除并移至 .trash 中
下面则是 juicefs 与 hadoop 生态进行融合
2.3 hadoop
首先一个问题就是为什么不使用上述所说的 fuse 实现 POSIX 接口呢?原因有下面两点:
- fuse 需要提前在 hadoop 集群各个节点安装 juicefs 客户端并挂载
- file:/// 协议在使用 hadoop api 时性能比较差
因此与 hadoop 继承则使用 juicefs 专门为 hadoop 设计的 java 接口,100% 兼容 hadoop api
因为 juicefs 使用 go 开发每个平台都需要自己进行编译,其操作也很简单:
编译依赖的工具
- Go 1.15+
- JDK 8+
- Maven 3.3+
- Git
- make
- GCC 5.4+
git clone https://github.com/juicedata/juicefs.git
cd juicefs/sdk/java
make
编译完成后,可以在 sdk/java/target
目录中找到编译好的 JAR
文件,包括两个版本:
- 包含第三方依赖的包:
juicefs-hadoop-X.Y.Z.jar
- 不包含第三方依赖的包:
original-juicefs-hadoop-X.Y.Z.jar
建议使用包含第三方依赖的版本。如果不想编译可以使用官方编译好的全平台通用的 SDK(唯一的缺点就是包比较大)
wget https://github.com/juicedata/juicefs/releases/download/v1.0.3/juicefs-hadoop-1.0.3.jar
将其放入 hadoop classpath 下即可(执行 hadoop classpath 可以查看都有哪些路径),随后配置core-site.xml
让 hadoop cli 可以读取到元数据集即可,下面是最小配置
<configuration><property><name>fs.jfs.impl</name><value>io.juicefs.JuiceFileSystem</value></property><property><name>fs.AbstractFileSystem.jfs.impl</name><value>io.juicefs.JuiceFS</value></property><property><name>juicefs.meta</name><value>redis://:NIXIANGBUDAODEMIMA@xxx.xxx.xxx.xxx:6379/1</value></property>
</configuration>
先通过 fuse 挂载本地上传一点(cp)数据用于测试,接下来测试 hadoop cli
hadoop fs -ls -R jfs://juicefs/
细心的小伙伴可能已经发现了,执行 hadoop cli 的机器已经不是刚才部署的那一台了,命令中的 juicefs 就是 JFS_NAME,下面随意测试一下 hadoop cli 的增删改查
当前的测试机器是我的开发机器,可以发现 juicefs 与之前的 hadoop 是并存的
下面测试使用 hadoop 的 java api 来测试
pom 文件如下
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>tech.kpretty</groupId><artifactId>juicefs</artifactId><version>1.0-SNAPSHOT</version><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><hadoop.version>3.3.4</hadoop.version><juicefs.version>1.0.3</juicefs.version></properties><dependencies><dependency><groupId>org.apache.hadoop</groupId><artifactId>hadoop-common</artifactId><version>${hadoop.version}</version></dependency><dependency><groupId>io.juicefs</groupId><artifactId>juicefs-hadoop</artifactId><version>${juicefs.version}</version></dependency></dependencies></project>
代码如下:
package tech.kpretty.juicefs;import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.*;import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;/*** @author wjun* @date 2023/3/15 13:55*/
public class JuiceFsDemo {public static void main(String[] args) throws IOException, URISyntaxException {Configuration conf = new Configuration();conf.set("fs.jfs.impl", "io.juicefs.JuiceFileSystem");conf.set("fs.AbstractFileSystem.jfs.impl", "io.juicefs.JuiceFS");conf.set("juicefs.meta", "redis://:NIXIANGBUDAODEMIMA@xxx.xxx.xxx.xxx:6379/1");FileSystem fs = FileSystem.get(new URI("jfs://juicefs/"), conf);// 上传文件fs.copyFromLocalFile(new Path("/Users/wjun/Downloads/学习资料/trial.tar.gz"), new Path("/"));RemoteIterator<LocatedFileStatus> listFiles = fs.listFiles(new Path("/"), true);while (listFiles.hasNext()) {LocatedFileStatus fileStatus = listFiles.next();System.out.printf("%s\t%s\t%s\t%s\n",fileStatus.getPermission(),fileStatus.getOwner(),fileStatus.getGroup(),fileStatus.getPath());}fs.close();}
}
本质上就是将 core-site.xml 文件 set 进去即可,或者 addResource 指定文件路径。运行结果如下
2.4 hive
如果之前环境已经存在 hive 且上述 hadoop 已经配置成功,那么 hive 就什么都不需要了,直接启动即可
创建数据库并将 location 指向 jfs,这样后续该库下面的表默认都创建 jfs 下
hive (default)> create database juice_demo location 'jfs://juicefs/user/hive/warehouse/juice_demo';
2023/03/18 17:20:11.957141 juicefs[16680] <WARNING>: AOF is not enabled, you may lose data if Redis is not shutdown properly. [info.go:83]
OK
Time taken: 1.663 seconds
--------------------
hive (default)> use juice_demo;
OK
Time taken: 0.022 seconds
下面进行一些简单测试
创建表并查看表结构
插入数据并查询
2.5 spark
将 juicefs-hadoop-1.0.3.jar 放到 spark 的 jars 下,这里建议将 juicefs-hadoop-1.0.3.jar 统一放到一个路径后续所有的组件通过符号链接进行调用
ln -sf ../../hadoop/share/hadoop/common/juicefs-hadoop-1.0.3.jar juicefs-hadoop-1.0.3.jar
spark sql 连接 hive metastore 计算上面的 demo1 表,可 hive 一样的操作
相关文章
- AI Tool 免责申明
AI Tool 免责申明 在使用本网站提供的 AI Tool 体验站服务前,请您务必仔细阅读并理解本《免责声明》(以下简称“本声明”)。请您知悉,如果您选择继续访问本网站、或使用本网站提供的本服务以及通过各类方式利用本网站的行为&…...
2023/3/28 17:21:04 - Linux - 第9节 - Linux多线程
1.Linux线程概念 1.1.线程的概念 书本中对线程的描述: 1.在进程内部运行的执行流 2.线程比进程粒度更细,调度成本更低 3.线程是CPU调度的基本单位 注:上面的说法都没有问题,这里我们以Linux内核的角度切入来讲解线程。 线程的概念…...
2023/3/28 17:20:19 - mysql以txt文本方式快速导入导出百万数据
1.先查看有没有设置权限 如果没有权限,会出现: The MySQL server is running with the --secure-file-priv option so it cannot execute this statement show variables like %secure%; # 查看 secure-file-priv 当前的值是什么 show variables like …...
2023/3/28 17:20:07 - 结合 Casbin 对 http 请求做 RBAC 鉴权以及添加请求路由参数支持
目录 总结 背景 实操 安装 Casbin 创建一个 Casbin 模型 创建一个 Casbin 策略 加载 Casbin 模型和策略并创建一个路由 总结 在本文中,我们将介绍如何结合 Casbin 对 HTTP 请求进行基于角色的访问控制 (RBAC) 鉴权,并支持请求路由参数。我们将使用…...
2023/3/28 17:19:54 - Pytorch : 自动求导
在训练神经网络时,最常用的算法是反向传播算法。在该算法中,参数(模型权重)根据损失函数相对于给定参数的梯度进行调整。损失函数计算神经网络产生的期望输出和实际输出之间的差值。目标是使损失函数的结果尽可能接近于零。该算法通过网络反向遍历来调整…...
2023/3/28 17:19:30 - 每周一算法:高精度加法
高精度数值处理 在C++中,数值的加减乘除运算都已经在系统内部被定义好了,我们可以很方便的对两个变量进行简单运算。但其中变量的取值范围,各不相同,以整数为例,最大的是long long类型,范围是 [ − 2 63 , 2 63 ) [-2^{63},2^{63}) [−2...
2023/3/28 17:19:20 - 神经网络可视化工具netron安装教程
文章目录一. netron简介二. 不同操作系统下的安装使用方式2.1 在线版本:只要浏览器就可以2.2 不同操作系统安装使用三. netron支持的网络框架一. netron简介 在实际的项目中,经常会遇到各种网络模型,需要我们快速去了解网络结构。如果单纯的…...
2023/3/28 17:19:02 - 信息打点-JS架构框架识别泄漏提取API接口枚举FUZZ爬虫插件项目
文章目录概述什么是JS渗透测试?例子JS安全问题流行的Js框架有那些?如何判定JS开发应用?如何获取更多的JS文件?前端架构-手工搜索分析前端架构-半自动Burp分析自带功能官方插件第三方插件前端架构-自动化项目分析Jsfinder-从表现中…...
2023/3/28 17:17:05 - 【Unity游戏开发教程】零基础带你从小白到超神28——反向动力学
什么是反向动力学 一般我们都是通过父节点来调动子节点运动,而在实际开发过程中,有时候我们需要子节点带动父节点进行相应的动作。这种情况就是反向动力学。其实在国内的游戏中很少看见IK动画,一般而言国外的游戏较多。 通俗讲:就是使用场景中的各种物体来控制和影响角色身…...
2023/3/28 17:15:47 - Leveldb源码解读------Memtable(跳表)详解
在leveldb中的memtable实际上是对核心数据结构skipList做了一个包装,并对外提供了接口。 使用让我们一起来研究一下跳表 为什么使用跳表 因为memtable为了更快的查询,是一个sortmap要求。一般会采用红黑树,不过LevelDB采用的是Skiplist。S…...
2023/3/28 17:15:12 - Git统计项目成员代码提交量
目录 一、前言 二、Git Bash 三、统计信息 1.统计某项目中成员数量 2.统计所有用户的提交总次数 3.统计所有用户指定时间段的提交次数 4.按用户名统计提交次数 完整脚本如下 一、前言 项目中有很多成员,如何查看各个时间段每个组员的代码提交量,下…...
2023/3/28 17:11:01 - Vue实现单页缓存,下一页刷新
vue单页缓存实现方案分析 实现前进刷新,返回不刷新的功能,并且返回时可以记住上一页的滚动位置,有两套方案可选 方案一:vue的keep-alive组件 具体使用如下: <keep-alive max"10"><router-view…...
2023/3/28 17:09:36 - Downie 4 4.6.12 MAC上最好的一款视频下载工具
Downie for Mac 简介 Downie是Mac下一个简单的下载管理器,可以让您快速将不同的视频网站上的视频下载并保存到电脑磁盘里然后使用您的默认媒体播放器观看它们。 Downie 4 Downie 4 for Mac Downie 4 for Mac软件特点 支持许多站点 -当前支持1000多个不同的站点&…...
2023/3/28 17:03:43 - vscode搭建Django环境五:vscode配置react开发环境
1、安装node 请在官网下载安装:https://nodejs.org/zh-cn/vscode 中新建终端输入指令node -v,能显示版本号,说明 node 已经装好了输入指令npm -v,能显示版本号,说明 npm 可以使用了 nodejs安装参考:https…...
2023/3/28 17:03:28 - TiDB入门篇-数据物理备份和恢复
简介 快照备份是集群全量备份的一种实现。它基于 TiDB 的多版本并发控制 (MVCC) 实现,将指定快照包含的所有数据备份到目标存储中。备份下来的数据大小约等于集群(压缩后的)单副本数据大小。备份完成之后,你可以在一个空集群或不…...
2023/3/28 17:02:48 - 电脑录屏怎么录?超详细的录屏教程来了
案例:电脑录屏怎么录?求详细的电脑录屏教程! “最近的工作需要用到电脑录屏,但是我不知道电脑录屏怎么录?去网上搜索了一下教程都是比较大概的,我这个新手小白根本看不懂。在这里想问问大家,有…...
2023/3/28 17:02:09 - 从0使用TCP手撸http服务器一
背景介绍: 成熟的http服务器框架非常多,例如SB,flask,.net.....这些框架基本上都是运行在操作系统之上,非常的高级。但是我们做嵌入式的望尘莫及!当然如果是linux的设备,可能还能用上轻量级的http服务器框架࿰…...
2023/3/28 17:01:16 - Linux- 浅谈ELF目标文件格式
理解了进程的描述和创建之后,自然会想到我们编写的可执行程序是如何作为一个进程工作的?这就涉及可执行文件的格式、编译、链接和装载等相关知识。 这里先提一个常见的名词“目标文件”,是指编译器生成的文件。“目标”指目标平台,…...
2023/3/28 16:59:58 - 2022(二等奖)C859基于WebGIS的南京市排污口管理系统
作品介绍 一、需求分析 (一)社会需求 《国务院办公厅关于加强入河入海排污口监督管理工作的实施意见》明确提出,入河入海排污口(以下简称排污口)是指直接或通过管道、沟、渠等排污通道向环境水体排放污水的口门,是流…...
2023/3/28 16:58:54 - MobTech|场景唤醒的实现
什么是场景唤醒? 场景唤醒是moblink的一项核心功能,可以实现从打开的Web页面,一键唤醒App,并恢复对应的场景。 场景是指用户在App内的某个特定页面或状态,比如商品详情页、活动页、个人主页等。每个场景都有一个唯一…...
2023/3/28 16:57:55 - echarts 关系调用高亮示例 dispatchAction及其遇到的问题
如图所示 <template><div class"Chart"><div class"main_box"><div class"diagram_box" v-if"activeChart diagram"><div class"drawer"><drawer:drawer.sync"drawer":cusStyl…...
2023/3/28 16:56:33 - L1-018 大笨钟 L1-020 帅到没朋友 L1-034 点赞
微博上有个自称“大笨钟V”的家伙,每天敲钟催促码农们爱惜身体早点睡觉。不过由于笨钟自己作息也不是很规律,所以敲钟并不定时。一般敲钟的点数是根据敲钟时间而定的,如果正好在某个整点敲,那么“当”数就等于那个整点数ÿ…...
2023/3/28 16:55:06 - 两个数组的交集(力扣刷题)
给定两个数组 nums1 和 nums2 ,返回 它们的交集 。输出结果中的每个元素一定是 唯一 的。我们可以 不考虑输出结果的顺序 。 来源:力扣(LeetCode) 链接:https://leetcode.cn/problems/intersection-of-two-arrays 说…...
2023/3/28 16:54:40 - 【HashMap】jdk1.8中HashMap的插入扩容源码学习分析
jdk1.8中HashMap的插入扩容源码学习分析 一、成员变量 首先介绍HashMap中各个成员变量的作用,在HashMap中有以下成员变量 size记录了HashMap中键值对的个数 loadFactor(加载因子)用来决定size达到容量的百分之多少时触发扩容机制 默认是0…...
2023/3/28 16:53:02 - uni-app css尺寸单位rpx介绍
一,前言 1.在使用uni-app开发小程序时支持的尺寸单位如下 (1)基础单位:px , rpx (2)h5单位:rem ,vm ,vh 2.rpx是微信小程序提出的一种响应式px 二&#x…...
2023/3/28 16:52:49 - 纳瓦尔的推荐读物
非虚构类 《无穷的开始:世界进步的本源》,戴维多伊奇这本书不是很好理解,但确实让我变得更聪明了。 《人类简史:从动物到上帝》,尤瓦尔赫拉利这本书介绍了人类的历史。书中的观察、框架和心智模型会让你以不同的方式看…...
2023/3/28 16:50:33 - 【JavaScript】43_DOM编程:DOM修改与demo
10、DOM的修改 appendChild() 用于给一个节点添加子节点 list.appendChild(li) insertAdjacentElement() 可以向元素的任意位置添加元素 两个参数: 1.要添加的位置 2.要添加的元素 beforeend 标签的最后 afterbegin 标签的开始 beforebegin 在元素的前边插…...
2023/3/28 16:50:09 - Ubuntu下解决 ×.so.×: wrong ELF class: ELFCLASS64 的问题
安装软件时出现问题 .so.:wrong ELF class: ELFCLASS64 ,大致的意思是软件是32位的,需要32位的 .so.动态链接库,而系统是64位的所提供的该 动态链接库.so.是64位的,所以不能用。 首先可以查看自己的64位系统是否开启了32位支持功…...
2023/3/28 16:48:11 - [学习笔记]PowerBI数据分析与可视化-B站数据大白
参考资料 B站视频-Power BI 数据分析与可视化 前言 原视频中可能的勘误在笔记中有修改。CtrlF搜索“勘误”两个字可以快速定位到勘误。 原视频中可能的差异在笔记中有提及。CtrlF搜索“差异”两个字可以快速定位到勘误。 2. 建模与DAX函数 2.01 建立关系模型 表可以分为维…...
2023/3/28 16:47:41 - 如何进行安全可靠的API身份验证?
前言: 在开发安全的 REST API 时,身份验证是必不可少的。你可以将你的应用程序想象成一个聚会,那么身份验证就像一扇门,决定哪些客人可以进入——或者更准确地说,哪些请求可以进出。 接下来我将介绍四种常用的身份验证…...
2023/3/28 16:46:37
最新文章
- AI Tool 免责申明
AI Tool 免责申明 在使用本网站提供的 AI Tool 体验站服务前,请您务必仔细阅读并理解本《免责声明》(以下简称“本声明”)。请您知悉,如果您选择继续访问本网站、或使用本网站提供的本服务以及通过各类方式利用本网站的行为&…...
2023/3/28 17:21:04 - Linux - 第9节 - Linux多线程
1.Linux线程概念 1.1.线程的概念 书本中对线程的描述: 1.在进程内部运行的执行流 2.线程比进程粒度更细,调度成本更低 3.线程是CPU调度的基本单位 注:上面的说法都没有问题,这里我们以Linux内核的角度切入来讲解线程。 线程的概念…...
2023/3/28 17:20:19 - mysql以txt文本方式快速导入导出百万数据
1.先查看有没有设置权限 如果没有权限,会出现: The MySQL server is running with the --secure-file-priv option so it cannot execute this statement show variables like %secure%; # 查看 secure-file-priv 当前的值是什么 show variables like …...
2023/3/28 17:20:07 - 结合 Casbin 对 http 请求做 RBAC 鉴权以及添加请求路由参数支持
目录 总结 背景 实操 安装 Casbin 创建一个 Casbin 模型 创建一个 Casbin 策略 加载 Casbin 模型和策略并创建一个路由 总结 在本文中,我们将介绍如何结合 Casbin 对 HTTP 请求进行基于角色的访问控制 (RBAC) 鉴权,并支持请求路由参数。我们将使用…...
2023/3/28 17:19:54 - Pytorch : 自动求导
在训练神经网络时,最常用的算法是反向传播算法。在该算法中,参数(模型权重)根据损失函数相对于给定参数的梯度进行调整。损失函数计算神经网络产生的期望输出和实际输出之间的差值。目标是使损失函数的结果尽可能接近于零。该算法通过网络反向遍历来调整…...
2023/3/28 17:19:30 - 每周一算法:高精度加法
高精度数值处理 在C++中,数值的加减乘除运算都已经在系统内部被定义好了,我们可以很方便的对两个变量进行简单运算。但其中变量的取值范围,各不相同,以整数为例,最大的是long long类型,范围是 [ − 2 63 , 2 63 ) [-2^{63},2^{63}) [−2...
2023/3/28 17:19:20 - 神经网络可视化工具netron安装教程
文章目录一. netron简介二. 不同操作系统下的安装使用方式2.1 在线版本:只要浏览器就可以2.2 不同操作系统安装使用三. netron支持的网络框架一. netron简介 在实际的项目中,经常会遇到各种网络模型,需要我们快速去了解网络结构。如果单纯的…...
2023/3/28 17:19:02 - 信息打点-JS架构框架识别泄漏提取API接口枚举FUZZ爬虫插件项目
文章目录概述什么是JS渗透测试?例子JS安全问题流行的Js框架有那些?如何判定JS开发应用?如何获取更多的JS文件?前端架构-手工搜索分析前端架构-半自动Burp分析自带功能官方插件第三方插件前端架构-自动化项目分析Jsfinder-从表现中…...
2023/3/28 17:17:05 - 【Unity游戏开发教程】零基础带你从小白到超神28——反向动力学
什么是反向动力学 一般我们都是通过父节点来调动子节点运动,而在实际开发过程中,有时候我们需要子节点带动父节点进行相应的动作。这种情况就是反向动力学。其实在国内的游戏中很少看见IK动画,一般而言国外的游戏较多。 通俗讲:就是使用场景中的各种物体来控制和影响角色身…...
2023/3/28 17:15:47 - Leveldb源码解读------Memtable(跳表)详解
在leveldb中的memtable实际上是对核心数据结构skipList做了一个包装,并对外提供了接口。 使用让我们一起来研究一下跳表 为什么使用跳表 因为memtable为了更快的查询,是一个sortmap要求。一般会采用红黑树,不过LevelDB采用的是Skiplist。S…...
2023/3/28 17:15:12 - Git统计项目成员代码提交量
目录 一、前言 二、Git Bash 三、统计信息 1.统计某项目中成员数量 2.统计所有用户的提交总次数 3.统计所有用户指定时间段的提交次数 4.按用户名统计提交次数 完整脚本如下 一、前言 项目中有很多成员,如何查看各个时间段每个组员的代码提交量,下…...
2023/3/28 17:11:01 - Vue实现单页缓存,下一页刷新
vue单页缓存实现方案分析 实现前进刷新,返回不刷新的功能,并且返回时可以记住上一页的滚动位置,有两套方案可选 方案一:vue的keep-alive组件 具体使用如下: <keep-alive max"10"><router-view…...
2023/3/28 17:09:36 - Downie 4 4.6.12 MAC上最好的一款视频下载工具
Downie for Mac 简介 Downie是Mac下一个简单的下载管理器,可以让您快速将不同的视频网站上的视频下载并保存到电脑磁盘里然后使用您的默认媒体播放器观看它们。 Downie 4 Downie 4 for Mac Downie 4 for Mac软件特点 支持许多站点 -当前支持1000多个不同的站点&…...
2023/3/28 17:03:43 - vscode搭建Django环境五:vscode配置react开发环境
1、安装node 请在官网下载安装:https://nodejs.org/zh-cn/vscode 中新建终端输入指令node -v,能显示版本号,说明 node 已经装好了输入指令npm -v,能显示版本号,说明 npm 可以使用了 nodejs安装参考:https…...
2023/3/28 17:03:28 - TiDB入门篇-数据物理备份和恢复
简介 快照备份是集群全量备份的一种实现。它基于 TiDB 的多版本并发控制 (MVCC) 实现,将指定快照包含的所有数据备份到目标存储中。备份下来的数据大小约等于集群(压缩后的)单副本数据大小。备份完成之后,你可以在一个空集群或不…...
2023/3/28 17:02:48 - 电脑录屏怎么录?超详细的录屏教程来了
案例:电脑录屏怎么录?求详细的电脑录屏教程! “最近的工作需要用到电脑录屏,但是我不知道电脑录屏怎么录?去网上搜索了一下教程都是比较大概的,我这个新手小白根本看不懂。在这里想问问大家,有…...
2023/3/28 17:02:09 - 从0使用TCP手撸http服务器一
背景介绍: 成熟的http服务器框架非常多,例如SB,flask,.net.....这些框架基本上都是运行在操作系统之上,非常的高级。但是我们做嵌入式的望尘莫及!当然如果是linux的设备,可能还能用上轻量级的http服务器框架࿰…...
2023/3/28 17:01:16 - Linux- 浅谈ELF目标文件格式
理解了进程的描述和创建之后,自然会想到我们编写的可执行程序是如何作为一个进程工作的?这就涉及可执行文件的格式、编译、链接和装载等相关知识。 这里先提一个常见的名词“目标文件”,是指编译器生成的文件。“目标”指目标平台,…...
2023/3/28 16:59:58 - 2022(二等奖)C859基于WebGIS的南京市排污口管理系统
作品介绍 一、需求分析 (一)社会需求 《国务院办公厅关于加强入河入海排污口监督管理工作的实施意见》明确提出,入河入海排污口(以下简称排污口)是指直接或通过管道、沟、渠等排污通道向环境水体排放污水的口门,是流…...
2023/3/28 16:58:54 - MobTech|场景唤醒的实现
什么是场景唤醒? 场景唤醒是moblink的一项核心功能,可以实现从打开的Web页面,一键唤醒App,并恢复对应的场景。 场景是指用户在App内的某个特定页面或状态,比如商品详情页、活动页、个人主页等。每个场景都有一个唯一…...
2023/3/28 16:57:55 - echarts 关系调用高亮示例 dispatchAction及其遇到的问题
如图所示 <template><div class"Chart"><div class"main_box"><div class"diagram_box" v-if"activeChart diagram"><div class"drawer"><drawer:drawer.sync"drawer":cusStyl…...
2023/3/28 16:56:33 - L1-018 大笨钟 L1-020 帅到没朋友 L1-034 点赞
微博上有个自称“大笨钟V”的家伙,每天敲钟催促码农们爱惜身体早点睡觉。不过由于笨钟自己作息也不是很规律,所以敲钟并不定时。一般敲钟的点数是根据敲钟时间而定的,如果正好在某个整点敲,那么“当”数就等于那个整点数ÿ…...
2023/3/28 16:55:06 - 两个数组的交集(力扣刷题)
给定两个数组 nums1 和 nums2 ,返回 它们的交集 。输出结果中的每个元素一定是 唯一 的。我们可以 不考虑输出结果的顺序 。 来源:力扣(LeetCode) 链接:https://leetcode.cn/problems/intersection-of-two-arrays 说…...
2023/3/28 16:54:40 - 【HashMap】jdk1.8中HashMap的插入扩容源码学习分析
jdk1.8中HashMap的插入扩容源码学习分析 一、成员变量 首先介绍HashMap中各个成员变量的作用,在HashMap中有以下成员变量 size记录了HashMap中键值对的个数 loadFactor(加载因子)用来决定size达到容量的百分之多少时触发扩容机制 默认是0…...
2023/3/28 16:53:02 - uni-app css尺寸单位rpx介绍
一,前言 1.在使用uni-app开发小程序时支持的尺寸单位如下 (1)基础单位:px , rpx (2)h5单位:rem ,vm ,vh 2.rpx是微信小程序提出的一种响应式px 二&#x…...
2023/3/28 16:52:49 - 纳瓦尔的推荐读物
非虚构类 《无穷的开始:世界进步的本源》,戴维多伊奇这本书不是很好理解,但确实让我变得更聪明了。 《人类简史:从动物到上帝》,尤瓦尔赫拉利这本书介绍了人类的历史。书中的观察、框架和心智模型会让你以不同的方式看…...
2023/3/28 16:50:33 - 【JavaScript】43_DOM编程:DOM修改与demo
10、DOM的修改 appendChild() 用于给一个节点添加子节点 list.appendChild(li) insertAdjacentElement() 可以向元素的任意位置添加元素 两个参数: 1.要添加的位置 2.要添加的元素 beforeend 标签的最后 afterbegin 标签的开始 beforebegin 在元素的前边插…...
2023/3/28 16:50:09 - Ubuntu下解决 ×.so.×: wrong ELF class: ELFCLASS64 的问题
安装软件时出现问题 .so.:wrong ELF class: ELFCLASS64 ,大致的意思是软件是32位的,需要32位的 .so.动态链接库,而系统是64位的所提供的该 动态链接库.so.是64位的,所以不能用。 首先可以查看自己的64位系统是否开启了32位支持功…...
2023/3/28 16:48:11 - [学习笔记]PowerBI数据分析与可视化-B站数据大白
参考资料 B站视频-Power BI 数据分析与可视化 前言 原视频中可能的勘误在笔记中有修改。CtrlF搜索“勘误”两个字可以快速定位到勘误。 原视频中可能的差异在笔记中有提及。CtrlF搜索“差异”两个字可以快速定位到勘误。 2. 建模与DAX函数 2.01 建立关系模型 表可以分为维…...
2023/3/28 16:47:41 - 如何进行安全可靠的API身份验证?
前言: 在开发安全的 REST API 时,身份验证是必不可少的。你可以将你的应用程序想象成一个聚会,那么身份验证就像一扇门,决定哪些客人可以进入——或者更准确地说,哪些请求可以进出。 接下来我将介绍四种常用的身份验证…...
2023/3/28 16:46:37