BAB IV ANALISIS DAN PERANCANGAN Bab ini akan membahas mengenai permasalahan yang terjadi pada aplikasi yang menggunakan arsitektur 3 tier dan strategi penanganan masalahnya. 4.1 Identifikasi Masalah Arsitektur 3 tier (Gambar IV-1) terdiri dari user interface tier (contoh: web server) yang menangani masalah tampilan ke client, middle tier yang menangani logika aplikasi, dan database tier yang menangani masalah persistensi data. Aplikasi jenis ini mempunyai ciri distrukturkan sebagai gabungan dari komponen-komponen yang mempunyai hubungan yang diletakkan di dalam suatu container oleh application server. Berbagai macam service yang diperlukan oleh aplikasi seperti transaksi, persistensi, keamanan, dan konkurensi disediakan melalui container. Dengan cara tersebut, developer dapat menentukan service yang diperlukan oleh komponen secara deklaratif tanpa harus mengubah kode komponen secara langsung. Gambar IV-1 Arsitektur 3 tier Arsitektur jenis ini juga mendukung konfigurasi yang fleksibel seperti partisi dan clustering untuk meningkatkan performa dan skalabilitas. Pengunaan replikasi untuk meningkatkan availabilitas juga dapat diterapkan pada setiap tier tergantung dari kebutuhan aplikasi. Pada aplikasi yang menggunakan arsitektur tiga tier seperti diilustrasikan pada gambar IV-1, interaksi antara client dengan web server dilakukan melalui Internet. Infrastruktur yang mendukung interaksi ini tidak berada di bawah kendali langsung dari penyedia layanan aplikasi yang umumnya hanya mengurusi web IV-1 IV-2 tier dan tier berikutnya. Availabilitas dari layanan tersebut dapat ditingkatkan dengan membuat setiap tier tereplikasi. Diantara tier-tier yang disebutkan di atas, middle tier dan database tier merupakan komponen yang paling penting karena middle tier merupakan tempat melakukan komputasi logika aplikasi serta database tier merupakan tempat penyimpanan data persisten. Pada Bab I bagian latar belakang telah dijelaskan mengenai replikasi di middle tier beserta alasan pemilihannya sebagai fokus tugas akhir ini. Satu konsep yang penting yang harus diperhatikan dalam melakukan replikasi adalah suatu transaksi hanya dieksekusi sekali. Contohnya pada online shop dimana pelanggan dapat melihat katalog, memilih item dan memasukkan ke shopping cart, dan pada akhirnya memesan dan membayar dengan kartu kredit. Aktivitas tersebut melibatkan data transaksional (stok, validasi kartu, data pelanggan) yang terletak di berbagai database server. Dalam contoh tersebut, sistem harus menjamin transaksi tersebut hanya dilakukan sekali (sifat atomik) walaupun terjadi kegagalan sistem. Tanpa ada jaminan tersebut, pesanan pelanggan dapat terduplikasi atau dapat kehilangan pesanan tanpa mengetahuinya. Vendor dari application server di middle tier umumnya menyediakan solusi clustering untuk meningkatkan performa (melalui load-balancing ) dan skalabilitas. Sistem yang ter-cluster memungkinkan penggunaan banyak server untuk menangani banyak client yang pada akhirnya akan meningkatkan throughput dari sistem. Permasalahan muncul karena penanganan failover pada cluster system ini terbatas untuk jenis komputasi yang stateless (request yang tidak memodifikasi state yang tersimpan di application server) sedangkan mid-tier server juga membutuhkan penanganan failover untuk komputasi yang stateful. Meskipun masalah penanganan failover untuk komputasi yang stateful dapat diatasi dengan replikasi komputasi di mid-tier, masalah lain muncul di sisi database tier yaitu untuk sistem yang tereplikasi, jika terjadi kegagalan pada middle tier server, backup dapat mengambil alih komputasi dan meneruskan transaksi yang gagal. Namun yang menjadi masalah adalah saat terjadi kegagalan, semua transaksi yang aktif akan dibatalkan oleh database server, meskipun client mungkin telah menerima hasil IV-3 eksekusi request yang merupakan bagian dari transaksi yang batal tersebut. Saat transaksi tersebut dieksekusi oleh backup mid-tier server, mungkin saja eksekusi transaksi ini menghasilkan data yang berbeda dengan transaksi asalnya karena apabila koneksi antara middle tier dengan DBMS terputus, semua lock pada data akan dilepas sehingga ada kemungkinan client lain yang mempunyai prioritas yang lebih tinggi untuk melakukan transaksi daripada backup server melakukan perubahan terhadap data tersebut. AS1 DBMS AS1: -Start Transaction -Statement A -Statement B -Crash AS2: -Statement C -Statement D -Commit AS2 Gambar IV-2 Skenario Permasalahan Permasalahan yang dijelaskan di atas dapat disederhanakan ke dalam skenario sebagai berikut.Seperti terlihat pada gambar IV-2 ,AS1 adalah Application Server pertama yang menjadi master dan AS2 adalah Application Server kedua yang menjadi backup. AS1 memulai transaksi, melakukan statement A dan B, kemudian crash. Reaksi normal DBMS jika terjadi crash pada client adalah melepas lock pada data dan rollback transaksi. Jika DBMS melakukan hal tersebut maka AS2 tidak dapat meneruskan transaksi yang dimulai oleh AS1 dan tidak mendapatkan hasil yang diinginkan. 4.2 Koneksi dan Transaksi pada JDBC Subbab ini akan menjelaskan bagaimana penanganan koneksi dan transaksi pada JDBC. IV-4 4.2.1 Koneksi API JDBC mendefinisikan interface Connection untuk merepresentasikan koneksi terhadap suatu basis data. Ada dua mekanisme utama untuk koneksi terhadap basis data yaitu menggunakan kelas DriverManager atau kelas DataSource. Contoh koneksi jdbc ke database MySQL dengan menggunakan kelas DriverManager: String userName = "testuser"; String password = "testpass"; String url = "jdbc:mysql://localhost/test?user=" + userName + "&password=" + password; Class.forName ("com.mysql.jdbc.Driver").newInstance (); conn = DriverManager.getConnection (url); Pada connection string di atas dapat ditambahkan parameter tambahan seperti penambahan username dan password untuk otentifikasi. 4.2.2 Transaksi JDBC tidak menangani secara langsung begin transaction. Agar suatu transaksi dapat dilakukan, parameter autocommit harus di-set menjadi false dengan cara memanggil method setAutoCommit(false) dari object connection. Untuk commit suatu transaksi dipanggil method commit dari object connection sedangkan untuk rollback akan dipanggil method rollback dari object connection. Ada beberapa tingkat isolasi pada transaksi dalam kasus transaksi yang konkuren. Kemungkinan interaksi di antara transaksi yang konkuren dapat dikategorikan sebagai berikut: - dirty read dapat terjadi jika suatu transaksi diperbolehkan melihat perubahan yang belum di-commit terhadap suatu data. Jika transaksi di-rollback, ada kemungkinan transaksi yang membaca data tersebut mendapatkan data yang salah. - Nonrepeatable read terjadi ketika: a. Transaksi A membaca suatu row b. Transaksi B merubah row yang dibaca oleh A c. Transaksi A membaca row yang sama yang telah diubah oleh B IV-5 - Phantom read terjadi ketika: a. Transaksi A membaca semua row yang memenuhi kondisi WHERE b. Transaksi B menambahkan suatu row yang memenuhi kondisi WHERE c. Transaksi A mengevaluasi ulang kondisi WHERE tersebut dan mendapatkan row tambahan Untuk tugas akhir ini tingkat isolasi yang akan digunakan adalah transaction serializable yang mencegah terjadinya dirty read, nonrepeatable read maupun phantom read. 4.3 Rancangan solusi Untuk memudahkan penulisan,pada subbab ini penggunaan istilah client ditujukan pada middle-tier server dan penggunaan istilah server ditujukan untuk database server. Dari identifikasi masalah pada subbab 4.1 dapat disimpulkan dua masalah penting dalam melakukan replikasi di middle tier yaitu - tidak boleh terjadinya duplikasi dalam pengiriman request dari client ke server - kegagalan di middle tier tidak boleh menyebabkan database server membatalkan transaksi yang sedang berlangsung. Masalah pertama diasumsikan sudah ditangani di application server dan tidak menjadi fokus dalam tugas akhir ini. Untuk menangani masalah kedua yang menjadi fokus dalam tugas akhir ini, diperlukan solusi untuk pembentukan koneksi backup dan solusi dalam penanganan failover. Pendekatan yang dipilih untuk memodelkan replikasi di middle tier dan menangani masalah yang kedua adalah strategi primarybackup. Pemilihan strategi primary-backup disebabkan strategi ini merupakan yang umum dan praktikal digunakan untuk memodelkan replikasi di middle tier [BUD93]. Alasan lainnya adalah karena proses yang terjadi di application server bersifat non deterministik (input yang sama mungkin menghasilkan hasil yang berbeda) sehingga tidak cocok apabila digunakan metode active replication yang mengharuskan server yang bersifat deterministik[SCH90]. IV-6 4.3.1 Asumsi Ada beberapa asumsi yang harus diberikan dalam pembuatan rancangan solusi: 1. Fail over di sisi client sudah ditangani (backup mengetahui primary crash, mengetahui state terakhir primary dan meneruskan transaksi yang terputus) 2. Tidak ada duplikasi statement yang dikirimkan oleh client ke server (Exactly Once Execution/Transaction). 4.3.2 Solusi Koneksi Backup DBMS standar akan memperlakukan setiap koneksi sebagai koneksi yang unik dan tidak berhubungan antara koneksi yang satu dengan koneksi yang lain. Agar suatu client menjadi backup dari client utama (primary), maka client harus memberitahu bahwa koneksi yang akan dibentuk merupakan backup dari koneksi utama. Ada beberapa solusi untuk memberitahu server bahwa koneksi yang akan dibentuk adalah koneksi backup. Solusi pertama adalah menambahkan field baru pada client authentication packet yang berisi id koneksi utama. Pada saat client utama melakukan koneksi ke server, client utama akan menyimpan id koneksi sehingga sebelum client backup melakukan koneksi ke server, client backup dapat meminta id koneksi utama dari client utama yang diperlukan untuk melakukan koneksi ke server. Kelebihan dari solusi ini adalah client backup bebas menentukan client mana yang menjadi primary-nya. Kekurangannya adalah menambah overhead pembentukan koneksi karena ukuran paket diperbesar dengan menambahkan field “id koneksi utama”, selain itu solusi ini juga mengharuskan perubahan di JDBC driver. Solusi kedua adalah menggunakan field “user” yang sudah tersedia pada client authentication packet. Field “user” yang merupakan login name yang dimasukkan ketika client melakukan koneksi ke server dapat dimanfaatkan dengan mengasumsikan bahwa client pertama yang melakukan koneksi dengan nama user tertentu menjadi client primary. Kemudian client lain yang melakukan koneksi dengan nama user yang sama dengan client utama setelah client utama terbentuk akan disebut sebagai client backup. Kelebihan dari solusi ini adalah tidak adanya IV-7 penambahan ukuran paket serta lebih sederhana dari solusi yang pertama. Kelemahannya adalah client backup harus menggunakan login name yang sama dengan client utama. Solusi kedua merupakan solusi yang dipilih karena tidak perlu mengubah protokol dan ukuran paket pada saat handshaking. Selain itu solusi ini dipilih karena umumnya master dan backup dari sistem yang tereplikasi tergabung dalam satu grup dan mempunyai identitas unik yang hanya dimiliki oleh grup tersebut. Field “user” pada client authentication packet dapat menjadi identitas unik dari suatu grup yang tereplikasi. 4.3.2.1 Struktur Data Untuk mengimplementasi solusi kedua pada subbab 4.4.2 diperlukan suatu struktur data global (Gambar IV-3) yang menyimpan informasi mengenai nama grup dan koneksi. Struktur data yang dipilih adalah struktur data multimap. Struktur data multimap berbentuk seperti associative array yang berkait dimana key yang berisi nama yang digunakan untuk login dan value-nya berupa linked list yang menyimpan objek THD yang menyimpan informasi mengenai koneksi yang berasosiasi dengan nama sebagai key. IV-8 Key Value1 Value2 Nama-1 THD(Master) THD(Slave) Nama-2 THD(Master) Nama-3 Nama-n Gambar IV-3 Struktur data Multimap 4.3.2.2 Rancangan Penanganan Koneksi Gambar IV-4 Sequence Diagram penanganan koneksi IV-9 Gambar IV-4 menjelaskan mengenai interaksi client, mysqld, dan objek THD ketika terjadi permintaan koneksi baru oleh client. Langkah-langkah yang dilakukan ketika client menginisiasi koneksi ke mysqld sampai server siap menerima query dari client adalah sebagai berikut: - Client melakukan proses handshaking ke server (mysqld) - mysqld akan memanggil fungsi handle_connection_sockets yang memanggil system call “accept” untuk membentuk koneksi TCP, kemudian menciptakan thread baru dengan fungsi create_new_thread. - Thread baru tersebut memanggil fungsi handle_one_connection yang akan menangani perintah dari client dan mengurus resource koneksi. Dari langkah-langkah yang disebutkan di atas dapat disimpulkan bahwa setiap koneksi akan ditangani oleh sebuah thread. Informasi di thread primary harus dapat diakses oleh thread backup apabila client primary mengalami kegagalan. Agar informasi di satu thread dapat diakses oleh thread lain, maka harus ada variabel global yang dapat diakses secara bersama-sama. Struktur data multimap pada gambar IV-3 akan digunakan sebagai variabel global yang diakses secara bersama-sama untuk bertukar informasi. Prosedur Insert_THD merupakan prosedur yang ditambahkan sebelum handle_one_connection dan berfungsi untuk mengisi key pada struktur data multimap dengan parameter ”user” kemudian mengkopi objek THD untuk menjadi value. 4.3.3 Rancangan Solusi Failover Reaksi standar yang dilakukan MySQL server apabila mendeteksi terjadinya pemutusan koneksi adalah membereskan semua informasi mengenai dari memory kemudian mematikan thread yang mengurusi koneksi tersebut. Untuk mencegah suatu transaksi dibatalkan, maka state transaksi tersebut harus tetap disimpan di dalam memory walaupun thread tersebut berhenti sehingga thread lain yang menjadi backup koneksi dapat melihat state tersebut dan melanjutkan koneksi. Untuk mengimplementasikan solusi tersebut dibutuhkan suatu struktur yang menyimpan informasi mengenai jumlah client primary yang ada serta jumlah backup IV-10 dari primary yang bersangkutan sehingga apabila client utama crash, server dapat mengetahui keberadaan backup dan tidak membereskan resource transaksi yang tersimpan di memory. Struktur data yang digunakan untuk mengimplementasikan solusi ini adalah struktur data multimap (Gambar IV-3). Informasi mengenai jumlah client primary dapat dilihat dari jumlah key pada struktur data multimap sedangkan keterkaitan antara primary dan backup dapat dilihat dari value multimap yang berupa linked list, value pertama menyatakan primary dan value-value selanjutnya menyatakan backup dari value pertama. Gambar IV-5 Sequence Diagram Pemutusan Koneksi Gambar IV-5 menjelaskan mengenai interaksi antara client dan objek THD. Kondisi awalnya adalah client sudah terkoneksi ke server dan objek THD sudah terbentuk dan siap berkomunikasi dengan client. Fungsi do_command merupakan fungsi yang membuat thread dalam kondisi blocking dan siap menerima query dari client. Berikut adalah langkah-langkah interaksi antara client dan THD dari client mengirimkan IV-11 perintah; client crash sampai objek THD memutus koneksi dan membereskan resource: - Objek THD siap menerima query dari client dengan memanggil method Do_command() - Client mengirimkan perintah start transaction untuk memulai transaksi dan mengirimkan statement A yang meminta perubahan pada tabel di basis data. - Objek THD akan memanggil fungsi Dispatch_command() yang akan menjalankan query tersebut dan mengirimkan hasilnya kembali kepada client dalam bentuk result set. - Setelah mengirimkan result set ke client, objek THD akan kembali memanggil fungsi do_command() dan membuat thread kembali berada dalam kondisi blocking dan siap menerima perintah selanjutnya dari client. - Client mengalami kegagalan (crash) setelah menerima result set kemudian objek THD mendeteksi kegagalan tersebut dan akan memanggil fungsi close_connection() yang akan membereskan koneksi TCP dan fungsi end_thread() akan memanggil destruktor dari objek THD. Fungsi transfer_state() ditambahkan sebelum fungsi close_connection() dan end_thread() dipanggil. Fungsi tersebut bertujuan untuk mengecek keberadaan koneksi backup dan apabila koneksi backup ditemukan maka akan dilakukan transfer state . State yang ditransfer merupakan member dari objek THD pada tabel III-1. Member-member yang ditransfer adalah kelompok lock, basis data, transaksi, dan handler data.