MySQL性能优化(三)Buffer Pool实现原理

文章目录

    • 1.回顾缓冲池 Buffer Pool
    • 2.配置Buffer Pool的大小
    • 3.Buffer Pool:数据结构
      • 3.1.磁盘数据结构:数据页
      • 3.2.缓冲池数据结构:数据页(缓存页)
      • 3.3.缓存页对应的描述信息
    • 4.Buffer Pool:初始化
    • 5.Buffer Pool:free链表
    • 6.Buffer Pool:flush链表
    • 7.Buffer Pool:淘汰缓存页
      • 7.1.缓存命中率
      • 7.2.LRU链表
      • 7.3.预读机制/全盘扫描
      • 7.4.冷热分离LRU
      • 7.5. 热数据LRU移动
      • 7.6. 冷数据LRU刷盘
    • 8.多个Buffer Pool优化并发能力
      • 8.1.chunk机制支持动态调整buffer pool
      • 8.2.Buffer pool总内存应该设置多少?
      • 8.3.Buffer pool应该设置多少个?

1.回顾缓冲池 Buffer Pool

我们来看看下面这个更新SQL的流程图,不管流程多么复杂,有一点可以肯定的,最终数据落地,是落地在磁盘文件上。但是我们在对数据库执行增删改操作的时候,不可能直接更新磁盘上的数据的,因为如果你对磁盘进行随机读写操作,那速度是相当的慢,随便一个大磁盘文件的随机读写操作,可能都要几百毫秒。如果要是那么搞的话,可能你的数据库每秒也就只能处理几百个请求了!
在这里插入图片描述
实际上我们对数据库执行增删改操作的时候,实际上主要都是针对内存里的Buffer Pool中的数据进行的,也就是你实际上主要是对数据库的内存里的数据结构进行了增删改。同时配合了后续的redo log、刷磁盘等机制和操作。所以Buffer Pool就是数据库的一个内存组件,里面缓存了磁盘上的真实数据,然后我们的Java系统对数据库执行的增删改操作,其实主要就是对这个内存数据结构中的缓存数据执行的。

2.配置Buffer Pool的大小

因为Buffer Pool本质其实就是数据库的一个内存组件,你可以理解为他就是一片内存数据结构,所以这个内存数据结构肯定是有一定的大小的,不可能是无限大的。这个Buffer Pool默认情况下是128MB,还是有一点偏小了,我们实际生产环境下完全可以对Buffer Pool进行调整

比如我们的数据库如果是16核32G的机器,那么你就可以给Buffer Pool分配个2GB的内存,使用下面的配置就可以了。

nnodb_buffer_pool_size = 2147483648

我们可以先查看下我们innodb_buffer_pool_size的大小,执行如下SQL,可以发现为134217728
134217728 /1024 / 1024 =128M

show global variables like 'innodb_buffer_pool_size';

在这里插入图片描述
设置大小

SET GLOBAL innodb_buffer_pool_size= 32423423

3.Buffer Pool:数据结构

3.1.磁盘数据结构:数据页

现在我们知道了数据库中一定有一片内存区域是Buffer Pool了,那么我们的数据是如何放在BufferPool中的?
我们都知道数据库的核心数据模型就是表+字段+行的概念,也就是说我们都知道数据库里有一个一个的表,一个表有很多字段,然后一个表里有很多行数据,每行数据都有自己的字段值。所以大家觉得我们的数据是一行一行的放在Buffer Pool里面的吗?
这就明显不是了,实际上MySQL对数据抽象出来了一个数据页的概念,他是把很多行数据放在了一个数据页里,也就是说我们的磁盘文件中就是会有很多的数据页,每一页数据里放了很多行数据,如下图所示。
在这里插入图片描述

所以实际上假设我们要更新一行数据,此时数据库会找到这行数据所在的数据页,然后从磁盘文件里把这行数据所在的数据页直接给加载到Buffer Pool里去也就是说,Buffer Pool中存放的是一个一个的数据页,如下图。
在这里插入图片描述

3.2.缓冲池数据结构:数据页(缓存页)

实际上默认情况下,磁盘中存放的数据页的大小是16KB,也就是说,一页数据包含了16KB的内容。
而Buffer Pool中存放的一个一个的数据页,我们通常叫做缓存页,因为毕竟Buffer Pool是一个缓冲池,里面的数据都是从磁盘缓存到内存去的。而Buffer Pool中默认情况下,一个缓存页的大小和磁盘上的一个数据页的大小是一一对应起来的,都是16KB。
在这里插入图片描述

3.3.缓存页对应的描述信息

对于每个缓存页,他实际上都会有一个描述信息,这个描述信息大体可以认为是用来描述这个缓存页的。比如包含如下的一些东西:这个数据页所属的表空间、数据页的编号、这个缓存页在Buffer Pool中的地址以及别的一些杂七杂八的东西。每个缓存页都会对应一个描述信息,这个描述信息本身也是一块数据,在Buffer Pool中,每个缓存页的描述数据放在最前面,然后各个缓存页放在后面。
在这里插入图片描述
Buffer Pool中的描述数据大概相当于缓存页大小的5%左右,也就是每个描述数据大概是800个字节左右的大小,然后假设你设置的buffer pool大小是128MB,实际上Buffer Pool真正的最终大小会超出一些,可能有个130多MB的样子,因为他里面还要存放每个缓存页的描述数据。

4.Buffer Pool:初始化

数据库只要一启动,就会按照你设置的Buffer Pool大小,稍微再加大一点,去找操作系统申请一块内存区域,作为Buffer Pool的内存区域。然后当内存区域申请完毕之后,数据库就会按照默认的缓存页的16KB的大小以及对应的800个字节左右的描述数据的大小,在Buffer Pool中划分出来一个一个的缓存页和一个一个的他们对应的描述数据。然后当数据库把Buffer Pool划分完毕之后,看起来就是之前我们看到的那张图了,如下图所示
在这里插入图片描述
只不过这个时候,Buffer Pool中的一个一个的缓存页都是空的,里面什么都没有,要等数据库运行起来之后,当我们要对数据执行增删改查的操作的时候,才会把数据对应的页从磁盘文件里读取出来,放入Buffer Pool中的缓存页中。

5.Buffer Pool:free链表

当你的数据库运行起来之后,你肯定会不停的执行增删改查的操作,此时就需要不停的从磁盘上读取一个一个的数据页放入Buffer Pool中的对应的缓存页里去,把数据缓存起来,那么以后就可以对这个数据在内存里执行增删改查了。
但是此时在从磁盘上读取数据页放入Buffer Pool中的缓存页的时候,必然涉及到一个问题,那就是哪些缓存页是空闲的?因为默认情况下磁盘上的数据页和缓存页是一 一对应起来的,都是16KB,一个数据页对应一个缓存页。所以我们必须要知道Buffer Pool中哪些缓存页是空闲的状态。

free链表,他是一个双向链表数据结构,这个free链表里,每个节点就是一个空闲的缓存页的描述数据块的地址,也就是说,只要你一个缓存页是空闲的,那么他的描述数据块就会被放入这个free链表中。
数据库启动的时候,可能所有的缓存页都是空闲的,因为此时可能是一个空的数据库,一条数据都没有,所以此时所有缓存页的描述数据块,都会被放入这个free链表中。
在这里插入图片描述
个free链表里面就是各个缓存页的描述数据块,只要缓存页是空闲的,那么他们对应的描述数据块就会加入到这个free链表中,每个节点都会双向链接自己的前后节点,组成一个双向链表。

free链表,他本身其实就是由Buffer Pool里的描述数据块组成的,你可以认为是每个描述数据块里都有两个指针,一个是free_pre,一个是free_next,分别指向自己的上一个free链表的节点。

对于free链表而言,只有一个基础节点是不属于Buffer Pool的,他是40字节大小的一个节点,里面就存放了free链表的头节点的地址,尾节点的地址,还有free链表里当前有多少个节点。

那么磁盘数据页如何读取到缓冲池数据页的?
首先,我们需要从free链表里获取一个描述数据块,然后就可以对应的获取到这个描述数据块对应的空闲缓存页,我们看下图所示:
在这里插入图片描述
接着我们就可以把磁盘上的数据页读取到对应的缓存页里去,同时把相关的一些描述数据写入缓存页的描述数据块里去,比如这个数据页所属的表空间之类的信息,最后把那个描述数据块从free链表里去除就可以了,如下图所示:
在这里插入图片描述
我们在执行增删改查的时候,肯定是先看看这个数据页有没有被缓存,如果没被缓存就走上面的逻辑,从free链表中找到一个空闲的缓存页,从磁盘上读取数据页写入缓存页,写入描述数据,从free链表中移除这个描述数据块。但是如果数据页已经被缓存了,那么就会直接使用了。

所以其实数据库还会有一个**哈希表数据结构,他会用表空间号+数据页号,作为一个key,然后缓存页的地址作为value。**读取一个数据页到缓存之后,都会在这个哈希表中写入一个key-value对,key就是表空间号+数据页号,value就是缓存页的地址,那么下次如果你再使用这个数据页,就可以从哈希表里直接读取出来他已经被放入一个缓存页了。
在这里插入图片描述

6.Buffer Pool:flush链表

flush链表本质也是通过缓存页的描述数据块中的两个指针,让被修改过的缓存页的描述数据块,组成一个双向链表。凡是被修改过的缓存页,都会把他的描述数据块加入到flush链表中去,flush的意思就是这些都是脏页,后续都是要flush刷新到磁盘上去的,所以flush链表的结构如下图所示,跟free链表几乎是一样的。
在这里插入图片描述

7.Buffer Pool:淘汰缓存页

随着你不停的把磁盘上的数据页加载到空闲的缓存页里去,free链表中的空闲缓存页是不是会越来越少?因为只要你把一个数据页加载到一个空闲缓存页里去,free链表中就会减少一个空闲缓存页。free链表中迟早有一天会没有空闲缓存页了。就像redis一样,内存中存储的数据满了,怎么淘汰数据?

淘汰缓存页,顾名思义,你必须把一个缓存页里被修改过的数据,给他刷到磁盘上的数据页里去,然后这个缓存页就可以清空了,让他重新变成一个空闲的缓存页。
在这里插入图片描述

7.1.缓存命中率

假设现在有两个缓存页,一个缓存页的数据,经常会被修改和查询,比如在100次请求中,有30次都是在查询和修改这个缓存页里的数据。那么此时我们可以说这种情况下,缓存命中率很高。

另外一个缓存页里的数据,就是刚从磁盘加载到缓存页之后,被修改和查询过1次,之后100次请求中没有一次是修改和查询这个缓存页的数据的,那么此时我们就说缓存命中率有点低,因为大部分请求可能还需要走磁查询数据,他们要操作的数据不在缓存中。

因此,在进行缓存页淘汰的时候,命中率使我们考虑的一个原则。

7.2.LRU链表

的LRU就是Least Recently Used,最近最少使用的意思。通过这个LRU链表,我们可以知道哪些缓存页是最近最少被使用的,那么当你缓存页需要腾出来一个刷入磁盘的时候,不就可以选择那个LRU链表中最近最少被使用的缓存页了么?

假设我们从磁盘加载一个数据页到缓存页的时候,就把这个缓存页的描述数据块放到LRU链表头部去,那么只要有数据的缓存页,他都会在LRU里了,而且最近被加载数据的缓存页,都会放到LRU链表的头部去。

只要我们从磁盘加载一个数据页到缓存页的时候,就把这个缓存页的描述数据块放到LRU链表头部去,那么只要有数据的缓存页,他都会在LRU里了,而且最近被加载数据的缓存页,都会放到LRU链表的头部去。因此在进行淘汰缓存页的时候,直接在LRU链表的尾部找到一个缓存页,然后你就把LRU链表尾部的那个缓存页刷入磁盘中,然后把你需要的磁盘数据页加载到腾出来的空闲缓存页中就可以
了!
在这里插入图片描述

7.3.预读机制/全盘扫描

谓预读机制,说的就是当你从磁盘上加载一个数据页的时候,他可能会连带着把这个数据页相邻的其他数据页,也加载到缓存里去!如下所示:
在这里插入图片描述
那么这个时候,你要是把LRU链表尾部的缓存页给刷入磁盘,这是绝对不合理的,最合理的反而是把上图中LRU链表的第二个通过预读机制加载进来的缓存页给刷入磁盘和清空,毕竟他几乎是没什么人会访问的!
到底哪些情况下会触发MySQL的预读机制呢?

  1. innodb_read_ahead_threshold

有一个参数是innodb_read_ahead_threshold,他的默认值是56,意思就是如果顺序的访问了一个区里的多个数据页,访问的数据页的数量超过了这个阈值,此时就会触发预读机制,把下一个相邻区中的所有数据页都加载到缓存里去。

  1. innodb_random_read_ahead

如果Buffer Pool里缓存了一个区里的13个连续的数据页,而且这些数据页都是比较频繁会被访问的,此时就会直接触发预读机制,把这个区里的其他的数据页都加载到缓存里去,这个机制是通过参数innodb_random_read_ahead来控制的,他默认是OFF,也就是这个规则是关闭的.

  1. 全表扫描
    是类似如下的SQL语句:SELECT * FROM USERS,此时他没加任何一个where条件,会导致他直接一下子把这个表里所有的数据页,都从磁盘加载到Buffer Pool里去。

7.4.冷热分离LRU

上面所说的这些问题都是因为所有缓存页都混在一个LRU链表里,才导致的。真正MySQL在设计LRU链表的时候,采取的实际上是冷热数据分离的思想。
真正的LRU链表,会被拆分为两个部分,一部分是热数据,一部分是冷数据,这个冷热数据的比例是由innodb_old_blocks_pct参数控制的,他默认是37,也就是说冷数据占比37%。第一次被加载了数据的缓存页,都会不停的移动到冷数据区域的链表头部。
在这里插入图片描述
MySQL设定了一个规则,他设计了一个innodb_old_blocks_time参数,默认值1000,也就是1000毫秒。假设你加载了一个数据页到缓存去,然后过了1s之后你还访问了这个缓存页,说明你后续很可能会经常要访问它,这个时间限制就是1s,因此只有1s后你访问了这个缓存页,他才会给你把缓存页放到热数据区域的链表头部去。
在这里插入图片描述
综上,我们知道了在淘汰缓存的时候,一定是优先淘汰冷数据区域几乎不怎么被访问的缓存页

7.5. 热数据LRU移动

接着我们来看看LRU链表的热数据区域的一个性能优化的点,就是说,在热数据区域中,如果你访问了一个缓存页,是不是应该要把他立马移动到热数据区域的链表头部去?如果这样的话,是不是这么频繁的进行移动是不是性能也并不是太好?

当并发量大的时候,因为要加锁,会存在锁竞争,每次移动显然效率就会下降。因此 MySQL 针对这一点又做了优化,如果一个缓存页处于热数据区域,且在热数据区域的前 1/4 区域(注意是热数据区域的 1/4,不是整个链表的 1/4),那么当访问这个缓存页的时候,就不用把它移动到热数据区域的头部;如果缓存页处于热数据的后 3/4 区域,那么当访问这个缓存页的时候,会把它移动到热数据区域的头部。

举个例子,假设热数据区域的链表里有100个缓存页,那么排在前面的25个缓存页,他即使被访问了,也不会移动到链表头部去的。但是对于排在后面的75个缓存页,他只要被访问,就会移动到链表头部去。这样的话,他就可以尽可能的减少链表中的节点移动了

7.6. 冷数据LRU刷盘

首先第一个时机,并不是在缓存页满的时候,才会挑选LRU冷数据区域尾部的几个缓存页刷入磁盘,而是有一个后台线程,他会运行一个定时任务,这个定时任务每隔一段时间就会把LRU链表的冷数据区域的尾部的一些缓存页,刷入磁盘里去,清空这几个缓存页,把他们加入回free链表去!所以实际上在缓存页没用完的时候,可能就会清空一些缓存页了,我们看下面的图示
在这里插入图片描述

8.多个Buffer Pool优化并发能力

MySQL同时接收到了多个请求,他自然会用多个线程来处理这多个请求,每个线程会负责处理一个请求。
在这里插入图片描述
现在多个线程来并发的访问这个Buffer Pool了,此时他们都是在访问内存里的一些共享的数据结构,比如说缓存页、各种链表之类的,那么此时是不是必然要进行加锁?对,多线程并发访问一个Buffer Pool,必然是要加锁的,然后让一个线程先完成一系列的操作,比如说加载数据页到缓存页,更新free链表,更新lru链表,然后释放锁,接着下一个线程再执行一系列的操作。

大部分情况下,每个线程都是查询或者更新缓存页里的数据,这个操作是发生在内存里的,基本都是微秒级的,很快很快,包括更新free、flush、lru这些链表,他因为都是基于链表进行一些指针操作,性能也是极高的。

因此我们可以以给MySQL设置多个Buffer Pool来优化他的并发能力。
一般来说,MySQL默认的规则是,如果你给Buffer Pool分配的内存小于1GB,那么最多就只会给你一个BufferPool。
但是如果你的机器内存很大,那么你必然会给Buffer Pool分配较大的内存,比如给他个8G内存,那么此时你是同时可以设置多个Buffer Pool的,比如说下面的MySQL服务器端的配置。

[server]
innodb_buffer_pool_size = 8589934592
innodb_buffer_pool_instances = 4

我们给buffer pool设置了8GB的总内存,然后设置了他应该有4个Buffer Pool,此时就是说,每个buffer pool的大小就是2GB,这个时候,MySQL在运行的时候就会有4个Buffer Pool了!每个Buffer Pool负责管理一部分的缓存页和描述数据块,有自己独立的free、flush、lru等链表。
在这里插入图片描述

8.1.chunk机制支持动态调整buffer pool

buffer pool是由很多chunk组成的,他的大小是innodb_buffer_pool_chunk_size参数控制的,默认值就是128MB。每个chunk就是一系列的描述数据块和缓存页,这样的话,就是把buffer pool按照chunk为单位,拆分为了一系列的小数据块,但是每个buffer pool是共用一套free、flush、lru的链表的
在这里插入图片描述
给大家讲解这个chunk机制,倒不是让大家在数据库运行的时候动态调整buffer pool大小,其实这不是重点,重点是大家要了解数据库的buffer pool的真实的数据结构,是可以由多个buffer pool组成的,每个buffer pool是多个chunk组成的,然后你只要知道他运行期间可以支持动态调整大小就可以了。

8.2.Buffer pool总内存应该设置多少?

建议一个比较合理的、健康的比例,是给buffer pool设置你的机器内存的50%~60%左右比如你有32GB的机器,那么给buffer设置个20GB的内存,剩下的留给OS和其他人来用,这样比较合理一些。假设你的机器是128GB的内存,那么buffer pool可以设置个80GB左右,大概就是这样的一个规则。

8.3.Buffer pool应该设置多少个?

接着确定了buffer pool的总大小之后,就得考虑一下设置多少个buffer pool,以及chunk的大小了
此时要记住,有一个很关键的公式就是:
buffer pool总大小 = chunk大小 x chunk的个数 x buffer pool数量

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

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

相关文章

MySQL性能优化(四)redo log实现原理

文章目录1.redo log的作用2.redo log的结构2.1.redo log 记录2.2.redo log block2.3.redo log buffer3.redo log buffer 刷盘1.redo log的作用 首先我们都知道,执行增删改SQL语句的时候,都是针对一个表中的某些数据去执行的,此时的话&#x…

MySQL性能优化(五)undo log是如何实现MVCC的?

之前我们最开始的几篇文章就讲过,你除了写redolog日志还必须要写undo log日志,这个undo log日志是至关重要的,没有他,你根本都没办法回滚事务! 1.事务 1.1.多线程并发执行多个事务 对于我们的业务系统去访问数据库而…

Linux中Shell脚本--awk的用法

语法格式:awk [选项] ‘指令’ 操作文件 常用选项:-F 指定分隔符,分隔符用""引起来 -v:varvalue在awk程序开始之前指定一个值valu给变量var,这些变量值用于awk程序的BEGIN快 -f:后面跟一个保存…

linux下的shell脚本(基础)

Shell是一种脚本语言,那么,就必须有解释器来执行这些脚本,常见的脚本解释器有: bash:是Linux标准默认的shell。bash由Brian Fox和Chet Ramey共同完成,是BourneAgain Shell的缩写,内部命令一共有…

mysql rsync复制,mysql复制又同步

mysql复制再同步由于一个老旧系统没有使用LVM分区,导致mylvmbackup不能使用。为了重新全量同步数据库,发现rsync可以使用,并且锁住数据库的时间不长。1. 首先刷新数据库到文件flush tables with read lock;unlock tables;2. 执行rsync进行数据库同步/usr…

解决springboot中只支持get请求,无法支持post请求

解决springboot中只支持get请求,无法支持post请求 报错信息如下: 405 相关类如下: RestController RequestMapping public class HttpServiceController {Autowiredprivate HttpSecretReport httpSecretReport;Autowiredprivate HttpSecret…

mysql2005卸载步骤,二次安装mysql步骤

1.先将mysql服务停止,并关闭服务页面(否则后面报错:“指定的服务已经标记为删除”):打开“任务管理器”可以找到服务页面2.在控制面板对mysql进行删除。找到并将其卸载,如果没有直接跳过3.在注册表中删除相关目录。(使用组合键&qu…

Spring Boot 默认数据源 HikariDataSource_Spring Boot 中使用 Hikari

Spring Boot 默认数据源 HikariDataSource springboot2.x之后,系统的默认数据源由原来的的org.apache.tomcat.jdbc.pool.DataSource更改为com.zaxxer.hikari.HikariDataSource。 HikariDataSource 号称 Java WEB 当前速度最快的数据源,相比于传统的 C3…

matlab取出等高线上的数据,在Python或MATLAB中从等高线图中提取数据

这是一个小型的Matlab脚本,可以完成这项工作(使用一些GUI,在图的斜角处读取guidlines):%// Import the data:imdata importdata(your_picture_file);Gray rgb2gray(imdata.cdata);colorLim [-1 1]; %// this should be set manually%// Ge…

SpringBoot-默认数据源HikariDataSource对数据库操作及自动装配原理

默认数据源HikariDataSource对数据库操作 在创建项目时选择JDBC以及MySQL驱动&#xff0c;让SpringBoot自动装配所需组件 创建完成后默认的pom.xml文件如下 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.o…

matlab fgetl用法,Matlab fgetl strsplit 函数

函数功能&#xff1a;从文件中调用一行数据matlab中fgetl函数&#xff0c;并除去行末的换行符。语法格式&#xff1a;tline fgetl(fid)fid是通过fopen函数打开文件后得到的一个整型的文件标志。fgetl从这个文件中调用一行数据并丢弃其中的换行符。如果抓取成功tline容纳了调用…

HikariCP源码简洁剖析——HikariDataSource_HikariCP的使用和源码

文章目录HikariDataSource的作用源码剖析核心变量构造方法获取链接实例HikariCP的使用和源码简介HikariCP是什么&#xff1f;HikariCP 解决了哪些问题&#xff1f;为什么要使用 HikariCP&#xff1f;本文要讲什么&#xff1f;如何使用 HikariCP需求项目环境引入依赖编写 hikari…

MySQL如何创建沙箱,沙箱环境搭建 - osc_y8w65yuq的个人空间 - OSCHINA - 中文开源技术交流社区...

[toc]测试环境搭建沙箱环境&#xff1a;-------测试环境搭建基础配置&#xff1a;# 1、在沙箱环境下实名认证&#xff1a;https://openhome.alipay.com/platform/appDaily.htm?tabinfo# 2、电脑网站支付API&#xff1a;https://docs.open.alipay.com/270/105898/# 3、完成RSA密…

PHP单选框实现的方法,jQuery简单实现遍历单选框的方法

本文实例讲述了jQuery简单实现遍历单选框的方法。分享给大家供大家参考&#xff0c;具体如下&#xff1a;1、问题背景&#xff1a;有四个单选框&#xff0c;分别为一年四季&#xff0c;现在需要判断是否选中&#xff0c;如果选中这个单选框&#xff0c;就将其值赋值给输入框2、…

String怎么转成BigDecimal_Java.math.BigDecimal类的使用

1.引言 浮点数值不适用于无法接受舍入误差的金融计算中。 例如&#xff0c;命令System.out.prmtln (2.0-1.1)将打印出0.8999999999999999&#xff0c;而不是人们想象的0.9 。 2.0-1.1的运算结果 这种舍入误差的主要原因是浮点数值采用二进制系统表示&#xff0c;而在二进制系统…

JTS Java空间几何计算、距离、最近点、subLine等计算

文章目录前言地理坐标系和投影坐标系地理坐标系投影坐标系地图投影墨卡托/Web墨卡托常见坐标系地理坐标系和投影坐标系互转EPSG:3857和EPSG:4326Java各坐标系之间的转换&#xff08;高斯、WGS84经纬度、Web墨卡托、瓦片坐标&#xff09;GeotoolsJTSvividsolutions和locationtec…

JTS学习笔记

简介 JTS由加拿大的VividSolutions公司开发&#xff0c;是一个用Java语言描述的几何拓扑套件&#xff0c;遵循OpenGIS的Simple Feature Specification&#xff0c;封装了2D几何类型和非常多的空间分析操作&#xff0c;而且包含了不少常见的计算几何算法实现。 JTS被广泛地应用…

填坑:Maven工程引用GeoTools依赖

这两天在做一个系统的后台&#xff0c;需要用到GeoTools做后端空间分析&#xff0c;记录一下自己遇到的问题。 项目通过Maven进行构建&#xff0c;参照文档Maven Quickstart添加GeoTools依赖和远程仓库地址。 <dependencies><dependency><groupId>org.geotoo…

墨卡托投影介绍

一、墨卡托投影 墨卡托投影&#xff0c;又称正轴等角圆柱投影&#xff0c;由荷兰地图学家墨卡托(G.Mercator)于1569年创拟。假设地球被套在一个圆柱中&#xff0c;赤道与圆柱相切&#xff0c;然后在地球中心放一盏灯&#xff0c;把球面上的图形投影到圆柱体上&#xff0c;再把…

GIS算法:可视化工具JTS TestBuilder

java、python、js都有可以引用的第三方包&#xff0c;实现GIS的空间算法。 java是jts&#xff0c;python是shapely&#xff0c;js是turf。 其中jts值得首先拥有&#xff0c;因为jts提供了一个界面工具JTS TestBuilder&#xff0c;可以在上面绘制图形&#xff0c;验证各种算法…