معرفی و اخبار عمومی

چرا TimescaleDB انتخابی مناسب برای داده‌های سری زمانی است ؟

بررسی معماری TimescaleDB در ذخیره و بازیابی موثر داده‌های سری زمانی بر روی دیتابیس پستگرس

مقدمه

در سالهای اخیر شاهد افزایش ناگهانی حجم داده‌ها بوده ایم که عمدتا به دلیل بازارهای تلفیقی برای برنامه های IoT و یادگیری ماشین (داده‌های تحلیلی و لاگ‌ها) بوده است. تخمین زده می‌شود که برای هر فرد زنده در این سیاره تا سال ۲۰۲۰ تقریباً ۱٫۷ مگابایت داده در هر دقیقه تولید می شود. بیشتر این داده ها در دریاچه های داده[۱] یا انبارهای داده ، به صورت خام یا تلخیص شده ذخیره می شوند. بخش بزرگی از این داده ها به عنوان داده های سری زمانی توسط IoT ، دستگاه ها و برنامه‌های نظارت یا برنامه های تلفن همراه تولید می شود.

beenhere

داده‌های سری زمانی

داده‌های سری زمانی داده‌هایی هستند که هر رکورد آنها شامل زمان بوده، تحلیل و پردازش آنها به طور معمول وابسته به بازه‌های زمانی است.

از جمله این نوع داده‌ها می‌توان به داده‌های بورس، آب‌و‌هوا، توئیت‌ها و حتی اخبار اشاره کرد.سری‌های زمانی در تمامی حوزه‌های علوم کاربردی و مهندسی که زمان در آنها اندازه‌گیری و ذخیره می‌شود از سالیان دور حضور داشته‌اند. بنابراین ، مکانیسم های ماندگاری داده‌ها برای سری‌های زمانی از جمله کارهای قدیمی برای پایگاه داده‌ها هستند. بانکهای اطلاعاتی سری زمانی(TSDB)، نوع خاصی از پایگاه‌های داده هستند که برای ذخیره و پردازش بهینه داده‌های سری‌زمانی (زمان‌محور) ایجاد شده‌اند.

نمونه‌ای از داده‌های سری زمانی

اساس داده‌های سری زمانی، اندازه‌گیری‌های مکرر پارامترها در طول زمان است. اغلب اوقات، فواصل منظم هستند، اما این یک الزام نیست. هدف اصلی یک پایگاه‌داده سری‌های زمانی، ذخیره یا ثبت داده های یک حسگر یا داده‌های دیگر در طول زمان است. ذخیره سازی داده های سری زمانی هم می تواند توسط پایگاه داده های رابطه ای و هم توسط پایگاه داده های غیر رابطه ای  انجام شود. هدف این مقاله هم بررسی تغییرات انجام گرفته در معماری پایگاه داده‌های رابطه ای برای ذخیره موثر داده‌های سری زمانی در پایگاه داده های رابطه ای است. همچنین نشان داده خواهد شد که با باز­معماری پایگاه داده های رابطه ای برای داده های سری زمانی، می توان از مزایای بسیار مهم پایگاه داده های رابطه­‌ای مانند پشتیبانی قوی از secondary Index، زبان پرس و جوی غنی SQL، پشتیبانی کامل از انواع Join ها و … بهره برد.

مثالی از کوئری‌های موردنیاز برای داده‌های سری زمانی را در زیر می‌توانید مشاهده کنید. قالب آشنای SQL نیاز به توضیح را مرتفع می‌کند و خود کدها به حد کافی گویا هست (مزیت SQL در کار با داده‌های سری‌زمانی) :

Stylus

پایگاه داده های NoSQL یا رابطه ای؟

در سال‌های اخیر، حجم داده‌های سری زمانی به شدت توسعه‌یافته و نیاز به ابزارهایی برای مدیریت داده‌های سری زمانی، در این مقیاس، بیش از پیش احساس می‌شود. تاکنون بیشتر ابزارهای تولید شده برای ذخیره و پردازش داده‌های سری زمانی، مبتنی بر مدل‌های داده‌ای NoSQL‌بوده است.

مقایسه درصد استفاده از پایگاه های رابطه ای و غیر  رابطه ای

واقعیت این است که دلیل اقبال افراد برای مدیریت داده‌‌های سری زمانی به پایگاه داده های NoSQLبه  بیشتر به بحث مقیاس‌پذیری آنها برمی‌گردد که به دلیل حجم بالای داده‌های سری زمانی، یک الزام مهم است. از طرفی، پایگاه داده‌های رابطه‌ای ویژگی های بسیار مفیدی دارند که در بسیار از پایگاه داده های NoSQLوجود ندارد یا به صورت ضعیف پشتیبانی می شود. از جمله این موارد می‌توان به secondary Index، زبان پرس و جوی غنی SQL، پشتیبانی کامل از انواع Join ها و … اشاره کرد. بنابراین اگر بتوان مشکل مقیاس‌پذیری داده‌ها را به نحوی حل کرد، می توان این ادعا را داشت که پایگاه داده های رابطه‌ای می توانند گزینه بسیار مناسبی برای نگهداری داده­ های سری زمانی باشند.

چرا پایگاه داد های رابطه ای (معمولاً) مقیاس پذیری بالایی ندارند؟

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

در اکثر پایگاه داده های رابطه ای یک جدول به عنوان مجموعه ای از صفحات با طول ثابت از داده ( به عنوان مثال در PostgreSQL صفحات با سایز ۸KB ) ذخیره می شوند و در بالای آنها سیستم از یک ساختار داده‌ای مانند B-tree برای شاخص گذاری داده ها استفاده می‌کند. با استفاده از این ایندکس ها یک کوئری به صورت بسیار سریعتری می تواند یک سطر مشخص را بدون اینکه بخواهد کل یک جدول را بررسی کند پیدا کند. اگر داده‌هایی که با آنها کار می‌کنیم، حجم کمی داشته باشند که در نتیجه ایندکس‌های آنها کوچک باشد، می‌توان همه آنها را در حافظه نگه داشت. اما اگر داده‌ها زیاد باشند که در اغلب موارد اینگونه است، نمی‌توان همه آنها را در حافظه نگه داشت و اینجاست که مشکل بعدی پیش می‌‌آید :‌ درگیری بیش از حد دیسک و کاهش شدید سرعت کار با داده‌ها.

به روزرسانی یک قسمت تصادفی از درخت شاخص می تواند disk I/O قابل توجهی را درگیر کند، زیرا صفحات از دیسک به حافظه خوانده شده، اصلاح و بر روی دیسک بازنویسی می‌شوند. برای این منظور، یک پایگاه داده رابطه ای مانند PostgreSQL یک B-treeرا برای هر index نگه می دارد، تا مقادیر موجود در ایندکس به طور موثری دستیابی شوند و عملیات مدیریت داده‌ها با سریعترین حالت ممکن صورت گیرد. مشکل زمانی به وجود می آید که ستون‌های زیادی ایندکس شوند (به ازای هر ستونی که زیاد با آن سروکار داریم و سرعت بازیابی اطلاعات بر اساس آن ستون برای ما مهم است، از ایندکس‌ها استفاده می‌کنیم). با این توصیف، چون پایگاه داده فقط دسترسی به دیسک در محدوده page-sized را دارد، ممکن است با یک به روز رسانی کوچک، به دلیل وجود ایندکس‌های زیاد بر روی یک رکورد، Swap و تبادل زیادی بین حافظه و دیسک اتفاق بیفتد. هزینه این Swap می تواند در گراف کارایی شکل زیر که مربوط به PostgreSQLاست دیده شود. جایی که بهره‌وری درج، با توجه به افزایش اندازه جداول (تقریبا بعد از اندازه ۵۰M ) با شیب نسبتا تندی کاهش پیدا می کند. حافظه مورد استفاده برای این تست کارایی از نوع SSDبوده و تعداد کاربران ۱۰ نفر که هرکدام سطرهای مختلفی را درج می کردند.

بررسی نرخ درج داده‌ها با افزایش حجم داده‌ها و کاربران

ملاحظات کارایی پایگاه داده‌های NoSQL

مشکل اصلی مقیاس‌پذیری پایگاه‌‌های داده‌های رابطه‌ای را بررسی کردیم که به دلیل وجود ایندکس‌ها در این نوع دیتابیس‌ها و درگیر شدن زیاد دیسک بخاطر نرخ بالای تغییرات همزمان بود که به دلیل نوع ایندکس انتخاب شده (B+Tree) ناگزیر می‌نمود. برای حل این مشکل، تعداد زیادی از پایگاه داده های NoSQLاز ساختار دیگری برای ایندکس کردن داده‌ها استفاده می‌کنند که با نام Log-structured merge (LSM) trees شناخته می‌شود. این ساختار در شکل زیر نشان داده شده است.

ساختار LSM که در آن تغییرات ابتدا در حافظه بافر می شوند، مرتب شده و بر روی دیسک به صورت فایلهایی مرتب ذخیره می‌شوند.

در این ساختار، همه آپدیت ها ابتدا در یک جدول مرتب شده در درون حافظه نوشته می شوند و سپس به صورت دسته ای از داده های مرتب و تغییر ناپذیر بر روی دیسک نوشته می شوند. یعنی همه نوشتن ها در یک درخت LSM در یک جدول مرتب شده در حافظه انجام می شوند  که وقتی به یک اندازه مناسب رسیدند (به عنوان ” sorted string table” یا SSTable) به عنوان یک فایل داده  تغییرناپذیر به دیسک منتقل می شوند. این فایل‌های مرتب شده یا همان SSTable ها، در بازه‌های زمانی منظم با هم ادغام شده و یک SSTable بزرگتر را می‌سازند و اگر چندین تغییر بر روی یک رکورد انجام شده باشد، فقط آخرین تغییر در این فایل جدید باقی مانده، بقیه حذف می‌شود. این جداول هم به تدریج با داده‌های موجود در دیتابیس ادغام و دیتابیس، آپدیت می‌شود. هنگام جستجو و بازیابی اطلاعات، داده‌های موجود در دیتابیس با داده‌های موجود در این فایلهای مرتب، مقایسه شده و همواره جدیدترین نسخه، به کاربر نشان داده‌ می‌شود. این روش، هر چند هزینه‌های بازیابی اطلاعات را افزایش می‌دهد اما هزینه تغییرات و نوشتن‌های متوالی را به شدت، کاهش می دهد.

در این ساختار، تمام تغییرات ابتدا درون یک جدول مرتب شده در حافظه نوشته میشود و سپس در قالب SSTable به دیسک منتقل می‌شوند.

معماری بیان شده در بالا در اکثر پایگاه داده های NoSQL مانند LevelDB, Google BigTable, Cassandra, MongoDB (WiredTiger), and InfluxDB استفاده شده است و به نظر ساختار مناسبی می آید ولی چند چالش در مورد آن وجود دارد:

  • نیاز به حافظه زیاد (برخلاف یک B-Tree، در یک درخت LSM هیچ ترتیب منحصر بفردی وجود ندارد و همچنین هیچ ایندکس سراسری برای بر روی همه کلیدهای موجود در SSTable‌ها وجود ندارد و این کار پیدا کردن یک کلید خاص را بسیار پیچیده می کند.برای رفع این مورد می توان ایندکسهای تمام SSTable ها را به طور کامل در حافظه قرار داد که این مساله مقدار حافظه مورد نیاز را افزایش می دهد).
  • پشتیبانی ضعیف از Secondary Index (با توجه به اینکه آنها هیچ نظم و ترتیب سراسری ندارند، درختان LSM به طور طبیعی از شاخص های ثانویه پشتیبانی نمی کنند).
  • فقدان Join
  • از دست دادن اکو سیستم SQL ( جامعه جهانی بسیار وسیعی از SQL استفاده می کنند).
  • عدم کارآیی برای دستورات جستجوی باز‌ه ای : با توجه به ساختار key-Value، کوئری های که به صورت range هستند، به صورت بهینه پاسخ داده نمی‌شوند.

آیا راه حل بهتری برای مدیریت داده های سری زمانی وجود دارد؟ برای فهم این موضوع نیاز به شناخت دقیق تر داده‌های سری زمانی داریم.

داده های سری زمانی متفاوت هستند!

مشکل اصلی در رابطه با پایگاه داده های سری زمانی از جایی شروع شد که شرکت IBMدر سال ۱۹۷۰، Seminal System R را راه انداخت و از پایگاه داده های رابطه ای برای پردازش تراکنش های آنلاین (OLTP) استفاده شد.

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

در داده های سری زمانی ، با جریان پیوسته‌ای از داده‌ها و یا اندازه‌گیری‌ها (در مورد حسگرها) مواجه هستیم که در همه آنها، عملیات اصلی مورد نیاز، اضافه کردن “اطلاعات جدید” به پایگاه‌داده به صورت پیوسته است. البته این امکان وجود دارد که اطلاعات بسیار دیرتر از زمانی برسد که تولید شده یا برچسب زمانی خورده  و یا به علت تاخیر شبکه / سیستم یا به دلیل اصلاحات برای به روز رسانی داده‌های موجود، این امر نوعاً استثنا است، نه یک قاعده ثابت.

بنابراین بین نوع عملیات مورد نیاز سیستم‌های تراکنش محور و سری زمانی، تفاوت‌های ماهوی را شاهد هستیم.

در OLTP یا داده‌های تراکنش محور :

  • آپدیت در درجه اول اهمیت قرار دارد یعنی باید بتوان با سرعت و کارآیی مناسب، داده ها را اصلاح کرد.
  • نوشتن‌ها به صورت تصادفی توزیع شده هستند و نمی‌توان پیش‌بینی کرد نوشتن بعدی، قرار است بر روی کدام داده انجام شود.
  • اغلب تراکنش ها شامل چندین جدول مختلف می‌شوند یعنی باید چندین کلید اصلی را جستجو و داده‌های آنها را بازیابی کرد.

در داده‌های سری زمانی:

  • Insertها در درجه اول اهمیت هستند.
  • نوشتن ها تصادفی نیست و در بازه زمانی اخیر انجام می شود. (زمان‌مند هستند و به ترتیب زمانی وارد می‌شوند)
  • کلید اصلی اغلب یک TimeStampاست و ممکن است علاوه بر TimeStampموارد دیگری نیز چون ServerID، ِDeviceID و … همراه با TimeStampباشد.

راه حل پایگاه داده‌های رابطه‌ای برای پردازش سری زمانی

در شکل زیر راه حل استاندارد اولیه پایگاه داده های رابطه ای برای پردازش جریان داده ای و ایده نوین اَبَرجدول در TimescaleDBدیده می شود. در راه حل اولیه که همان استفاده از ایندکس‌های B+‌است، بخشی از نودهای میانی، در حافظه نگهداری می‌شوند تا فرآیند جستجو و بازیابی اطلاعات سرعت مناسب داشته باشد اما در رهیافت جدید TimescaleDB، داده‌ها به بخش‌ها یا Chunkهایی تقسیم و ذخیره می‌شوند و همواره آخرین بخش‌ها در حافظه نگهداری می‌شود. کاربران از طریق اَبَرجدول‌ها به این بخش‌ها دسترسی خواهند داشت.

به عبارت دقیق‌تر، در پایگاه داده TimescaleDBکه قصد دارد از پایگاه‌داده رابطه‌ای پستگرس برای ذخیره داده‌های سری زمانی به نحو موثر استفاده کند، از مفهوم Hyper table و Chunk استفاده می شود. یک جدول مجازی یا اَبَرجدول، در واقع یک تجرید یا یک دید مجازی از همه جداول منفردی است که داده ها را در خود جای داده اند. این جداول منفرد تشکیل دهنده یک اَبَرجدول، chunk نامیده می شوند.

 هر Chunkدر یک جدول پایگاه داده داخلی (به عنوان یک جدول معمولی) ذخیره می‌شود، بنابراین ایندکس ها فقط با اندازه هر Chunkرشد می کنند و نه به اندازه کل. در HyperTableاز آنجا که داده‌‌ها معمولاً در یک بازه محدود (چند ثانیه قبل یا بعد از زمان جاری سیستم بسته به تاخیر یا عدم تنظیم بودن ساعت دستگاه‌ها) وارد می‌شوند، می‌توان همواره آخرین Chunkرا در حافظه نگه‌ داشت. با این‌کار  از یک Swap  پرهزینه به دیسک جلوگیری می شود.

Adaptive Time/Space Chunking

ایده اصلی مقیاس‌پذیری و روش مدیریت داده‌ها در TimescaleDBرا مشاهده کردید. در این بخش، به راه حل نهایی و معماری TimescaleDBمی‌پردازیم. راه حل های قبلی که مطرح شد، تلاش می کردند که از نوشتن های کوچک بر روی دیسک حذر کنند. آنها تلاش می کردند که مشکل OLTPرا که مسئله Update در محلهای تصادفی بود را حل کنند. اما مساله داده های سری زمانی متفاوت است: در اینجا چیزی که بسیار مهم است درج است نه ویرایش. Insert همواره در بازه زمانی اخیر انجام می شود و برخلاف OLTPکه به روز رسانی داده‌ها معمولاً در مکانهای تصادفی صورت میگیرد، می توان گفت که Workload داده های سری زمانی به صورت append only است.

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

در نگاه اول ممکن است به نظر برسد که این کار شبیه ایندکس گذاری بر روی Time است که به ما قابلیت نوشتن و خواندن کارا را می دهد. اما هنگامی که ما می خواهیم از ایندکس دیگری مانند ServerIDیا DeviceIDو یا هر کلید اصلی دیگری به عنوان Secondary Index داشته باشیم، متوجه می شویم که این روش مناسب نبوده و ما را به درج به صورت تصادفی در درخت B-tree برای استفاده از ایندکس دوم مجبور می کند.

برای حل این مشکل، می‌توان از ایندکس گذاری سلسله مراتبی استفاده کرد. دو حالت مختلف این ایندکس گذاری سلسله مراتبی را در شکل زیر می‌توانید مشاهده کنید:

اما می‌توان برای مدیریت موثر زمان و سایر داده‌ها، (بُعد زمان و بُعد مکان/وسیله/کاربر و ….) از روش دیگری هم استفاده کرد که روش بخش‌بندی تطبیقی زمان/مکان adaptive time/space chunking  نامیده می­شود و در TimescaleDBاستفاده شده است.

 در این روش به جای ایندکس سازی بر اساس زمان و یا ایندکس دوم مورد نیاز بر روی داده‌ها، Cunking یا بخش‌بندی داده ها به صورت همزمان بر حسب دو بعد بازه زمانی و کلید اصلی ساخته می شود (کلید اصلی برای نمونه می تواند ServerIDو یا هر چیز دیگری باشد). برای تمایز ایجاد کردن از Partitionها، ما به Chunkهای اشاره می کنیم که  به طور معمول با تقسیم فضای اصلی کلید تعریف می شوند.

در روش بخش‌بندی تطبیقی، داده‌ها به چانک‌هایی با محوریت زمان تقسیم شده و در هر چانک یا بخش، داده‌ها بر اساس کلید دوم، مرتب شده‌اند که این موضوع باعث می‌شود که بتوان یک اندیس سراسری بر اساس کلید دوم هم تعریف کرد و همزمان هم بر اساس زمان بتوان به داده‌ها دسترسی داشت و هم بر اساس، مکان (یا هر کلید دیگری) .

با این روش، داده‌های ورودی به صورت مفهومی هنگام درج در دیتابیس، در مکان مناسب از یک چانک یا بخش قرار می‌گیرند.

داده‌ها هنگام درج از دید کاربر در یک جدول بزرگ (HyperTable) درج می‌شوند اما در پس پشت، هر داده بسته به اندیس تعیین شده، در جداول چانک مربوطه قرار میگیرد.

 مزایای Chunking

از آنجا که هریک از این chunk ها به صورت جدولهایی در پایگاه داده ذخیره می شوند، و Query Plannerاز محدوده chunkها آگاه است (اندیس زمان و مکان)، Query Planner می تواند به سرعت تعیین کند که کدام داده عملیاتی متعلق به کدام chunk است. این موضوع می تواند هم برای درج سطرها، وهم برای انتخاب مجموعه ای از chunkها که برای اجرای کوئری مورد نیاز است، استفاده شود.

انتخاب موثر چانک‌های مورد نیاز برای پردازش هر کوئری

ویژگی بسیار خوب این روش این است که همه ایندکس های ما بر رو chunk ها که کوچکتر هستند ساخته می شوند نه بر روی جدول ها که کل دیتاست را نمایش می دهند. بنابراین اگر ما سایز chunkها را به طور مناسبی انتخاب کنیم، می توانیم آخرین جدول به همراه درخت های B-trree آن را به طور کامل در حافظه قرار دهیم و از swapکردن به دیسک جلوگیری کنیم، در حالی که از ویژگی پیشتیبانی از چند ایندکس نیز بهره برده‌ایم.

از دیگر مزایای chunking می توان به به این مورد اشاره کرده که با استفاده از chunkها می توان بر روی یک نود با اضافه کردن دیسک،  Scale Up داشت یعنی بدون نیاز به افزودن نودی دیگر در شبکه، با افزودن تعداد دیسک‌های یک سیستم، امکان توزیع خودکار چانک‌ها در بین دیسک‌ها را توسط خود دیتابیس فراهم کرد. با استفاده از این تکنیک سرعت Insert افزایش پیدا می کند و امکان کوئری گرفتن موازی وجود دارد.

تقسیم جداول اصلی به چانک‌ها، امکان توزیع آنها بر روی دیسک‌های متفاوت بر روی یک سیستم را به ما میدهد.(مقیاس‌پذیری عمودی)

علاوه بر اینکه می توان بر روی یک نود Scale up داشت، می توان با استفاده از چندین سرور به صورت توزیع شده Scale Out نیز داشت. به این صورت که chunk ها بر روی سرور های مختلف توزیع می شوند.

تقسیم جداول اصلی به چانک‌ها، امکان توزیع آنها در شبکه را به ما میدهد.(مقیاس‌پذیری افقی)

روش پیاده سازی Chunking

chunkها نقش اصلی را در معماری TimescaleDB‌ایفا می‌کنند و بنابراین مدیریت درست آنها، تاثیر زیادی روی کارآیی این دیتابیس خواهد داشت.

برای پیاده‌سازی چانک‌ها سه روش اصلی داریم که هنگام طراحی جداول در TimescaleDB‌قابل تنظیم است :

  • بازه زمانی ثابت : در این روش، بسته به نوع و حجم داده‌ها، بازه زمانی را معیار ایجاد چانک‌ها تعریف می‌کنیم. مثلاً بازه یک روزه، باعث می‌شود تمام داده‌های یک روز درون یک چانک قرار بگیرند و با شروع روز جدید، یک چانک (یک جدول داخلی جدید) ایجاد شود.مشکل این روش این است که اگر حجم داده های روزانه به تدریج زیاد شود و مثلا داده های یک روز از حد مطلوبی که در نظرگرفته بودیم تجاوز کند، با کاهش کارآیی مواجه خواهیم شد.
  • اندازه چانک ثابت : در این روش، حجم ثابتی برای جداول داخلی یعنی چانک‌ها در نظر میگیریم . مثلا فرض کنید ۱ گیگابایت را به عنوان اندازه یک چانک تعیین می‌کنیم. با رسیدن حجم داده‌ها در یک چانک به این سقف، چانک فعلی بسته شده، بازه زمانی ابتدا و انتهای آن ذخیره شده(برای ایندکس گذاری و جستجوهای بعدی ) و چانک جدید ایجاد می‌شود. مشکل این روش هم این است که داده‌هایی که با تاخیر می‌رسند، چون در بازه زمانی یک چانک بسته شده قرار می‌گیرند، باید به داده‌های آن اضافه شوند. این موضوع ، باعث افزایش حجم ناخواسته چانک‌ها می‌شود که بسته به کاربرد، ممکن است حجم افزوده شده چندان قابل اعتنا نباشد و یا برعکس، مشکلاتی در کارآیی سیستم ایجاد کند.
  • بازه‌های زمانی تطبیق شونده : راه حل سوم که رهیافتی مابین دو روش قبلی است، تعیین بازه زمانی و حداکثر داده مجاز قابل ذخیره در یک چانک است. چانک‌ها بر اساس بازه زمانی تعیین شده ایجاد می شوند اما اگر از سقف مشخص شده عبور کنند، درون آن بازه زمانی، چانک جدیدی ایجاد خواهد شد. این موضوع تضمین می کند همیشه آخرین چانک با اندازه تعیین شده تطابق دارد و قابل نگهداری در حافظه است.

انتخاب روش مناسب، به شما و نیازمندیهایتان بستگی دارد.

بررسی سریع یک مثال کاربردی

برای اینکه یک دید عملی و کاربردی نسبت به TimescaleDB‌پیدا کنید و نحوه طراحی و کوئری گرفتن اطلاعات را در یک نگاه ببینید مثالی از ذخیره داده های ترافیک را با هم مرور می‌کنیم. فرض کنید قرار است به صورت روزانه اطلاعات دوربین‌های نظارتی درون شهری را ذخیره کنید. از آنجا که داده‌ها ماهیت زمان‌محور دارند و کوئری‌های مورد نیاز اغلب در بازه‌های زمانی صورت می‌گیرند، این بخش از داده‌ها را درون پستگرس، با افزونه TimescaleDB‌مدیریت می کنیم . جدول vehicle_Traffc را به صورت زیر درون پستگرس ایجاد می‌کنیم :

Stylus

سپس اَبَرجدول متناظر را در TimescaleDB‌ می‌سازیم :

Stylus

همانطور که مشاهده می‌کنید، بازه زمانی هر چانک را یک روز تعیین کرده‌ایم. در مرحله بعد، با همان دستورات معمول SQL به درج داده در جدول vehicle_traffic می‌پردازیم . بعد از ورود حجم داده مناسب(مثلاً برای چند روز مختلف) اگر از دستور Explain استفاده کنیم تا ببینیم پشت صحنه، کوئری به چه صورت پاسخ داده می‌شود، می‌بینیم که داده‌ها از چندین چانک مختلف بازیابی می‌شوند :

Stylus

نمونه‌ای از کوئری‌هایی که می‌توانیم روی این داده‌ها داشته باشیم را در ادامه مشاهده می‌کنید :

HTML

همانطور که می‌بینید، sql در تمام این مراحل، حرف اول را می‌زند که نکته بسیار مهمی در به کارگیری عملی داده‌های سری زمانی در دنیای واقعی است.

کارایی روش ارائه شده نسبت به روش سنتی درPostgerSQL

استفاده از بهینه‌سازی هایی که در بالا بدانها اشاره شد، باعث شده است انتخاب TimescaleDB‌ در مقایسه با پستگرس برای داده‌های سری زمانی به یک اصل واضح تبدیل شود. نمودارهای زیر این موضوع را نشان می‌دهند.(منبع)

همانطور که قابل مشاهده است TimescaleDB‌با توجه به بالا رفتن حجم داده، نرخ Insertتقریبا ثابتی دارد و کارایی Insertکاهش چندانی پیدا نمی کند و می توان گفت که تقریبا مستقل از سایز دیتاست است. در کوئری‌های پیچیده هم TimescaleDB‌به وضوح، برتری خود را نشان داده است:

سایر مقایسه‌ها و نمودارها را در این آدرس می‌توانید مشاهده کنید.

سال گذشته مقاله‌ای خواندم که در آن TimescaleDB‌و کاساندرا برای ذخیره و بازیابی داده‌های سری زمانی مقایسه شده بودند که در آن، TimescaleDBبا پنج نود، کاساندرا با ۳۰ نورد را با اختلاف زیاد پشت سر گذاشته بود (البته برای داده‌های سری زمانی و برای داده‌هایی که با دیتامدل سطر گسترده کاساندرا مطابق هستند این مساله صدق نمی‌کند)

نتیجه گیری

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

[۱] Data lakes

امتیاز کاربران: ۴٫۷۸ ( ۲ رای)

مجتبی بنائی

دانشجوی دکترای نرم‌افزار دانشگاه تهران (yun.ir/smbanaie)، مدرس دانشگاه و فعال در حوزه توسعه نرم‌افزار و مهندسی داده که تمرکز کاری خود را در چند سال اخیر بر روی مطالعه و تحقیق در حوزه کلان‌داده و زیرساخت‌های پردازش داده و تولید محتوای تخصصی و کاربردی به زبان فارسی و انتشار آنها در سایت مهندسی داده گذاشته است. مدیریت پروژه‌های نرم‌افزاری و طراحی سامانه‌های مقیاس‌پذیر اطلاعاتی از دیگر فعالیتهای صورت گرفته ایشان در چند سال گذشته است.

۲ دیدگاه

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

جای خالی در معادله زیر را با کی برد انگلیسی وارد کنید : * Time limit is exhausted. Please reload CAPTCHA.

این سایت از اکیسمت برای کاهش هرزنامه استفاده می کند. بیاموزید که چگونه اطلاعات دیدگاه های شما پردازش می‌شوند.

دکمه بازگشت به بالا