GaussDB技术解读——GaussDB架构介绍(一)

news2024/11/16 13:28:25

目录

1 GaussDB 关键架构目标

2 GaussDB分布式架构

2.1 GaussDB 分布式关键技术架构

3  数据计算路由层(Coordinator)关键技术方案

3.1 分布式优化器

3.2 分布式执行框架


GaussDB是华为自主创新研发的关系型数据库,基于华为在数据库领域20多年的战略投入,通过多维度的技术创新,在行业实践中构筑了高可用、高安全、高性能、高弹性、高智能的技术优势,在数据库替换场景中,具备易部署、易迁移的特性。作为国内当前唯一能够做到软硬协同、全栈自主的数据库,GaussDB已经在金融、政务、能源、交通等关键信息基础设施行业积累了丰富的实践经验,是企业数字化转型、核心数据上云、分布式改造的信赖之选。

从本期开始,Gauss松鼠会将陆续推出GaussDB技术解读系列文章,带您了解GaussDB的架构及关键技术原理。本篇将从GaussDB 关键架构目标、GaussDB分布式架构、数据计算路由层(Coordinator)关键技术方案等三方面对GaussDB架构进行介绍。

1 GaussDB 关键架构目标

GaussDB在架构设计上,采用组件化原则,分为GaussDB Kernel内核和GaussDB Kernel OM两部分。在产品形态上,提供面向云数据库服务GaussDB(for openGauss)的分布式安装包和集中式安装包,提供面向本地化安装的小型化安装包。

根据华为云提供的调查报告,当前全球数据库市场增长超预期,云是数据库增长最重要驱动力。得益于云数据库的迅猛发展,AWS市场份额超越IBM,成为数据库市场空间第三位,聚焦公有云、混合云构筑具备竞争力的可商用分布式数据库版本,数据库已成为公有云Top收入来源,同时通过数据库服务能够更大地提升公有云服务粘性。GaussDB Kernel面向云服务提供GaussDB产品,主要客户包含金融(银行、证券、保险)行业、政府(政务云、财政等)和大企业客户。结合产品可信要求定义及可信实施策略分析的内容,以及业界数据库厂商前沿动态,GaussDB Kernel在云服务场景中的架构目标按照一下几个维度来展开:

  • 高性能:建立基于x86平台与鲲鹏平台的绝对性能领先,鲲鹏平台相对x86平台保证50%性能优势,达到单机170万tpmC,分布式全局强一致32节点1500万tpmC,承载用户关键业务负载;具备性能韧性能力,5倍压力下性能不抖动、十倍压力下系统不崩溃,同时具备抗过载逃生能力;具备大并发、低时延能力,单节点支持1万并发、单集群支持10万级并发访问请求,ms至秒级事务处理时延,支撑政企客户核心业务负载。

  • 云原生:通过GTM-Lite技术轻量化处理全局读一致性点与写一致性点,集群扩展性达到256节点,未来通过全球时钟技术演进,在跨Region全局一致性下去除单点瓶颈;面向业务陡增等业务场景,构建基于哈希聚簇的存储结构和弹性扩容方案,实现秒级存储节点扩缩容和业务无感的计算节点弹性伸缩;构建分布式备机只读技术,只读性能提升100%以上。

  • 高可用:AZ内主备高可用,1主多备,RPO=0、RTO<10s;同城跨AZ高可用,RPO=0、RTO<60s;跨Region容灾,RPO<10s、RTO<5min;提供备份恢复、PITR、闪回、ALT等企业级高可用特性;构建基于Paxos协议的多副本高可用和并行逻辑复制技术,实现RPO=0的同城双集群高可用容灾和基于流式复制的多地多中心容灾,保证机房级、区域级、城市级故障下的数据库高可用。

  • 高安全:继承可信实施策略中安全可信需求,从安全,韧性,隐私等维度构筑安全可信能力,结合业界安全技术前沿发展,设计全密态数据库和防篡改数据库,保证用户敏感数据免于泄露和篡改;构建数据库安全自治管控方法,识别和拦截攻击者的异常行为;构建从接入、访问控制、加密到审计全方位纵深防御的安全防护体系。

  • 高智能:面向云化场景故障运维诉求,基于AI技术,提供端到端自治运维管理能力,全面提升数据库产品服务可靠性和可用性;构筑自学习数据库内核,尤其是智能优化器,解决数据库内优化执行过程中计划不准、无法自适应等难题;结合业界前沿技术,构建库内AI引擎,基于SQL-like简易语法,提供数据库内置的机器学习训练和推理能力,为用户提供普惠AI;提供向量数据库能力,支撑盘古大模型、NAIE-NetGPT和GTS领域知识库等场景,提高大模型的预测效率。

GaussDB Kernel提供的本地化版本的架构目标包括:

  • 高性能:支撑业务1千并发能力,性能达1000+ TPS;

  • 高可用:提供多种部署形态的能力:一主一备、一主多备等;

  • 高安全:支持数据库备份加密、网络连接安全管理及传输加密;支持三权分立,即数据库管理员、安全管理员、审计管理员权限职责分离;支持访问控制;

  • 高智能:提供丰富高效的DFx运维监测手段,后续朝向基于AI的自治运维调优方向发展,降低BCM相关产品或解决方案的运维成本,提升易用性;

  • 小型化:数据库安装包大小<25MB,且数据库刚启动后的底噪内存<250MB。

2 GaussDB分布式架构

2.1 GaussDB 分布式关键技术架构

  • Coordinator:  负责接收SQL请求,路由分发请求到对应的数据节点。同时维护系统元数据(路由分片信息,表定义)。

图1 Coordinator逻辑模型

  • Datanode:  数据节点存储分片数据。副本复制采用Quorum/Paxos协议。

图2 DN逻辑模型

  • SECURITY: 安全子系统,主要包含了Kerberos认证,登录认证,安全审计,角色管理与访问控制,安全通信,透明数据加密,防篡改账本,全密态数据,数据脱敏等功能。

图3 安全逻辑模型

  • GTM:  全局事务管理器, 负责产生CSN号,提供全局统一快照。

图4 GTM逻辑模型

  • CM:  集群管理系统, 主要包括 CM Agent,  CM Server和分布式配置中心。

图5 CM逻辑模型

  • OM运维子系统,主要包括了安装,卸载,启动,停止数据库,备份恢复,升级,扩容数据库,打补丁,节点替换, 巡检功能,故障定位定界,参数管理,初始化工具及本地客户端工具。

图6 OM逻辑模型

  • AI子系统,主要自治运维管理系统,如索引推荐、慢SQL诊断、分布键推荐;库内AI引擎;智能优化器,如智能基数估计和计划自适应选择。

图7 AI逻辑模型

  • 驱动子系统,包括支持JDBC、ODBC、Python、GO等主流数据库驱动接口,适用于Java/C/C++/python/go 应用程序开发者。对于高级开发者而言,亦可采用libpq动态库接口和ecpg接口的方式,对数据库进行接入访问。

图8 驱动逻辑模型

关键模块2层逻辑模型:

存储引擎模块:

图9

SQL引擎:

图10

兼容性和接口模块:

图11

基础组件:

图12

分布式管理:

图13

3  数据计算路由层(Coordinator)关键技术方案

GaussDB Kernel V5版本的Catalog还是本地存储, 所以还需要考虑catalog的持久化问题.未来演进元数据解耦,Coordinator 无状态, 就不需要考虑Catalog持久化问题了。但是跨节点场景下的事务提交在Coordinator上还是要持久化的。

图14 Coordinator模块图

路由信息:每个表数据共分16384个hash bucket来存储,每个DN对应存储若干个hash bucket的数据。SQL优化器模块会根据Query的条件自动剪枝DN。

Pooler连接池:维护和每个DN连接的socket信息,缓存建立的连接。

3.1 分布式优化器

优化器的查询重写基础依赖于关系代数的等价变换。等价变换关系如下图所示:

图15 关系代数的等价变换

基于规则的查询重写,基本规则如下。

  • 常量化简:如 SELECT * FROM t1 WHERE c1=1+1; 等价于SELECT * FROM t1 WHERE c1=2;

  • 消除DISTINCT:CREATE TABLE t1(c1 INT PRIMARY KEY, c2 INT); SELECT DISTINCT(c1) FROM t1; SELECT c1 FROM t1;

  • IN谓词展开:SELECT * FROM t1 WHERE c1 IN (10,20,30); 等价于SELECT * FROM t1 WHERE c1=10 or c1=20 OR c1=30;

  • 视图展开:CREATE VIEW v1 AS (SELECT * FROM t1,t2 WHERE t1.c1=t2.c2); SELECT * FROM v1; 等价于 SELECT * FROM t1,t2 WHERE t1.c1=t2.c2;

  • 条件下移:t1 join t2 on … and t1.b=5 等价于 (t1 where t1.b=5) join t2

  • 条件传递闭包:a=b and a=3 -> b=3

  • 消除子链接:如 select * from t1 where exists(select 1 from t2 where t1.a=t2.a); 等级于 select * from t1 (semi join) (select a from t2) t2 where t1.a=t2.a;

查询重写规则较多,在此不一一列举。

在基于代价的查询优化技术上,主要关注三个关键问题。分别是:结果集行数估算、执行代价估算以及路径搜索。其核心目标是,为多个物理执行的代价进行评分,最后选择出一个最优的计划,输出到执行器。

行数估算方面,通过analyze手段,收集基表的统计信息,统计信息包括:各个数据表的规模、行数以及页面数等。在表中,也会统计各个列的信息,包括distinct值(该列不相同的值的个数),空值的比例,MCV(most common value,用于记录数据倾斜情况)以及直方图(用于记录数据分布情况),根据基表统计信息,估算过滤、join的中间结果统计信息。未来将基于AI进行多维度统计信息收集,收集更准确的行数信息,以辅助更优的计划选择。

执行代价估算方面,根据数据量估算不同算子的执行代价,各个执行算子的代价之和即为执行计划的总代价。算子的代价,主要包含几个方面:CPU代价、IO代价、网络代价(分布式多分片场景)等。未来需要根据物理环境的不同,调整不同算子的执行代价比例,同时通过AI技术构建更精准的代价模型。

表1 代价估算算子种类

算子分类作用主要算子

表扫描算子

从存储层扫描数据

Seqscan, Indexscan

连接算子

进行两表连接

Hashjoin, MergeJoin, Nestloop

聚集算子

进行聚集操作

Hashagg, Groupagg

网络传输算子

网络上传输数据

Stream(redistribute, broadcast)

排序算子

进行排序算子

Sort

路径搜索方面,GaussDB Kernel V5采用自底向上的路径搜索算法,对于单表访问路径,一般有两种:

  • 全表扫描:对表中的数据逐个访问。

  • 索引扫描:借助索引来访问表中的数据,通常需要结合谓词一起使用。

优化器首先根据表的数据量、过滤条件、和可用的索引结合代价模型来估算各种不同扫描路径的代价。例如:给定表定义CREATE TABLE t1(c1 int); 如果表中数据为1,2,3…100000000连续的整型值并且在c1列上有B+树索引,那么对于SELECT * FROM t1 WHERE c1=1; 来说,只要读取1个索引页面和1个表页面就可以获取到数据。然而对于全表扫描,需要读取1亿条数据才能获取同样的结果。在这种情况下索引扫描的路径胜出。

索引扫描并不是在所有情况下都优于全表扫描,它们的优劣取决于过滤条件能够过滤掉多少数据,通常数据库管理系统会采用B+树来建立索引,如果在选择率比较高的情况下,B+树索引会带来大量的随机I/O,这会降低索引扫描算子的访问效率。比如SELECT * FROM t1 WHERE c1>0;这条语句,索引扫描需要访问索引中的全部数据和表中的全部数据,并且带来巨量的随机I/O,而全表扫描只需要顺序的访问表中的全部数据,因此在这种情况下,全表扫描的代价更低。

多表路径生成的难点主要在于如何枚举所有的表连接顺序(Join Reorder)和连接算法(Join Algorithm)。假设有两个表t1和t2做JOIN操作,根据关系代数中的交换律原则,可以枚举的连接顺序有t1 × t2和t2 × t1两种,JOIN的物理连接算子有Hash Join、Nested Loop Join、Merge Join三种类型。这样一来,可供选择的路径有6种之多。这个数量随着表的增多会呈指数级增长,因此高效的搜索算法显得至关重要。GaussDB Kernel 通常采用自底向上的路径搜索方法,首先生成了每个表的扫描路径,这些扫描路径在执行计划的最底层(第一层),在第二层开始考虑两表连接的最优路径,即枚举计算出每两表连接的可能性,在第三层考虑三表连接的最优路径,即枚举计算出三表连接的可能性,直到最顶层为止生成全局最优的执行计划。假设有4个表做JOIN操作,它们的连接路径生成过程如下:

  • 单表最优路径:依次生成{1},{2},{3},{4}单表的最优路径。

  • 二表最优路径:依次生成{1 2},{1 3},{1 4},{2 3},{2 4},{3 4}的最优路径。

  • 三表最优路径:依次生成{1 2 3},{1 2 4},{2 3 4},{1 3 4}的最优路径。

  • 四表最优路径:生成{1 2 3 4}的最优路径即为最终路径。

多表路径问题核心为Join Order,这是NP(Nondeterministic Polynomially,非确定性多项式)类问题,在多个关系连接中找出最优路径,比较常用的算法是基于代价的动态规划算法,随着关联表个数的增多,会发生表搜索空间膨胀的问题,进而影响优化器路径选择的效率,可以采用基于代价的遗传算法等随机搜索算法来解决。

另外为了防止搜索空间过大,可以采用下列三种剪枝策略:

  • 尽可能先考虑有连接条件的路径,尽量推迟笛卡尔积。

  • 在搜索的过程中基于代价估算对执行路径采用LowBound剪枝,放弃一些代价较高的执行路径。

  • 保留具有特殊物理属性的执行路径,例如有些执行路径的结果具有有序性的特点,这些执行路径可能在后序的优化过程中避免再次排序。

分布式执行计划生成方面,相关关键技术流程如图所示:

图16 分布式执行计划生成

3.2 分布式执行框架

GaussDB Kernel V5 执行框架位于SQL优化器与存储引擎之间,负责根据优化器输出的执行计划,执行数据存取以及相关的计算操作,将相关结果返回到客户端。其目标是,更好地利用各个节点的计算资源,更快地完成执行任务,并返回结果。

  • 单节点执行引擎:GaussDB Kernel V5 支持行存表的行执行引擎,以及列存表向量化执行引擎,提供Adaptor算子(RowAdapter,VectorAdapter)支持行列存储的自适应切换。对于行执行引擎来说,经过逐层的算子处理,一次处理一个元组,直到再无元组为止,详细过程不在此处赘述。对于列执行引擎来说,一次处理一个batch,尽量读取更多的数据,减少IO的次数,提供高CPU的利用效率,流水线执行过程中,调用次数尽量少。

图17 行列存执行引擎自动切换

  • 执行引擎主要算子:执行引擎提供算子种类如下。

图18 执行引擎主要算子

执行算子主要功能详细列表如下。

扫描算子(Scan Plan Node):扫描节点负责从底层数据来源抽取数据,数据来源可能是来自文件系统,也可能来自网络(分布式查询)。一般而言扫描节点都位于执行树的叶子节点,作为执行数的数据输入来源,典型代表SeqScan、IndexScan、SubQueryScan。

表2 扫描算子

算子类型含义

Seqscan

顺序扫描行存储引擎

CstoreScan

扫描列存储引擎

DfsScan

顺序扫描HDFS存储引擎

Stream

扫描网络算子(分布式数据库特有)

BitmapHeapScan

BitmapIndexScan

利用bitmap获取元组

TidScan

通过Tid获取元组

SubQueryScan

子查询扫描

ValueScan

扫描Value列表

CteScan

扫描CommTableExpr

WorkTableScan

扫描中间结果集

FunctionScan

函数扫描

IndexScan

索引扫描

IndexOnlyScan

直接从索引返回元组

ForgeinScan

外部表扫描

StreamScan

网络数据扫描

控制算子(Control Plan Node):控制算子一般不映射代数运算符,是为了执行器完成一些特殊的流程引入的算子,例如Limit、RecursiveUnion、Union

表3 控制算子

算子类型含义

Result

顺序扫描行存储引擎

ModifyTable

INSERT/UPDATE/DELETE操作的算子

Append

多个关系集合的追加操作

MergeAppend

多个有序关系集合的追加操作

BitmapAnd

顺序扫描HDFS存储引擎

BitmapOr

扫描网络算子(分布式数据库特有)

RecursiveUnion

利用bitmap获取元组

物化算子(Materialize Plan Node):物化算子一般指算法要求,在做算子逻辑处理的时候,要求把下层的数据进行缓存处理,因为对于下层算子返回的数据量不可提前预知,因此需要在算法上考虑数据无法全部放置到内存的情况,例如Agg、Sort

表4 物化算子

算子类型含义

Materialize

物化

Sort

对下层数据进行排序

Group

对下层已经排序的数据进行分组

Agg

对下层数据进行分组(无序)

Unique

对下层数据进行去重操作

Hash

对下层数据进行缓存,存储到一个hash表里

SetOp

对下层数据进行缓存,用于处理intersect等集合操作

WindowAgg

窗口函数

Limit

处理limit子句

连接算子(Join Plan Node):这类算子是为了应对数据库中最常见的关联操作,Join表关联。

表5 连接算子

算子类型含义

Nestloop

对下层两股数据流实现循环嵌套连接操作

MergeJoin

对下层两股排序数据流实现归并连接操作

HashJoin

对下层两股数据流实现哈希连接操作

  • 线程池模型

每个组件 CN,  DN,  GTM, CMS  都是独立进程模型,  每个进程内部采用线程池模型。

图19 线程池模型

  • ThreadPoolControler:线程池总控,负责线程池的初始化和资源管理

  • ThreadSessionControler :会话生命周期管理

  • ThreadPoolGroup:线程组,可以定义灵活的线程数量和帮核策略

  • ThreadPoolListener: 监听线程,负责事件的分发和管理

  • ThreadPoolWorker: 工作线程

设计关键要点:

  • 线程池根据CPU的core分成多个thread group

  • 每个thread group里有一个listen thread和多个worker thread

  • listern thread负责监听一批活动连接,同时分配任务给worker thread

  • worker thread以事务维度接受任务派发来执行

本篇中,GaussDB架构从GaussDB 关键架构目标、GaussDB分布式架构、数据计算路由层(Coordinator)关键技术方案等三方面展开了介绍,下篇文章将从数据持久化存取层(DataNode)关键技术方案、全局事务管理层(GTM)关键技术方案、集群管理层(CM)关键技术方案等方面介绍GaussDB架构,敬请期待!

欢迎小伙伴们交流~

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

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

相关文章

vivo手机如何改ip地址

在数字化时代&#xff0c;网络已成为我们日常生活和工作中不可或缺的一部分。而IP地址&#xff0c;作为网络连接的唯一标识&#xff0c;有时出于安全或隐私的需要&#xff0c;我们可能希望对其进行更改。对于使用vivo手机的用户来说&#xff0c;如何轻松修改IP地址可能是一个令…

2024后端服务架构升级

文章目录 背景改造方案新架构图技术选型思考 服务拆分公共组件设计自部署算法服务排期计划 全球多活改造背景架构图分布式ID大表分区处理范围使用用途改造方案排期计划升级预算 背景 1、xx业务经过多轮的业务决策和调整&#xff0c;存在非常多技术包袱&#xff0c;带了不好的用…

Nvidia Jetson/Orin +FPGA+AI大算力边缘计算盒子:轨道交通监控系统

株洲中车时代电气股份有限公司&#xff08;下称中车时代电气&#xff09;是中国中车旗下股份制企业&#xff0c;其前身及母公司——中车株洲电力机车研究所有限公司创立于1959年。中车时代电气扎根株洲&#xff0c;走好两条钢轨&#xff0c;走出两条钢轨。中车时代电气秉承“双…

Flink系列三:Flink架构、独立集群搭建及Flink on YARN模式详解

一、Flink架构 Flink 是一个分布式系统&#xff0c;需要有效分配和管理计算资源才能执行流应用程序。它集成了所有常见的集群资源管理器&#xff0c;例如Hadoop yarn&#xff0c;但也可以设置作为独立集群甚至库运行。 Flink 集群剖析 Flink 运行时由两种类型的进程组成&…

【自然语言处理】【Scaling Law】Observational Scaling Laws:跨不同模型构建Scaling Law

相关博客 【自然语言处理】【Scaling Law】Observational Scaling Laws&#xff1a;跨不同模型构建Scaling Law 【自然语言处理】【Scaling Law】语言模型物理学 第3.3部分&#xff1a;知识容量Scaling Laws 【自然语言处理】Transformer中的一种线性特征 【自然语言处理】【大…

Innodb Buffer Pool缓存机制(三)Innodb Buffer Pool内部组成

一、控制块缓存页 Buffer Pool中默认的缓存页大小和在磁盘上默认的页大小是一样的&#xff0c;都是16KB。为了更好的管理这些在Buffer Pool中的缓存页&#xff0c;InnoDB为每一个缓存页都创建了一些所谓的控制信息&#xff0c;这些控制信息包括该页所属的表空间编号、页号、缓存…

自动控制:自治系统与非自治系统的稳定性分析

自动控制&#xff1a;自治系统与非自治系统的稳定性分析 在自动控制领域&#xff0c;理解自治系统和非自治系统的区别对于分析系统稳定性至关重要。自治系统的运动方程只与系统的状态有关&#xff0c;而非自治系统的运动方程则与系统的状态和时间都有关系。本文将探讨非自治系…

SqlServer2016企业版安装

前言 好久没有知识的累积&#xff0c;最近工作上遇到新的SqlServer2016安装&#xff0c;记录一下 参考文章 SQL Server 2016软件安装包和安装教程 - 哔哩哔哩 (bilibili.com) 安装包准备 需要提前准备软件安装包如下 cn_sql_server_2016_enterprise_x64_dvd_8699450&…

3. 使用tcpdump抓取rdma数据包

系列文章 第1章 多机多卡运行nccl-tests 和channel获取第2章 多机多卡nccl-tests 对比分析第3章 使用tcpdump抓取rdma数据包 目录 系列文章一、准备工作1. 源码编译tcpdump2. 安装wireshark 二、Tcpdump抓包三、Wireshark分析 一、准备工作 1. 源码编译tcpdump 使用 tcpdump…

动物收容所

题目链接 动物收容所 题目描述 注意点 若没有可以收养的动物&#xff0c;则返回[-1,-1]收纳所的最大容量为20000编号随着收养动物的增加自增 解答思路 利用队列先进先出的特点将猫和狗分别存进两个队列中&#xff0c;关键是dequeueAny这个方法中如果此时猫和狗的队列中都有…

【算法无用系列】电影推荐——余弦相似度计算用户相似度原理

【算法无用系列】通过余弦相似度计算电影、用户相似度 话不多说&#xff0c;本文通过电影推荐系统中&#xff0c;基于余弦相似度算法计算出用户相似和电影相似原理。希望可以帮助一些代码不懂的同学一些思路。 记录用户电影评分数据 一般情况来说&#xff0c;会根据用户的行为…

安装Ubuntu桌面系统(虚拟机)

VirtualBox创建虚拟机&#xff08;为安装Ubuntu桌面系统&#xff09;-CSDN博客 虚拟机的创建方法如上链接。当虚拟机开始引导之后&#xff0c;便正式开始Ubuntu桌面版的安装过程。Ubuntu桌面版界面做得很漂亮&#xff0c;操作起来也方便&#xff0c;很适合作为入门Linux的操作…

探索安全之道 | 企业漏洞管理:从理念到行动

如今&#xff0c;网络安全已经成为了企业管理中不可或缺的一部分&#xff0c;而漏洞管理则是网络安全的重中之重。那么企业应该如何做好漏洞管理呢&#xff1f;不妨从业界标准到企业实践来一探究竟&#xff01;通过对业界标准的深入了解&#xff0c;企业可以建立起完善的漏洞管…

Java+SVNCloud+Mysql课程设计

文章目录 1、主要内容2、所需准备3、与sql访问的中间类&#xff1a;SqlMessage4、窗口界面5、main方法 1、主要内容 课程设计&#xff0c;主要通过Javas wing创建窗口&#xff0c;jdbc连接云端mysql数据库进行基本操作&#xff0c;支持随机生成数据并用动态展示数据结果。 先…

重生之 SpringBoot3 入门保姆级学习(16、函数式 Web 编程)

重生之 SpringBoot3 入门保姆级学习&#xff08;16、函数式 Web 编程&#xff09; 3.4 函数式 Web 3.4 函数式 Web 个人写过 go 类似于 go gin 框架 1、场景 场景: User RESTful - CRUD GET/user/1 获取1号用户GET/users 获取所有用户POST/user 清求体携带JSON&#xff0c;新…

Java注解使用与自定义

一、什么是注解 注解是元数据的一种形式&#xff0c;它提供有关程序的数据&#xff0c;该数据不属于程序本身。注解对其注释的代码操作没有直接影响。换句话说&#xff0c;注解携带元数据&#xff0c;并且会引入一些和元数据相关的操作&#xff0c;但不会影响被注解的代码的逻…

程序员自我修养

目录 一、技术能力二、持续学习三、问题解决能力四、代码质量五、团队合作六、责任心七、时间与任务管理八、适应变化九、客户导向十、安全性意识十一、文档撰写十二、伦理与法律意识十三、健康生活 程序员作为现代技术行业的核心成员&#xff0c;不仅需要掌握扎实的技术技能&…

在 Java 项目中扫描识别图片中的文字(详细教程)

目录 需求&#xff1a; 步骤&#xff1a; 1、maven配置&#xff08;pom.xml&#xff09;&#xff1a; 2、下载依赖文件&#xff1a; 3、代码&#xff1a; post进行测试&#xff1a; 测试图片&#xff1a; 测试结果&#xff1a; 需求&#xff1a; 上传图片文件进行扫描…

MongoDB CRUD操作:地理位置应用——通过地理空间查询查找餐厅

MongoDB CRUD操作&#xff1a;地理位置应用——通过地理空间查询查找餐厅 文章目录 MongoDB CRUD操作&#xff1a;地理位置应用——通过地理空间查询查找餐厅地图的扭曲搜索餐厅浏览数据查找当前邻居查找附近所有餐厅查找一定距离内的餐厅使用$geoWithin&#xff0c;不排序使用…