Evolusi pendekatan penyebaran kode di Reddit

gambar

Kami, di tim layanan pembayaran blockchain Wirex , memahami pengalaman kebutuhan untuk terus memperbaiki dan meningkatkan solusi teknologi yang ada. Penulis materi di bawah ini berbicara tentang sejarah evolusi penyebaran kode platform berita sosial terkenal Reddit.

"Penting untuk mengikuti arah perkembangan Anda agar dapat mengirimkannya ke arah yang tepat waktu."

Tim Reddit terus-menerus menyebarkan kode. Semua anggota tim pengembangan secara teratur menulis kode yang diperiksa ulang oleh penulis sendiri, dan diuji dari luar, sehingga ia kemudian dapat pergi ke "produksi". Setiap minggu kami membuat setidaknya 200 "penyebaran", yang masing-masing biasanya memakan waktu kurang dari 10 menit.

Sistem yang menyediakan semua ini telah berkembang selama bertahun-tahun. Mari kita lihat apa yang telah berubah di dalamnya selama ini, dan apa yang tetap tidak berubah.

Awal cerita: penyebaran stabil dan berulang (2007-2010)


Seluruh sistem yang kita miliki saat ini telah berkembang dari satu seed - sebuah skrip Perl yang disebut push. Sudah lama ditulis, di waktu yang sangat berbeda untuk Reddit. Seluruh tim teknis kami sangat kecil pada waktu itu sehingga masuk ke dalam satu "ruang rapat" kecil . Kami tidak menggunakan AWS saat itu. Situs ini bekerja pada sejumlah server yang terbatas, dan kapasitas tambahan apa pun harus ditambahkan secara manual. Semuanya bekerja pada satu aplikasi Python monolitik besar yang disebut r2.

Satu hal selama bertahun-tahun tetap tidak berubah. Permintaan diklasifikasikan dalam penyeimbang beban dan didistribusikan di antara "kumpulan" yang berisi server aplikasi yang kurang lebih identik. Misalnya, halaman daftar topik dan komentar diproses oleh kumpulan server yang berbeda. Sebenarnya, setiap proses r2 dapat menangani semua jenis permintaan, namun, pembagian ke dalam kumpulan memungkinkan Anda untuk melindungi masing-masing dari lompatan tiba-tiba dalam lalu lintas di kolam yang berdekatan. Dengan demikian, jika terjadi pertumbuhan lalu lintas, kegagalan tidak mengancam seluruh sistem, tetapi kumpulan individu.

gambar

Daftar server target secara manual ditulis dalam kode alat push, dan proses penyebaran bekerja dengan sistem monolitik. Alat berjalan melalui daftar server, memeriksa SSH, menjalankan salah satu urutan perintah yang telah ditentukan yang memperbarui salinan kode saat ini menggunakan git, dan memulai kembali semua proses aplikasi. Inti dari proses ini (kode ini sangat disederhanakan untuk pemahaman umum):

#            `make -C /home/reddit/reddit static` `rsync /home/reddit/reddit/static public:/var/www/` #    app-        #    ,   foreach $h (@hostlist) { `git push $h:/home/reddit/reddit master` `ssh $h make -C /home/reddit/reddit` `ssh $h /bin/restart-reddit.sh` } 

Penyebaran berlangsung secara berurutan, satu demi satu server. Untuk semua kesederhanaannya, skema ini memiliki nilai tambah yang penting: sangat mirip dengan " penyebaran kenari ". Dengan menyebarkan kode pada beberapa server dan melihat kesalahan, Anda segera menyadari bahwa ada bug, Anda dapat mengganggu proses (Ctrl-C) dan memutar kembali sebelum masalah muncul dengan semua permintaan sekaligus. Kemudahan penyebaran membuatnya mudah dan tanpa konsekuensi serius untuk memeriksa barang-barang dalam produksi dan memutar kembali jika mereka tidak bekerja. Selain itu, mudah untuk menentukan penyebaran tertentu yang menyebabkan kesalahan, di mana secara spesifik dan apa yang perlu dibatalkan.

Mekanisme seperti itu melakukan pekerjaan yang baik untuk memastikan stabilitas dan kontrol selama penyebaran. Alat ini bekerja sangat cepat. Segalanya berjalan dengan baik.

Resimen kami tiba (2011)


Lalu kami mempekerjakan lebih banyak orang, sekarang ada enam pengembang, dan "ruang pertemuan" baru kami menjadi lebih luas . Kami mulai menyadari bahwa proses penerapan kode sekarang membutuhkan lebih banyak koordinasi, terutama ketika rekan kerja dari rumah. Utilitas push telah diperbarui: sekarang mengumumkan awal dan akhir penyebaran menggunakan IRC chatbot, yang hanya duduk di IRC dan mengumumkan acara. Proses yang dilakukan selama penyebaran tidak mengalami perubahan apa pun, tetapi sekarang sistem melakukan segalanya untuk pengembang dan memberi tahu semua orang tentang modifikasi yang dilakukan.

Sejak saat itu, penggunaan obrolan dimulai dalam alur kerja penggunaan. Bicara tentang mengelola penyebaran dari obrolan cukup populer pada waktu itu, namun, karena kami menggunakan server IRC pihak ketiga, kami tidak dapat mempercayai obrolan seratus persen dalam mengelola lingkungan produksi, dan oleh karena itu prosesnya tetap pada tingkat arus informasi satu arah.

Seiring pertumbuhan lalu lintas ke situs, infrastruktur yang mendukungnya juga meningkat. Dari waktu ke waktu, kami terus meluncurkan grup server aplikasi baru dan menjalankannya. Prosesnya masih belum otomatis. Secara khusus, daftar host yang ditekan masih perlu diperbarui secara manual.

Kekuatan kumpulan biasanya ditingkatkan dengan menambahkan beberapa server sekaligus. Akibatnya, mendorong berturut-turut berjalan melalui daftar berhasil menggulung perubahan ke seluruh kelompok server di kumpulan yang sama, tanpa mempengaruhi yang lain, yaitu, tidak ada diversifikasi oleh kumpulan.

gambar

UWSGI digunakan untuk mengontrol proses pekerja, dan ketika kami memberikan aplikasi perintah reboot, aplikasi itu membunuh semua proses yang ada sekaligus, menggantikannya dengan yang baru. Proses baru membutuhkan waktu untuk bersiap untuk memproses permintaan. Dalam kasus restart yang tidak disengaja dari sekelompok server yang terletak di kumpulan yang sama, kombinasi dari kedua keadaan ini sangat memengaruhi kemampuan kumpulan ini untuk melayani permintaan. Jadi kami berlari ke batas kecepatan penyebaran kode yang aman ke semua server. Ketika jumlah server bertambah, begitu pula durasi seluruh prosedur.

Penerapan Instrumen Daur Ulang (2012)


Kami mendesain ulang alat penyebaran secara menyeluruh. Dan meskipun namanya, meskipun ada perubahan total, tetap sama (push), kali ini ditulis dengan Python. Versi baru telah mengalami beberapa peningkatan besar.

Pertama-tama, ia mengambil daftar host dari DNS, dan bukan dari urutan yang dikodekan dalam kode. Ini hanya memperbolehkan daftar untuk diperbarui, tanpa perlu memperbarui kode push. Permulaan sistem penemuan layanan telah muncul.

Untuk mengatasi masalah restart berulang, kami mengocok daftar host sebelum penyebaran. Mengacak risiko berkurang dan memungkinkan untuk mempercepat proses.

gambar

Versi asli mengacak daftar secara acak setiap kali, namun, ini membuatnya sulit untuk memutar kembali dengan cepat, karena setiap kali daftar kelompok server pertama berbeda. Oleh karena itu, kami mengoreksi pencampuran: sekarang menghasilkan pesanan tertentu yang dapat digunakan selama penerapan berulang setelah rollback.

Perubahan kecil tapi penting lainnya adalah penerapan terus-menerus dari beberapa versi kode yang tetap. Versi sebelumnya dari alat selalu memperbarui cabang master pada host target, tetapi apa yang terjadi jika master berubah tepat selama penyebaran karena fakta bahwa seseorang secara keliru meluncurkan kode? Menerapkan beberapa revisi git yang diberikan alih-alih memanggil dengan nama cabang memungkinkan untuk memastikan bahwa versi kode yang sama digunakan pada setiap server produksi.

Dan akhirnya, alat baru ini membedakan kodenya (terutama bekerja dengan daftar host dan mengaksesnya melalui SSH) dan perintah yang dijalankan di server. Itu masih sangat tergantung pada kebutuhan r2, tetapi memiliki sesuatu seperti prototipe API. Ini memungkinkan r2 untuk mengikuti langkah-langkah penyebarannya sendiri, yang membuat perubahan bergulir lebih mudah dan membebaskan aliran. Berikut ini adalah contoh dari perintah yang dijalankan pada server terpisah. Kode, sekali lagi, bukan kode yang tepat, tetapi secara keseluruhan urutan ini menjelaskan alur kerja r2 dengan baik:

 sudo /opt/reddit/deploy.py fetch reddit sudo /opt/reddit/deploy.py deploy reddit f3bbbd66a6 sudo /opt/reddit/deploy.py fetch-names sudo /opt/reddit/deploy.py restart all 

Yang perlu diperhatikan adalah fetch-names: instruksi ini unik untuk r2.

Autoscaling (2013)


Kemudian kami akhirnya memutuskan untuk beralih ke cloud dengan penskalaan otomatis (topik untuk seluruh pos terpisah). Ini memungkinkan kami untuk menyimpan sejumlah besar uang pada saat-saat ketika situs tidak dimuat dengan lalu lintas dan secara otomatis meningkatkan kapasitas untuk mengatasi setiap kenaikan tajam dalam permintaan.

Penyempurnaan sebelumnya, yang memuat daftar host dari DNS secara otomatis, menjadikan transisi ini sebagai hal yang biasa. Daftar host berubah lebih sering daripada sebelumnya, tetapi dari sudut pandang alat penyebaran, ini tidak memainkan peran apa pun. Perubahan, yang awalnya diperkenalkan sebagai peningkatan kualitas, telah menjadi salah satu komponen kunci yang diperlukan untuk menjalankan autoscaling.

Namun, autoscaling telah menyebabkan beberapa kasus batas yang menarik. Ada kebutuhan untuk mengontrol peluncuran. Apa yang terjadi jika server mulai benar selama penyebaran? Kami perlu memastikan bahwa setiap server baru yang sedang berjalan memeriksa ketersediaan kode baru dan mengambilnya, jika ada. Kami tidak bisa melupakan server yang offline pada saat penempatan. Alat ini diperlukan untuk menjadi lebih pintar dan belajar untuk menentukan bahwa server menjadi offline sebagai bagian dari prosedur, dan bukan sebagai akibat dari kesalahan yang terjadi selama penyebaran. Dalam kasus terakhir, dia harus memperingatkan semua rekan kerja yang terlibat dalam masalah tersebut.

Pada saat yang sama, kami, omong-omong, dan karena berbagai alasan, beralih dari uWSGI ke Gunicorn . Namun, dari sudut pandang topik posting ini, transisi seperti itu tidak mengarah pada perubahan signifikan.

Jadi itu bekerja sebentar.

Terlalu banyak server (2014)


Seiring waktu, jumlah server yang diperlukan untuk melayani lalu lintas puncak tumbuh. Ini mengarah pada fakta bahwa penyebaran membutuhkan lebih banyak waktu. Dalam skenario terburuk, satu penyebaran normal membutuhkan waktu sekitar satu jam - hasil yang buruk.

Kami menulis ulang alat sehingga dapat mendukung kerja paralel dengan host. Versi baru disebut rollingpin . Versi lama membutuhkan banyak waktu untuk menginisialisasi koneksi ssh dan menunggu penyelesaian semua perintah, sehingga paralelisasi dalam batas yang wajar memungkinkan kami untuk mempercepat penyebaran. Waktu penerapan kembali berkurang menjadi lima menit.

gambar

Untuk mengurangi dampak mem-boot ulang beberapa server secara bersamaan, komponen pencampuran alat ini menjadi lebih cerdas. Alih-alih membolak-balik daftar, ia mengurutkan pool server sehingga host dari satu pool terpisah sejauh mungkin .

Perubahan paling penting dalam alat baru adalah bahwa API antara alat penyebaran dan alat-alat di setiap server didefinisikan jauh lebih jelas dan terpisah dari kebutuhan r2. Awalnya, ini dilakukan karena keinginan untuk membuat kode lebih berorientasi sumber terbuka, tetapi segera pendekatan ini sangat berguna dengan cara lain. Berikut ini adalah contoh penerapan dengan pemilihan perintah API yang diluncurkan dari jarak jauh:

gambar

Terlalu banyak orang (2015)


Tiba-tiba, sesaat datang ketika, ternyata, banyak orang sudah mengerjakan r2. Itu keren, dan pada saat yang sama berarti akan ada lebih banyak penyebaran. Mematuhi aturan penyebaran satu per satu menjadi semakin sulit. Para pengembang harus sepakat satu sama lain tentang prosedur untuk mengeluarkan kode. Untuk mengoptimalkan situasi, kami menambahkan elemen lain ke chatbot yang mengoordinasikan antrian penyebaran. Insinyur meminta cadangan penempatan dan menerimanya, atau kode mereka "antri". Ini membantu merampingkan penyebaran, dan mereka yang ingin menyelesaikannya bisa dengan tenang menunggu giliran mereka.

Tambahan penting lainnya ketika tim tumbuh adalah untuk melacak penyebaran di satu tempat . Kami mengubah alat penyebaran untuk mengirim metrik ke Graphite. Ini membuatnya mudah untuk melacak korelasi antara penerapan dan perubahan metrik.

Banyak (dua) layanan (juga 2015)


Tiba-tiba saja, momen perilisan layanan kedua secara online datang. Itu adalah versi mobile dari situs web dengan tumpukan yang sama sekali berbeda, servernya sendiri dan proses pembuatannya. Ini adalah tes nyata pertama dari API alat penyebaran terpisah. Selain itu, kemampuan untuk mengerjakan semua tahap perakitan di "lokasi" yang berbeda untuk setiap proyek memungkinkannya untuk menahan beban dan mengatasi pemeliharaan dua layanan dalam sistem yang sama.

25 layanan (2016)


Selama tahun berikutnya, kami menyaksikan ekspansi tim yang cepat. Alih-alih dua layanan, dua lusin muncul, bukannya dua tim pengembangan, lima belas. Sebagian besar layanan dibangun baik di Baseplate , kerangka kerja backend kami, atau pada aplikasi klien, mirip dengan web seluler. Infrastruktur di belakang penyebaran adalah sama untuk semua orang. Segera, banyak layanan baru lainnya akan dirilis secara online, dan semua ini sebagian besar disebabkan oleh fleksibilitas dari rollingpin. Ini memungkinkan Anda untuk menyederhanakan peluncuran layanan baru menggunakan alat yang sudah dikenal banyak orang.

Airbag (2017)


Karena jumlah server di monolith meningkat, waktu penyebaran meningkat. Kami ingin secara signifikan meningkatkan jumlah penyebaran paralel, tetapi ini akan menyebabkan terlalu banyak reboot secara bersamaan dari server aplikasi. Hal-hal seperti itu, tentu saja, menyebabkan penurunan throughput dan hilangnya kemampuan untuk melayani permintaan yang masuk karena kelebihan beban server yang tersisa.

Proses Gunicorn utama menggunakan model yang sama dengan uWSGI, memuat ulang semua pekerja pada saat yang sama. Proses pekerja baru tidak dapat melayani permintaan sampai mereka penuh. Waktu peluncuran monolit kami berkisar antara 10 hingga 30 detik. Ini berarti bahwa selama periode waktu ini kami tidak akan dapat memproses permintaan sama sekali. Untuk menemukan jalan keluar dari situasi ini, kami mengganti proses gunicorn utama dengan manajer kerja Stripe Einhorn , sambil mempertahankan tumpukan HTTP Gunicorn dan wadah WSGI . Selama reboot, Einhorn menciptakan pekerja baru, menunggu sampai siap, menghilangkan satu pekerja lama, dan mengulangi prosesnya sampai pembaruan selesai. Ini menciptakan airbag dan memungkinkan kami menjaga bandwidth pada tingkat selama penyebaran.

Model baru menciptakan masalah lain. Seperti disebutkan sebelumnya, mengganti pekerja dengan yang baru dan selesai membutuhkan waktu hingga 30 detik. Ini berarti bahwa jika ada bug dalam kode, itu tidak muncul segera dan berhasil menyebar ke banyak server sebelum terdeteksi. Untuk mencegah hal ini, kami memperkenalkan mekanisme untuk memblokir transisi dari prosedur penyebaran ke server baru, yang berlaku sampai semua proses pekerja dimulai kembali. Itu dilaksanakan sederhana - dengan polling keadaan einhorn dan menunggu kesiapan semua pekerja baru. Untuk menjaga kecepatan di tingkat yang sama, kami memperluas jumlah server yang diproses secara paralel, yang sepenuhnya aman di bawah kondisi baru.

Mekanisme seperti itu memungkinkan kami untuk secara bersamaan menyebar ke sejumlah mesin yang lebih besar, dan waktu penyebaran, yang mencakup sekitar 800 server, dikurangi menjadi 7 menit, dengan mempertimbangkan jeda tambahan akun untuk memeriksa bug.

Melihat ke belakang


Infrastruktur penyebaran yang dijelaskan di sini adalah produk yang lahir dari perbaikan yang konsisten selama bertahun-tahun, dan bukan upaya yang terfokus satu kali. Gaung keputusan yang diambil satu kali dan tercapai pada tahap awal kompromi masih membuat diri mereka terasa dalam sistem saat ini, dan ini selalu terjadi pada semua tahap. Pendekatan evolusioner semacam itu memiliki pro dan kontra: ia memerlukan upaya minimal pada tahap apa pun, namun ada risiko cepat atau lambat untuk terhenti. Penting untuk mengikuti arah perkembangan Anda agar dapat mengirimkannya ke arah yang tepat waktu.

Masa depan


Infrastruktur Reddit harus siap untuk dukungan berkelanjutan dari tim saat ia tumbuh dan meluncurkan hal-hal baru. Tingkat pertumbuhan perusahaan lebih cepat dari sebelumnya, dan kami sedang mengerjakan proyek yang lebih menarik dan berskala besar dari semua yang kami lakukan sebelumnya. Masalah yang kita hadapi saat ini adalah dua hal: di satu sisi, itu adalah kebutuhan untuk meningkatkan otonomi pengembang, di sisi lain, untuk menjaga keamanan infrastruktur produksi dan meningkatkan airbag, yang memungkinkan pengembang untuk melakukan penyebaran dengan cepat dan percaya diri.

gambar

Source: https://habr.com/ru/post/id404577/


All Articles