فیل اوور کلسٹر PostgreSQL + Patroni۔ عمل درآمد کا تجربہ

مضمون میں میں آپ کو بتاؤں گا کہ ہم نے PostgreSQL فالٹ ٹولرنس کے مسئلے سے کیسے رجوع کیا، یہ ہمارے لیے کیوں اہم ہو گیا اور آخر میں کیا ہوا۔

ہمارے پاس بہت زیادہ بھری ہوئی سروس ہے: دنیا بھر میں 2,5 ملین صارفین، ہر روز 50K+ فعال صارفین۔ سرورز آئرلینڈ کے ایک علاقے میں ایمازون میں واقع ہیں: 100+ مختلف سرورز مسلسل کام کر رہے ہیں، جن میں سے تقریباً 50 ڈیٹا بیس کے ساتھ ہیں۔

پورا بیک اینڈ ایک بڑی یک سنگی سٹیٹفل جاوا ایپلی کیشن ہے جو کلائنٹ کے ساتھ مستقل ویب ساکٹ کنکشن رکھتا ہے۔ جب متعدد صارفین ایک ہی وقت میں ایک ہی بورڈ پر کام کرتے ہیں، تو وہ سبھی تبدیلیاں حقیقی وقت میں دیکھتے ہیں، کیونکہ ہم ہر تبدیلی کو ڈیٹا بیس میں لکھتے ہیں۔ ہمارے ڈیٹا بیس میں فی سیکنڈ تقریباً 10K درخواستیں ہیں۔ Redis میں سب سے زیادہ لوڈ پر، ہم فی سیکنڈ 80-100K درخواستیں لکھتے ہیں۔
فیل اوور کلسٹر PostgreSQL + Patroni۔ عمل درآمد کا تجربہ

ہم نے Redis سے PostgreSQL میں کیوں تبدیل کیا؟

ابتدائی طور پر، ہماری سروس Redis کے ساتھ کام کرتی تھی، ایک کلیدی قدر کی دکان جو سرور کی RAM میں تمام ڈیٹا محفوظ کرتی ہے۔

Redis کے فوائد:

  1. اعلی ردعمل کی رفتار، کیونکہ سب کچھ میموری میں محفوظ ہے؛
  2. بیک اپ اور نقل میں آسانی۔

ہمارے لیے Redis کے نقصانات:

  1. کوئی حقیقی لین دین نہیں ہے۔ ہم نے انہیں اپنی درخواست کی سطح پر نقل کرنے کی کوشش کی۔ بدقسمتی سے، یہ ہمیشہ اچھا کام نہیں کرتا تھا اور بہت پیچیدہ کوڈ لکھنے کی ضرورت تھی۔
  2. ڈیٹا کی مقدار میموری کی مقدار سے محدود ہے۔ جیسے جیسے ڈیٹا کی مقدار بڑھے گی، میموری بڑھے گی، اور آخر میں، ہم منتخب مثال کی خصوصیات کو دیکھیں گے، جو AWS میں مثال کی قسم کو تبدیل کرنے کے لیے ہماری سروس کو روکنے کی ضرورت ہے۔
  3. کم تاخیر کی سطح کو مسلسل برقرار رکھنا ضروری ہے، کیونکہ۔ ہمارے پاس درخواستوں کی ایک بہت بڑی تعداد ہے۔ ہمارے لیے تاخیر کی بہترین سطح 17-20 ms ہے۔ 30-40 ms کی سطح پر، ہمیں ہماری درخواست اور سروس کی تنزلی کی درخواستوں کے طویل جوابات ملتے ہیں۔ بدقسمتی سے، یہ ہمارے ساتھ ستمبر 2018 میں ہوا، جب کسی وجہ سے Redis کے ساتھ ہونے والے واقعات میں سے ایک کو معمول سے 2 گنا زیادہ تاخیر ہوئی۔ اس مسئلے کو حل کرنے کے لیے، ہم نے غیر طے شدہ دیکھ بھال کے لیے مڈ ڈے کی سروس بند کر دی اور مسئلہ Redis مثال کو تبدیل کر دیا۔
  4. کوڈ میں معمولی غلطیوں کے باوجود ڈیٹا کی عدم مطابقت حاصل کرنا آسان ہے اور پھر اس ڈیٹا کو درست کرنے کے لیے کوڈ لکھنے میں کافی وقت صرف کرنا پڑتا ہے۔

ہم نے نقصانات کو مدنظر رکھا اور محسوس کیا کہ ہمیں معمول کے لین دین اور تاخیر پر کم انحصار کے ساتھ، زیادہ آسان چیز کی طرف جانے کی ضرورت ہے۔ تحقیق کی، بہت سے اختیارات کا تجزیہ کیا اور PostgreSQL کا انتخاب کیا۔

ہم پہلے ہی 1,5 سالوں سے ایک نئے ڈیٹا بیس میں منتقل ہو رہے ہیں اور ڈیٹا کا صرف ایک چھوٹا سا حصہ منتقل کیا ہے، لہذا اب ہم Redis اور PostgreSQL کے ساتھ بیک وقت کام کر رہے ہیں۔ ڈیٹا بیس کے درمیان ڈیٹا کو منتقل کرنے اور تبدیل کرنے کے مراحل کے بارے میں مزید معلومات میں لکھا گیا ہے۔ میرے ساتھی کا مضمون.

جب ہم نے پہلی بار حرکت کرنا شروع کی تو ہماری درخواست نے براہ راست ڈیٹا بیس کے ساتھ کام کیا اور ماسٹر Redis اور PostgreSQL تک رسائی حاصل کی۔ PostgreSQL کلسٹر ایک ماسٹر اور غیر مطابقت پذیر نقل کے ساتھ ایک نقل پر مشتمل ہے۔ ڈیٹا بیس اسکیم اس طرح نظر آتی تھی:
فیل اوور کلسٹر PostgreSQL + Patroni۔ عمل درآمد کا تجربہ

PgBouncer کو نافذ کرنا

جب ہم آگے بڑھ رہے تھے، پروڈکٹ بھی ترقی کر رہا تھا: صارفین کی تعداد اور PostgreSQL کے ساتھ کام کرنے والے سرورز کی تعداد میں اضافہ ہوا، اور ہمارے پاس رابطوں کی کمی ہونے لگی۔ PostgreSQL ہر کنکشن کے لیے ایک الگ عمل تخلیق کرتا ہے اور وسائل استعمال کرتا ہے۔ آپ کنکشنز کی تعداد کو ایک خاص نقطہ تک بڑھا سکتے ہیں، بصورت دیگر ڈیٹا بیس کی سب سے زیادہ کارکردگی حاصل کرنے کا موقع ہے۔ ایسی صورت حال میں مثالی آپشن یہ ہوگا کہ کنکشن مینیجر کا انتخاب کیا جائے جو بیس کے سامنے کھڑا ہو۔

ہمارے پاس کنکشن مینیجر کے لیے دو اختیارات تھے: Pgpool اور PgBouncer۔ لیکن پہلا ڈیٹا بیس کے ساتھ کام کرنے کے لین دین کے موڈ کو سپورٹ نہیں کرتا، اس لیے ہم نے PgBouncer کا انتخاب کیا۔

ہم نے کام کی درج ذیل اسکیم ترتیب دی ہے: ہماری ایپلیکیشن ایک PgBouncer تک رسائی حاصل کرتی ہے، جس کے پیچھے PostgreSQL ماسٹرز ہیں، اور ہر ماسٹر کے پیچھے غیر مطابقت پذیر نقل کے ساتھ ایک نقل ہے۔
فیل اوور کلسٹر PostgreSQL + Patroni۔ عمل درآمد کا تجربہ

اسی وقت، ہم پوسٹگری ایس کیو ایل میں ڈیٹا کی پوری مقدار کو محفوظ نہیں کر سکتے تھے اور ڈیٹا بیس کے ساتھ کام کرنے کی رفتار ہمارے لیے اہم تھی، اس لیے ہم نے پوسٹگری ایس کیو ایل کو ایپلی کیشن کی سطح پر شارڈنگ کرنا شروع کر دیا۔ اوپر بیان کردہ اسکیم اس کے لیے نسبتاً آسان ہے: ایک نیا PostgreSQL شارڈ شامل کرتے وقت، PgBouncer کنفیگریشن کو اپ ڈیٹ کرنا کافی ہے اور ایپلیکیشن فوری طور پر نئے شارڈ کے ساتھ کام کر سکتی ہے۔

پی جی باؤنسر فیل اوور

اس اسکیم نے اس لمحے تک کام کیا جب صرف PgBouncer مثال کی موت ہوگئی۔ ہم AWS میں ہیں، جہاں تمام واقعات ہارڈ ویئر پر چل رہے ہیں جو وقتاً فوقتاً مر جاتے ہیں۔ ایسے معاملات میں، مثال آسانی سے نئے ہارڈ ویئر پر چلی جاتی ہے اور دوبارہ کام کرتی ہے۔ یہ PgBouncer کے ساتھ ہوا، لیکن یہ دستیاب نہیں ہو گیا۔ اس زوال کا نتیجہ 25 منٹ تک ہماری سروس کی عدم دستیابی تھی۔ AWS ایسے حالات کے لیے صارف کی طرف سے فالتو پن کا استعمال کرنے کی سفارش کرتا ہے، جو اس وقت ہمارے ملک میں نافذ نہیں کیا گیا تھا۔

اس کے بعد، ہم نے سنجیدگی سے PgBouncer اور PostgreSQL کلسٹرز کی فالٹ ٹولرنس کے بارے میں سوچا، کیونکہ ہمارے AWS اکاؤنٹ میں کسی بھی مثال کے ساتھ ایسی ہی صورتحال ہو سکتی ہے۔

ہم نے PgBouncer فالٹ ٹولرنس اسکیم اس طرح بنائی ہے: تمام ایپلیکیشن سرورز نیٹ ورک لوڈ بیلنسر تک رسائی حاصل کرتے ہیں، جس کے پیچھے دو PgBouncers ہوتے ہیں۔ ہر PgBouncer ہر شارڈ کے ایک ہی PostgreSQL ماسٹر کو دیکھتا ہے۔ اگر AWS مثال کا حادثہ دوبارہ ہوتا ہے، تو تمام ٹریفک کو دوسرے PgBouncer کے ذریعے ری ڈائریکٹ کیا جاتا ہے۔ نیٹ ورک لوڈ بیلنسر فیل اوور AWS کے ذریعے فراہم کیا گیا ہے۔

یہ اسکیم نئے PgBouncer سرورز کو شامل کرنا آسان بناتی ہے۔
فیل اوور کلسٹر PostgreSQL + Patroni۔ عمل درآمد کا تجربہ

PostgreSQL فیل اوور کلسٹر بنائیں

اس مسئلے کو حل کرتے وقت، ہم نے مختلف اختیارات پر غور کیا: خود تحریر شدہ فیل اوور، repmgr، AWS RDS، Patroni۔

خود لکھے ہوئے اسکرپٹ

وہ ماسٹر کے کام کی نگرانی کر سکتے ہیں اور، اگر یہ ناکام ہو جاتا ہے، تو نقل کو ماسٹر کے لیے فروغ دے سکتے ہیں اور PgBouncer کی ترتیب کو اپ ڈیٹ کر سکتے ہیں۔

اس نقطہ نظر کے فوائد زیادہ سے زیادہ سادگی ہیں، کیونکہ آپ خود اسکرپٹ لکھتے ہیں اور بخوبی سمجھتے ہیں کہ وہ کیسے کام کرتے ہیں۔

Cons:

  • ہوسکتا ہے کہ ماسٹر کی موت نہ ہوئی ہو، اس کے بجائے نیٹ ورک کی ناکامی واقع ہوئی ہو۔ فیل اوور، اس سے ناواقف، نقل کو ماسٹر کو فروغ دے گا، جبکہ پرانا ماسٹر کام کرتا رہے گا۔ نتیجے کے طور پر، ہمیں ماسٹر کے کردار میں دو سرور ملیں گے اور ہم نہیں جان پائیں گے کہ ان میں سے کس کے پاس تازہ ترین ڈیٹا ہے۔ اس صورتحال کو اسپلٹ برین بھی کہا جاتا ہے۔
  • ہم بغیر جواب کے رہ گئے۔ ہماری ترتیب میں، ماسٹر اور ایک نقل، سوئچ کرنے کے بعد، نقل ماسٹر کی طرف بڑھ جاتی ہے اور ہمارے پاس اب نقل نہیں ہے، لہذا ہمیں دستی طور پر ایک نئی نقل شامل کرنا ہوگی۔
  • ہمیں فیل اوور آپریشن کی اضافی نگرانی کی ضرورت ہے، جبکہ ہمارے پاس 12 PostgreSQL شارڈز ہیں، جس کا مطلب ہے کہ ہمیں 12 کلسٹرز کی نگرانی کرنی ہے۔ شارڈز کی تعداد میں اضافے کے ساتھ، آپ کو فیل اوور کو اپ ڈیٹ کرنا بھی یاد رکھنا چاہیے۔

خود سے لکھا ہوا فیل اوور بہت پیچیدہ لگتا ہے اور اسے غیر معمولی مدد کی ضرورت ہوتی ہے۔ ایک واحد PostgreSQL کلسٹر کے ساتھ، یہ سب سے آسان آپشن ہوگا، لیکن یہ پیمانہ نہیں ہے، اس لیے یہ ہمارے لیے موزوں نہیں ہے۔

Repmgr

Replication Manager for PostgreSQL کلسٹرز، جو PostgreSQL کلسٹر کے آپریشن کا انتظام کر سکتا ہے۔ ایک ہی وقت میں، اس میں باکس سے باہر کوئی خودکار فیل اوور نہیں ہے، لہذا کام کے لیے آپ کو تیار شدہ حل کے اوپر اپنا "ریپر" لکھنا ہوگا۔ لہذا ہر چیز خود لکھی ہوئی اسکرپٹ کے مقابلے میں اور بھی پیچیدہ ہوسکتی ہے، لہذا ہم نے Repmgr کو بھی آزمایا نہیں۔

AWS RDS

ہماری ضرورت کی ہر چیز کی حمایت کرتا ہے، بیک اپ بنانے کا طریقہ جانتا ہے اور کنکشن کا ایک تالاب برقرار رکھتا ہے۔ اس میں خودکار سوئچنگ ہے: جب ماسٹر کی موت ہو جاتی ہے، تو نقل نیا ماسٹر بن جاتا ہے، اور AWS dns ریکارڈ کو نئے ماسٹر میں تبدیل کر دیتا ہے، جبکہ نقلیں مختلف AZs میں موجود ہو سکتی ہیں۔

نقصانات میں ٹھیک ایڈجسٹمنٹ کی کمی شامل ہے۔ ٹھیک ٹیوننگ کی مثال کے طور پر: ہماری مثالوں میں tcp کنکشن کے لیے پابندیاں ہیں، جو بدقسمتی سے RDS میں نہیں کی جا سکتی ہیں:

net.ipv4.tcp_keepalive_time=10
net.ipv4.tcp_keepalive_intvl=1
net.ipv4.tcp_keepalive_probes=5
net.ipv4.tcp_retries2=3

اس کے علاوہ، AWS RDS معمول کی مثال کی قیمت سے تقریباً دوگنا مہنگا ہے، جو اس حل کو ترک کرنے کی بنیادی وجہ تھی۔

پیٹرونی

یہ گتھب پر اچھی دستاویزات، خودکار فیل اوور اور سورس کوڈ کے ساتھ PostgreSQL کے انتظام کے لیے ایک ازگر کا ٹیمپلیٹ ہے۔

پیٹرونی کے فوائد:

  • ہر ترتیب کے پیرامیٹر کو بیان کیا گیا ہے، یہ واضح ہے کہ یہ کیسے کام کرتا ہے۔
  • خودکار فیل اوور باکس سے باہر کام کرتا ہے۔
  • python میں لکھا گیا، اور چونکہ ہم خود python میں بہت کچھ لکھتے ہیں، اس لیے ہمارے لیے مسائل سے نمٹنا آسان ہو جائے گا اور، شاید، پروجیکٹ کی ترقی میں بھی مدد ملے گی۔
  • PostgreSQL کو مکمل طور پر منظم کرتا ہے، آپ کو کلسٹر کے تمام نوڈس پر کنفیگریشن کو ایک ساتھ تبدیل کرنے کی اجازت دیتا ہے، اور اگر نئی کنفیگریشن کو لاگو کرنے کے لیے کلسٹر کو دوبارہ شروع کرنے کی ضرورت ہے، تو یہ Patroni کا استعمال کرتے ہوئے دوبارہ کیا جا سکتا ہے۔

Cons:

  • دستاویزات سے یہ واضح نہیں ہے کہ PgBouncer کے ساتھ صحیح طریقے سے کیسے کام کیا جائے۔ اگرچہ اسے مائنس کہنا مشکل ہے، کیونکہ Patroni کا کام PostgreSQL کا انتظام کرنا ہے، اور Patroni سے کنکشن کیسے چلے گا یہ ہمارا مسئلہ ہے۔
  • بڑی جلدوں پر پیٹرونی کے نفاذ کی چند مثالیں ہیں، جب کہ شروع سے لاگو کرنے کی بہت سی مثالیں موجود ہیں۔

نتیجے کے طور پر، ہم نے فیل اوور کلسٹر بنانے کے لیے Patroni کا انتخاب کیا۔

پیٹرونی عمل درآمد کا عمل

Patroni سے پہلے، ہمارے پاس ایک ماسٹر کی ترتیب میں 12 PostgreSQL شارڈز تھے اور ایک ریپلیکا غیر مطابقت پذیر نقل کے ساتھ۔ ایپلیکیشن سرورز نے نیٹ ورک لوڈ بیلنسر کے ذریعے ڈیٹا بیس تک رسائی حاصل کی، جس کے پیچھے PgBouncer کے ساتھ دو مثالیں تھیں، اور ان کے پیچھے تمام PostgreSQL سرورز تھے۔
فیل اوور کلسٹر PostgreSQL + Patroni۔ عمل درآمد کا تجربہ

Patroni کو لاگو کرنے کے لیے، ہمیں تقسیم شدہ اسٹوریج کلسٹر کنفیگریشن کو منتخب کرنے کی ضرورت ہے۔ Patroni تقسیم شدہ کنفیگریشن اسٹوریج سسٹمز جیسے etcd، Zookeeper، Consul کے ساتھ کام کرتا ہے۔ ہمارے پاس مارکیٹ میں صرف ایک مکمل قونصل کلسٹر ہے، جو Vault کے ساتھ مل کر کام کرتا ہے اور ہم اسے مزید استعمال نہیں کرتے ہیں۔ اپنے مطلوبہ مقصد کے لیے قونصل کا استعمال شروع کرنے کی ایک بڑی وجہ۔

پیٹرونی قونصل کے ساتھ کیسے کام کرتا ہے۔

ہمارے پاس ایک قونصل کلسٹر ہے، جو تین نوڈس پر مشتمل ہے، اور ایک پیٹرونی کلسٹر، جس میں ایک لیڈر اور ایک نقل ہوتا ہے (پیٹرونی میں، آقا کو کلسٹر لیڈر کہا جاتا ہے، اور غلاموں کو نقل کہا جاتا ہے)۔ پیٹرونی کلسٹر کی ہر مثال مسلسل قونصل کو کلسٹر کی حالت کے بارے میں معلومات بھیجتی ہے۔ لہذا، قونصل سے آپ ہمیشہ پیٹرونی کلسٹر کی موجودہ ترتیب معلوم کر سکتے ہیں اور اس وقت رہنما کون ہے۔

فیل اوور کلسٹر PostgreSQL + Patroni۔ عمل درآمد کا تجربہ

پیٹرونی کو قونصل سے مربوط کرنے کے لیے، آفیشل دستاویزات کا مطالعہ کرنا کافی ہے، جس میں کہا گیا ہے کہ آپ کو HTTP یا https فارمیٹ میں میزبان کی وضاحت کرنے کی ضرورت ہے، اس بات پر منحصر ہے کہ ہم قونصل کے ساتھ کیسے کام کرتے ہیں، اور کنکشن اسکیم اختیاری طور پر:

host: the host:port for the Consul endpoint, in format: http(s)://host:port
scheme: (optional) http or https, defaults to http

یہ آسان لگتا ہے، لیکن یہاں سے نقصانات شروع ہوتے ہیں۔ قونصل کے ساتھ، ہم https کے ذریعے ایک محفوظ کنکشن پر کام کرتے ہیں اور ہمارے کنکشن کی تشکیل اس طرح نظر آئے گی:

consul:
  host: https://server.production.consul:8080 
  verify: true
  cacert: {{ consul_cacert }}
  cert: {{ consul_cert }}
  key: {{ consul_key }}

لیکن یہ کام نہیں کرتا۔ اسٹارٹ اپ پر، پیٹرونی قونصل سے رابطہ نہیں کر سکتا، کیونکہ یہ بہرحال HTTP سے گزرنے کی کوشش کرتا ہے۔

پیٹرونی کے سورس کوڈ نے اس مسئلے سے نمٹنے میں مدد کی۔ اچھی بات ہے کہ یہ python میں لکھا ہے۔ یہ پتہ چلتا ہے کہ میزبان پیرامیٹر کو کسی بھی طرح سے پارس نہیں کیا گیا ہے، اور پروٹوکول کو اسکیم میں بیان کرنا ضروری ہے۔ قونصل کے ساتھ کام کرنے کے لیے ورکنگ کنفیگریشن بلاک ہمارے لیے اس طرح نظر آتا ہے:

consul:
  host: server.production.consul:8080
  scheme: https
  verify: true
  cacert: {{ consul_cacert }}
  cert: {{ consul_cert }}
  key: {{ consul_key }}

قونصل ٹیمپلیٹ

لہذا، ہم نے ترتیب کے لیے اسٹوریج کا انتخاب کیا ہے۔ اب ہمیں یہ سمجھنے کی ضرورت ہے کہ پیٹرونی کلسٹر میں لیڈر کو تبدیل کرتے وقت پی جی باؤنسر اپنی کنفیگریشن کو کیسے بدلے گا۔ دستاویزات میں اس سوال کا کوئی جواب نہیں ہے، کیونکہ. وہاں، اصولی طور پر، PgBouncer کے ساتھ کام کی وضاحت نہیں کی گئی ہے۔

ایک حل کی تلاش میں، ہمیں ایک مضمون ملا (بدقسمتی سے عنوان یاد نہیں ہے) جس میں لکھا گیا تھا کہ پی جی باؤنسر اور پیٹرونی کی جوڑی بنانے میں Сonsul-template نے بہت مدد کی۔ اس نے ہمیں یہ تحقیق کرنے پر آمادہ کیا کہ قونصل ٹیمپلیٹ کیسے کام کرتا ہے۔

معلوم ہوا کہ Consul-template Consul میں PostgreSQL کلسٹر کی ترتیب کو مسلسل مانیٹر کرتا ہے۔ جب لیڈر تبدیل ہوتا ہے، تو یہ PgBouncer کنفیگریشن کو اپ ڈیٹ کرتا ہے اور اسے دوبارہ لوڈ کرنے کے لیے کمانڈ بھیجتا ہے۔

فیل اوور کلسٹر PostgreSQL + Patroni۔ عمل درآمد کا تجربہ

ٹیمپلیٹ کا ایک بڑا فائدہ یہ ہے کہ اسے کوڈ کے طور پر محفوظ کیا جاتا ہے، لہذا جب کوئی نیا شارڈ شامل کرتے ہیں، تو یہ کافی ہوتا ہے کہ ایک نیا عہد کرنا اور ٹیمپلیٹ کو خود بخود اپ ڈیٹ کرنا، بنیادی ڈھانچے کو کوڈ کے اصول کے طور پر سپورٹ کرنا۔

پیٹرونی کے ساتھ نیا فن تعمیر

نتیجے کے طور پر، ہمیں کام کی درج ذیل اسکیم ملی:
فیل اوور کلسٹر PostgreSQL + Patroni۔ عمل درآمد کا تجربہ

تمام ایپلیکیشن سرورز بیلنسر تک رسائی حاصل کرتے ہیں → اس کے پیچھے PgBouncer کی دو مثالیں ہیں → ہر ایک مثال پر، Consul-template کو لانچ کیا جاتا ہے، جو ہر Patroni کلسٹر کی حیثیت کو مانیٹر کرتا ہے اور PgBouncer config کی مطابقت کو مانیٹر کرتا ہے، جو ہر کلسٹر کے موجودہ لیڈر کو درخواستیں بھیجتا ہے۔

دستی جانچ

ہم نے اس اسکیم کو ایک چھوٹے ٹیسٹ ماحول پر شروع کرنے سے پہلے چلایا اور خودکار سوئچنگ کے آپریشن کو چیک کیا۔ انہوں نے بورڈ کھولا، اسٹیکر کو منتقل کیا، اور اس وقت انہوں نے کلسٹر کے لیڈر کو "مار دیا"۔ AWS میں، یہ اتنا ہی آسان ہے جتنا کہ کنسول کے ذریعے مثال کو بند کرنا۔

فیل اوور کلسٹر PostgreSQL + Patroni۔ عمل درآمد کا تجربہ

اسٹیکر 10-20 سیکنڈ کے اندر واپس آ گیا، اور پھر عام طور پر حرکت کرنا شروع کر دیا۔ اس کا مطلب یہ ہے کہ پیٹرونی کلسٹر نے صحیح طریقے سے کام کیا: اس نے لیڈر کو تبدیل کیا، معلومات کو قونصل کو بھیج دیا، اور کونسل-ٹیمپلیٹ نے فوری طور پر اس معلومات کو اٹھایا، پی جی باؤنسر کنفیگریشن کو تبدیل کیا اور دوبارہ لوڈ کرنے کے لیے کمانڈ بھیج دیا۔

زیادہ بوجھ کے نیچے کیسے زندہ رہیں اور ڈاؤن ٹائم کو کم سے کم رکھیں؟

سب کچھ بالکل کام کرتا ہے! لیکن نئے سوالات ہیں: یہ زیادہ بوجھ کے تحت کیسے کام کرے گا؟ پیداوار میں ہر چیز کو جلدی اور محفوظ طریقے سے کیسے نکالا جائے؟

آزمائشی ماحول جس پر ہم لوڈ ٹیسٹنگ کرتے ہیں پہلے سوال کا جواب دینے میں ہماری مدد کرتا ہے۔ یہ فن تعمیر کے لحاظ سے پیداوار سے مکمل طور پر مماثل ہے اور اس نے ٹیسٹ ڈیٹا تیار کیا ہے جو پیداوار کے حجم میں تقریباً برابر ہے۔ ہم ٹیسٹ کے دوران PostgreSQL ماسٹرز میں سے صرف ایک کو "مارنے" کا فیصلہ کرتے ہیں اور دیکھتے ہیں کہ کیا ہوتا ہے۔ لیکن اس سے پہلے، خودکار رولنگ کو چیک کرنا ضروری ہے، کیونکہ اس ماحول میں ہمارے پاس کئی PostgreSQL شارڈز ہیں، لہذا ہمیں پروڈکشن سے پہلے کنفیگریشن اسکرپٹس کی بہترین جانچ ملے گی۔

دونوں کام مہتواکانکشی نظر آتے ہیں، لیکن ہمارے پاس PostgreSQL 9.6 ہے۔ کیا ہم فوری طور پر 11.2 میں اپ گریڈ کر سکتے ہیں؟

ہم اسے 2 مراحل میں کرنے کا فیصلہ کرتے ہیں: پہلے 11.2 میں اپ گریڈ کریں، پھر Patroni لانچ کریں۔

PostgreSQL اپ ڈیٹ

PostgreSQL ورژن کو تیزی سے اپ ڈیٹ کرنے کے لیے، آپشن کا استعمال کریں۔ -k، جس میں ہارڈ لنکس ڈسک پر بنائے جاتے ہیں اور آپ کے ڈیٹا کو کاپی کرنے کی ضرورت نہیں ہے۔ 300-400 GB کی بنیادوں پر، اپ ڈیٹ میں 1 سیکنڈ لگتا ہے۔

ہمارے پاس بہت سارے شارڈز ہیں، لہذا اپ ڈیٹ کو خود بخود کرنے کی ضرورت ہے۔ ایسا کرنے کے لیے، ہم نے ایک جوابی پلے بک لکھی جو ہمارے لیے اپ ڈیٹ کے پورے عمل کو سنبھالتی ہے:

/usr/lib/postgresql/11/bin/pg_upgrade 
<b>--link </b>
--old-datadir='' --new-datadir='' 
 --old-bindir=''  --new-bindir='' 
 --old-options=' -c config_file=' 
 --new-options=' -c config_file='

یہاں یہ نوٹ کرنا ضروری ہے کہ اپ گریڈ شروع کرنے سے پہلے، آپ کو اسے پیرامیٹر کے ساتھ انجام دینا ہوگا۔ --چیکاس بات کو یقینی بنانے کے لیے کہ آپ اپ گریڈ کر سکتے ہیں۔ ہماری اسکرپٹ اپ گریڈ کی مدت کے لیے کنفیگرس کا متبادل بھی بناتی ہے۔ ہمارا اسکرپٹ 30 سیکنڈ میں مکمل ہوا، جو ایک بہترین نتیجہ ہے۔

Patroni لانچ کریں۔

دوسرا مسئلہ حل کرنے کے لیے، صرف پیٹرونی کی ترتیب کو دیکھیں۔ آفیشل ریپوزٹری میں initdb کے ساتھ ایک مثال کنفیگریشن ہے، جو کہ جب آپ پہلی بار Patroni شروع کرتے ہیں تو نئے ڈیٹا بیس کو شروع کرنے کے لیے ذمہ دار ہے۔ لیکن چونکہ ہمارے پاس پہلے سے ہی ایک ریڈی میڈ ڈیٹا بیس ہے، اس لیے ہم نے اس سیکشن کو کنفیگریشن سے ہٹا دیا۔

جب ہم نے پہلے سے موجود PostgreSQL کلسٹر پر Patroni کو انسٹال کرنا شروع کیا اور اسے چلانا شروع کیا تو ہم ایک نئی پریشانی کا شکار ہوئے: دونوں سرورز ایک لیڈر کے طور پر شروع ہوئے۔ پیٹرونی کلسٹر کی ابتدائی حالت کے بارے میں کچھ نہیں جانتا ہے اور دونوں سرورز کو ایک ہی نام کے ساتھ دو الگ الگ کلسٹرز کے طور پر شروع کرنے کی کوشش کرتا ہے۔ اس مسئلے کو حل کرنے کے لیے، آپ کو غلام پر ڈیٹا کے ساتھ ڈائریکٹری کو حذف کرنے کی ضرورت ہے:

rm -rf /var/lib/postgresql/

یہ صرف غلام پر کرنے کی ضرورت ہے!

جب ایک کلین ریپلیکا منسلک ہوتا ہے، پیٹرونی ایک بیس بیک اپ لیڈر بناتا ہے اور اسے ریپلیکا میں بحال کرتا ہے، اور پھر وال لاگس کے مطابق موجودہ حالت کو پکڑتا ہے۔

ایک اور مشکل جس کا ہمیں سامنا کرنا پڑا وہ یہ ہے کہ تمام PostgreSQL کلسٹرز کا نام بطور ڈیفالٹ مین رکھا جاتا ہے۔ جب ہر کلسٹر دوسرے کے بارے میں کچھ نہیں جانتا ہے، تو یہ عام بات ہے۔ لیکن جب آپ Patroni استعمال کرنا چاہتے ہیں، تو تمام کلسٹرز کا ایک منفرد نام ہونا چاہیے۔ حل یہ ہے کہ PostgreSQL کنفیگریشن میں کلسٹر کا نام تبدیل کیا جائے۔

لوڈ ٹیسٹ

ہم نے ایک ٹیسٹ شروع کیا ہے جو بورڈز پر صارف کے تجربے کی تقلید کرتا ہے۔ جب بوجھ ہماری اوسط یومیہ قیمت تک پہنچ گیا، ہم نے بالکل وہی ٹیسٹ دہرایا، ہم نے PostgreSQL لیڈر کے ساتھ ایک مثال کو بند کر دیا۔ خودکار فیل اوور نے ہماری توقع کے مطابق کام کیا: پیٹرونی نے لیڈر کو تبدیل کر دیا، قونصل ٹیمپلیٹ نے PgBouncer کنفیگریشن کو اپ ڈیٹ کیا اور دوبارہ لوڈ کرنے کے لیے کمانڈ بھیجی۔ گرافانا میں ہمارے گراف کے مطابق، یہ واضح تھا کہ ڈیٹا بیس کے کنکشن سے منسلک سرورز سے 20-30 سیکنڈ کی تاخیر اور تھوڑی سی غلطیاں ہیں۔ یہ ایک عام صورت حال ہے، ایسی اقدار ہمارے فیل اوور کے لیے قابل قبول ہیں اور یقینی طور پر سروس ڈاؤن ٹائم سے بہتر ہیں۔

پیٹرونی کو پیداوار میں لانا

نتیجے کے طور پر، ہم مندرجہ ذیل منصوبہ کے ساتھ آئے:

  • PgBouncer سرورز پر قونصل ٹیمپلیٹ تعینات کریں اور لانچ کریں۔
  • PostgreSQL ورژن 11.2 میں اپ ڈیٹس؛
  • کلسٹر کا نام تبدیل کریں؛
  • پیٹرونی کلسٹر شروع کرنا۔

اسی وقت، ہماری اسکیم ہمیں تقریباً کسی بھی وقت پہلا نقطہ بنانے کی اجازت دیتی ہے، ہم ہر PgBouncer کو کام سے ہٹا سکتے ہیں اور اس پر قونصل ٹیمپلیٹ تعینات اور چلا سکتے ہیں۔ تو ہم نے کیا۔

فوری تعیناتی کے لیے، ہم نے Ansible کا استعمال کیا، کیونکہ ہم نے پہلے سے ہی تمام پلے بکس کو ٹیسٹ کے ماحول پر جانچ لیا ہے، اور مکمل اسکرپٹ کے نفاذ کا وقت ہر شارڈ کے لیے 1,5 سے 2 منٹ تک تھا۔ ہم اپنی سروس کو روکے بغیر ہر شارڈ کے بدلے ہر چیز کو رول آؤٹ کر سکتے ہیں، لیکن ہمیں ہر پوسٹگری ایس کیو ایل کو کئی منٹوں کے لیے بند کرنا پڑے گا۔ اس صورت میں، جن صارفین کا ڈیٹا اس شارڈ پر ہے وہ اس وقت پوری طرح کام نہیں کر سکتے، اور یہ ہمارے لیے ناقابل قبول ہے۔

اس صورت حال سے باہر نکلنے کا راستہ منصوبہ بندی کی دیکھ بھال تھا، جو ہر 3 ماہ بعد ہوتا ہے. یہ طے شدہ کام کے لیے ایک ونڈو ہے، جب ہم اپنی سروس کو مکمل طور پر بند کر دیتے ہیں اور اپنے ڈیٹا بیس کے واقعات کو اپ گریڈ کرتے ہیں۔ اگلی کھڑکی تک ایک ہفتہ باقی تھا، اور ہم نے صرف انتظار کرنے اور مزید تیاری کرنے کا فیصلہ کیا۔ انتظار کے وقت کے دوران، ہم نے خود کو مزید محفوظ کیا: ہر PostgreSQL شارڈ کے لیے، ہم نے تازہ ترین ڈیٹا رکھنے میں ناکامی کی صورت میں ایک اضافی نقل تیار کی، اور ہر شارڈ کے لیے ایک نئی مثال شامل کی، جو پیٹرونی کلسٹر میں ایک نئی نقل بننا چاہیے، تاکہ ڈیٹا کو ڈیلیٹ کرنے کی کمانڈ پر عمل نہ کیا جائے۔ اس سب نے غلطی کے خطرے کو کم کرنے میں مدد کی۔
فیل اوور کلسٹر PostgreSQL + Patroni۔ عمل درآمد کا تجربہ

ہم نے اپنی سروس دوبارہ شروع کی، سب کچھ جیسا کہ ہونا چاہیے تھا، صارفین کام کرتے رہے، لیکن گرافس پر ہم نے قونصل سرورز پر غیر معمولی طور پر زیادہ بوجھ دیکھا۔
فیل اوور کلسٹر PostgreSQL + Patroni۔ عمل درآمد کا تجربہ

ہم نے یہ امتحانی ماحول میں کیوں نہیں دیکھا؟ یہ مسئلہ بہت اچھی طرح سے واضح کرتا ہے کہ بنیادی ڈھانچے کو کوڈ کے اصول کے طور پر پیروی کرنا اور ٹیسٹ ماحول سے لے کر پیداوار تک پورے انفراسٹرکچر کو بہتر کرنا ضروری ہے۔ دوسری صورت میں، ہمیں جو مسئلہ ملا ہے اسے حاصل کرنا بہت آسان ہے۔ کیا ہوا؟ قونصل سب سے پہلے پروڈکشن پر ظاہر ہوا، اور پھر ٹیسٹ کے ماحول پر، نتیجے کے طور پر، ٹیسٹ کے ماحول پر، قونصل کا ورژن پروڈکشن سے زیادہ تھا۔ صرف ایک ریلیز میں، قونصل ٹیمپلیٹ کے ساتھ کام کرتے وقت ایک CPU لیک کو حل کیا گیا تھا۔ لہذا، ہم نے آسانی سے قونصل کو اپ ڈیٹ کیا، اس طرح مسئلہ حل ہو گیا۔

پیٹرونی کلسٹر کو دوبارہ شروع کریں۔

تاہم، ہمیں ایک نیا مسئلہ درپیش ہے، جس کا ہمیں شبہ بھی نہیں تھا۔ قونصل کو اپ ڈیٹ کرتے وقت، ہم صرف قونصل لیو کمانڈ کا استعمال کرتے ہوئے کلسٹر سے قونصل نوڈ کو ہٹا دیتے ہیں → Patroni دوسرے قونصل سرور سے جڑ جاتا ہے → سب کچھ کام کرتا ہے۔ لیکن جب ہم قونصل کلسٹر کی آخری مثال پر پہنچے اور اس پر قونصل کی چھٹی کی کمانڈ بھیجی تو تمام پیٹرونی کلسٹرز آسانی سے دوبارہ شروع ہو گئے، اور لاگز میں ہمیں درج ذیل خرابی نظر آئی:

ERROR: get_cluster
Traceback (most recent call last):
...
RetryFailedError: 'Exceeded retry deadline'
ERROR: Error communicating with DCS
<b>LOG: database system is shut down</b>

پیٹرونی کلسٹر اپنے کلسٹر کے بارے میں معلومات حاصل کرنے سے قاصر تھا اور دوبارہ شروع ہوا۔

حل تلاش کرنے کے لیے، ہم نے گیتھب پر ایک مسئلے کے ذریعے پیٹرونی مصنفین سے رابطہ کیا۔ انہوں نے ہماری کنفیگریشن فائلوں میں بہتری کی تجویز پیش کی:

consul:
 consul.checks: []
bootstrap:
 dcs:
   retry_timeout: 8

ہم آزمائشی ماحول میں اس مسئلے کو نقل کرنے کے قابل تھے اور وہاں ان اختیارات کا تجربہ کیا، لیکن بدقسمتی سے انہوں نے کام نہیں کیا۔

مسئلہ ابھی تک حل طلب ہے۔ ہم مندرجہ ذیل حل آزمانے کا ارادہ رکھتے ہیں:

  • ہر پیٹرونی کلسٹر مثال پر قونصل ایجنٹ کا استعمال کریں؛
  • کوڈ میں مسئلہ حل کریں۔

ہم سمجھتے ہیں کہ غلطی کہاں ہوئی ہے: مسئلہ شاید پہلے سے طے شدہ ٹائم آؤٹ کا استعمال ہے، جسے کنفیگریشن فائل کے ذریعے اوور رائڈ نہیں کیا گیا ہے۔ جب آخری قونصل سرور کو کلسٹر سے ہٹا دیا جاتا ہے، تو پورا قونصل کلسٹر ایک سیکنڈ سے زیادہ لٹک جاتا ہے، اس کی وجہ سے پیٹرونی کلسٹر کا درجہ حاصل نہیں کر سکتا اور پورے کلسٹر کو مکمل طور پر دوبارہ شروع کر دیتا ہے۔

خوش قسمتی سے، ہمیں مزید خرابیوں کا سامنا نہیں کرنا پڑا۔

Patroni کے استعمال کے نتائج

Patroni کے کامیاب آغاز کے بعد، ہم نے ہر کلسٹر میں ایک اضافی نقل شامل کی۔ اب ہر ایک جھرمٹ میں کورم کی ایک جھلک ہے: ایک لیڈر اور دو نقلیں، سوئچنگ کے دوران سپلٹ برین کی صورت میں حفاظتی جال کے لیے۔
فیل اوور کلسٹر PostgreSQL + Patroni۔ عمل درآمد کا تجربہ

پیٹرونی تین ماہ سے زیادہ عرصے سے پروڈکشن پر کام کر رہی ہے۔ اس وقت کے دوران، وہ پہلے ہی ہماری مدد کرنے میں کامیاب ہو چکا ہے۔ حال ہی میں، AWS میں کلسٹرز میں سے ایک کا لیڈر مر گیا، خودکار فیل اوور کام کر گیا اور صارفین کام کرتے رہے۔ پیٹرونی نے اپنا بنیادی کام پورا کیا۔

Patroni کے استعمال کا ایک چھوٹا سا خلاصہ:

  • ترتیب کی تبدیلیوں میں آسانی۔ ایک موقع پر کنفیگریشن کو تبدیل کرنا کافی ہے اور اسے پورے کلسٹر تک کھینچ لیا جائے گا۔ اگر نئی کنفیگریشن کو لاگو کرنے کے لیے ریبوٹ کی ضرورت ہے، تو پیٹرونی آپ کو بتائے گا۔ Patroni ایک ہی کمانڈ کے ساتھ پورے کلسٹر کو دوبارہ شروع کر سکتا ہے، جو کہ بہت آسان بھی ہے۔
  • خودکار فیل اوور کام کرتا ہے اور پہلے ہی ہماری مدد کرنے کا انتظام کر چکا ہے۔
  • پوسٹگری ایس کیو ایل اپ ڈیٹ بغیر ایپلیکیشن ڈاؤن ٹائم کے۔ آپ کو پہلے نقلیں نئے ورژن میں اپ ڈیٹ کرنا ہوں گی، پھر پیٹرونی کلسٹر میں لیڈر کو تبدیل کریں اور پرانے لیڈر کو اپ ڈیٹ کریں۔ اس صورت میں، خودکار فیل اوور کی ضروری جانچ ہوتی ہے۔

ماخذ: www.habr.com

نیا تبصرہ شامل کریں