تاپ فیکاپوف فیروزه ای

تاپ فیکاپوف فیروزه ای

همه چیز خوب است! 

نام من نیکیتا است، من سرپرست تیم تیم مهندسی Cian هستم. یکی از وظایف من در شرکت این است که تعداد حوادث مربوط به زیرساخت ها در تولید را به صفر برسانم.
آنچه در ادامه به آن پرداخته خواهد شد برای ما دردسرهای زیادی به همراه داشت و هدف این مقاله جلوگیری از تکرار اشتباهات ما توسط افراد دیگر و یا حداقل کاهش تاثیر آنهاست. 

مقدمه

مدت‌ها پیش، زمانی که Cian از یکپارچه‌ها تشکیل می‌شد و هنوز اشاره‌ای به ریزسرویس‌ها وجود نداشت، ما با بررسی 3-5 صفحه، در دسترس بودن یک منبع را اندازه‌گیری کردیم. 

آنها پاسخ می دهند - همه چیز خوب است، اگر برای مدت طولانی پاسخ ندهند - هشدار. اینکه چه مدت باید از کار بیکار می شدند تا آن را یک حادثه تلقی کنند، مردم در جلسات تصمیم می گرفتند. تیمی از مهندسان همیشه درگیر بررسی این حادثه بودند. وقتی تحقیقات تکمیل شد، آنها یک پس از مرگ نوشتند - نوعی گزارش از طریق ایمیل در قالب: چه اتفاقی افتاد، چقدر طول کشید، چه کاری در لحظه انجام دادیم، در آینده چه خواهیم کرد. 

صفحات اصلی سایت یا اینکه چطور می فهمیم که به ته رسیده ایم

 
برای اینکه به نحوی اولویت خطا را درک کنیم، مهم ترین صفحات سایت را برای عملکرد تجاری شناسایی کرده ایم. با استفاده از آنها، تعداد درخواست‌های موفق/ناموفق و زمان‌بندی را می‌شماریم. این روشی است که ما زمان کار را اندازه گیری می کنیم. 

فرض کنید متوجه شدیم که تعدادی بخش بسیار مهم در سایت وجود دارد که وظیفه سرویس اصلی - جستجو و ارسال تبلیغات را بر عهده دارند. اگر تعداد درخواست‌هایی که با شکست مواجه می‌شوند بیش از 1٪ باشد، این یک حادثه حیاتی است. اگر در طی 15 دقیقه در زمان پرایم تایم میزان خطا از 0,1٪ تجاوز کند، این نیز یک حادثه بحرانی در نظر گرفته می شود. این معیارها بیشتر حوادث را در بر می گیرد، بقیه موارد خارج از حوصله این مقاله است.

تاپ فیکاپوف فیروزه ای

بهترین حوادث Cian

بنابراین، ما قطعاً یاد گرفته ایم که این واقعیت را تعیین کنیم که یک حادثه اتفاق افتاده است. 

اکنون هر حادثه ای به تفصیل شرح داده شده و در حماسه جیرا منعکس شده است. به هر حال: برای این ما یک پروژه جداگانه به نام FAIL شروع کردیم - فقط می توان حماسه ها را در آن ایجاد کرد. 

اگر تمام شکست های چند سال گذشته را جمع آوری کنید، رهبران عبارتند از: 

  • حوادث مربوط به mssql.
  • حوادث ناشی از عوامل خارجی؛
  • خطاهای مدیریت

بیایید با جزئیات بیشتری به اشتباهات مدیران و همچنین برخی از شکست های جالب دیگر نگاه کنیم.

رتبه پنجم - "قرار دادن چیزها در DNS"

سه شنبه طوفانی بود. تصمیم گرفتیم نظم را در خوشه DNS بازیابی کنیم. 

من می خواستم سرورهای DNS داخلی را از bind به powerdns منتقل کنم و سرورهای کاملاً جداگانه ای را برای این کار اختصاص دهم ، جایی که چیزی به جز DNS وجود ندارد. 

ما یک سرور DNS را در هر مکان از DCهای خود قرار دادیم، و لحظه انتقال مناطق از bind به powerdns و تغییر زیرساخت به سرورهای جدید فرا رسید. 

در بحبوحه انتقال، از تمام سرورهایی که در کش محلی مشخص شده بودند، فقط یک سرور باقی ماند که در مرکز داده در سن پترزبورگ بود. این دی سی در ابتدا برای ما غیر بحرانی اعلام شد، اما ناگهان تبدیل به یک نقطه شکست شد.
در همین دوره جابجایی بود که کانال بین مسکو و سن پترزبورگ سقوط کرد. ما در واقع به مدت پنج دقیقه بدون DNS ماندیم و زمانی که میزبان مشکل را برطرف کرد، دوباره به حالت اولیه برگشتیم. 

نتیجه گیری:

اگر قبلاً هنگام آماده شدن برای کار از عوامل خارجی غافل می شدیم ، اکنون آنها نیز در لیست آنچه ما برای آن آماده می کنیم گنجانده شده اند. و اکنون ما تلاش می کنیم تا اطمینان حاصل کنیم که همه اجزاء n-2 رزرو شده اند و در طول کار می توانیم این سطح را به n-1 کاهش دهیم.

  • هنگام تهیه یک برنامه اقدام، نقاطی را که ممکن است سرویس با شکست مواجه شود را علامت گذاری کنید و از قبل به سناریویی فکر کنید که همه چیز از قبل "از بد به بدتر" رفته است.
  • سرورهای DNS داخلی را در مکان های جغرافیایی / مراکز داده / رک ها / سوئیچ ها / ورودی های مختلف توزیع کنید.
  • روی هر سرور، یک سرور DNS کش محلی نصب کنید که درخواست‌ها را به سرورهای اصلی DNS هدایت می‌کند و اگر در دسترس نباشد، از حافظه پنهان پاسخ می‌دهد. 

رتبه چهارم - "قرار دادن چیزها در Nginx"

یک روز خوب، تیم ما به این نتیجه رسید که «ما به اندازه کافی از این کار لذت بردیم» و روند بازسازی پیکربندی‌های nginx آغاز شد. هدف اصلی آوردن تنظیمات به یک ساختار بصری است. قبلاً همه چیز "تاریخی تثبیت شده" بود و هیچ منطقی نداشت. اکنون هر server_name به فایلی با همین نام منتقل شده است و تمام تنظیمات در پوشه ها توزیع شده است. به هر حال، پیکربندی شامل 253949 خط یا 7836520 کاراکتر است و تقریباً 7 مگابایت را اشغال می کند. سطح بالای ساختار: 

ساختار 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

خیلی بهتر شد، اما در فرآیند تغییر نام و توزیع تنظیمات، برخی از آنها پسوند اشتباهی داشتند و در دستورالعمل include *.conf قرار نمی گرفتند. در نتیجه برخی از هاست ها از دسترس خارج شدند و 301 را به صفحه اصلی بازگرداندند. با توجه به اینکه کد پاسخ 5xx/4xx نبود، بلافاصله متوجه این موضوع نشد، بلکه فقط در صبح بود. پس از آن شروع به نوشتن تست هایی برای بررسی اجزای زیرساخت کردیم.

نتیجه گیری: 

  • پیکربندی های خود را به درستی ساختار دهید (نه فقط nginx) و در مراحل اولیه پروژه به ساختار آن فکر کنید. به این ترتیب آنها را برای تیم قابل درک تر می کنید که به نوبه خود باعث کاهش TTM می شود.
  • برای برخی از اجزای زیرساخت تست بنویسید. به عنوان مثال: بررسی اینکه همه server_names وضعیت صحیح + بدنه پاسخ را می دهند. کافی است فقط چند اسکریپت در دسترس داشته باشید که عملکردهای اساسی مؤلفه را بررسی می کند، تا در ساعت 3 صبح به یاد بیاورید که چه چیز دیگری باید بررسی شود. 

مقام سوم - "ناگهان فضا در کاساندرا تمام شد"

داده‌ها به‌طور پیوسته رشد می‌کردند و همه چیز خوب بود تا لحظه‌ای که تعمیر کیس‌های بزرگ در خوشه Cassandra شروع به شکست کرد، زیرا فشرده‌سازی نمی‌توانست روی آنها کار کند. 

یک روز طوفانی، خوشه تقریباً تبدیل به کدو تنبل شد، یعنی:

  • حدود 20٪ از کل فضای باقی مانده در خوشه وجود دارد.
  • اضافه کردن کامل گره ها غیرممکن است، زیرا پاکسازی پس از افزودن یک گره به دلیل کمبود فضا روی پارتیشن ها انجام نمی شود.
  • بهره وری به تدریج کاهش می یابد زیرا تراکم کار نمی کند. 
  • خوشه در حالت اضطراری است.

تاپ فیکاپوف فیروزه ای

خروج - ما 5 گره دیگر را بدون پاکسازی اضافه کردیم، پس از آن شروع به حذف سیستماتیک آنها از خوشه و دوباره وارد کردن آنها کردیم، مانند گره های خالی که فضای خالی آنها تمام شده است. زمان بسیار بیشتری از آنچه ما می خواهیم صرف شد. خطر در دسترس نبودن جزئی یا کامل خوشه وجود داشت. 

نتیجه گیری:

  • در تمام سرورهای Cassandra، بیش از 60 درصد فضای هر پارتیشن نباید اشغال شود. 
  • آنها نباید بیش از 50٪ cpu بارگذاری شوند.
  • شما نباید برنامه ریزی ظرفیت را فراموش کنید و باید برای هر جزء بر اساس ویژگی های آن فکر کنید.
  • هر چه تعداد گره ها در خوشه بیشتر باشد، بهتر است. سرورهای حاوی مقدار کمی داده سریعتر بارگذاری می شوند و احیای چنین خوشه ای آسان تر است. 

مکان دوم - "داده ها از ذخیره سازی کلید-مقدار کنسول ناپدید شدند"

برای کشف خدمات، ما مانند بسیاری از کنسول استفاده می کنیم. اما ما همچنین از مقدار کلید آن برای طرح آبی-سبز یکپارچه استفاده می کنیم. اطلاعات مربوط به بالادست های فعال و غیرفعال را ذخیره می کند که در حین استقرار مکان آنها تغییر می کند. برای این منظور یک سرویس استقرار نوشته شد که با KV تعامل داشت. در نقطه ای، داده های KV ناپدید شدند. از حافظه بازیابی شد، اما با تعدادی خطا. در نتیجه، در حین آپلود، بار روی upstream ها به طور ناموزون توزیع شد و به دلیل بارگذاری بیش از حد backend ها روی CPU، خطاهای 502 زیادی دریافت کردیم. در نتیجه، ما از کنسول KV به postgres منتقل شدیم، جایی که دیگر حذف آنها چندان آسان نیست.  

نتیجه گیری:

  • خدمات بدون مجوز نباید حاوی داده های حیاتی برای عملکرد سایت باشد. به عنوان مثال، اگر در ES مجوز ندارید، بهتر است دسترسی در سطح شبکه را از هر جایی که نیاز نیست رد کنید، فقط موارد ضروری را بگذارید و همچنین action.destructive_requires_name: true را تنظیم کنید.
  • مکانیزم پشتیبان گیری و بازیابی خود را از قبل تمرین کنید. به عنوان مثال، از قبل یک اسکریپت بسازید (مثلاً در پایتون) که بتواند پشتیبان گیری و بازیابی کند.

مقام اول - "کاپیتان آنابیویو" 

در برخی موارد، در مواردی که بیش از 10 سرور در backend وجود داشت، متوجه توزیع نابرابر بار در upstreams nginx شدیم. با توجه به اینکه دور رابین به ترتیب درخواست ها را از اول به آخرین بالادست ارسال می کرد و هر بارگذاری مجدد nginx شروع می شد، اولین آپ استریم ها همیشه درخواست های بیشتری نسبت به بقیه دریافت می کردند در نتیجه کندتر کار می کردند و کل سایت آسیب می دید. با افزایش حجم ترافیک، این امر به طور فزاینده ای قابل توجه شد. به‌روزرسانی ساده nginx برای فعال کردن تصادفی کار نمی‌کند - ما باید تعدادی از کدهای lua را که در نسخه 1 (در آن لحظه) انجام نشده بود، دوباره انجام دهیم. ما مجبور شدیم nginx 1.15 خود را وصله کنیم و پشتیبانی تصادفی را در آن معرفی کنیم. این مشکل را حل کرد. این اشکال برنده رده "کاپیتان غیر آشکار" است.

نتیجه گیری:

کشف این باگ بسیار جالب و هیجان انگیز بود). 

  • نظارت خود را طوری سازماندهی کنید که به شما کمک کند چنین نوساناتی را سریع پیدا کنید. به عنوان مثال، می توانید از ELK برای نظارت بر rps در هر پشتیبان هر بالادست استفاده کنید، زمان پاسخ آنها را از نقطه نظر nginx نظارت کنید. در این مورد، این به ما کمک کرد تا مشکل را شناسایی کنیم. 

در نتیجه، با رویکرد دقیق‌تری نسبت به کاری که انجام می‌دادید، می‌توان از بسیاری از شکست‌ها جلوگیری کرد. ما همیشه باید قانون مورفی را به خاطر بسپاریم: هر چیزی که ممکن است اشتباه شود، اشتباه خواهد شد، و بر اساس آن کامپوننت ها را بسازید. 

منبع: www.habr.com

اضافه کردن نظر