地盤ボーリング・浸水想定・自然災害伝承碑・不動産取引履歴など8つのレイヤーを全国対応させました。もっとも重かった土地利用細分メッシュ(全9年度・約64GB)がなぜ19時間52分かかったのか、途中で起きた2件のインシデントと、無人化と人の判断を切り分けた運用設計を、実録としてまとめます。
こんにちは、MAPRISE開発チームです。前回の記事では登記所備付地図とPLATEAUの全国対応について書きましたが、その後も並行して他のレイヤーの全国展開を進めており、今回さらに8つのレイヤーが本番で全国対応を完了しました。今日は機能紹介ではなく、その展開作業そのものの記録です。特に、全レイヤーの中でもっとも処理時間を要した土地利用細分メッシュについて、なぜ19時間52分もかかったのか、途中で何が起きたのかを、汗をかいた分だけ正直に書きます。
今回全国対応した8レイヤー
| レイヤー | 対応拡大 | 件数・容量 |
|---|---|---|
| 国勢調査小地域(集計ビュー同期) | 九州域 → 全国 | 23,872件 → 214,367件 |
| 地盤ボーリング柱状図(KuniJiban) | 九州7県 → 全国47都道府県 | 38,072本 → 262,284本 |
| 内水浸水想定区域(KSJ A51) | 福岡市・大牟田市 → 22都道府県 | 49,575行 → 202,869行 |
| 自然災害伝承碑 | 九州7県 → 全国47都道府県 | 278件 → 2,463件 |
| 不動産取引価格情報(2005〜2025年) | 九州7県 → 全国47都道府県 | 645,463件 → 6,577,049件 |
| 多段階浸水想定区域(KSJ A53) | 国管理1整備局相当 → 全国8地方整備局 | 501,714行 → 3,850,088行 |
| PLATEAU建物(3D都市モデル) | 九州27自治体 → 全国265自治体 | 1,956,743棟 → 23,759,999棟 |
| 土地利用細分メッシュ(KSJ L03-b、1976〜2021) | 九州 → 全国9年度 | 全国合計 約64.1GB |
いずれも投入前後で既存データの件数・内容が変わっていないことを確認したうえで本番反映し、実際のタイル配信エンドポイントで新規エリアのデータが返ることまで確認しています。
九州で培ったノウハウをどう活かしたか
九州7県での対応を通じて積み上げてきたやり方を、そのまま47都道府県・数百自治体規模に当てはめると、確認作業だけで終わらない規模になります。今回はいくつかの点で、九州での知見を土台にしながら手法を発展させました。
並行実行: 不動産取引データの過去21年分バックフィルでは、当初「2並列で約1.75倍高速化」という見積りに対し、実際には8〜9並列を採用しました。reinfolib APIにIPベースの明確なレート制限がないこと、DB側も8〜9本の独立接続による同時INSERTでロック競合が起きないことを実測で確認したうえでの判断です。結果、6バッチすべてが0エラーで完走し、実測の高速化率は約3.4〜4.9倍に達しました。
段階的検証の徹底: 8レイヤーいずれの投入も、「dry-run(全件ROLLBACKで書込ゼロを確認)→件数一致確認→本投入→投入前後の全県別件数diffで非対象県の完全不変を確認」という手順を踏んでいます。地味ですが、この手順を省略すると、後述するような性能バグや仕様の落とし穴に投入後まで気づけない可能性が高くなります。
環境制約への対処: 今回複数のセッションで、ブラウザの視覚的レンダリング確認ができない(document.visibilityState: hiddenのままでMapLibreの初期化が走らない)という制約に繰り返し直面しました。代替として、本番ドメインに対しPMTilesプロトコル準拠のHTTP Range GETを直接実行する、あるいは本番ページのJavaScriptコンテキストでfetch()を実行してサーバー側curlの結果とバイト単位で突き合わせる、という手法を使っています。ピクセルの目視確認はできなくても、実際にエンドユーザーが辿る配信経路そのものを検証できるため、確認の質としては十分に厳格です。
なぜ土地利用細分メッシュだけ19時間52分かかったのか
8レイヤーの中で、土地利用細分メッシュ(1976・1987・1991・1997・2006・2009・2014・2016・2021年度の全9年度)だけが際立って時間を要しました。パイプライン起動は2026年8月16日20時28分、全9年度の完了は翌17日16時20分、実測で約19時間52分です。
まず律速要因を実測で特定した
想像で並列化の設計をする前に、九州2006年度20メッシュでパイロットビルドを行い、各フェーズの実時間を計測しました。
| フェーズ | 所要時間 |
|---|---|
| GeoJSON変換(ogr2ogr、20メッシュ) | 233秒 |
| tippecanoe | 916秒(15.3分) |
ダウンロードはサブ秒単位で無視できる規模である一方、tippecanoeだけで15分以上を要しており、律速要因は明確にCPU・メモリ側(tippecanoeのジオメトリ再整列処理)にあることが分かりました。GeoJSON圧縮前後のサイズ比は16.40倍で、都市部・農村部でほぼ一定という結果も得られたため、この比率をそのまま全国スケールへの外挿に使えると判断しました。
外挿の見積りは外れた(良い方向に)
当初、九州実績(19メッシュで数百MB〜1GB強)を単純にメッシュ数比(全国175〜180メッシュ、約9.2〜9.5倍)で外挿すると、全国では数十〜100GB規模になるという懸念がありました。しかし実測は9.28GBにとどまりました。理由は、九州は地形・土地利用が密で圧縮効率が低い地域を多く含む一方、全国スケールでは山間部・離島・海上境界を含む多数のメッシュが低密度で高圧縮率になり、単純なメッシュ数比では過大評価になるためだと判明しました。
一方で、tippecanoe実測スループット(327秒/GB-GeoJSON)から逆算した全国9年度の推定総所要時間は約15.7時間となり、これがそのまま今回の作業時間の大部分を占めることになりました(実績19時間52分のうち、後述する2件のインシデント対応の時間も含みます)。
並列化の設計方針
フェーズごとに律速要因が異なるため、並列化の方針もフェーズごとに変えています。
- ダウンロード(I/O律速):
ThreadPoolExecutor(max_workers=6)で並行化。政府サイトへの配慮として過度な同時接続数は避けました。 - GeoJSON変換(CPU律速): 物理vCPU数(2)に合わせ
max_workers=2。並行実行数を物理コア数以上にしないという知見をそのまま適用しています。 - tippecanoe(メモリ律速): 1プロセスで500MB以上のメモリを使用する実績があるため、単一プロセス・年度間も完全逐次としました。
EC2の一時増強についても検討しましたが、CPU Creditモードが無制限(Unlimited)であること、および以前あった「本番DBの高負荷時にpg_isreadyが偽陽性でDOWNと誤検知しkill -9で強制停止させる」障害の原因(ヘルスチェックスクリプトの自己修復ロジック)が前日までに撤去済みであることを確認できたため、一時増強は不要と判断し、nice・ioniceで本番DB・Martinへの影響を緩和しながら現行スペックで逐次実行する方針を採りました。
発生した2件のインシデント
19時間52分の中で、実行時ブロッカーが2件発生しました。いずれも推測で対処せず、根本原因を実測で特定してから修正しています。
インシデント1: 1976年度のS3アップロード失敗
原因は、ローカル開発機専用のAWSプロファイル指定(--profile)を、そのままEC2向けスクリプトに持ち込んでしまっていたことでした。EC2上にはそのプロファイルが存在しないため失敗しますが、tippecanoeによるビルド自体はすでに成功していたため、成果物を破棄せずに済みました。EC2のインスタンスロールを使った正しい認証で復旧し、恒久対策としてスクリプトから--profile指定そのものを削除しました。
インシデント2: 2006年度、tippecanoeが「No space left on device」で失敗
設計時のディスク容量想定が、九州限定版の実績(出力350MB〜1.2GB/年度)を前提にしていたことが原因でした。全国版の実際の出力サイズは1年度あたり7〜8GBに達し、9年度分すべてのGeoJSON中間ファイルを同時に保持する設計は成立しません。すでに検証・S3アップロードが完了していた年度分のローカルコピーを解放することで42GBを復旧させ、恒久対策として「S3アップロード成功後にhead-objectでサイズ照合したうえでローカルの出力ファイルを削除する」設計へ変更しました(生ZIPファイルは監査証跡として保持し続けます)。
最終的に全国合計約64.1GBをS3へ配信し、9年度全件についてS3から生ヘッダーを直接取得する独立監査スクリプトで全件PASSを確認しています。
継続的に運用するための仕組み
一度全国対応を終えても、これらのデータは完成するわけではありません。国が新しい年度のデータを公開すれば取り込みが必要になりますし、自治体ごとに整備状況も変わっていきます。今回、PLATEAUと土地利用細分メッシュの両方について、新しいデータの公開を検知する仕組みを見直しました。
PLATEAU側: 既存の月次監視(G空間情報センターのCKANメタデータ照会)に加えて、Stage1投入で発見した「構造種別コードの未知値」問題を継続的に追跡する仕組みを追加しました。国土交通省が公表する公式コード表そのものの改版を月次で監視し、改版が検知されたときにだけ、除外中の自治体をdry-run(本番書込を一切伴わない検品ゲートの再実行)で再検査するという二層構成です。無条件の高頻度自動実行はコストに見合わないため、「まず軽量な監視で変化の兆候を掴み、兆候があったときだけ重い再検査を行う」という設計にしています。
土地利用細分メッシュ側: 既存の監視は固定URLを対象にしていましたが、実際に調べたところ、国のサイトは同じデータセットに対して過去版・現行版・マスター一覧経由のリンクという3種類のURLが同時に生存しており、新しい版が既存URLの更新ではなく全く新しいURLで公開されることがあると分かりました。固定URL監視のままでは、次の版が新URLで公開されて旧URLが凍結放置された場合に検知漏れが起こり得ます。そこで、国のマスター一覧ページからその時点の代表URLを毎回動的に解決し、そのURLを監視する方式へ変更しました。
なぜ全自動化しないのか: どちらの仕組みも、検知した先の「実際にデータを取り込むかどうか」の判断は人が行う設計にしています(notify→L3承認→ingestという段階的なフロー)。理由は単純で、Stage1で実際に7自治体が想定していなかった検品ゲート失敗を起こした実績があるとおり、「新しい自治体・新しい年度のデータは必ず安全に取り込める」という前提が成り立たないためです。また、土地利用細分メッシュの1回のビルドだけで十数時間規模のCPU・ディスク負荷が発生することも、人が事前に把握すべき規模の変更だと考えています。無人化するのは「変化を検知して知らせるところまで」、実際に取り込むかどうかの最終判断は人が行う——このすみ分けを、今回あらためて明確にしました。
品質チェックと回帰チェック
全国対応にあたって、既存の九州分データを壊さないことと、投入するデータそのものの品質を保つことの両方に、それぞれ別の仕組みを設けています。
fail-closedな検品ゲート: PLATEAUの建物投入では、245自治体のうち238自治体は成功しましたが、残り7自治体は建物の構造種別コードが公式コード表に存在しない値(607・612・613)を含んでいたため、検品ゲートが自動的に止めました。未知のコードに遭遇したときに推測で対応表を拡張するのではなく、投入自体を保留し、人が原典を確認してから判断する、という設計です。実際、この保留判断のおかげで、根拠のない対応表を本番に持ち込まずに済んでいます。
投入前後の非接触確認: 不動産取引データの投入では、6バッチそれぞれについて投入前後の全都道府県別件数を突き合わせ、変化したのは当該バッチの対象県のみであることを確認しました。地盤ボーリング柱状図の投入SQLにも、九州データが1件でも混入していたら即座に処理を中断する安全ガードを組み込んでいます。
独立監査: 土地利用細分メッシュでは、ビルドスクリプト自身の完了報告を鵜呑みにせず、S3から生のPMTilesヘッダーを直接取得して検証する、別系統の監査スクリプトを走らせています。内水浸水想定区域では、除外対象の自治体(データが存在しないはずのエリア)に対しても実際にタイルリクエストを送り、正しく「データなし」の応答が返ることを確認する陰性対照を行いました。
これらはどれも地味な作業ですが、「投入が完了しました」という報告そのものを信用せず、実際のデータで機械的に裏取りする、という姿勢を貫くことで、公開してから気づく不具合を減らせると考えています。
おわりに
今回ご紹介した8つのレイヤーの全国対応と、その裏側で起きた19時間52分のtippecanoeビルドの記録は、派手さはありませんが、地図データという「終わりのない」情報を扱ううえで避けて通れない作業です。地図データは、位置という共通の軸を通じて、統計・地価・災害履歴・建物・地盤といった性質の異なる情報を1つの場所に積み重ねられる、ビッグデータの宝庫だと考えています。継続的に積み重ねてきた歴史を定量化し、デジタルとAIの力でさまざまな角度から分析できるようにすることで、その恩恵をより多くの人に届けられるシステムを、これからも地道につくっていきます。
ご意見・ご質問は info@maprise.jp までお気軽にお寄せください。
本記事で紹介した各データは、国土交通省・法務省・国土地理院・総務省統計局等が公開するオープンデータを情報源としています。件数・容量・所要時間は、いずれも一次資料である各タスクの完了報告書に記載の実測値に基づいており、本記事公開時点のものです。今後の運用により変動する可能性があります。
タグ: #全国展開 #データ品質 #監視 #回帰テスト #tippecanoe
他言語のシェアテキスト (例外運用向け)
通常は上の Quick share をご利用ください (X 系は日本語、LinkedIn は英語に固定)。下の 4 ペインは「英語記事を X で日本語紹介したい」「日本語記事の LinkedIn 投稿を日本語で出したい」等の例外運用に使えます。各テキストはコピー編集してから投稿することも、そのまま投稿画面を開くこともできます。
📝 8レイヤー全国化と、土地利用メッシュが動いた19時間52分の記録 地盤ボーリング・浸水想定・自然災害伝承碑・不動産取引履歴など8つのレイヤーを全国対応させました。もっとも重かった土地利用細分メッシュ(全9年度・約64GB)がなぜ19時間52分かかったのか、途中で起きた2件のインシデントと、無人化と人の判断を切り分けた運用設計を、実録としてまとめます。 https://maprise.jp/ja/blog/nationwide-sprint-eight-layers/ #全国展開 #データ品質
🆕 新しいブログ記事を公開しました。 《8レイヤー全国化と、土地利用メッシュが動いた19時間52分の記録》 地盤ボーリング・浸水想定・自然災害伝承碑・不動産取引履歴など8つのレイヤーを全国対応させました。もっとも重かった土地利用細分メッシュ(全9年度・約64GB)がなぜ19時間52分かかったのか、途中で起きた2件のインシデントと、無人化と人の判断を切り分けた運用設計を、実録としてまとめます。 👉 詳しくはこちら: https://maprise.jp/ja/blog/nationwide-sprint-eight-layers/ #tippecanoe
📝 Eight Layers Nationwide, and the 19-Hour-52-Minute Land-Use Mesh Build We took eight layers nationwide — borehole logs, flood inundation zones, disaster monuments, real-estate transaction history, and more. The heav… https://maprise.jp/en/blog/nationwide-sprint-eight-layers/ #Nationwideexpansion #Dataquality
🆕 New on the MAPRISE blog. 《Eight Layers Nationwide, and the 19-Hour-52-Minute Land-Use Mesh Build》 We took eight layers nationwide — borehole logs, flood inundation zones, disaster monuments, real-estate transaction history, and more. The heaviest of the eight, the land-use detailed mesh (all 9 fiscal years, roughly 64GB), took 19 hours and 52 minutes. Here's why, the two incidents we hit along the way, and how we split zero-touch automation from human judgment in the operating design. 👉 Read the full post: https://maprise.jp/en/blog/nationwide-sprint-eight-layers/ #Nationwideexpansion #Dataquality #Monitoring #Regressiontesting #tippecanoe