Nạp 1 nghìn tỷ bản ghi dữ liệu thời tiết vào TimescaleDB
(aliramadhan.me)- Để phân tích nhanh các biến động thời tiết lịch sử trên toàn cầu, cần đưa dữ liệu tái phân tích ERA5 vào PostgreSQL/TimescaleDB; với các biến và lưới được chọn, quy mô vào khoảng 754 tỷ hàng
- ERA5 cung cấp độ phân giải theo giờ từ năm 1940 và lưới vĩ độ/kinh độ 0,25 độ, nhưng trong cấu trúc NetCDF, việc trích xuất chuỗi thời gian dài hạn tại một điểm vẫn có thể mất 20–30 phút
inserttừng hàng đơn lẻ chỉ đạt khoảng 3 nghìn hàng/giây, nên sẽ cần khoảng 8 năm để nạp toàn bộ; ngay cảinsertnhiều hàng cũng chỉ ở mức 25 nghìn–30 nghìn hàng/giây theo psycopg3, tương đương gần 10 tháng- PostgreSQL
copyvàcursor.copy()của psycopg3 khác nhau tùy việc CSV đã được chuẩn bị sẵn hay chưa; tính cả overhead thì khoảng 100 nghìn hàng/giây, và còn có thể đẩy cao hơn bằng chạy song song cùng tinh chỉnh cấu hình - Khi nạp trực tiếp từ dataframe, cách phù hợp là copy thẳng vào hypertable bằng psycopg3; khi đã có sẵn CSV thì
timescaledb-parallel-copyphù hợp hơn, và trên hệ thống này 12–16 worker có vẻ là điểm tối ưu cho song song hóa
Xây dựng kho dữ liệu thời tiết toàn cầu
- Mục tiêu là xây dựng một kho dữ liệu có thể truy vấn dữ liệu thời tiết lịch sử trên toàn cầu để phân tích các tín hiệu biến đổi khí hậu đã thực sự xảy ra
- Các phân tích ví dụ gồm Jakarta có thực sự nóng hơn hay bão xuất hiện thường xuyên hơn không, toàn bộ Chile có ấm hơn hay nhiều mây hơn không, và các thay đổi theo từng khu vực có dạng như thế nào
- Để phân tích toàn cục nhanh, các truy vấn trên kho dữ liệu phải đủ nhanh, và bước đầu tiên là nạp khối lượng dữ liệu rất lớn vào cơ sở dữ liệu
- Nền tảng được chọn là PostgreSQL; TimescaleDB là lựa chọn triển vọng để tăng tốc truy vấn theo thời gian, còn PostGIS có tiềm năng cho tăng tốc truy vấn không gian địa lý về sau
Dữ liệu tái phân tích ERA5 và quy mô 754 tỷ hàng
- Thay vì dùng số đo thời tiết thực tế, bài viết sử dụng dữ liệu ERA5 climate reanalysis
- Các quan trắc lịch sử có thể thưa thớt ở một số khu vực và thời điểm trong quá khứ
- ERA5 là đầu ra của mô hình khí hậu được ràng buộc để khớp với quan trắc, và được dùng rộng rãi trong nghiên cứu thời tiết và khí hậu
- ERA5 bao phủ toàn bộ Trái Đất ở độ phân giải 0,25 độ, với độ phân giải theo giờ từ năm 1940
- Mỗi ảnh chụp thời gian có 727.080 giá trị cho mỗi biến
- Có 1.038.240 điểm lưới, gồm 1.440 kinh độ và 721 vĩ độ bao gồm cả hai cực
- Khi lập chỉ mục theo thời gian và vị trí, mỗi biến sẽ có 753.836.544.000 hàng, tức khoảng 754 tỷ hàng
- Các biến được nạp gồm nhiệt độ, tốc độ gió 10m theo hướng đông-tây và bắc-nam, tổng lượng mây, lượng mưa và lượng tuyết rơi
- Bảng dữ liệu có các cột
time,location_id,latitude,longitudecùng các cột cho từng biến thời tiết- Việc giữ cả
location_idlẫn cột vĩ độ/kinh độ là để benchmark truy vấn và chỉ mục về sau
- Việc giữ cả
Điểm mà cấu trúc file NetCDF trở nên chậm
- ERA5 được phân phối dưới dạng file NetCDF, thường chứa dữ liệu theo từng ngày, tháng hoặc năm
- Cấu trúc chunk theo thời gian giúp truy vấn dữ liệu tại một thời điểm cụ thể nhanh và đơn giản
- Nhưng để xem mẫu theo thời gian, như chuỗi thời gian dài hạn tại một điểm, phải đọc rất nhiều file nên trở nên chậm
- Ví dụ, việc trích xuất chuỗi thời gian nhiệt độ tại một vị trí có thể mất 20–30 phút
- Các truy vấn không gian địa lý phức tạp, đặc biệt là truy vấn có thêm trục thời gian, vừa chậm vừa khó thực hiện
- Các công cụ như xarray, dask, Pangeo có thể tăng tốc, nhưng quá trình này nhìn chung vẫn chậm
insert: từ từng hàng đơn lẻ đến nhiều hàng
- Cách đơn giản nhất là dùng
insertđể thêm từng hàng một inserttừng hàng kéo theo nhiều loại chi phí- PostgreSQL phải phân tích câu lệnh, kiểm tra tên bảng và cột, rồi lập kế hoạch thực thi
- Có thể cần khóa để đảm bảo tính toàn vẹn dữ liệu
- Dữ liệu được ghi vào bộ đệm để phục vụ WAL (write-ahead logging)
- Dữ liệu được chèn vào vùng đĩa thực của bảng
- Khi transaction được commit, thay đổi mới được ghi nhận vĩnh viễn
- Trong Python, bài viết benchmark ba cách chèn từng hàng
- Dùng pandas
df.to_sql()vớichunksize=1 - Dùng truy vấn tham số hóa của psycopg3
- Dùng truy vấn tham số hóa của SQLAlchemy
- Dùng pandas
- Kết quả chèn từng hàng cho thấy psycopg3 nhỉnh hơn một chút và SQLAlchemy chậm nhất
- Hypertable của TimescaleDB chậm hơn đôi chút so với bảng PostgreSQL thông thường
- Hiệu năng cao nhất chỉ khoảng 3 nghìn hàng/giây, tức sẽ mất khoảng 8 năm để nạp toàn bộ dữ liệu
insertnhiều hàng đưa nhiều dòng vào một câu lệnh để giảm số lần round-trip mạng, chi phí parse và lập kế hoạch- psycopg3 nhanh nhất ở mức 25 nghìn–30 nghìn hàng/giây
- pandas có thể chậm hơn vì cấu trúc chèn dựa trên dictionary thay vì tuple
- SQLAlchemy có thể phát sinh thêm overhead từ quản lý session và lớp trừu tượng biểu thức SQL
- Dù vậy, toàn bộ quá trình nạp vẫn cần khoảng 0,8 năm, tức gần 10 tháng
copy: con đường nạp dữ liệu hàng loạt của PostgreSQL
- PostgreSQL
copylà tính năng nạp dữ liệu hàng loạt bằng cách đọc các hàng từ file CSV hoặc nhị phân - Vì được tối ưu cho bulk load, nó giảm chi phí parse, lập kế hoạch và sử dụng WAL tốt hơn nên nhanh hơn
insertnhiều hàng - Bài viết so sánh hai đường đi
- Lưu dữ liệu NetCDF ra CSV rồi nạp bằng
copy - Không tạo file CSV mà stream trực tiếp vào PostgreSQL bằng psycopg3
cursor.copy()
- Lưu dữ liệu NetCDF ra CSV rồi nạp bằng
- Khi file CSV đã sẵn sàng,
copycó thể đạt tốc độ chèn gần 400 nghìn hàng/giây - Nếu tính cả overhead ghi file CSV hoặc tạo tuple, cả
copylẫn psycopg3 đều ở mức khoảng 100 nghìn hàng/giây, trong đó psycopg3 nhỉnh hơn một chút - Ngay cả ở tốc độ này, việc nạp toàn bộ dữ liệu vẫn cần khoảng 3 tháng
Tốc độ nạp duy trì và copy song song
- Khi chèn rất nhiều hàng, có thể xuất hiện các nút thắt như ghi đĩa, cạnh tranh I/O giữa WAL và chèn bảng, autovacuum, hay checkpoint
- Trong thử nghiệm nạp khoảng 772 triệu hàng qua 744 batch, với một worker đơn lẻ không thấy mức suy giảm tốc độ quá lớn
copy csvcó các đợt giảm tốc thường xuyên và dễ biến động hơn- psycopg3 nhìn chung nhanh hơn
- Chênh lệch giữa bảng thường và hypertable không lớn
- Bài viết dùng joblib để chạy song song nhiều tác vụ
copyhoặc nhiều cursor psycopg3 - Chèn vào một bảng đơn lẻ không phải loại công việc song song hóa tốt, và hiệu năng nhìn chung chững lại sau 16 worker
pg_bulkload và timescaledb-parallel-copy
- Ngoài PostgreSQL
copy, bài viết còn benchmark pg_bulkload và timescaledb-parallel-copy - pg_bulkload có vẻ nhanh hơn ở cấu hình mặc định, nhưng mặc định nó bỏ qua shared buffers và bỏ luôn WAL logging, nên có thể không khôi phục được dữ liệu sau sự cố
- Trong cùng điều kiện tắt
fsync, timescaledb-parallel-copy với nhiều worker lại tốt hơn pg_bulkload - timescaledb-parallel-copy cho phép chỉ định số worker để chèn song song
- Hiệu năng ban đầu tốt, nhưng trên hệ thống này nó chạm nút thắt trước mốc 100 triệu hàng, sau đó tốc độ chèn giảm mạnh rồi hồi phục theo dạng dao động
- Tốc độ nạp duy trì ở bảng thường khoảng 600 nghìn–700 nghìn hàng/giây, còn hypertable khoảng 300 nghìn hàng/giây
- pg_bulkload không cho chỉ định số worker, nhưng có tùy chọn
writer=parallelđể dùng nhiều luồng cho việc đọc, parse và ghi
Tinh chỉnh cấu hình PostgreSQL và đánh đổi về độ bền dữ liệu
- Có thể đạt thêm hiệu năng bằng cách điều chỉnh các thiết lập không đảm bảo độ bền của PostgreSQL
- Các thiết lập chính là tắt
fsyncđể tránh flush xuống đĩa, và tắtfull_page_writesđể bỏ cơ chế bảo vệ trước partial page write - Các thiết lập này có thể làm rủi ro với tính toàn vẹn cơ sở dữ liệu khi xảy ra sự cố
- Unlogged table không tạo WAL nên ghi nhanh hơn, nhưng có thể bị cắt mất dữ liệu khi khôi phục sau crash
- Sau đó cần chuyển sang bảng logged thông thường, và quá trình này có thể chậm và chạy đơn luồng
- Hypertable không thể là unlogged, nên nếu cần hypertable thì sẽ phải thêm bước chuyển đổi hoặc migrate
Lựa chọn cuối cùng: nạp trực tiếp vào hypertable
- Nếu đích đến là hypertable, thì nạp trực tiếp vào hypertable nhanh hơn cách nạp vào bảng thường rồi chuyển đổi sang hypertable
- Trong một thử nghiệm đơn giản với khoảng 772 triệu hàng được nạp bằng psycopg3
copyvà 16 worker, việc chèn trực tiếp vào hypertable mất ít thời gian hơn so với chèn vào bảng thường rồi chuyển đổi- Trong trường hợp này, chèn trực tiếp vào hypertable chỉ mất khoảng 80% thời gian của phương án còn lại
- Quá trình chuyển đổi và migrate không nhanh và có vẻ giống đơn luồng
- Cách làm được khuyến nghị là
- Nếu nạp trực tiếp từ dataframe, hãy dùng psycopg3 để
copythẳng vào hypertable - Nếu đã có sẵn file CSV, hãy dùng
timescaledb-parallel-copy - Trên hệ thống này, 12–16 worker có vẻ là điểm hợp lý cho song song hóa
- Nếu nạp trực tiếp từ dataframe, hãy dùng psycopg3 để
Kết luận benchmark tổng thể và thời gian cần thiết
- Với một worker duy nhất và bật các thiết lập bảo vệ, trần tốc độ nạp duy trì tính cả overhead trên phần cứng này có vẻ vào khoảng 140 nghìn hàng/giây
- Với nhiều worker, psycopg3
copycursor có thể nâng tốc độ nạp duy trì lên khoảng 250 nghìn hàng/giây mà vẫn giữ các thiết lập bảo vệ - Quá trình chèn không song song hóa hiệu quả lắm, và vùng hợp lý có vẻ là 4–16 worker
- Nếu chấp nhận rủi ro và tắt
fsync, psycopg3 có thể duy trì khoảng 462 nghìn hàng/giây - Cần thận trọng vì pg_bulkload mặc định đã vô hiệu hóa
fsync - Nếu duy trì được khoảng 462 nghìn hàng/giây, thì việc nạp khoảng 754 tỷ hàng sẽ mất khoảng 20 ngày
Mã nguồn và môi trường benchmark
- Mã cho việc tải ERA5, tạo bảng, chèn/
copy, benchmark và vẽ biểu đồ nằm tại timescaledb-insert-benchmarks - Mỗi benchmark đều khởi chạy một Docker container mới để giữ môi trường nhất quán
- Không giữ lại storage giữa các Docker container
- File NetCDF và CSV được đọc từ HDD
- Cơ sở dữ liệu được lưu trên NVMe SSD
- Cấu hình phần cứng
- CPU: 2x 12-core Intel Xeon Silver 4214
- RAM: 16x 16 GiB Samsung ECC DDR4 2666 MT/s
- SSD: Intel 2 TB NVMe
- HDD: Seagate Exos X16 14TB 7200 RPM
- Cấu hình phần mềm
- Ubuntu 20.04, Linux kernel 5.15
- PostgreSQL 15.5
- TimescaleDB 2.13.0
- pg_bulkload 3.1.20
- Cấu hình PostgreSQL dùng các giá trị do
timescaledb-tunekhuyến nghị cho 250.57GB bộ nhớ và 48 CPU, còn trong benchmark thì kích thước WAL được điều chỉnh riêng
2 bình luận
Ý kiến trên GN+ đang dùng kính ngữ à..?
Các ý kiến trên Hacker News
Tôi đã làm khá nhiều về phân tích không gian địa lý trong công việc, và dữ liệu không gian địa lý tinh tế hơn tưởng nhiều vì phải hiểu chính xác hệ quy chiếu tọa độ (CRS) và phép chiếu dùng để trực quan hóa.
Nếu không có hạ tầng mang metadata đi cùng dữ liệu một cách đúng đắn, CRS sẽ liên tục khiến bạn bất an.
Tôi đã dùng các tính năng liên quan của AWS, Postgres/PostGIS, Spark/Databricks, Snowflake, Trino và ArcGIS, nhưng với các tác vụ không gian địa lý quy mô lớn, tôi thấy Google BigQuery vượt trội áp đảo.
Một truy vấn trên PostGIS chạy trên EC2 m6a khổng lồ từng mất vài giờ và tốn khá nhiều chi phí, nhưng trên bậc miễn phí của BigQuery thì chưa đến 5 giây.
Tôi dùng dữ liệu công khai của FEMA; Snowflake và các dịch vụ AWS bị chặn vì cột geometry vượt quá kích thước byte tối đa, còn Spark thì không có kiểu dữ liệu không gian địa lý và các extension mã nguồn mở cũng chưa ổn.
Nếu chạy on-premise thì tình hình có thể khác, nhưng với mức 20TB, chi phí lưu trữ BigQuery nhiều khả năng cũng dưới $100/tháng, nên tôi không muốn tự vận hành làm gì.
Điều này khả thi vì ban đầu tôi dùng chỉ mục H3 và toàn bộ dataset trung gian đều nằm trong bộ nhớ.
Cấu hình là Mac Studio 128GB + Asahi Linux + file parquet mmap + DuckDB; tôi cũng chạy Airflow, và dùng Nix để tăng tốc build cho developer cũng như chạy các tác vụ Airflow của đội dữ liệu.
GCP rất tốt khi miễn phí hoặc rẻ, nhưng đến một lúc nào đó nó có thể làm bạn bất ngờ bằng một hóa đơn lớn hơn, dù mức sử dụng không tăng.
Không biết bạn đã so sánh với Apache Sedona chưa, và cụ thể là thiếu những gì?
Tôi đang làm ở Wherobots, công ty do các tác giả Apache Sedona thành lập, nên rất muốn nghe phản hồi.
https://sedona.apache.org/latest/
https://wherobots.com/
Tôi đồng ý rằng một số công cụ sẽ “vỡ” với các cột rất rộng, nhưng các hệ Postgres hướng cột khác có vẻ có thể hỗ trợ mà không gặp vấn đề.
Hơi bất ngờ là có vẻ bạn không dùng Redshift, đối thủ trực tiếp của BigQuery; cột
supercủa Redshift còn có thể đặt lớn hơn cả giới hạn tối đa của BigQuery.Tôi thường thấy mọi người phải tự rút ra một cách khó nhọc rằng rất khó đánh bại PostGIS.
Việc Trino/Presto và Spark bị chững lại trong mảng này cũng đặc biệt đáng suy ngẫm.
Trên Postgres tôi đã cache một phần các bảng lớn, còn trên BigQuery thì dựng lại từ đầu, vậy mà vẫn như thế.
Với công cụ có thể tự vận hành, tôi thích Postgres hơn, nhưng khó mà phản bác khi hiệu năng tốt hơn nhiều lần, ở mức một chữ số.
Bài viết thật sự rất hay.
Tôi phụ trách DevRel ở Timescale, và rất vui khi thấy cộng đồng tạo ra một bài viết tốt như vậy.
Một trong những lý do hypertable chậm hơn gần như chắc chắn là vì mặc định nó tạo chỉ mục trên cột timestamp.
Bảng thông thường không có chỉ mục nên có thể đã nhanh hơn.
Trong
create_hypertable, dùngcreate_default_indexes=>falsecó thể bỏ qua việc tạo chỉ mục; hoặc cũng có thể xóa chỉ mục trước khi nạp dữ liệu.Cuối cùng thì bạn vẫn sẽ cần chỉ mục đó, nhưng với kiểu nạp hàng loạt như thế này, tốt hơn là nạp xong rồi tạo một lần.
Tôi cũng tò mò HDD đọc dữ liệu chịu được đến đâu trong cấu hình có mức song song hóa cao như vậy.
create_default_indexes=>falsecũng như việc hypertable mặc định tạo chỉ mục thời gian, và tôi sẽ thêm một chú thích giải thích phần này.Tôi cũng muốn benchmark thử việc insert khi không có chỉ mục thời gian rồi sau đó tạo chỉ mục thủ công.
Có vẻ HDD vẫn ổn ngay cả với 32 worker.
Khi xem mức sử dụng đĩa bằng btop, SSD nơi chạy Postgres trông gần với nút thắt cổ chai hơn HDD, nên tôi kết luận rằng đầu tư đổi SSD dùng cho Postgres sang loại nhanh hơn sẽ đáng hơn so với chuyển dữ liệu từ HDD sang SSD.
Không hiểu tại sao lại phải làm như vậy
Hầu hết các bộ dữ liệu thời tiết/khí hậu, bao gồm ERA5, đều được cấu trúc rất chặt chẽ trên một lưới vĩ độ-kinh độ đều đặn
Ngay cả khi chỉ trích xuất chuỗi thời gian cho một vị trí cụ thể, điểm mạnh của các bộ dữ liệu kiểu này nằm ở cấu trúc và ngữ cảnh không-thời gian vốn có; nếu mục tiêu không phải chỉ là trích xuất chuỗi thời gian điểm thì việc phá vỡ hoàn toàn cấu trúc đó không hợp lý lắm
Thậm chí trong trường hợp chỉ lấy chuỗi thời gian điểm, ví dụ như chuỗi nhiệt độ bề mặt ở giữa đại dương thì hầu như chẳng có mấy dịp dùng đến, nên có lẽ bạn sẽ muốn cắt giảm dữ liệu khá mạnh tay
Phần lớn các ứng dụng nghiên cứu/vận hành của những bộ dữ liệu như ERA5 có vẻ phù hợp hơn với các bản sao tối ưu cho đám mây nhưng vẫn giữ cấu trúc gốc, như ARCO-ERA5 của Google Public Datasets
Những phiên bản này giữ nguyên cấu trúc gốc, đồng thời chia chunk để phù hợp với truy cập song song quy mô lớn trên lưu trữ đám mây
Trong gần như mọi trường hợp tôi từng thấy trong sự nghiệp, chỉ một kho lưu trữ dựa trên Zarr với cách chunking thông thường đã đủ nhanh cho hầu hết các mục đích đáng quan tâm
https://cloud.google.com/storage/docs/public-datasets/era5
Tuy vậy, như rabernat đã nói, việc trích xuất chuỗi thời gian dài từ bản sao trên đám mây cũng chậm
Cuối cùng tôi cũng muốn chạy các truy vấn không-thời gian phức tạp, chẳng hạn tính percentile 99 của nhiệt độ mùa hè ở Chile giai đoạn 1940~1980
Tôi không nghi ngờ việc bản sao đám mây có thể nhanh hơn, nhưng điều đó mâu thuẫn với ngân sách $0
Nó được tối ưu cho truy vấn không gian, không phải truy vấn chuỗi thời gian
Tôi vừa chạy benchmark, và mất 20 phút để lấy chuỗi thời gian của một biến duy nhất tại một điểm
Điều này cho thấy rất rõ rằng nếu mô hình sử dụng dự kiến là chuỗi thời gian thì cần chunking tối ưu cho chuỗi thời gian
Một số phòng lab đã có pipeline dựa trên RDBMS với thuật toán và dữ liệu công khai đan xen vào nhau; không ai muốn triển khai lại, và cũng không có kinh phí để làm việc đó
Cải tiến tốt nhất mà chúng tôi đạt được chỉ là chuyển từ MySQL cũ sang Postgres + PostGIS
Timescale có lẽ cũng đã giúp ích
Cũng có những lý do buộc phải chạy cục bộ, như quyền riêng tư, quyền truy cập cluster, và ngân sách
Bài hay
Điều còn thiếu ở đây, theo tôi, là phân tích xem việc chuyển dữ liệu thời tiết sang cơ sở dữ liệu quan hệ mang lại gì
Động lực là tăng tốc độ truy vấn, nhưng cần có một baseline để so sánh
Với tư cách là maintainer của Xarray và Zarr, đồng thời là nhà sáng lập https://earthmover.io/, tôi khá quen thuộc với bức tranh công nghệ này; nếu chunk dữ liệu trong Zarr một cách phù hợp, chỉ cần giải pháp serverless + object storage cũng có thể xử lý truy vấn chuỗi thời gian của dữ liệu thời tiết với độ trễ dưới 1 giây
Nhanh hơn rất nhiều so với 30 phút được nêu trong bài
Xét đến độ khó của việc nạp dữ liệu trong bài này, rất đáng để đánh giá nghiêm túc những cách như vậy trước khi đi theo hướng RDBMS
Cũng có thể đặt một API phía trước để biến nó thành dạng như truy vấn
Đúng là tôi chưa biện minh đủ cho cách tiếp cận RDBMS
Lý do chính tôi chọn Postgres + Timescale là vì tôi muốn học chúng, và nghịch với dữ liệu ERA5 có vẻ thú vị nhất
Có lẽ sức hấp dẫn còn nằm ở việc dữ liệu thời tiết đủ lớn để trở thành một thử thách
Không có bằng chứng, nhưng tôi tò mò liệu TimescaleDB + PostGIS được tinh chỉnh và đánh index tốt có giúp ích cho các truy vấn không-thời gian phức tạp như percentile 99 của nhiệt độ mùa hè ở Chile giai đoạn 1940~1980 hay không
Vì trong trường hợp này có thể phải đọc nhiều chunk Zarr
Tôi cũng thích ý tưởng có một bảng riêng để cache các thống kê kiểu này, nhưng làm bằng Zarr cũng không quá khó
Lần tới tôi định benchmark truy vấn và index, nên chắc sẽ biết thêm
Có vẻ tồn tại một mâu thuẫn căn bản: chunk lớn thì tốt cho trực quan hóa vùng rộng và truy vấn lớn, còn chunk nhỏ thì tốt cho truy vấn theo điểm hoặc chuỗi thời gian
Việc duy trì riêng các phiên bản chunking khác nhau cho những bộ dữ liệu địa không gian lớn như vậy là khả thi, nhưng không hiệu quả về chi phí lắm
Tôi từng nghe nói
kerchunkđược dùng để lấy ưu điểm của cả hai phía, nhưng như vậy có vẻ sẽ mất các lựa chọn nén dữ liệu, và tôi nghĩ độ phức tạp cũng tăng lên khá nhiềuTôi thắc mắc nên cân bằng giữa nhiều use case như thế nào cho tốt
Tôi đã đóng góp cho tài liệu nạp dữ liệu hàng loạt của Postgres được tham chiếu ở đây; đó là một bài viết điểm qua khá tốt nhiều kỹ thuật
Tôi từng làm khá nhiều việc kiểu này để tăng tốc nạp cơ sở dữ liệu OpenStreetMap, và bản cập nhật công khai gần nhất nằm ở https://www.youtube.com/watch?v=BCMnu7xay2Y
Kể từ đó, nhờ tiến bộ phần cứng, cải tiến GIS trong PG15, và việc osm2pgsql áp dụng kỹ thuật middle-way-node-index-id-shift, thời gian nạp bộ planet đã giảm xuống dưới 4 giờ
Nếu đề xuất với tác giả, thì một số thử nghiệm đang gián tiếp loại bỏ việc ghi WAL thông qua pg_bulkload và COPY
Vào thời điểm Craig Ringer viết bài SO được liên kết, điều này chưa được tài liệu hóa, nhưng trong cấu hình có thể tắt hẳn WAL
Tất nhiên nếu gặp sự cố, bạn sẽ mất bảng đang xử lý, và nếu công việc kéo dài vài tuần thì chuyện đó có thể xảy ra
Nhưng với dữ liệu chuỗi thời gian, nếu thiết kế cấu trúc nạp hợp lý thì không khó để chỉ mất chunk cuối cùng
Với nạp dữ liệu hàng loạt, dữ liệu WAL về cơ bản là không cần thiết
Nếu gặp sự cố, chỉ cần dọn phần mép bên phải của dữ liệu đã nạp rồi bắt đầu lại
Các thiết lập
postgresql.conftôi dùng để tắt WAL và các overhead khác như sau:wal_level = minimalmax_wal_senders = 0synchronous_commit = offfsync = offfull_page_writes = offautovacuum = offcheckpoint_timeout = 60minCuối cùng, để giảm công việc vacuum khi nạp theo các chunk lớn, thường tôi tắt autovacuum như trên và định kỳ chạy
VACUUM FREEZEphía sau partition theo ngày hiện đang được nạpĐây là với PG thông thường, và nó cho phép bỏ qua một phần công việc mà cơ sở dữ liệu phải quan tâm trong giai đoạn trung gian khi transaction mới đã được ghi nhưng chưa hiển thị với tất cả mọi người
Đặc biệt trong nạp theo chunk, thật vui khi nghe một chuyên gia nói rằng dữ liệu WAL không thực sự cần thiết cho nạp hàng loạt
Tôi chưa có UPS, nhưng hy vọng có thể vượt qua khoảng 20 ngày nạp dữ liệu mà không mất điện; ngay cả trường hợp xấu nhất thì có lẽ chỉ cần tiếp tục là được
Nếu OP là tác giả, có thể bạn cũng sẽ thấy thí nghiệm tương tự tôi làm khoảng 4 năm trước khá thú vị
Cùng bộ dữ liệu, cùng mục tiêu lưu trữ, mục tiêu cũng tương tự
https://rdrn.me/optimising-sql/
Hướng khảo sát tương tự, nhưng tôi dùng Postgres thông thường thay vì Timescale; trong cấu hình của tôi, với giả định dữ liệu đã nằm trong bộ nhớ, sao chép dữ liệu nhị phân trực tiếp nhanh hơn COPY khoảng 3 lần
Tôi có ghi chú chân trang về lý do không thử binary COPY, về cơ bản là vì có người khác nói hiệu năng gây thất vọng
Dù vậy có lẽ tôi vẫn nên tự thử
https://aliramadhan.me/2024/03/31/trillion-rows.html#fn:copy-binary-note
Tôi cũng thích hình thức có chú thích bên lề
Việc bạn cung cấp hàm ghi mảng cấu trúc numpy sang nhị phân Postgres rất hữu ích; trước đây tôi chưa tìm ra cách làm việc này
“Cơ sở dữ liệu quan hệ có phù hợp với dữ liệu thời tiết dạng lưới không? Không biết, nhưng cứ thử thì sẽ biết.”
Tôi thích thái độ này
Nó hoàn toàn trái ngược với phong cách “thực ra thì...” của các bài viết kỹ thuật chính thống khác, nên tôi rất thích
Tôi cũng thích việc bài viết giữ chân độc giả đến tận cuối trong suốt hành trình đó
Tôi đã tìm kiếm rất nhiều nhưng không tìm được câu trả lời dứt khoát cho use case của mình, nên quyết định tự chạy benchmark
Bài viết thú vị
Đoạn “Nếu duy trì khoảng 462k insert/giây thì mất khoảng 20 ngày cho khoảng 754 tỷ hàng, nghe không tệ. Còn ngắn hơn thời gian tôi viết bài này.” buồn cười thật
Tôi cũng đang nghiêng về việc viết các bài blog dài và sâu hơn, nên đồng cảm rằng nó tốn nhiều công sức hơn tưởng tượng
Nếu muốn vẽ biểu đồ chuỗi thời gian hoặc nhiều biểu đồ trực tiếp từ truy vấn SQL, qStudio là một SQL IDE miễn phí và hoạt động với nhiều DB, bao gồm TimescaleDB
https://www.timestored.com/qstudio/database/timescale
Tuyên bố miễn trừ: đây là công cụ tôi tạo ra
Tôi nghĩ có thể thêm hỗ trợ Timeplus
Timeplus là cơ sở dữ liệu ưu tiên streaming dựa trên ClickHouse, và engine DB lõi Timeplus Proton là mã nguồn mở
qStudio cũng là mã nguồn mở và được viết bằng Java, nên có vẻ hỗ trợ RDBMS mới sẽ cần JDBC driver
Nếu đúng vậy, Timeplus Proton có một JDBC driver mã nguồn mở dựa trên driver ClickHouse, kèm các chỉnh sửa cho mục đích streaming
https://www.timeplus.com/
https://github.com/timeplus-io/proton
https://github.com/timeseries/qstudio
https://github.com/timeplus-io/proton-java-driver
Hiện tôi mới chỉ insert dữ liệu, nhưng sắp tới sẽ thử query và plotting
Tôi cũng dùng dữ liệu tái phân tích ERA5 và cần chuỗi thời gian nhanh
Vì dữ liệu được xếp theo lưới
[lat, lon]cho từng khoảng thời gian đã chọn, ví dụ dạng[dữ liệu theo giờ trong một tháng, lat, lon], nên nếu muốn lấy hơn 20 năm thì sẽ thành bài toán chuyển vị một ma trận khổng lồCách tôi làm là tải từng tệp netCDF xuống, chuyển vị, rồi đưa vào một tệp HDF 3D khổng lồ có cấu trúc
[lat, lon, hour]Trên workstation của tôi, mất khoảng 30 phút để tạo dữ liệu 1 năm cho một biến, nhưng sau đó việc lấy một vị trí
(lat, lon)đơn lẻ chỉ tính bằng mili giâyĐây là cách ban đầu thì vất vả nhưng về lâu dài có lợi
Đơn giản vậy thôi, nhưng tôi không phải chuyên gia cơ sở dữ liệu, chỉ là một nhà khí hậu học
Có vẻ rabernat và open-meteo đã bình luận ở đây cũng dùng cách tương tự và cho rằng nó nhanh