Cyan fakapov teratas

Cyan fakapov teratas

Baik untuk semua! 

Nama saya Nikita, saya ketua tim dari tim teknik Cian. Salah satu tanggung jawab saya di perusahaan adalah mengurangi jumlah insiden terkait infrastruktur produksi menjadi nol.
Apa yang akan dibahas di bawah ini sangat menyusahkan kami, dan tujuan artikel ini adalah untuk mencegah orang lain mengulangi kesalahan kami atau setidaknya meminimalkan dampaknya. 

Preamble

Dahulu kala, ketika Cian terdiri dari monolit, dan belum ada petunjuk tentang layanan mikro, kami mengukur ketersediaan sumber daya dengan memeriksa 3-5 halaman. 

Mereka menjawab - semuanya baik-baik saja, jika mereka tidak menjawab untuk waktu yang lama - waspada. Berapa lama mereka harus tidak bekerja agar dianggap sebagai insiden ditentukan oleh orang-orang dalam rapat. Sebuah tim insinyur selalu terlibat dalam penyelidikan insiden tersebut. Ketika penyelidikan selesai, mereka menulis postmortem - semacam laporan melalui email dengan format: apa yang terjadi, berapa lama, apa yang kami lakukan saat ini, apa yang akan kami lakukan di masa depan. 

Halaman utama situs atau bagaimana kami memahami bahwa kami telah mencapai bagian bawah

 
Untuk memahami prioritas kesalahan, kami telah mengidentifikasi halaman situs yang paling penting untuk fungsionalitas bisnis. Dengan menggunakannya, kami menghitung jumlah permintaan dan batas waktu yang berhasil/tidak berhasil. Inilah cara kami mengukur waktu aktif. 

Katakanlah kita mengetahui bahwa ada sejumlah bagian situs yang sangat penting yang bertanggung jawab atas layanan utama - mencari dan mengirimkan iklan. Jika jumlah permintaan yang gagal melebihi 1%, ini merupakan insiden kritis. Jika dalam waktu 15 menit pada prime time tingkat kesalahan melebihi 0,1%, maka ini juga dianggap sebagai insiden kritis. Kriteria ini mencakup sebagian besar insiden; sisanya berada di luar cakupan artikel ini.

Cyan fakapov teratas

Insiden terbaik teratas Cian

Jadi, kita sudah pasti belajar menentukan fakta bahwa suatu peristiwa terjadi. 

Kini setiap kejadian dijelaskan secara detail dan tercermin dalam epos Jira. Omong-omong: untuk ini kami memulai proyek terpisah, yang disebut GAGAL - hanya epos yang dapat dibuat di dalamnya. 

Jika Anda mengumpulkan semua kegagalan selama beberapa tahun terakhir, pemimpinnya adalah: 

  • insiden terkait mssql;
  • kejadian yang disebabkan oleh faktor eksternal;
  • kesalahan admin.

Mari kita lihat lebih detail kesalahan administrator, serta beberapa kegagalan menarik lainnya.

Tempat kelima - “Menertibkan DNS”

Saat itu hari Selasa yang penuh badai. Kami memutuskan untuk memulihkan ketertiban di cluster DNS. 

Saya ingin mentransfer server DNS internal dari bind ke powerdns, mengalokasikan server yang sepenuhnya terpisah untuk ini, di mana tidak ada apa pun selain DNS. 

Kami menempatkan satu server DNS di setiap lokasi DC kami, dan saatnya tiba untuk memindahkan zona dari bind ke powerdns dan mengalihkan infrastruktur ke server baru. 

Di tengah perpindahan, dari semua server yang ditentukan dalam ikatan cache lokal di semua server, hanya satu yang tersisa, yaitu di pusat data di St. Petersburg. DC ini awalnya dinyatakan tidak kritis bagi kami, namun tiba-tiba menjadi satu titik kegagalan.
Selama periode relokasi inilah kanal antara Moskow dan Sankt Peterburg runtuh. Kami sebenarnya dibiarkan tanpa DNS selama lima menit dan bangkit kembali ketika hoster memperbaiki masalahnya. 

Kesimpulan:

Jika sebelumnya kita mengabaikan faktor eksternal dalam persiapan kerja, kini faktor tersebut juga masuk dalam daftar apa yang sedang kita persiapkan. Dan sekarang kami berusaha untuk memastikan bahwa semua komponen dicadangkan n-2, dan selama pekerjaan kami dapat menurunkan level ini ke n-1.

  • Saat menyusun rencana tindakan, tandai titik-titik di mana layanan mungkin gagal, dan pikirkan terlebih dahulu skenario di mana segala sesuatunya berubah “dari buruk menjadi lebih buruk”.
  • Distribusikan server DNS internal di berbagai geolokasi/pusat data/rak/saklar/input.
  • Di setiap server, instal server DNS caching lokal, yang mengalihkan permintaan ke server DNS utama, dan jika tidak tersedia, server akan merespons dari cache. 

Tempat keempat - “Menata segala sesuatunya di Nginx”

Suatu hari, tim kami memutuskan bahwa “kami sudah muak dengan hal ini,” dan proses pemfaktoran ulang konfigurasi nginx pun dimulai. Tujuan utamanya adalah membawa konfigurasi ke struktur yang intuitif. Sebelumnya, segala sesuatu “ditetapkan secara historis” dan tidak mengandung logika apa pun. Sekarang setiap nama_server telah dipindahkan ke file dengan nama yang sama dan semua konfigurasi telah didistribusikan ke dalam folder. Omong-omong, konfigurasinya berisi 253949 baris atau 7836520 karakter dan memakan hampir 7 megabita. Struktur tingkat atas: 

Struktur Nginx

├── access
│   ├── allow.list
...
│   └── whitelist.conf
├── geobase
│   ├── exclude.conf
...
│   └── geo_ip_to_region_id.conf
├── geodb
│   ├── GeoIP.dat
│   ├── GeoIP2-Country.mmdb
│   └── GeoLiteCity.dat
├── inc
│   ├── error.inc
...
│   └── proxy.inc
├── lists.d
│   ├── bot.conf
...
│   ├── dynamic
│   └── geo.conf
├── lua
│   ├── cookie.lua
│   ├── log
│   │   └── log.lua
│   ├── logics
│   │   ├── include.lua
│   │   ├── ...
│   │   └── utils.lua
│   └── prom
│       ├── stats.lua
│       └── stats_prometheus.lua
├── map.d
│   ├── access.conf
│   ├── .. 
│   └── zones.conf
├── nginx.conf
├── robots.txt
├── server.d
│   ├── cian.ru
│   │   ├── cian.ru.conf
│   │   ├── ...
│   │   └── my.cian.ru.conf
├── service.d
│   ├── ...
│   └── status.conf
└── upstream.d
    ├── cian-mcs.conf
    ├── ...
    └── wafserver.conf

Ini menjadi jauh lebih baik, tetapi dalam proses mengganti nama dan mendistribusikan konfigurasi, beberapa di antaranya memiliki ekstensi yang salah dan tidak disertakan dalam direktif include *.conf. Akibatnya, beberapa host menjadi tidak tersedia dan mengembalikan 301 ke halaman utama. Karena kode responnya bukan 5xx/4xx, hal ini tidak langsung diketahui, melainkan hanya di pagi hari. Setelah itu, kami mulai menulis tes untuk memeriksa komponen infrastruktur.

Kesimpulan: 

  • Susun konfigurasi Anda dengan benar (bukan hanya nginx) dan pikirkan strukturnya pada tahap awal proyek. Dengan cara ini Anda akan membuatnya lebih mudah dipahami oleh tim, yang pada gilirannya akan mengurangi TTM.
  • Tes tulis untuk beberapa komponen infrastruktur. Misalnya: memeriksa apakah semua nama_server kunci memberikan status + isi respons yang benar. Cukup memiliki beberapa skrip yang memeriksa fungsi dasar komponen, agar tidak panik mengingat pada jam 3 pagi apa lagi yang perlu diperiksa. 

Tempat ketiga - “Tiba-tiba kehabisan ruang di Cassandra”

Data terus bertambah, dan semuanya baik-baik saja hingga perbaikan ruang kasus besar mulai gagal di cluster Cassandra, karena pemadatan tidak dapat dilakukan. 

Pada suatu hari terjadi badai, tandan tersebut hampir berubah menjadi labu, yaitu:

  • ada sekitar 20% dari total ruang yang tersisa di cluster;
  • Tidak mungkin untuk menambahkan node sepenuhnya, karena pembersihan tidak dilakukan setelah menambahkan node karena kurangnya ruang pada partisi;
  • produktivitas berangsur-angsur turun karena pemadatan tidak berhasil; 
  • Cluster berada dalam mode darurat.

Cyan fakapov teratas

Keluar - kami menambahkan 5 node lagi tanpa pembersihan, setelah itu kami mulai menghapusnya secara sistematis dari cluster dan memasukkannya kembali, seperti node kosong yang kehabisan ruang. Lebih banyak waktu yang dihabiskan daripada yang kita inginkan. Ada risiko tidak tersedianya sebagian atau seluruh cluster. 

Kesimpulan:

  • Di semua server cassandra, tidak lebih dari 60% ruang di setiap partisi harus ditempati. 
  • Mereka harus dimuat pada CPU tidak lebih dari 50%.
  • Anda tidak boleh melupakan perencanaan kapasitas dan perlu memikirkannya secara matang untuk setiap komponen, berdasarkan spesifikasinya.
  • Semakin banyak node dalam cluster, semakin baik. Server yang berisi sejumlah kecil data akan kelebihan beban lebih cepat, dan cluster seperti itu lebih mudah untuk dihidupkan kembali. 

Tempat kedua - “Data hilang dari penyimpanan nilai kunci konsul”

Untuk penemuan layanan, kami, seperti kebanyakan orang, menggunakan konsul. Namun kami juga menggunakan nilai kuncinya untuk tata letak monolit berwarna biru-hijau. Ini menyimpan informasi tentang upstream aktif dan tidak aktif, yang berpindah tempat selama penerapan. Untuk tujuan ini, layanan penerapan ditulis yang berinteraksi dengan KV. Suatu saat, data dari KV menghilang. Dipulihkan dari memori, tetapi dengan sejumlah kesalahan. Akibatnya, selama pengunggahan, beban di bagian upstream tidak terdistribusi secara merata, dan kami menerima banyak kesalahan 502 karena backend kelebihan beban pada CPU. Akibatnya, kami berpindah dari konsul KV ke postgres, yang tidak lagi mudah untuk menghapusnya.  

Kesimpulan:

  • Layanan tanpa otorisasi apa pun tidak boleh berisi data penting untuk pengoperasian situs. Misalnya, jika Anda tidak memiliki otorisasi di ES, akan lebih baik untuk menolak akses di tingkat jaringan dari mana pun yang tidak diperlukan, biarkan hanya yang diperlukan, dan setel juga action.destructive_requires_name: true.
  • Latih mekanisme pencadangan dan pemulihan Anda terlebih dahulu. Misalnya, buatlah skrip terlebih dahulu (misalnya dengan Python) yang dapat mem-backup dan memulihkan.

Tempat pertama - "Kapten Tidak Jelas" 

Pada titik tertentu, kami melihat distribusi beban yang tidak merata pada upstream nginx jika terdapat 10+ server di backend. Karena fakta bahwa round-robin mengirim permintaan dari upstream pertama ke upstream terakhir secara berurutan, dan setiap pemuatan ulang nginx dimulai, upstream pertama selalu menerima lebih banyak permintaan daripada yang lain. Akibatnya, mereka bekerja lebih lambat dan seluruh situs menderita. Hal ini menjadi semakin nyata seiring dengan meningkatnya jumlah lalu lintas. Memperbarui nginx untuk mengaktifkan random saja tidak berhasil - kita perlu mengulang sekumpulan kode lua yang tidak digunakan pada versi 1 (pada saat itu). Kami harus menambal nginx 1.15 kami, memperkenalkan dukungan acak ke dalamnya. Ini menyelesaikan masalahnya. Bug ini memenangkan kategori “Captain Non-Obviousness”.

Kesimpulan:

Sangat menarik dan mengasyikkan untuk menjelajahi bug ini). 

  • Atur pemantauan Anda sehingga membantu Anda menemukan fluktuasi tersebut dengan cepat. Misalnya, Anda dapat menggunakan ELK untuk memantau rps di setiap backend setiap upstream, memantau waktu responsnya dari sudut pandang nginx. Dalam hal ini, ini membantu kami mengidentifikasi masalahnya. 

Akibatnya, sebagian besar kegagalan sebenarnya bisa dihindari dengan pendekatan yang lebih cermat terhadap apa yang Anda lakukan. Kita harus selalu mengingat hukum Murphy: Apa pun yang salah akan menjadi salah, dan membangun komponen berdasarkan itu. 

Sumber: www.habr.com

Tambah komentar