Analisis Performa Sistem pada Pemisahan Database Analitik dengan Transaksional
on
JNATIA Volume 1, Nomor 3, Mei 2023
Jurnal Nasional Teknologi Informasi dan Aplikasinya
p-ISSN: 2986-3929
Analisis Performa Sistem pada Pemisahan Database Analitik dengan Transaksional
I Made Ari Madya Santosaa1, I Gusti Ngurah Anom Cahyadi Putraa2
aProgram Studi Informatika, Fakultas Matematika dan Ilmu Pengetahuan Alam, Universitas Udayana
Jalan Raya Kampus Udayana, Bukit Jimbaran, Kuta Selatan, Badung, Bali Indonesia 1[email protected] 2[email protected]
Abstract
The speed and efficiency of a system currently has a very important role. Currently there are several solutions to answer these challenges, one of which is to separate the database on the system. In this study, an analysis was carried out on the separation of databases on a transactional and analytic system. Analysis is carried out with a research flow that begins with problem identification followed by sampling data on technology companies that have transactional systems, then implementing transactional and analytical programs on microservices architecture, conducting tests with Load-Testing, followed by analysis of test results, and then drawing conclusions. After conducting research in accordance with the research flow, it was concluded that the separation of databases on transactional and analytic systems is better for producing faster system performance compared to transactional and analytic systems using the same database.
Keywords: Big Data, Optimization, Transactional, Analytical Systems, Microservices
Salah satu tantangan dalam sistem informasi saat ini adalah kinerja sistem yang cepat dan efisien. Untuk menyelesaikan masalah ini, pemrosesan data terdistribusi menjadi salah satu solusi yang banyak digunakan [1]. Terdapat dua tipe pemrosesan data dalam sistem distribusi yaitu Transactional Processing (OLTP) dan Analytical Processing (OLAP) yang merupakan cara pemrosesan yang berbeda namun saling melengkapi. OLTP digunakan untuk memproses operasi transaksi bisnis, sedangkan OLAP digunakan untuk analisis dan pengambilan keputusan dengan menggunakan data historis.
Pada saat ini, terdapat beberapa solusi untuk mengintegrasikan OLTP dan OLAP pada sistem yang sama, salah satunya adalah dengan menggunakan pemisahan servis dan database [2]. Pemisahan database memungkinkan pengelolaan data yang lebih efisien, sementara pemisahan servis memungkinkan pengelolaan servis yang lebih efektif. Oleh karena itu, implementasi pemisahan servis dan database analitik dengan transaksional menjadi salah satu solusi yang paling populer saat ini [3].
Namun, penggunaan database terdistribusi juga memiliki beberapa tantangan. Masalah utama dalam penggunaan database terdistribusi adalah konsistensi data dan skalabilitas [4]. Oleh karena itu, metode konsistensi data yang tepat harus digunakan untuk memastikan bahwa data yang tersedia dalam database terdistribusi konsisten dan akurat. Selain itu, sistem database terdistribusi juga harus dapat mengatasi masalah skalabilitas untuk memastikan bahwa sistem dapat menangani volume data yang besar dan meningkat seiring waktu.
Dalam kaitannya dengan performa sistem, pemisahan database dan servis juga dapat membantu dalam mengoptimalkan kinerja sistem. Dalam sebuah penelitian oleh Li et al. (2019), mereka menunjukkan bahwa pemrosesan transaksional dan analitis pada database terdistribusi dapat meningkatkan kinerja sistem, khususnya dalam hal throughput dan latensi [3]. Kim et al. (2019)
juga melakukan penelitian yang menunjukkan bahwa arsitektur database terdistribusi dapat membantu mengintegrasikan pemrosesan transaksional dan analitis [4].
Dalam rangka memaksimalkan performa sistem, diperlukan juga penggunaan database yang tepat. Widiastuti dan Adhita (2019) mengemukakan bahwa penggunaan database dapat mempengaruhi performa sistem informasi [5]. Oleh karena itu, pemilihan database yang tepat menjadi kunci penting dalam mengoptimalkan performa sistem.
Penulis mengikuti alur dan juga tahapan yang ditunjukan pada Gambar 1 untuk emastikan kelancaran dari penelitian ini
Gambar 1. Alur penelitian
Penjelasan dari alur penelitian di atas sebagai berikut.
-
a. Identifikasi Masalah
Pada awal penelitian, penulis melakukan identifikasi permasalahan di lapangan dan juga melakukan penelitian dengan menggunakan literatur yang dapat membantu penelitian. Kemudian, masalah yang ditemukan oleh penulis adalah lambatnya pengambilan data pada database dan tingginya penggunaan CPU dan RAM ketika melakukan transaksional dan juga analitik terhadap suatu layanan.
-
b. Pencarian Sampel Data
Pada tahap ini, sampel data dicari melalui survey terhadap perusahaan teknologi yang memiliki produk berupa sistem transaksional. Dilakukan observasi dan wawancara untuk mengetahui bagaimana bentuk data dari sistem transaksional yang dimiliki oleh perusahaan terkait.
-
c. Implementasi Program Transaksional dan Analitik Menggunakan Arsitektur Microservices
Pada tahap ini, penulis membuat sebuah sistem untuk melakukan transaksional dan analitik. Terdapat satu servis untuk melakukan transaksional dan satu servis analitik serta penulis juga membuat dua database dengan data yang sama.
-
d. Tahap Load-Testing
Pengujian dilakukan dengan metode Load-Testing menggunakan K6 dan memperhatikan beberapa metris.
-
e. Analisis Hasil Pengujian
Peneliti melakukan analisis terhadap beberapa metris dan hasil database monitoring untuk menarik sebuah kesimpulan.
-
f. Kesimpulan
Pada tahap ini, penulis menarik kesimpulan dari beberapa metris dan hasil database monitoring untuk menarik kesimpulan dari hasil penelitian ini.
-
2.2. Arsitektur Microservices
Penelitian ini menggunakan arsitektur microservices untuk melihat dampak dari layanan single-point-of-failure, atau layanan yang kegagalannya mengganggu pengoperasian sistem. Ini adalah masalah fatal dalam arsitektur layanan mikro. Microservices adalah model arsitektur [6]. Ide dasar di balik jenis arsitektur ini adalah membagi sistem yang lebih besar menjadi sistem yang lebih kecil. Hal ini dapat mengurangi kompleksitas sistem [7], membuat sistem yang lebih kecil menjadi lebih mandiri, dan membuat hubungan antara sistem atau layanan menjadi kurang rumit. Selain itu, sistem yang mandiri membutuhkan proses pengembangan dan implementasi yang lebih mandiri. Keuntungan lain dari microservices adalah jika suatu layanan gagal, kegagalan tersebut hanya diisolasi dan tidak mengganggu layanan lain, kecuali jika layanan tersebut merupakan kegagalan tunggal. Gambar 2 dan Gambar 3 menunjukkan arsitektur yang penulis gunakan dalam penelitian ini,
Gambar 2. Arsitektur Microservices 1
Gambar 3. Arsitektur Microservices 2
-
2.3. Load-Testing
Pengujian yang dilakukan pada penelitian ini menggunakan metode Load-Testing dengan bantuan K6. Metode Load-Testing akan mensimulasikan pengguna yang mengirim permintaan sesuai dengan parameter yang diberikan ke program [8]. K6 merupakan alat bantu untuk melakukan Load-Testing yang bersifat open-source. Dengan ini kita bisa menguji performa dan keandalan sistem untuk mencari tahu masalah lebih awal. K6 akan mengembalikan hasil berupa beberapa metris yang berkaitan tentang permintaan yang telah dikirim. Metris ini akan membantu penulis untuk mengukur kecepatan penerimaan data pada penelitian ini. Beberapa metris yang digunakan pada penelitian dapat dilihat pada Tabel 1
Tabel 1. Metris Load-Testing
Key Deskripsi
http_req_duration Metris yang merepresentasikan durasi dari permintaan hingga menerima data pada HTTP Request (http_req_sending + http_req_waiting + http_req_receiving)
Berdasarkan alur penelitian dan juga studi literatur yang telah dijelaskan pada bab sebelumnya. Maka hasil penelitian yang peneliti lakukan dapat dijabarkan sebagai berikut.
Peneiltian ini melakukan pencarian sampel data ke perushaan teknologi yang memiliki sistem transaksional. Sampel data dicari dengan cara melakukan survey dan observasi terhadap perusahaan terkait. Didapatkan format data pada tabel transaksi yang digunakan oleh perusahaan dalam sistem transaksioal yang dapat dilihat pada Tabel 2
Tabel 2. Format Data Tabel Transaksi
Column |
Type |
transaction_no |
Int |
date |
Varchar |
product_no |
Int |
product_name |
Varchar |
price |
Double |
quantity |
Int |
customer_no |
Int |
country |
varchar |
Proses implementasi program transaksional dan analitik dilakukan pada basis kode atau codebase berbeda dengan menggunakan bahasa pemrograman Go. Potongan kode inti dari program transaksional dapat dilihat pada Tabel 3 dan analitik pada Tabel 4.
Tabel 3. Potongan Kode Inti Transaksional
Baris Kode
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
func createTransaksi(c *gin.Context) { var transaksi Transaksi
if err := c.ShouldBindJSON(&transaksi); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error":
err.Error()}) return
}
if err := db.Create(&transaksi).Error; err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, transaksi) }
func getTransaksi(c *gin.Context) {
id := c.Param("id")
var transaksi Transaksi
if err := db.First(&transaksi, id).Error; err != nil { if errors.Is(err, gorm.ErrRecordNotFound) {
c.JSON(http.StatusNotFound, gin.H{"error": "record not found"}) } else {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
} return
}
c.JSON(http.StatusOK, transaksi) }
func updateTransaksi(c *gin.Context) {
id := c.Param("id")
var transaksi Transaksi
if err := db.First(&transaksi, id).Error; err != nil { if errors.Is(err, gorm.ErrRecordNotFound) {
c.JSON(http.StatusNotFound, gin.H{"error": "record not found"}) } else {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
} return
}
if err := c.ShouldBindJSON(&transaksi); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error":
err.Error()})
return
Baris Kode
114 }
115
116 if err := db.Save(&transaksi).Error; err != nil {
117 c.JSON(http.StatusInternalServerError,
118 gin.H{"error": err.Error()})
return
119 }
120
121 c.JSON(http.StatusOK, transaksi)
122 }
123
124 func deleteTransaksi(c *gin.Context) {
125 db := c.MustGet("db").(*gorm.DB)
126
127 // Get the transaksi record with the specified ID
128 var transaksi Transaksi
129 if err := db.Where("id = ?",
130 c.Param("id")).First(&transaksi).Error; err != nil {
c.JSON(http.StatusNotFound, gin.H{"error": "Record not
131 found!"})
return
132 }
133
134 // Delete the transaksi record from the database
135 db.Delete(&transaksi)
136
137 // Return a success message as JSON
138 c.JSON(http.StatusOK, gin.H{
139 "message": "Record deleted successfully!",
140 })
141 }
142
Tabel 4. Potongan Kode Inti Analitik
Baris Kode
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
func getRevenueByProduct(c *gin.Context) { var revenueByProduct []RevenueByProduct
if err :=
db.Table("transaksis").Select("product_no, sum(price * quantity) as
revenue").Group("product_no").Find(&revenueByProduct).Err or; err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return }
c.JSON(http.StatusOK, revenueByProduct) }
func getRevenueByDate(c *gin.Context) {
var revenueByDate []struct {
Baris Kode
85 Date string `json:"date"`
86 Revenue float64 `json:"revenue
87
88
89
90
91
92
93
if err := db.Table("transaksis").Select("date, sum(price * quantity) as revenue").Group("date").Find(&revenueByDate).Error; err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, revenueByDate) }
Pada Tabel 3 merupakan kode program untuk melakukan transaksi pada umumnya seperti membuat transaksi, mengubah transaksi, melihat transaksi, dan juga menghapus transaksi. Kemudian pada kode analitik di Tabel 4, analitik yang dilakukan adalah menghitung pendapatan berdasarkan tanggal dan berdasarkan produk.
Pengujian dari sistem ini adalah dengan melakukan Load-Testing menggunakan K6. Program untuk melakukan Load-Testing ditulis dengan menggunakan bahasa pemrograman JavaScript. Kode pengujian menggunakan K6 dapat dilihat pada kode di Tabel 5.
Table 5. Kode Load-Testing
Baris |
Kode |
1 |
import http from 'k6/http'; |
2 |
import { check, sleep } from 'k6'; |
3 | |
4 |
export let options = { |
5 |
stages: [ |
6 |
{ duration: '1m', target: 20 } |
7 |
] |
8 |
}; |
9 | |
10 |
export function testCreateTransaksi() { |
11 |
let payload = { |
12 |
country: 'Indonesia', |
13 |
customer_no: 1, |
14 |
date: '2023-04-24', |
15 |
price: 100.0, |
16 |
product_name: 'Product A', |
17 |
product_no: 1, |
18 |
quantity: 1, |
19 |
transaction_no: 1 |
20 |
}; |
21 | |
22 |
let headers = { 'Content-Type': 'application/json' }; |
23 | |
24 |
Baris Kode
let res = http.post('http://localhost:8081/transaksi', JSON.stringify(payload), { headers: headers });
check(res, { 'status is 201': (r) => r.status === 201 });
}
export function testGetProductRevenue() { let res =
http.get('http://localhost:8080/transaksi/revenue-by-product');
check(res, { 'status is 200': (r) => r.status === 200});
}
export function testUpdateTransaksi() {
country: 'Indonesia',
date: '2023-04-24',
price: 200.0, product_name: 'Product A',
};
let headers = { 'Content-Type': 'application/json' };
let res = http.put('http://localhost:8081/transaksi/1', JSON.stringify(payload), { headers: headers });
check(res, { 'status is 200': (r) => r.status === 200});
}
export function testDeleteTransaksi() { let res = http.del('http://localhost:8081/transaksi/1');
check(res, { 'status is 200': (r) => r.status === 200});
}
// Create a new transaksi record
testCreateTransaksi();
// Get the total revenue by product
testGetProductRevenue();
// Update an existing transaksi record
testUpdateTransaksi();
// Delete an existing transaksi record
testDeleteTransaksi();
// Wait for 1 second before repeating the cycle sleep(1);
}
Implementasi dari Load-Testing dapat dilihat pada penggalan kode di atas. Pada kode tersebut terdapat beberapa fungsi yang menjalankan HTTP request ke beberapa endpoint untuk melakukan testing fungsionalitas dari API. Terdapat fungsi untuk membuat transaksi baru, mengambil total revenue dari produk, mengubah transaksi yang sudah ada, dan menghapus transaksi yang sudah ada. Selain itu, terdapat fungsi default yang menjalankan seluruh fungsi di atas secara berurutan dan akan diulang setiap 1 detik hingga durasi yang diatur pada options.stages habis. Pada options.stages, terdapat satu tahap (stage) pengujian yang mengatur bahwa selama 1 menit, akan ada 20 koneksi yang dibuat ke aplikasi. Dalam setiap HTTP request yang dilakukan, juga terdapat pengecekan (check) apakah status response dari API sesuai dengan yang diharapkan, misalnya status 201 untuk create atau 200 untuk read/update/delete. Sehingga didapatkan hasil dari Load-Testing seperti pada Gambar 4 dan juga Gambar 5 di bawah.
vus............................: 20 min=20
vus_max........................: 20 min=20
25.00⅜ ✓ 1040 X 3120
48 MB 797 kB/s 810 kB 13 kB/s avg=8.16μs min=0s med=2μs
avg=3.32μs min=0s med=0s
avg=39.79ms min=193μs med=1.99ms avg=78.15ms min=684μs med=59.62ms 50.00% ∕ 2080 x 2080 avg=41.46μs min=5μs med=30μs
avg=14.54μs min=2μs med=llμs
avg=0s min=0s med=0s
avg=39.73ms min=177μs med=1.92ms 4160 68.847578/s
avg=1.16s min=1.05s med=1.14s
1040 17.211895/s
max=1.22ms max=621μs ma×=316.77ms max=316.77ms
max=l.2ms max=534μs max=0s
ma×=316.65ms
ma×=l.32s
p(90)=5μs
p(90)=0s p(90)=146.83ms p(90)=186.58ms
p< 90)=84μs p(90)=27μs
p(90)=0s p(90)=146.7ms
p<90)=l.23s
p(95)=7μs
p(95)=0s p(95)=186.51ms p(95)=219.96ms
p(95)=108μs
p(95)=36μs p(95)=0s p(95)=186.44ms
p(95)=1.26s
running (Im00.4s), 00/20 VUs, 1040 complete and 0 interrupted iterations
default ✓ I============] 20 VUs lm0s
Gambar 4. Hasil Testing Dengan Satu Database
checks...................... data_received............... data_sent................... http_req_blocked............ http_req_connecting......... http_req_du rat ion...........
{ expected_response:true } http_req_failed............. http_req_receiving.......... http_req_sending............ http_req_tls_handshaking.... htt p_req_wa it ing............ http_reqs................... it e rat ion_du ra t ion.......... iterations..................
VUS......................... vus_max.....................
25.00% ✓ 1060 x 3180
49 MB 810 kB/s
826 kB 14 kB/s
avg=10.07μs min=0s |
med=2μs |
max=1.97ms |
p(90)=4μs |
p(95)=5μs |
avg=4.57μs min=0s |
med=0s |
max=719μs |
p(90)=0s |
p(95)=0s |
avg=34.74ms min=188μs |
med=l.13ms |
max=353.53ms |
p(90)=135.45ms |
p(95)=166.55ms |
avg=68.62ms min=585μs med=46.65ms 50.00% ✓ 2120 x 2120 |
max=353.53ms |
p(90)=166.55ms |
p(95)=197.69ms | |
avg=34.21μs min=4μs |
med=22μs |
ma×=2.41ms |
p(90)=62μs |
p(95)=80μs |
avg=11.62μs min=2μs |
med=9μs |
ma×=356μs |
p(90)=21μs |
p(95)=29μs |
avg=0s min=0s |
med=0s |
max=0s |
p(90)=0s |
p(95)=0s |
avg=34.7ms min=176μs 4240 69.99299/s |
med=l.lms |
max=353.38ms |
p(90)=135.37ms |
p(95)=166.47ms |
avg=1.13s min=1.05s |
med=1.13s |
ma×=1.37s |
p(90)=1.2s |
p(95)=1.24s |
1060 17.498247/s
20 min=20
20 min=20
running (Im00.6s), 00/20 VUs, 1060 complete and 0 interrupted iterations default ✓ [======] 20 VUs lm0s
Gambar 5. Hasil Testing Dengan Database Berbeda
Dalam pengukuran kinerja sistem transaksional dan analitik dengan database yang sama dan berbeda pada penelitian ini, dapat menggunakan perbandingan hasil dari Load-Testing pada kedua metode tersebut. Perbandingan dapat dilihat dengan mudah pada Tabel 6.
Tabel 6. Hasil metris Load-Testing
Metris |
Sistem Dengan Satu Database |
Sistem Dengan Database Berbeda |
Performa Tertinggi |
http_req_duration |
186.51 milidetik |
166.55 milidetik |
Sistem Dengan Database Berbeda |
Bedasarkan tabel diatas dapat dilihat metris http_req_duration menggunakan p (95) atau persentase request pada kecepatan yang jatuh pada persentase ke-95 agar lebih tepat dan menghindari outlier pada kedua hasil Load-Testing, Sistem transaksional dan analitik dengan menggunakan database yang berbeda mendapatkan hasil yang lebih baik dengan jangka waktu dari request hingga menerima data lebih cepat dibandingkan dengan satu database.
Berdasarkan metris http_req_duration menggunakan persentase request pada kecepatan yang jatuh pada persentase ke-95 atau p (95) dari hasil pengujian penelitian yang dilakukan yang dapat dilihat pada Tabel 6, ditemukan bahwa pemisahan database untuk sistem transaksional dan analitik memiliki kecepatan sistem yang lebih cepat dibanding sistem transaksional dan analitik hanya menggunakan satu database. Sehingga dapat direkomendasikan untuk pemisahan database pada sistem transaksional dan analitik, namun diperlukan juga sinkronisasi database agar data yang digunakan untuk transaksional dan analitik sama.
Daftar Pustaka
-
[1] Jafarzadeh, A., & Alizadeh, A. (2018). Design and implementation of a high-performance software-defined storage system for big data applications. IEEE Access, 6, 29934-29948.
-
[2] Chen, Y., Zhang, X., Hu, F., Guo, M., & Yan, X. (2019). An Automatic Data Separation Method for Analytical and Transactional Services. IEEE Access
-
[3] Li, J., Li, C., Li, L., Xu, X., & Feng, Y. (2019). Performance evaluation of transactional and analytical processing on distributed column-oriented database. IEEE Access, 7, 2093420944.
-
[4] Kim, T., Lee, Y., Lee, S., Lee, S., & Song, J. (2019). A distributed database architecture for integrating transactional and analytical data processing. Future Generation Computer Systems, 99, 205-215.
-
[5] Widiastuti, I., & Adhita, D. (2019). Pengaruh Penggunaan Database Terhadap Performa Sistem Informasi. Journal of Information Technology and Computer Science, 4(1), 1-7.
-
[6] F. Rademacher, S. Sachweh, and A. Zundorf, “Differences between model-driven development of service-oriented and microservice architecture,” Proc. - 2017 IEEE Int. Conf. Softw. Archit. Work. ICSAW 2017 Side Track Proc., pp. 38–45, 2017, doi:
10.1109/ICSAW.2017.32.
-
[7] M. Shahin, M. Ali Babar, and L. Zhu, “Continuous Integration, Delivery and Deployment: A Systematic Review on Approaches, Tools, Challenges and Practices,” IEEE Access, vol. 5, no. March, pp. 3909–3943, 2017, doi: 10.1109/ACCESS.2017.2685629.
-
[8] H. Schulz, T. Angerstein, and A. Van Hoorn, “Towards automating representative load testing in continuous software engineering,” ICPE 2018 - Companion 2018 ACM/SPEC Int. Conf. Perform. Eng., vol. 2018-January, pp. 123–126, 2018, doi:
10.1145/3185768.3186288.
856
Discussion and feedback