Penerapan Downtime Nol - Skema Db Transisi

14

Mencapai Zero Downtime Deployment menyentuh pada masalah yang sama tetapi saya memerlukan beberapa saran tentang strategi yang saya pertimbangkan.

Konteks

Aplikasi berbasis web dengan Apache / PHP untuk pemrosesan sisi server dan MySQL DB / sistem file untuk kegigihan.

Kami sedang membangun infrastruktur. Semua perangkat keras jaringan akan memiliki redundansi dan semua kabel jaringan utama akan digunakan dalam pasangan terikat untuk toleransi kesalahan. Server dikonfigurasikan sebagai pasangan ketersediaan tinggi untuk toleransi kesalahan perangkat keras dan akan seimbang beban untuk toleransi kesalahan mesin virtual dan kinerja umum.

Adalah maksud saya bahwa kami dapat menerapkan pembaruan ke aplikasi tanpa down-time. Saya telah bersusah payah ketika merancang infrastruktur untuk memastikan bahwa saya dapat menyediakan 100% up-time; akan sangat mengecewakan untuk memiliki downtime 10-15 menit setiap kali pembaruan diterapkan. Ini sangat penting karena kami bermaksud memiliki siklus rilis yang sangat cepat (kadang-kadang dapat mencapai satu atau lebih rilis per hari.

Topologi Jaringan

Ini adalah ringkasan dari jaringan:

                      Load Balancer
             |----------------------------|
              /       /         \       \  
             /       /           \       \ 
 | Web Server |  DB Server | Web Server |  DB Server |
 |-------------------------|-------------------------|
 |   Host-1   |   Host-2   |   Host-1   |   Host-2   |
 |-------------------------|-------------------------|
            Node A        \ /        Node B
              |            /            |
              |           / \           |
   |---------------------|   |---------------------|
           Switch 1                  Switch 2

   And onward to VRRP enabled routers and the internet

Catatan: Server DB menggunakan replikasi master-master

Strategi yang Disarankan

Untuk mencapai ini, saya saat ini sedang berpikir untuk memecah skrip upgrade skema DB menjadi dua bagian. Upgrade akan terlihat seperti ini:

  1. Web-Server pada node A diambil secara off-line; lalu lintas terus diproses oleh web-server pada node B.
  2. Perubahan Skema Transisi diterapkan ke server DB
  3. Web-Server Basis kode diperbarui, cache dihapus, dan tindakan pemutakhiran lainnya diambil.
  4. Web-Server A dibawa online dan web-server B diambil offline.
  5. Basis-kode-B server-web diperbarui, cache dihapus, dan tindakan pemutakhiran lainnya diambil.
  6. Web-server B dibawa online.
  7. Perubahan Skema Akhir diterapkan ke DB

'Skema Transisi' akan dirancang untuk membuat DB yang kompatibel dengan versi silang. Ini sebagian besar akan menggunakan tampilan tabel yang mensimulasikan skema versi lama sementara tabel itu sendiri akan diubah ke skema baru. Ini memungkinkan versi lama untuk berinteraksi dengan DB seperti biasa. Nama tabel akan menyertakan nomor versi skema untuk memastikan bahwa tidak akan ada kebingungan tentang tabel yang akan ditulis.

'Skema Akhir' akan menghapus kompatibilitas ke belakang dan merapikan skema.

Pertanyaan

Singkatnya, akankah ini berhasil?

lebih spesifik:

  1. Apakah akan ada masalah karena potensi untuk menulis bersamaan pada titik tertentu dari perubahan skema transisi? Apakah ada cara untuk memastikan bahwa grup kueri yang memodifikasi tabel dan membuat tampilan yang kompatibel mundur dijalankan secara berurutan? yaitu dengan kueri lain yang disimpan dalam buffer hingga perubahan skema selesai, yang umumnya hanya dalam milidetik.

  2. Apakah ada metode yang lebih sederhana yang memberikan tingkat stabilitas ini sementara juga memungkinkan pembaruan tanpa down-time? Ini juga lebih disukai untuk menghindari strategi skema 'evolusi' karena saya tidak ingin menjadi terkunci dalam kompatibilitas skema mundur.

Marvin
sumber

Jawaban:

4

Kedengarannya seperti apa yang benar-benar Anda cari tidak begitu banyak Ketersediaan Tinggi karena Anda akan membutuhkan Ketersediaan Berkelanjutan .

Pada dasarnya rencana Anda akan bekerja tetapi Anda tampaknya telah memperhatikan bahwa kelemahan utama dalam pengaturan Anda adalah bahwa perubahan skema database dalam rilis dapat mengakibatkan downtime atau kegagalan node yang masih tersedia untuk beroperasi dengan benar. Pendekatan Ketersediaan Berkelanjutan memecahkan ini dengan dasarnya menciptakan sejumlah lingkungan Produksi.

Produksi satu

Lingkungan ini adalah versi live Anda saat ini dari perangkat lunak yang digunakan oleh pengguna. Ini memiliki server web sendiri, server aplikasi, dan server database dan tablespace. Ini beroperasi secara independen dari lingkungan lainnya. Load Balancer yang memiliki titik akhir resolusi domain untuk layanan ini saat ini menunjuk ke server web ini.

Produksi Dua

Ini pada dasarnya merilis lingkungan pementasan yang identik dengan Production One. Anda dapat melakukan peningkatan rilis Anda di sini dan melakukan tes kewarasan Anda sebelum acara go live Anda. Ini juga memungkinkan Anda untuk melakukan perubahan database dengan aman di lingkungan ini. Load Balancer tidak menunjuk ke lingkungan ini saat ini.

Produksi DR

Ini adalah duplikat lain di pusat data terpisah yang terletak di kawasan berbeda di dunia. Ini memungkinkan Anda untuk gagal jika terjadi peristiwa bencana dengan melakukan saklar DNS di Load Balancer.

Hiduplah

Acara ini pada dasarnya memperbarui catatan DNS untuk siklus ke Produksi Dua dari Produksi Satu atau sebaliknya. Ini membutuhkan waktu untuk menyebar di seluruh server DNS dunia sehingga Anda membiarkan kedua lingkungan berjalan untuk sementara waktu. Beberapa pengguna MUNGKIN bekerja dalam sesi yang ada pada versi lama perangkat lunak Anda. Sebagian besar pengguna akan membuat sesi baru pada versi perangkat lunak Anda yang ditingkatkan.

Migrasi data

Satu-satunya kelemahan di sini adalah tidak semua data selama jendela itu tersedia untuk semua pengguna saat itu. Jelas ada data pengguna yang penting dalam database versi sebelumnya yang sekarang perlu dimigrasi dengan aman ke skema database baru. Ini dapat dilakukan dengan skrip ekspor dan migrasi data atau pengujian data yang teruji dengan baik atau proses ETL serupa.

Kesimpulan

Setelah Anda menyelesaikan acara rilis sepenuhnya, Production Two sekarang menjadi yang utama dan Anda mulai berupaya menginstal rilis berikutnya ke Production One untuk siklus penyebaran berikutnya.

Kekurangannya

Ini adalah pengaturan lingkungan yang kompleks dan memerlukan sejumlah besar sumber daya sistem, sering kali dua hingga tiga kali sumber daya sistem berhasil dilakukan. Pengoperasian dengan cara ini bisa mahal, terutama jika Anda memiliki sistem penggunaan besar yang sangat besar.

maple_shaft
sumber
Jadi, jika saya mengerti dengan benar, Anda menyarankan bahwa alih-alih perubahan skema DB 'transisi' yang diterapkan saat Db masih digunakan, Db-A disimpan online dengan skema lama sementara Db-B diperbarui ke yang baru skema. Ketika pembaruan siap untuk rilis, server web diubah dan data yang ditulis ke Db A saat pembaruan sedang disiapkan dimigrasikan ke Db B (mungkin dengan menerapkan semua perubahan setelah batas waktu tertentu).
Marvin
@PeterScott Anda mengerti. Hanya perlu diingat bahwa Anda tidak ingin menjalankan skrip sampai Anda yakin bahwa semua sesi aktif sudah berakhir di sistem lama dan sudah cukup lama bahwa semua cache DNS telah diperbarui ke CNAME atau alamat IP yang baru.
maple_shaft
1
Saya harus baik-baik saja pada kedua poin tersebut; sesi sedang berlangsung di Db daripada penyimpanan server untuk menghindari sesi terikat ke mesin virtual tertentu dan saya saat ini bermaksud untuk mencoba dan menggunakan load-balancer berbasis non-DNS. Saya tidak akan memiliki redundansi tingkat pusat data, tapi itu bisa menunggu selama satu tahun atau lebih setelah peluncuran aplikasi.
Marvin
2

Strategi Anda sehat. Saya hanya akan menawarkan untuk mempertimbangkan memperluas "Skema Transisi" ke dalam satu set lengkap "tabel transaksi".

Dengan tabel transaksi, SELECT (kueri) dilakukan terhadap tabel yang dinormalisasi untuk memastikan kebenaran. Tetapi semua database INSERT, UPDATE, dan DELETEs selalu ditulis ke tabel transaksi yang didenormalkan.

Kemudian, proses bersamaan yang terpisah menerapkan perubahan tersebut (mungkin menggunakan Prosedur Tersimpan) ke tabel yang dinormalisasi sesuai dengan aturan bisnis dan persyaratan skema yang ditetapkan.

Sebagian besar waktu, ini akan hampir seketika. Tetapi memisahkan tindakan memungkinkan sistem untuk mengakomodasi aktivitas berlebihan dan penundaan pembaruan skema.

Selama perubahan skema pada database (B), pembaruan data pada database aktif (A) akan masuk ke tabel transaksinya dan segera diterapkan ke tabel yang dinormalisasi.

Saat mengembalikan basis data (B), transaksi dari (A) akan diterapkan dengan menuliskannya ke tabel transaksi (B). Setelah bagian itu selesai, (A) dapat diturunkan dan skema perubahan diterapkan di sana. (B) akan selesai menerapkan transaksi dari (A) sambil juga menangani transaksi langsungnya yang akan mengantri seperti (A) dan "yang hidup" akan diterapkan dengan cara yang sama ketika (A) kembali.

Baris tabel transaksi mungkin terlihat seperti ...

| ROWID | TRANSNR | DB | TABLE | SQL STATEMENT
    0        0       A    Name   INSERT INTO Name ...
    1        0       A    Addr   INSERT INTO Addr ...
    2        0       A    Phone  INSERT INTO Phone ...
    3        1       A    Stats   UPDATE Stats SET NrOfUsers=...

"Tabel" transaksi sebenarnya dapat berupa baris dalam basis data NoSQL yang terpisah atau bahkan file berurutan, tergantung pada persyaratan kinerja. Bonusnya adalah pengkodean aplikasi (situs web dalam hal ini) menjadi sedikit lebih sederhana karena hanya menulis ke tabel transaksi.

Idenya mengikuti prinsip yang sama seperti pembukuan entri ganda, dan untuk alasan yang sama.

Tabel transaksi dianalogikan dengan "pembukuan" jurnal. Tabel yang dinormalkan sepenuhnya analog dengan "buku besar" pembukuan dengan masing-masing tabel agak seperti "akun" pembukuan.

Dalam pembukuan, setiap transaksi mendapat dua entri dalam jurnal. Satu untuk akun buku besar "yang didebit", dan satu lagi untuk akun "dikreditkan".

Dalam RDBMS, "jurnal" (tabel transaksi) mendapat entri untuk setiap tabel yang dinormalisasi untuk diubah oleh transaksi itu.

Kolom DB dalam ilustrasi tabel di atas menunjukkan di basis data mana transaksi berasal, sehingga memungkinkan baris antrian dari database lain disaring dan tidak diterapkan kembali ketika database kedua dibawa kembali.

DocSalvager
sumber
1
Saya suka perbandingan dengan pembukuan. Jadi, jika saya sudah mengerti, tabel transaksi memungkinkan saya untuk menempatkan penundaan yang sangat kecil pada penulisan data ke tabel dinormalisasi tertentu sehingga saya dapat menerapkan semua perubahan skema tanpa risiko gangguan di tengah jalan melalui perubahan? Kemudian, dengan skema tabel yang terbaru, saya dapat melanjutkan proses yang menerapkan transaksi yang dinormalisasi ke tabel yang dinormalisasi (proses ini mampu memetakan kueri data skema lama ke skema baru)?
Marvin
1
Iya. Anda akan memodifikasi prosedur tersimpan pemetaan (atau apa pun) untuk mengakomodasi data lama dan baru. Kolom NOT-NULL baru mungkin diisi dari data lama dengan kode yang berarti "meminta ini pada pembaruan pengguna." Kolom yang akan dipisah (yaitu FULLNAME menjadi FIRST dan LAST) akan membutuhkan beberapa algoritma. Saya sarankan menambahkan 1 atau lebih kolom "seperti komentar" ke tabel untuk persyaratan bisnis baru yang muncul. Jika tidak, saya jamin pengguna akan menggunakan kolom lain untuk tujuan itu dan memperbaiki data akan menjadi hampir mustahil.
DocSalvager
Bagaimana Anda mencegah kueri SELECT terstruktur untuk skema lama diterapkan ke skema baru? Saya bisa menggunakan membuat tampilan tabel dan mengganti nama tabel skema (dengan nomor versi skema) tapi ini masih bermasalah sementara perubahan skema sedang diterapkan karena mereka diterapkan langsung ke tabel yang dinormalisasi.
Marvin
1
Ketika Anda menambahkan tabel, kolom, atau apa pun ke RDBMS, Anda sebenarnya hanya menambahkan baris ke satu set tabel internal yang dapat ditulis hanya oleh mesin RDBMS. DBA mengelola database dengan meminta mereka melalui VIEW. Karena Oracle, IBM, MS, dll. Adalah para ahli dan mengatakan ini adalah cara terbaik, sepertinya kita harus mengikuti jejak mereka. Buat satu set PANDANGAN untuk setiap versi aplikasi. Anda dapat memodelkannya setelah tabel (biasanya cukup dinormalisasi) yang ingin Anda buat oleh pengembang sehingga Anda dapat menormalkan dengan benar untuk mencegah data yang rusak.
DocSalvager
Terima kasih. Saya harus memikirkan ini. saya sedang membangun lapisan ORM dalam aplikasi yang sepenuhnya menghapus semua logika persistensi negara dari domain utama; lebih berbasis di sisi server pemrograman saya cenderung untuk menyelesaikan masalah lebih dari sisi itu daripada sisi administrasi DB. Menggunakan strategi saya saat ini, Db akan cukup datar dengan ORM yang secara aktif mengelola tabel mentah. Menambahkan tampilan tabel dan, mungkin, log transaksi menambah kompleksitas yang lebih besar ke ORM tetapi juga memberi beberapa versi skema untuk didukung tanpa pemisahan data.
Marvin