ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

MinIO对象存储实践:解决GIS数据与瓦片缓存管理难题

MinIO对象存储实践:解决GIS数据与瓦片缓存管理难题 搞GIS数据的人十有八九都经历过这种场面整个项目组的成果都堆在一台工作站的D盘里谁要数据就靠U盘拷贝或者挂个共享盘随时担心被占用。等数据量上了几百GB光拷贝一个文件夹就能把人熬到怀疑人生更别提那种动辄几十万个文件的瓦片缓存目录在Windows共享里打开一次能卡半天。前两年我帮一家测绘单位搭内网数据存储环境当时就在思考怎么解决这些问题。当时项目里的数据主要分三类影像底图这类大文件、各类矢量数据和地图瓦片缓存。尤其是瓦片缓存一个项目一个地图切下来少说几十万个文件用传统文件系统管理实在痛苦。后来我用了MinIO搭了一套S3对象存储再让iDesktopX直接对接这套云存储把工作空间、瓦片缓存、成果数据都放进桶里整个数据流转都顺畅了很多。这篇文章就把我实际部署、配置、对接的完整过程写出来包括那些文档里不会写的坑给打算用MinIO做GIS数据存储的朋友做个参考。1. GIS数据存储为什么要上对象存储1.1 传统文件共享的痛点先说说传统方案哪里痛。瓦片缓存是典型的海量小文件场景。一个地图服务切完缓存目录结构通常是L00/R00/C00.png这种层级每个级别、每一行、每一列都是一个单独的文件。一个城市级别的影像地图瓦片数量轻松破百万。传统文件系统在处理这种场景时压力非常大原因是文件系统需要维护目录项、文件分配表这些元数据几十万个文件在一个目录里读写磁盘IO和元数据操作会成为双重瓶颈。我自己实测过从一台文件服务器往另一台机器拷贝含五十万文件的瓦片目录光文件名遍历就要跑将近二十分钟。更不要说多人同时通过共享盘打开这些文件锁冲突、传输中断、文件损坏是家常便饭。大影像文件的问题则是另一个方向。单景遥感影像动辄几个GB到几十个GB存在文件服务器上拷贝和分发都不方便。如果要用Web端展示还得先把影像发布成服务再把影像文件按服务要求的路径摆好整个流程牵一发动全身。工作空间文件虽然不大但它是项目的“入口”。传统的做法是每个人本地保存一份改完再拷贝合并版本稍不注意就乱了。1.2 对象存储的模型恰好适合GIS数据对象存储和传统文件系统最大的区别在于它根本没有“目录”这个概念。存储模型就是一个扁平的键值空间对象上传后有一个唯一的key所谓的目录结构只是key里的前缀而已。拿瓦片举例L00/R00/C00.png在对象存储里就是一个完整的对象key不需要预先创建L00目录、R00目录、C00目录。上传时直接在key里写这个路径就行读取时也直接用这个key构造HTTP URL访问。这样做的优势非常明显没有目录树的元数据维护压力水平扩展简单并发读写能力强客户端走HTTP协议就能访问。如果用生活化的类比文件系统像一个仓库货物要放到具体的货架层板上找货要先走到对应货架对象存储像一个快递柜每个格口有独立编号投递和取件都直接按编号操作不需要管柜子在仓库里的具体位置。对GIS数据来说还有一层额外的好处瓦片路径天然适合作为对象key。地图引擎渲染时请求http://store/tiles/地图名/L00/R00/C00.png这个逻辑和原来从本地读文件几乎一致但并发能力完全不同。1.3 为什么是MinIO而不是HDFS或公有云有人可能会问不是有HDFS吗不是有阿里云OSS这些公有云对象存储吗为什么我选了MinIO。先说HDFS。HDFS是为大数据批处理设计的适合MapReduce、Spark这种计算框架做顺序扫描和批量分析。它要把数据分块复制到多个DataNode适合超大文件大吞吐但对小文件的支持很差。NameNode把所有的元数据都放在内存里百万级别的瓦片文件直接能把NameNode内存吃满。用HDFS存GIS瓦片属于用牛刀杀鸡还杀不动。公有云对象存储当然是好东西S3本身就是AWS提出的标准。但很多GIS项目的数据敏感性高数据不能出单位内网。另外公有云按量计费长期存放几十TB数据成本未必低。网络带宽也可能成为瓶颈经常传大影像的时候卡在外网链路上。MinIO是开源软件兼容S3协议可以部署在纯内网环境。它本身非常轻量单机模式一条命令就能跑起来适合小团队几十GB到几个TB的存储需求。真正上规模的时候MinIO也能横向扩展成分布式集群用纠删码保证数据可靠性。对于GIS单位来说这套的伸缩空间完全够用。2. MinIO环境搭建开发到生产一套走完2.1 Docker快速搭建测试环境先聊最快的方式Docker。如果你只是想在本机或者一台测试服务器上快速跑起来体验一下MinIO的基本操作Docker是首选。我这边的命令比较固定docker run -d --name minio \ -p 9000:9000 -p 9001:9001 \ -e MINIO_ROOT_USERminioadmin \ -e MINIO_ROOT_PASSWORDminioadmin123 \ -v /data/minio:/data \ minio/minio server /data --console-address :9001这里有个容易踩的坑。9000端口是S3 API端口后面iDesktopX、mc、代码里连接MinIO走的就是这个端口。9001端口是管理控制台用来登录网页创建桶、管理用户的。这两个端口各管各的别搞混了。还要注意一下密码。MinIO要求管理密码最短8位否则容器起不来。如果你用123456这种短密码启动日志会直接报错。我一开始就是图省事用了短密码结果容器一直重启后来才发现是密码长度的问题。浏览器打开http://服务器IP:9001用上面设置的minioadmin和minioadmin123登录就能进入控制台。这个环境做功能验证、试试iDesktopX对接流程足够了。2.2 生产环境二进制部署与systemd托管测试环境随便跑没问题生产环境我还是建议用二进制方式部署用systemd托管进程。这样更可控也方便开机自启、异常拉起。先下载MinIO服务端二进制。以x86_64的Linux为例wget https://dl.min.io/server/minio/release/linux-amd64/minio install -m 755 minio /usr/local/bin/minio创建运行账号和数据目录useradd -r minio -s /sbin/nologin mkdir -p /data/minio chown -R minio:minio /data/minio然后写systemd管理文件/etc/systemd/system/minio.service[Unit] DescriptionMinIO Documentationhttps://min.io/docs/ Wantsnetwork-online.target Afternetwork-online.target [Service] Userminio Groupminio EnvironmentFile-/etc/default/minio ExecStart/usr/local/bin/minio server $MINIO_OPTS Restartalways LimitNOFILE65536 [Install] WantedBymulti-user.target环境变量文件/etc/default/minio里这么写MINIO_ROOT_USERminioadmin MINIO_ROOT_PASSWORD你的生产环境强密码 MINIO_OPTS--address :9000 --console-address :9001配置完成后启动systemctl daemon-reload systemctl enable --now minio systemctl status minio这里再说一个生产环境的细节。MinIO生产环境最好用独立的数据盘不要和系统盘混在一起。原因很简单对象存储的读写IO会持续占用磁盘与系统日志、数据库等争抢IO后期排查问题也麻烦。另外我建议把数据目录用单独的挂载点比如/data/minio这样后续扩容、迁移都方便。如果想让数据可靠性更高生产环境可以配置多节点纠删码模式。纠删码是对象存储的核心技术之一简单说就是数据分片后分散存储任意损坏一部分磁盘或节点数据都能恢复。MinIO官方推荐至少4个节点、每节点4块盘起步但对大多数GIS应用场景来说单机部署已经能满足性能要求先跑起来最重要。2.3 信创环境麒麟V10下的注意事项这两年国产化环境的项目越来越多我们这边也遇到过在麒麟V10上部署MinIO的需求。麒麟V10基于Linux内核MinIO官方虽然没有专门给麒麟发版本但只要是同CPU架构的Linux发行版跑起来基本没区别。关键点在CPU架构。如果是x86_64的麒麟下载linux-amd64的包如果是ARM架构比如鲲鹏920下载linux-arm64的包。千万别下错下错的话执行时直接报Exec format error。信创环境还有一个常见问题是glibc版本。一些老服务器自带的glibc版本比较旧而新版MinIO二进制的编译环境glibc要求较高。如果遇到version GLIBC_2.17 not found之类的报错可以下载官方标注的兼容旧系统版本。在我接触的实践中麒麟V10默认自带的glibc版本一般够用主要盯紧架构就行。另外麒麟系统默认是开防火墙的如果部署完发现控制台打不开先查一下防火墙有没有放行9000和9001端口firewall-cmd --zonepublic --add-port9000/tcp --permanent firewall-cmd --zonepublic --add-port9001/tcp --permanent firewall-cmd --reload我在信创环境踩过的最大一个坑反而是SELinux。麒麟默认SELinux可能是Enforcing模式systemd托管MinIO后数据目录的访问权限会被限制。最省事的办法是确认MinIO数据目录的SELinux上下文或者临时用setenforce 0验证问题确认是SELinux导致的再调整策略。当然生产环境不太建议直接关闭SELinux定位了问题再去精细化配置更稳妥。3. 桶、凭证和权限把MinIO配置成iDesktopX能用的存储3.1 创建AccessKey和桶MinIO安装好之后第一件事是配置访问凭证和创建桶。登录9001控制台左侧菜单找到“Access Keys”点“创建Access Key”。系统会生成一对密钥Access Key相当于用户名Secret Key相当于密码这里要特别提醒Secret Key只在创建那一刻完整显示一次关了就再也看不到了。所以生成后马上保存到一个安全的地方比如单位的密码管理软件里。如果丢了也没关系删掉旧的重新生成一个就行。接下来创建桶。在控制台左侧找“Buckets”点击“创建桶”命名比如ide-gis-data。桶命名有讲究S3协议里桶名全局唯一且不能包含大写字母和下划线只能用数字、小写字母和连字符。我一开始取了个GIS_Data的名字结果MinIO控制台直接不让创建提示命名不合法。其实这些操作用命令行工具mc更快后面会讲到。控制台操作适合不常碰命令行的同事批量操作我用mc多一点。3.2 权限模型私有桶、公共只读和预签名URLMinIO的权限体系分两层身份凭证和桶策略。身份凭证决定“你是谁”桶策略决定“你能对这个桶干什么”。iDesktopX接入时会给它配置一对AccessKey和SecretKey这样iDesktopX就有权限读写对应的桶了。桶策略分为几种私有、公共只读、公共读写和自定义策略。默认创建的桶是私有的任何匿名访问都会被拒绝。这个状态最适合iDesktopX内部使用因为有AK/SK的人才能读写数据安全有保障。但实际问题往往出现在这里地图瓦片生成后可能希望前端浏览器直接访问瓦片图片或者把某个成果链接发给甲方看。这时候就需要让特定对象能被匿名获取。很多人的第一反应是把桶设置成公共只读这么做确实简单但后患很大。公共只读意味着整个桶下的所有对象都能被匿名读取同时也能被匿名列举。别人只要知道你的桶地址就能列出你所有的数据对象这对项目数据来说风险很高。正确做法是用自定义策略只授权特定前缀的读取权限并且禁止列举。比如只允许匿名访问public/前缀下的对象策略这样写{ Version: 2012-10-17, Statement: [ { Effect: Allow, Action: [s3:GetObject], Resource: [arn:aws:s3:::ide-gis-data/public/*] } ] }用mc命令把这个策略应用到桶上mc anonymous set-json public-policy.json local/ide-gis-data这个策略下外部用户只能通过具体的对象URL访问比如http://192.168.1.10:9000/ide-gis-data/public/tiles/L00/R00/C00.png。但直接访问桶根路径或调用列举接口都会返回无权限。这是我最推荐的方式兼顾了共享需求和安全性。如果连指定前缀都不想让对方长期可访问只是临时分享某个文件用预签名URL更好。mc生成一个带有效期的临时链接mc share download local/ide-gis-data/成果数据/某项目结果.zip这个链接默认7天内有效过期自动失效。甲方收到链接直接浏览器下载不用装任何客户端非常方便。3.3 mc客户端的高频用法mc是MinIO官方提供的客户端工具功能很全日常运维必备。下载方式和服务端类似wget https://dl.min.io/client/mc/release/linux-amd64/mc install -m 755 mc /usr/local/bin/mc先配置一个“别名”指向你的MinIO服务mc alias set local http://127.0.0.1:9000 minioadmin 你的密码这里local是一个别名可随意命名后面的地址、AK/SK表示连接信息。配好之后下面这些命令我用的最频繁# 查看桶列表 mc ls local # 创建桶 mc mb local/ide-gis-data # 上传文件或目录 mc cp 本地路径 local/ide-gis-data/目标路径 mc mirror 本地瓦片目录 local/ide-gis-data/tiles # 下载 mc cp local/ide-gis-data/某个对象 ./本地路径 # 设置匿名访问 mc anonymous set download local/ide-gis-data mc anonymous set none local/ide-gis-data # 查看桶的所有对象 mc ls --recursive local/ide-gis-data # 查看MinIO服务状态 mc admin info local其中mc mirror是同步目录用的支持断点续传和增量同步。对于几十万瓦片文件上传到MinIO的场景这个命令比文件系统复制靠谱多了。4. iDesktopX对接MinIO的完整操作4.1 在iDesktopX里配置对象存储连接iDesktopX从较新的版本开始提供了对象存储对接能力。打开软件后在文件菜单附近找“对象存储”或“云存储”相关入口不同版本菜单位置略有差异但逻辑是一样的。进入配置界面后需要填写这些内容存储类型选择S3兼容或MinIO服务地址Endpoint例如http://192.168.1.10:9000Access Key和Secret Key前面在MinIO控制台创建的凭证Bucket填写ide-gis-data协议HTTP或HTTPS内网一般HTTP这里最容易出错的地方是Endpoint的写法。很多人会把整个桶地址写进去比如http://192.168.1.10:9000/ide-gis-data这是不对的。Endpoint只需要写到服务地址加端口桶名单独填。如果Endpoint里带了桶路径连接时会报错或者行为异常。填好后先点“测试连接”确认能连上再保存。连接成功后对象存储会作为一个可用的存储位置出现在资源面板中。从这一步开始工作空间、数据源、缓存都有了新的去处。我自己的体会是这一配置过程并不复杂真正复杂的是理解iDesktopX的“对象存储连接”到底代表什么。它相当于给软件挂载了一个网络存储位置后面所有涉及保存、打开的对话框里只要目标位置能选到这个云存储数据就能直接写进去。4.2 工作空间和数据源上云工作空间是iDesktopX项目的总入口里面记录了数据源连接、地图、场景、布局这些内容。工作空间文件本身很小几MB到几十MB顶天了放到对象存储里非常合适。在iDesktopX里把当前工作空间“另存为”保存类型里如果有“对象存储”或S3相关的选项选择后目标位置会自动指向你之前配置好的MinIO桶。保存成功后团队其他成员在各自的iDesktopX里配置同一个MinIO连接就能直接打开这个工作空间看到最新的项目状态。需要注意的是工作空间放对象存储适合“只读共享”或“串行编辑”。如果两个人同时打开同一个远程工作空间并保存后保存的人会覆盖先保存的人的内容而且没有提示。所以我的建议是对象存储上的工作空间作为唯一成果版本谁要编辑就先下载到本地改完再上传覆盖。这个流程虽然朴素但能避免大部分协作冲突。UDB和UDBX数据源文件存在对象存储上也可以但我不建议把正在编辑的数据源直接放在MinIO上高频读写。对象存储的单个对象写入是整文件覆盖不是文件系统那种随机读写块。如果数据源要频繁编辑保存还是在本地编辑完成后再整体上传。对象存储最适合“成果型、只读型”数据比如最终入库的矢量数据集、影像成果、发布用的瓦片缓存。4.3 瓦片缓存上云瓦片缓存是iDesktopX对接MinIO最有价值的部分。传统切图流程iDesktopX在本地生成缓存目录本地磁盘空间用来存海量小文件切完再把目录整体拷贝到服务器发布。这个过程有两次大成本一是本地磁盘被塞满二是拷贝时间极长。对接MinIO后生成瓦片缓存时可以直接把缓存目标设置成对象存储。切图进程生成的每一张瓦片直接通过S3协议写入MinIO。几十万、上百万的小文件不用再经历本地遍历、拷贝的折磨了。实际操作时有一点要把握好瓦片生成是IO密集任务直接写对象存储的网络IO比写本地NVMe慢这是物理限制。如果MinIO和iDesktopX在同一个千兆内网里生成速度完全可以接受。我同时生成过一份省级影像瓦片本地生成拷贝的总耗时和直接写MinIO几乎持平但省去了手动拷贝的步骤和磁盘占用。如果数据量特别大我建议分段生成比如按行政区或按比例尺范围分块处理避免一次任务跑十几个小时中途断网导致整个任务前功尽弃。4.4 与iServer的配合瓦片缓存放在MinIO后最终要发布成地图服务给前端访问。这个过程一般通过SuperMap iServer完成。iServer连接对象存储时也需要配置Endpoint、Bucket、AccessKey和SecretKey。这里有一个非常关键的细节iServer配置的路径前缀必须和iDesktopX写入瓦片时的路径一致。比如iDesktopX把瓦片写到了桶的tiles/某地图名/前缀下iServer访问对象存储时也要指定同样的前缀否则服务能起来但瓦片加载不出来浏览器控制台一片403。我在一个项目里就踩过这个坑。iDesktopX生成的瓦片在缓存/栅格瓦片/xxx/这种前缀下而iServer那边配置时少写了一层目录结果地图开天窗排查了大半天才反应过来是路径前缀不一致。如果计划用iServer读取MinIO上的瓦片建议在切图之前就统一设计好桶的目录结构比如ide-gis-data/ ├── workspaces/ # 工作空间 ├── datasources/ # 只读数据源 ├── tiles/ │ └── 栅格瓦片/项目名/ # 瓦片缓存 └── public/ └── 分享文件/ # 对外分享的成果这个结构在前期多花几分钟后期能省很多事。5. 上云之后多人协作和服务发布的真实变化5.1 数据分发方式的变化把数据放到MinIO上之后最直观的改变是分发方式。过去给甲方交付数据最常见的操作是把几百GB的文件夹拷贝到移动硬盘然后快递或者干脆让甲方来现场拷。这个过程既慢又容易出错。现在我对外的做法是把交付数据整理到桶的public/前缀下用自定义策略开只读权限再给甲方发一个直接的文件URL。如果文件不想长期暴露就用mc share download生成一个7天有效的临时链接。团队内部的协作模式也变了。外业采集的数据可以直接上传到MinIO的指定桶目录内业的iDesktopX打开工作空间时直接就能看到最新数据。以前靠U盘或网盘来回倒经常出现版本对不上的问题现在大家以对象存储上的版本为准配合一个简单的命名规范基本能杜绝混乱。跨办公地点访问同样受益。比如总部机房部署了MinIO分部的同事只要网络能通到总部直接用iDesktopX连接同一个Endpoint就能访问同一套数据。这比跨楼层网络共享盘稳定得多。5.2 性能体验与瓶颈很多人关心性能我说说实测感受。iDesktopX直接读MinIO上的工作空间和只读数据源时初次加载比本地略慢一点但在千兆内网环境下基本感知不到差别。真正明显的差异在瓦片生成和批量读写场景。瓦片生成直接写MinIO速度取决于两个因素网络带宽和MinIO的IO能力。实测下来在普通企业千兆内网里单机MinIO用机械硬盘存储切图速度大概是本地NVMe的60%到70%。如果MinIO用的是SSD差距能缩小到90%以上。对大多项目来说这个性能损失完全可以接受因为换来了后续不用再费劲拷贝的大便利。从服务端读取瓦片的角度看对象存储的并发表现明显好于传统共享盘。传统SMB文件共享在大量并发读同一目录时文件锁和元数据操作会拖垮IO而对象存储没这个问题。我这边一个影像服务从SMB共享迁移到MinIO之后同样并发下服务端CPU和磁盘等待时间都降了不少。瓶颈方面最常出现在外网访问场景。如果MinIO部署在内网而前端要通过公网访问瓦片带宽受限时瓦片加载会明显变慢。这个问题的常规解法是在MinIO前加一层CDN或者缓存服务或者把瓦片同步到公有云对象存储做分发。这些属于架构升级的范畴大项目再考虑。5.3 也可以这样扩展MinIO这套底座搭好之后不仅iDesktopX能用很多其他场景也能直接受益。比如MinIO支持桶版本控制开启后每次对象覆盖都会保留历史版本。这个功能用来做数据回溯很有用误删或误改的数据可以找回。再比如生命周期规则可以设置超过一定天数的瓦片自动过期删除对临时数据多的项目来说省心很多。如果后续数据量增长到单机撑不住MinIO可以平滑扩展成分布式集群数据通过纠删码跨节点存储。整个扩展过程对上层应用透明iDesktopX和iServer的连接地址不用大改。这也是我当时选MinIO而不是直接堆文件服务器的重要原因。6. 排坑实录常见问题与解决办法6.1 连接失败类iDesktopX测试连接失败但浏览器能打开MinIO控制台这个问题我见过好几次原因基本都是端口搞混了。MinIO的9001端口是控制台端口只提供网页管理界面不走S3 API。iDesktopX连接时填入的Endpoint端口必须是9000也就是S3 API端口。把接口地址从9001改成9000问题就解决了。连接时报 SignatureDoesNotMatch 或 InvalidAccessKeyId这两个报错通常指向两个原因AccessKey或SecretKey填写错误或者客户端与服务器时间不同步。S3签名机制会用到时间戳MinIO校验请求签名时如果发现客户端时间和服务器时间差太多直接拒签。虚拟化环境里虚拟机系统时间漂移是常事给服务器配置NTP时间同步是最省心的方案。报 NoSuchBucket桶不存在或者桶名写错了。用mc确认一下mc ls local如果桶列表里没有iDesktopX里填写的那个桶先去MinIO控制台或mc创建桶再回iDesktopX重试。6.2 访问权限类桶设成公共只读后别人能列出所有文件名这就是我前面强调过的问题。公共只读策略默认包含ListBucket权限匿名用户可以罗列桶内所有对象。解决办法是用自定义策略只授权GetObject禁止列举。前端地图服务只需要能根据URL读取瓦片不需要列举能力。瓦片生成时部分文件报403AccessKey的权限不足。检查一下这个AccessKey对应的用户是否对该桶有完整读写权限。MinIO创建的用户默认没有任何权限需要在控制台给用户分配对应的存储桶策略比如readwrite策略或者自定义策略。iServer读取对象存储上的瓦片部分瓦片加载失败路径前缀不一致是最大嫌疑。iServer配置的对象存储路径前缀必须和iDesktopX写入时的前缀完全一致。不要只改iServer的桶名而忘了路径也别因为iServer和iDesktopX界面显示方式不同就把前缀多写或少写一层。6.3 性能与兼容类大影像上传中断上传几个GB的大文件时网络抖动就可能导致失败。mc工具支持分片上传和断点续传推荐先用mc把大影像上传到MinIO再在iDesktopX里连接使用比直接在软件里长传更稳。如果一定要在iDesktopX里直接上传也建议在网络稳定的时段进行不要边传边用同一网络跑大流量任务。Windows下mc工具无法执行mc的Linux版和Windows版是分开的Windows环境下载mc.exe在PowerShell或CMD里运行。别把Linux版下载到Windows里用执行时会直接报错。Windows Server环境如果开启了执行策略限制用管理员权限执行Set-ExecutionPolicy RemoteSigned调整策略即可。版本兼容性差iDesktopX对接MinIO依赖S3协议理论上任何S3兼容的对象存储都行。但实际中MinIO版本太老和客户端版本太新或者反过来都可能遇到部分接口不兼容。如果遇到一些莫名其妙的连接或上传问题先确认两边版本大致在同一个时代。MinIO版本号可以从控制台左下角看到iDesktopX的版本在启动页或者关于里能看到。我个人在实际操作中的体会是MinIO和iDesktopX这套组合最大的价值不是替代某个具体工具而是把杂乱的数据组织方式统一成了标准的S3对象存储。数据有了固定的归属权限可以控制访问可以审计历史版本可以有分发方式也变得灵活很多。如果你正在被瓦片缓存、大影像分发、团队协作这些事困扰照着上面的方案搭一套试试。跑通之后你会发现以前那些让人头疼的拷贝、等待、版本覆盖问题大部分都不会再出现了。
返回列表