اسان Sublight تي PostgreSQL ۾ لکون ٿا: 1 ميزبان، 1 ڏينهن، 1TB

تازو مون توهان کي ٻڌايو ته ڪيئن، معياري ترڪيبون استعمال ڪندي SQL پڙهڻ جي سوالن جي ڪارڪردگي کي وڌايو PostgreSQL ڊيٽابيس مان. اڄ اسين ڳالهائينداسين ته ڪيئن رڪارڊنگ وڌيڪ موثر طريقي سان ڪري سگهجي ٿو ڊيٽابيس ۾ بغير ڪنهن "موڙ" کي استعمال ڪرڻ جي ترتيب ۾ - صرف صحيح طريقي سان ڊيٽا جي وهڪري کي منظم ڪندي.

اسان Sublight تي PostgreSQL ۾ لکون ٿا: 1 ميزبان، 1 ڏينهن، 1TB

#1. سيڪشن لڳائڻ

ڪيئن ۽ ڇو ان کي منظم ڪرڻ جي قابل آهي جي باري ۾ هڪ مضمون لاڳو ٿيل ورهاڱي "نظريي ۾" اڳ ۾ ئي ٿي چڪو آهي، هتي اسان پنهنجي اندر ڪجهه طريقن کي لاڳو ڪرڻ جي مشق بابت ڳالهائينداسين سوين PostgreSQL سرورز جي نگراني جي خدمت.

”گذريل ڏينهن جون ڳالهيون...“

شروعات ۾، ڪنهن به ايم وي پي وانگر، اسان جو پروجيڪٽ ڪافي هلڪي لوڊ هيٺ شروع ٿيو - مانيٽرنگ صرف ڏهن انتهائي نازڪ سرورن لاءِ ڪئي وئي، سڀئي ٽيبل نسبتاً جامع هئا... پر جيئن جيئن وقت گذرندو ويو، تيئن تيئن نگراني ڪيل ميزبانن جو تعداد وڌندو ويو. ، ۽ هڪ ڀيرو ٻيهر اسان هڪ سان گڏ ڪجهه ڪرڻ جي ڪوشش ڪئي ٽيبل 1.5TB سائيز ۾، اسان اهو محسوس ڪيو ته جيتوڻيڪ اهو ممڪن آهي ته هن طرح جيئرو جاري رکڻ، اهو تمام ڏکيو هو.

اهي زمانا لڳ ڀڳ مهاڀاري دورن وانگر هئا، PostgreSQL 9.x جا مختلف ورجن لاڳاپيل هئا، تنهن ڪري سڀ ورهاڱي کي ”دستي طور“ ٿيڻو هو. ٽيبل وراثت ۽ محرڪ متحرڪ سان رستو EXECUTE.

اسان Sublight تي PostgreSQL ۾ لکون ٿا: 1 ميزبان، 1 ڏينهن، 1TB
نتيجو حل ڪافي آفاقي ثابت ٿيو ته اهو سڀني جدولن ۾ ترجمو ڪري سگهجي ٿو:

  • هڪ خالي "هيڊر" والدين ٽيبل جو اعلان ڪيو ويو، جيڪو سڀني کي بيان ڪيو ويو آهي ضروري اشارا ۽ محرڪ.
  • ڪلائنٽ جي نقطي نظر کان رڪارڊ "روٽ" ٽيبل ۾ ٺاهيو ويو، ۽ اندروني طور تي استعمال ڪندي رستي جو محرڪ BEFORE INSERT رڪارڊ "جسماني طور تي" گهربل حصي ۾ داخل ڪيو ويو. جيڪڏهن اڃا تائين ڪا به شيء نه هئي، اسان هڪ استثنا کي پڪڙيو ۽ ...
  • … استعمال ڪندي CREATE TABLE ... (LIKE ... INCLUDING ...) والدين ٽيبل جي ٽيمپليٽ جي بنياد تي ٺاهي وئي مطلوب تاريخ تي پابندي سان سيڪشنتنهن ڪري جڏهن ڊيٽا حاصل ڪئي وئي آهي، پڙهڻ صرف ان ۾ ڪيو ويندو آهي.

PG10: پهرين ڪوشش

پر وراثت جي ذريعي ورهاڱي تاريخي طور تي هڪ فعال لکڻ واري وهڪرو يا ٻارن جي ورهاڱي جي وڏي تعداد سان معاملو ڪرڻ لاء مناسب نه آهي. مثال طور، توهان ياد ڪري سگهو ٿا ته گهربل سيڪشن کي چونڊڻ لاء الگورتھم هو چوگرد پيچيدگي، ته اهو 100+ حصن سان ڪم ڪري ٿو، توهان پاڻ سمجهو ٿا ته ڪيئن...

PG10 ۾ هن صورتحال کي تمام گهڻو بهتر ڪيو ويو سپورٽ لاڳو ڪرڻ سان ڏيهي ورهاڱي. ان ڪري، اسان اسٽوريج لڏپلاڻ کان پوء فوري طور تي ان کي لاڳو ڪرڻ جي ڪوشش ڪئي، پر ...

جيئن ته اهو دستي ذريعي کوٽڻ کان پوء ظاهر ٿيو، هن نسخي ۾ ورهاڱي واري جدول آهي:

  • انڊيڪس وضاحتن کي سپورٽ نٿو ڪري
  • ان تي محرڪ جي حمايت نه ڪندو آھي
  • ڪنهن جو ”نسل“ نٿو ٿي سگهي
  • حمايت نه ڪريو INSERT ... ON CONFLICT
  • پاڻمرادو سيڪشن ٺاهي نٿو سگھي

ريڪ سان پيشاني تي دردناڪ ڌڪ لڳڻ بعد، اسان محسوس ڪيو ته ايپليڪيشن کي تبديل ڪرڻ کان سواء اهو ناممڪن آهي، ۽ ڇهن مهينن لاء وڌيڪ تحقيق ملتوي ڪيو.

PG10: ٻيو موقعو

تنهن ڪري، اسان مسئلا حل ڪرڻ شروع ڪيو جيڪي هڪ هڪ ڪري پيدا ٿيا:

  1. ڇاڪاڻ ته محرڪ ۽ ON CONFLICT اسان ڏٺو ته اسان کي اڃا به انهن جي ضرورت آهي هتي ۽ اتي، تنهنڪري اسان انهن کي ڪم ڪرڻ لاء هڪ وچولي اسٽيج ٺاهيو پراکسي ٽيبل.
  2. "روٽنگ" کان نجات حاصل ڪئي. triggers ۾ - يعني، کان EXECUTE.
  3. ان کي الڳ الڳ ڪڍيائون ٽيمپليٽ ٽيبل سڀني انڊيڪس سانته جيئن اهي پراکسي ٽيبل ۾ به موجود نه هجن.

اسان Sublight تي PostgreSQL ۾ لکون ٿا: 1 ميزبان، 1 ڏينهن، 1TB
آخرڪار، هن سڀني کان پوء، اسان بنيادي طور تي مکيه ٽيبل کي ورهايو. نئين سيڪشن جي تخليق اڃا تائين ايپليڪيشن جي ضمير تي ڇڏيل آهي.

"سنگ" لغات

جيئن ڪنهن به تجزياتي نظام ۾، اسان وٽ پڻ هو "حقيقت" ۽ "ڪٽ" (ڊڪشنريون). اسان جي صورت ۾، هن صلاحيت ۾ اهي ڪم ڪيو، مثال طور، ٽيمپليٽ جسم ساڳيا سست سوال يا خود سوال جو متن.

”حقيقت“ اڳي ئي گهڻي عرصي کان روزانو سيڪشن ٿي چڪيون هيون، تنهن ڪري اسان آرام سان پراڻا حصا ختم ڪري ڇڏيا، ۽ انهن اسان کي تنگ نه ڪيو (لاگز!). پر لغتن سان مسئلو هو...

اهو چوڻ نه آهي ته انهن مان گهڻا هئا، پر تقريبن 100TB جي "حقيقتن" جي نتيجي ۾ 2.5TB لغت. توهان اهڙي ٽيبل مان ڪا به شيءِ آسانيءَ سان ختم نه ٿا ڪري سگهو، توهان ان کي مناسب وقت ۾ دٻائي نه ٿا سگهو، ۽ ان تي لکڻ آهستي آهستي آهستي آهستي آهستي آهستي آهستي آهستي آهستي آهستي ختم ٿي ويو.

هڪ ڊڪشنري وانگر... ان ۾، هر داخلا بلڪل هڪ ڀيرو پيش ڪرڻ گهرجي... ۽ اهو صحيح آهي، پر!... اسان کي ڪو به نه روڪي رهيو آهي. هر ڏينهن لاءِ الڳ لغت! ها، هي هڪ خاص بيڪار آڻيندو آهي، پر اهو اجازت ڏئي ٿو:

  • جلدي لکڻ/پڙهڻ ننڍي سائيز جي ڪري
  • گھٽ ياداشت استعمال ڪريو وڌيڪ ڪمپيڪٽ انڊيڪس سان ڪم ڪندي
  • گھٽ ڊيٽا ذخيرو ڪريو جلدي ختم ڪرڻ جي صلاحيت جي ڪري پراڻو

قدمن جي پوري پيچيده جي نتيجي ۾ سي پي يو لوڊ گھٽجي ويو ~ 30٪، ڊسڪ لوڊ ~ 50٪:

اسان Sublight تي PostgreSQL ۾ لکون ٿا: 1 ميزبان، 1 ڏينهن، 1TB
ساڳئي وقت، اسان ڊيٽابيس ۾ بلڪل ساڳي شيء لکڻ جاري رکون ٿا، صرف گهٽ لوڊ سان.

#2. ڊيٽابيس جي ارتقا ۽ ريفيڪٽرنگ

تنهن ڪري اسان ان تي آباد ٿياسون جيڪي اسان وٽ آهن هر ڏينهن جو پنهنجو حصو آهي ڊيٽا سان. دراصل، CHECK (dt = '2018-10-12'::date) - ۽ اتي هڪ ورهاڱي جي ڪنجي آهي ۽ رڪارڊ لاءِ شرط آهي ته هڪ مخصوص حصي ۾ اچي.

جيئن ته اسان جي خدمت ۾ سڀئي رپورٽون هڪ مخصوص تاريخ جي حوالي سان ٺهيل آهن، انهن لاء انڊيڪس "غير ورهاڱي واري وقت" کان وٺي سڀني قسمن جا آهن. (سرور، تاريخپلان سانچو), (سرور، تاريخ، پلان نوڊ), (تاريخ, ايرر ڪلاس، سرور)...

پر هاڻي اهي هر سيڪشن تي رهن ٿا توهان جون ڪاپيون هر هڪ اهڙي انڊيڪس... ۽ هر حصي جي اندر تاريخ هڪ مستقل آهي... اهو ظاهر ٿيو ته هاڻي اسان هر هڪ اهڙي انڊيڪس ۾ آهيون صرف هڪ مستقل داخل ڪريو هڪ فيلڊ جي طور تي، جيڪو ان جي حجم ۽ ان جي ڳولا جو وقت وڌائي ٿو، پر ڪو به نتيجو نه ٿو آڻي. اهي ريڪ پاڻ ڏانهن ڇڏي ويا، اڙي ...

اسان Sublight تي PostgreSQL ۾ لکون ٿا: 1 ميزبان، 1 ڏينهن، 1TB
اصلاح جي هدايت واضح آهي - سادو تاريخ جي فيلڊ کي هٽايو سڀني انڊيڪس مان ورهاڱي واري ٽيبل تي. اسان جي مقدار کي ڏنو ويو، حاصل ڪرڻ بابت آهي 1TB/هفتو!

هاڻي اچو ته نوٽ ڪريو ته هي ٽيرا بائيٽ اڃا به ڪنهن نه ڪنهن طريقي سان رڪارڊ ٿيڻو هو. اهو آهي، اسان پڻ ڊسڪ کي هاڻي گهٽ لوڊ ڪرڻ گهرجي! هي تصوير صاف صاف صاف ظاهر ڪري ٿو، جنهن کي اسان هڪ هفتي وقف ڪيو آهي:

اسان Sublight تي PostgreSQL ۾ لکون ٿا: 1 ميزبان، 1 ڏينهن، 1TB

#3. ”پکڙڻ“ چوٽيءَ جو بار

لوڊ ٿيل سسٽم جي وڏي مشڪلاتن مان هڪ آهي بيڪار هم وقت سازي ڪجھ آپريشن جيڪي ان جي ضرورت نه ڪندا آھن. ڪڏهن ڪڏهن "ڇاڪاڻ ته انهن نوٽيس نه ڪيو"، ڪڏهن ڪڏهن "اهو طريقو آسان هو"، پر جلدي يا بعد ۾ توهان کي ان کان نجات حاصل ڪرڻو پوندو.

اچو ته پوئين تصوير تي زوم ڪريو ۽ ڏسو ته اسان وٽ هڪ ڊسڪ آهي "پمپ" ٻٽي طول و عرض سان لوڊ هيٺ ڀرپاسي جي نمونن جي وچ ۾، جيڪي واضح طور تي "شمارياتي طور تي" اهڙين عملن سان نه ٿيڻ گهرجن:

اسان Sublight تي PostgreSQL ۾ لکون ٿا: 1 ميزبان، 1 ڏينهن، 1TB

اهو حاصل ڪرڻ بلڪل آسان آهي. اسان اڳ ۾ ئي نگراني شروع ڪئي آهي لڳ ڀڳ 1000 سرور، هر هڪ الڳ منطقي سلسلي سان پروسيس ڪيو ويندو آهي، ۽ هر ٿريڊ جمع ڪيل معلومات کي ري سيٽ ڪري ٿو ڊيٽابيس ڏانهن موڪليو وڃي هڪ خاص تعدد تي، ڪجهه هن طرح:

setInterval(sendToDB, interval)

هتي مسئلو بلڪل ان حقيقت ۾ آهي سڀ سلسلا لڳ ڀڳ هڪ ئي وقت تي شروع ٿين ٿا، تنهن ڪري انهن جا موڪلڻ جا وقت لڳ ڀڳ هميشه ”نقطي تي“ ٺهندا آهن. اوهه #2...

خوشقسمتيء سان، هن کي درست ڪرڻ بلڪل آسان آهي، شامل ڪرڻ "بي ترتيب" رن اپ وقت سان:

setInterval(sendToDB, interval * (1 + 0.1 * (Math.random() - 0.5)))

#4. جيڪو اسان کي ضرورت آهي اسان کي محفوظ ڪريون ٿا

ٽيون روايتي هاء لوڊ مسئلو آهي ڪيش ناهي جتي هو آهي سگهي ٿيڻ.

مثال طور، اسان ان کي ممڪن بڻايو ته تجزيو ڪرڻ پلان نوڊس جي لحاظ کان (هي سڀ Seq Scan on users)، پر فوري طور تي سوچيو ته اهي آهن، سڀ کان وڌيڪ حصو لاء، ساڳيا - اهي وساري ويا.

نه، يقينا، ڪجھ به نه لکيو ويو آهي ڊيٽابيس ڏانهن ٻيهر، هي ٽرڪ بند ڪري ٿو INSERT ... ON CONFLICT DO NOTHING. پر هي ڊيٽا اڃا تائين ڊيٽابيس تائين پهچي ٿو، ۽ اهو غير ضروري آهي تڪرار جي جانچ ڪرڻ لاء پڙهڻ ڪرڻو آهي. اوهه #3...

ڪيشنگ فعال ٿيڻ کان اڳ/بعد ۾ ڊيٽابيس ڏانهن موڪليل رڪارڊن جي تعداد ۾ فرق واضح آهي:

اسان Sublight تي PostgreSQL ۾ لکون ٿا: 1 ميزبان، 1 ڏينهن، 1TB

۽ هي آهي اسٽوريج لوڊ ۾ گڏو گڏ ڊپ:

اسان Sublight تي PostgreSQL ۾ لکون ٿا: 1 ميزبان، 1 ڏينهن، 1TB

ڪل

"Terabyte-في-ڏينهن" صرف خوفناڪ آواز آهي. جيڪڏهن توهان سڀ ڪجهه ٺيڪ ڪريو ٿا، پوء اهو صرف آهي 2^40 بائيٽ / 86400 سيڪنڊ = ~ 12.5MB/sته به ڊيسڪ ٽاپ IDE سکرو منعقد. 🙂

پر سنجيدگيءَ سان، ڏينهن ۾ به ڏهه ڀيرا ”اسڪيو“ لوڊ ڪرڻ سان، توهان آساني سان جديد SSDs جي صلاحيتن کي پورا ڪري سگهو ٿا.

اسان Sublight تي PostgreSQL ۾ لکون ٿا: 1 ميزبان، 1 ڏينهن، 1TB

جو ذريعو: www.habr.com

تبصرو شامل ڪريو