TimescaleDB dan Apache AGE: jadikan PostgreSQL time-series dan graph database
Kita akan bahas TimescaleDB, extension PostgreSQL untuk time-series. Juga akan bahas Apache AGE, extension PostgreSQL untuk graph-database.
PostgreSQL adalah perangkat lunak RDBMS gratis dan kode-sumber terbuka yang telah dikembangkan selama 27 tahun. Dengan sejarah yang cukup panjang, menjadikan PostgreSQL sebuah sistem yang stabil dan handal untuk menangani penyimpanan dan pengambilan data. Selain itu PostgreSQL dirancang untuk bisa ditambahkan berbagai fitur melalui Extension.
Pada tulisan kali ini kita akan membahas TimescaleDB, sebuah extension PostgreSQL yang menambahkan kemampuan menangani time-series database. Juga akan membahas Apache AGE (A Graph Extension), sebuah extension PostgreSQL untuk menambahkan kemampuan menangani graph database. Kita juga akan membuat data tiruan menggunakan Go-lang sebagai bahan percobaan.
Kenapa perlu TimescaleDB dan Apache AGE
Di pasaran ada banyak tersedia time-series database dan graph database dengan kelebihan dan kekurangan masing-masing. Namun karena TimescaleDB dan Apache AGE dibuat sebagai extension dengan pondasi PostgreSQL, kita akan mendapatkan beberapa keuntungan bawaan:
- hanya perlu mengelola sebuah software database yaitu PostgreSQL
- memanfaatkan fitur replikasi PostgreSQL untuk menambahkan beberapa replika
- High-Availability untuk PostgreSQL dengan Patroni
- masih menggunakan metric dan kakas monitoring yang sama untuk PostgreSQL
Susunan Tulisan
Tulisan ini disusun ke dalam bagian-bagian berikut:
- kenapa perlu TimescaleDB dan Apache AGE
- instalasi PostgreSQL v15
- instalasi extension TimescaleDB di PostgreSQL
- instalasi extension Apache AGE di PostgreSQL
- membuat database di PostgreSQL
- mencoba TimescaleDB di PostgreSQL
- mencoba Apache AGE di PostgreSQL
Kedua produk tersebut memiliki fitur yang banyak, sehingga tidak akan mungkin dibahas hanya dalam satu artikel. Sehingga percobaan TimescaleDB dan Apache AGE di PostgreSQL pada tulisan ini hanya ringkasan dan pengenalan menggunakannya. Anda bisa melakukan eksplorasi lebih jauh dengan membaca situs dokumentasi resmi kedua produk tersebut.
Instalasi PostgreSQL v15
Pada percobaan kali ini saya menggunakan lingkungan pengujian berikut:
- Ubuntu Server 22.04
- Amazon EC2 t3.large (2 vCPU, 8 GiB RAM)
- 100 GiB gp3 SSD
- PostgreSQL 15
Perbarui repositori APT (Advanced Package Tool):
sudo apt update
Tambahkan PostgreSQL repositori ke APT:
sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list'
Tambahkan kunci-publik GPG PostgreSQL:
wget -qO- https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo tee /etc/apt/trusted.gpg.d/pgdg.asc &>/dev/null
Perbarui lagi repositori APT:
sudo apt update
Pasang PostgreSQL Server dan Client v15:
sudo apt install \
postgresql-client-15 \
postgresql-15 \
-y
Verifikasi bahwa PostgreSQL sudah terpasang:
systemctl status postgresql
Instalasi extension TimescaleDB di PostgreSQL
Tambahkan paket yang dibutuhkan untuk instalasi dengan APT:
sudo apt install \
gnupg \
postgresql-common \
apt-transport-https \
lsb-release \
wget \
-y
Tambahkan repositori TimescaleDB ke APT:
echo "deb https://packagecloud.io/timescale/timescaledb/ubuntu/ $(lsb_release -c -s) main" | sudo tee /etc/apt/sources.list.d/timescaledb.list
Tambahkan kunci-publik GPG TimescaleDB:
wget --quiet -O - https://packagecloud.io/timescale/timescaledb/gpgkey | sudo gpg --dearmor -o /etc/apt/trusted.gpg.d/timescaledb.gpg
Perbarui daftar repositori:
sudo apt update
Pasang TimescaleDB dengan perintah:
sudo apt install \
timescaledb-2-postgresql-15 \
-y
Lakukan penyesuaian terhadap PostgreSQL untuk TimescaleDB dengan perintah:
sudo timescaledb-tune
Instalasi extension Apache AGE di PostgreSQL
Kita perlu melakukan kompilasi kode sumber Apache AGE, sehingga kita membutuhkan compiler GCC, Make, dan berbagai kakas pendukung dengan perintah berikut:
sudo apt install \
build-essential \
-y
Kita juga perlu memasang paket pendukung untuk kompilasi PostgreSQL extension:
sudo apt install \
postgresql-server-dev-15 \
-y
Pasang pustaka penting untuk kompilasi Apache AGE:
sudo apt-get install \
libreadline-dev \
zlib1g-dev \
flex \
bison \
-y
Unduh rilis kode Apache AGE, misal:
cd /tmp/
wget https://github.com/apache/age/releases/download/PG15%2Fv1.4.0-rc0/apache-age-1.4.0-src.tar.gz
Ekstrak file TAR tersebut, misal:
tar -xzvf https://github.com/apache/age/releases/download/PG15%2Fv1.4.0-rc0/apache-age-1.4.0-src.tar.gz
Jalankan perintah pg_config
:
cd /tmp/apache-age-1.4.0/
pg_config
Lakukan kompilasi kode-sumber Apache AGE:
sudo make install
Membuat Database di PostgreSQL
Kita akan membuat sebuah database di PostgreSQL untuk menyimpan data tiruan dan percobaan.
Buat database menggunakan PSQL, lalu keluar:
sudo -i -u postgres
psql
psql> create database eksperimen_db;
psql> \q
Mencoba TimescaleDB di PostgreSQL
Buka PSQL:
sudo -i -u postgres
psql -d eksperimen_db -X
psql> CREATE EXTENSION timescaledb;
Pada TimescaleDB kita menyimpan data time-series ke hyphertables, yaitu tabel PostgreSQL yang otomatis di-partisi dengan waktu. Di belakang layar, TimescaleDB melakukan hal-hal yang diperlukan untuk mengatur dan mengelola partisi. Sedangkan kita sebagai pengguna, menambahkan dan mengambil data seolah-olah hanya dari sebuah tabel PostgreSQL tunggal.
Sekarang mari buat tabel PostgreSQL biasa yang akan menyimpan data perdagangan saham:
CREATE TABLE stocks_real_time (
time TIMESTAMPTZ NOT NULL,
symbol TEXT NOT NULL,
price DOUBLE PRECISION NULL,
day_volume INT NULL
);
Selanjutnya konversi tabel tadi menjadi sebuah hypertable yang dipartisi di kolom time
dengan perintah berikut:
SELECT create_hypertable('stocks_real_time','time');
Lalu buat sebuah index agar query terhadap kolom symbol
dan time
menjadi lebih efisien:
CREATE INDEX ix_symbol_time ON stocks_real_time (symbol, time DESC);
Selain itu kita buat juga sebuah tabel PostgreSQL untuk menyimpan daftar nama perusahaan dan simbol-nya di perdagangan saham:
CREATE TABLE company (
symbol TEXT NOT NULL,
name TEXT NOT NULL
);
Sekarang kita memiliki sebuah hypertable bernama stocks_real_time
dan tabel PostgreSQL normal bernama company
. Anda bisa cek dengan perintah berikut:
psql> \dt
List of relations
Schema | Name | Type | Owner
--------+------------------+-------+----------
public | company | table | postgres
public | stocks_real_time | table | postgres
Selanjutnya kita akan memasukan data contoh yang disediakan oleh Timescale Inc. Contoh cara menyiapkan dengan menggunakan CLI di Linux:
sudo apt install unzip
cd /tmp/
wget https://assets.timescale.com/docs/downloads/get-started/real_time_stock_data.zip
unzip real_time_stock_data.zip
chmod 666 tutorial_sample_company.csv
chmod 666 tutorial_sample_tick.csv
Selanjutnya load data menggunakan psql:
sudo -i -u postgres
psql
psql> \COPY stocks_real_time FROM '/tmp/tutorial_sample_tick.csv' DELIMITER ',' CSV HEADER;
psql> \COPY company FROM '/tmp/tutorial_sample_company.csv' DELIMITER ',' CSV HEADER;
Sekarang kita bisa mulai query data, contohnya:
psql> SELECT * FROM stocks_real_time SRT LIMIT 10;
Contoh output:
time | symbol | price | day_volume
------------------------+--------+--------+------------
2023-10-25 23:59:59+00 | NFLX | 407.05 |
2023-10-25 23:59:59+00 | GOOG | 123.82 |
2023-10-25 23:59:59+00 | AMD | 93.85 |
2023-10-25 23:59:59+00 | AMZN | 119.08 |
2023-10-25 23:59:59+00 | BA | 176.55 |
2023-10-25 23:59:58+00 | GM | 29.1 |
2023-10-25 23:59:58+00 | CVX | 155.39 |
2023-10-25 23:59:58+00 | TSLA | 207.75 |
2023-10-25 23:59:58+00 | AAPL | 169.7 |
2023-10-25 23:59:58+00 | CVX | 155.39 |
(10 rows)
TimescaleDB memiliki fungsi-fungsi SQL yang bisa membantu analisis data time-series menjadi lebih mudah dan cepat. Contoh query untuk mengambil harga saham pertama dan terakhir dalam rentang 4 hari terakhir:
SELECT symbol, first(price,time), last(price, time)
FROM stocks_real_time srt
WHERE time > now() - INTERVAL '4 days'
GROUP BY symbol
ORDER BY symbol
LIMIT 10;
Contoh output:
symbol | first | last
--------+--------+----------
AAPL | 190.6 | 189.85
ABNB | 127 | 128.05
AMAT | 148.85 | 150
AMD | 118.26 | 122.2
AMZN | 143.18 | 146.6971
BA | 218.53 | 219.91
BAC | 29.66 | 29.73
BMY | 48.63 | 49.62
C | 44.97 | 45.23
CAT | 249.99 | 247.36
(10 rows)
TimescaleDB sendiri adalah produk yang memiliki banyak fitur dan manfaat. Anda bisa melakukan pengecekan secara lebih lengkap dengan mengunjungi situs dokumentasi mereka di sini.
Mencoba Apache AGE di PostgreSQL
Buka PSQL dengan user postgres
dan lakukan persiapan:
sudo -i -u postgres
psql -d eksperimen_db
psql> CREATE EXTENSION age;
psql> LOAD 'age';
psql> SET search_path = ag_catalog, "$user", public;
Dalam graph database, data terdiri dari:
- vertex, yaitu representasi objek
- edge, yaitu hubungan antar vertex
Anda dapat melihat ilustrasi percobaan graph-database kali ini pada Gambar 1.
Pada tulisan kali ini kita akan membuat contoh sederhana terdiri dari 2 produsen otomotif, dan 4 model mobil yang dibuatnya. Pertama-tama buat sebuah graph baru:
psql> SELECT create_graph('graph_otomotif');
Buat dua buah vertex dengan label produsen
otomotif Toyota dan BMW:
SELECT *
FROM cypher('graph_otomotif', $$
CREATE (:produsen {nama:'Toyota'})
$$) AS (v agtype);
SELECT *
FROM cypher('graph_otomotif', $$
CREATE (:produsen {nama:'BMW'})
$$) AS (v agtype);
Selanjutnya buat 4 buah vertex dengan label mobil
yaitu Camry, Corolla, X4 dan X7:
SELECT *
FROM cypher('graph_otomotif', $$
CREATE (:mobil {nama:'Camry'})
$$) AS (v agtype);
SELECT *
FROM cypher('graph_otomotif', $$
CREATE (:mobil {nama:'Corolla'})
$$) AS (v agtype);
SELECT *
FROM cypher('graph_otomotif', $$
CREATE (:mobil {nama:'X4'})
$$) AS (v agtype);
SELECT *
FROM cypher('graph_otomotif', $$
CREATE (:mobil {nama:'X7'})
$$) AS (v agtype);
Lalu buat edge antara vertex Toyota dengan Camry dan Corolla; serta vertex BMW dengan X4 dan X7:
SELECT *
FROM cypher('graph_otomotif', $$
MATCH (a:produsen), (b:mobil)
WHERE a.nama = 'Toyota' AND b.nama = 'Camry'
CREATE (a)-[e:MEMPRODUKSI]->(b)
RETURN e
$$) as (e agtype);
SELECT *
FROM cypher('graph_otomotif', $$
MATCH (a:produsen), (b:mobil)
WHERE a.nama = 'Toyota' AND b.nama = 'Corolla'
CREATE (a)-[e:MEMPRODUKSI]->(b)
RETURN e
$$) as (e agtype);
SELECT *
FROM cypher('graph_otomotif', $$
MATCH (a:produsen), (b:mobil)
WHERE a.nama = 'BMW' AND b.nama = 'X4'
CREATE (a)-[e:MEMPRODUKSI]->(b)
RETURN e
$$) as (e agtype);
SELECT *
FROM cypher('graph_otomotif', $$
MATCH (a:produsen), (b:mobil)
WHERE a.nama = 'BMW' AND b.nama = 'X7'
CREATE (a)-[e:MEMPRODUKSI]->(b)
RETURN e
$$) as (e agtype);
Anda bisa mengambil semua vertex dengan query berikut:
Mengambil semua vertex:
SELECT *
FROM cypher('graph_otomotif', $$
MATCH (v)
RETURN v
$$) AS (v agtype);
Contoh output:
Kita juga bisa mengambil daftar mobil yang diproduksi oleh sebuah produsen dengan query berikut:
SELECT *
FROM cypher('graph_otomotif', $$
MATCH (:produsen {nama: 'Toyota'})-[]->(mobil)
RETURN mobil
$$) AS (v agtype);
Contoh output:
Anda dapat melakukan pengecekan lebih lanjut terhadap fitur-fitur dan manfaat yang diberikan oleh Apache AGE di situs dokumentasi mereka di sini.
Simpulan TimescaleDB dan Apache AGE di PostgreSQL
TimescaleDB dan Apache AGE adalah dua produk yang cukup besar. TimescaleDB menambahkan fitur time-series untuk PostgreSQL, sedangkan Apache AGE menambahkan fitur graph-database untuk PostgreSQL. Tentu keduanya menjadi alternatif pilihan dari banyak produk time-series dan graph-database yang ada. Keunggulannya adalah tentu Anda dapat memanfaatkan berbagai pengetahuan, metode, alat otomatisasi, juga monitoring yang telah Anda miliki untuk mengelola PostgreSQL.