نیک آموز > وبلاگ > مهندسی داده > معماری Data Lakehouse چیست و چگونه کار میکند؟ معماری Data Lakehouse چیست و چگونه کار میکند؟ مهندسی داده نوشته شده توسط: نگین فاتحی تاریخ انتشار: ۰۴ مهر ۱۴۰۳ آخرین بروزرسانی: 01 اردیبهشت 1405 زمان مطالعه: 20 دقیقه ۳.۷ (۳) معماری Data Lakehouse که از سمت Databricks معرفی شد، نمونهای بهروزشده از دو نسل Data Architecture است. امروزه همه انبارهای داده ابری بزرگ، از خواندن فرمت Hudi، Iceberge یا Delta Lake به طور مستقیم در ذخیره سازی اشیا پشتیبانی میکنند. ابزار BigQuery هم یک موتور جستوجوی اختصاصی برای این کار ساخته و ارائه داده است. Apache XTable (که پیشتر با نام OneTable آن را میشناختیم)، انتزاعات و ابزارهایی را برای ترجمه متادادههای قالب جدول Lakehouse ارائه میدهد. تمام این ابزارها باعث شدند که فرضیه گذشته خود را دوباره بررسی کنم: آیا معماری Data Lakehouse فقط یک اصطلاح بازاریابی بود یا یک نیاز مبرم برای سازمانها؟ ما در مقاله پیشرو، به بررسی جواب این سوال میپردازیم و معماری Lakehouse را موشکافی میکنیم. فهرست محتوایی Toggle چالشهای مدلهای قبلی و راهکار معماری Data Lakehouseقابلیت اطمینانکهنگی دادههاپشتیبانی محدود از آنالیز پیشرفته دادههاهزینه کل مالکیتمزایای Lakehouse برای پوشاندن ضعف Data Warehouse و Data Lakeمدیریت دادهها بهشکل قابل اعتماد در دریاچههای دادهپشتیبانی از یادگیری ماشین و علم دادهعملکرد بهینه پایگاه داده SQLانگیزه ساخت Lakehouse از دیدگاه Databricksمعماری Data Lakehouse چگونه است؟نحوه پیاده سازی معماری Data Lakehouseلایه متاداده در معماری Data Lakehouseعملکرد SQL در Data Lakehouseمفهوم Cachingمفهوم Auxiliary Dataمفهوم Data layoutسخن پایانیسوالات متداول معماری Data Lakehouse ۱. معماری Data Lakehouse چه نیازی را در مقایسه با نسلهای قبلی معماری داده برطرف میکند؟۲. اصلیترین چالشهای معماری دو لایه (جدا بودن Data Lake و Data Warehouse) چیست؟۳. نقش لایه متاداده در معماری Data Lakehouse چیست و چرا مهم است؟۴. Lakehouse چگونه به بهبود عملکرد SQL روی حجم عظیم دادهها کمک میکند؟۵. چرا معماری Data Lakehouse برای کاربردهای یادگیری ماشین و علم داده مناسبتر از انبارداده است؟۶. Databricks معماری Data Lakehouse را بر چه زیرساخت و فرمتهایی پیادهسازی میکند؟ چالشهای مدلهای قبلی و راهکار معماری Data Lakehouse در گذشته، بهطورمعمول سازمانها محاسبات و ذخیرهسازی را برای ایجاد انبارهای داده بهشکل محلی، با هم ترکیب میکردند. هنگامیکه تقاضا برای آنالیز و مقیاس دادهها افزایش یافت، شرکتها مجبوربه صرف هزینه بیشتر برای سختافزارهای قویتر شدند. انبارداده برای اولینبار، با هدف کمک کردن به کاربران سازمانی برای مصورسازی داده ها و دریافت بینشهای تحلیلی معرفی شد. این فرآیندها توسط ادغام دادهها از پایگاههای داده عملیاتی در یک انبار متمرکز ممکن میشد. دادهها با انواع اسکیما نوشته میشوند تا از مصرف هوش تجاری بهشکل بهینه در مدل داده اطمینان حاصل شود. این رویکرد نسل اول پلتفرم تجزیهوتحلیل داده است. علاوهبراین، گنجاندن دادهها در قالبهای جدولی دیگر ممکن نبود؛ چون اینبار فقط با حروف و کلمات روبهرو نبودیم؛ بلکه با دادههای ساختارنیافته یا “Unstructured Data” طرف بودیم که باعث ایجاد مشکلات عظیمی در سیستم انبار داده میشدند؛ چون این سیستمها برای مدیریت دادههای ساختاریافته (Structured Data) طراحی شده بودند. درست همین نقطه از معماری داده بود که پلتفرمهای Data Analysing نسل دوم به کمکمان آمدند. مردم شروع به قرار دادن تمام دادههای خام در دریاچههای داده (معماری Data Lakehouse) و سیستمهای ذخیرهسازی کمهزینه با رابط فایلی کردند که دادهها را در قالبهای باز نگه میداشت. این قالبها از انواع فرمتهای Apache Parquet، CSV و ORC بودند. از سال ۲۰۱۵ به بعد، تکنولوژی جدید ذخیرهسازی ابری اشیا، مانند S3 یا GCS جایگزین HDFS شد. این تکنولوژیهای نوظهور و جذاب، از دوام و دسترسپذیری عالی برخوردار هستند. اگر این ویژگیها را در کنار هزینه بسیار کم آنها قرار دهید، ممکن است جذابتر هم بهنظر برسند. سایر معماریهای پدیدارشده در عصر Cloud در نسل دوم، تا حدودی یکسان هستند. انبار دادههایی مانند Redshift، Snowflake یا BigQuery جزو این یکدستی تلقی میشوند. با وجود تسلط این معماری، همچنان با چالشهای زیر مواجه بودیم: قابلیت اطمینان ادغام دریاچه و انبار داده دشوار و پرهزینه است و به تلاش مهندسی زیادی برای دادههای ETL بین دو سیستم نیاز دارد. کهنگی دادهها دادههای موجود در Data Warehouse، در مقایسه با دادههای معماری Data Lakehouse کهنه هستند. این موضوع یک عقبگرد از سیستمهای نسل اول است؛ جاییکه دادههای عملیاتی جدید بلافاصله برای درخواستهای تحلیلی در دسترس بودند. دوره آنلاین Data Lakehouse مقدماتی؛ از طراحی معماری تا پیادهسازی واقعی پشتیبانی محدود از آنالیز پیشرفته دادهها سیستمهای یادگیری ماشین، مانند TensorFlow یا XGBoost، باید مجموعه دادههای بزرگ را با استفاده از کدهای برنامهنویسی پیچیده پردازش کنند. خواندن این دادهها از ODBC/JDBC ایده خوبی نیست. همچنان که هیچ راهی هم برای دسترسی مستقیم به فرمتهای داخلی انبار داده وجود ندارد. به همین علت، عرضهکنندگان انبار داده، تبدیل آنها به فایل را توصیه میکنند. این پیشنهاد هم پیچیدگی کل سیستم را بیشتر میکند؛ البته که کاربران میتوانند این سیستمها را روی دادههای Data Lake با فرمتهای باز اجرا کنند. هزینه کل مالکیت علاوهبر پرداخت هزینه پایپلاینهای ETL، کاربران باید دو برابر هزینه ذخیرهسازی برای تکرار دادهها در دریاچه داده و انبارداده را در صورتحساب خود پرداخت کنند.براساس این مشاهدات، Databricks یک سوال فنی را مطرح میکند: «آیا میتوان دریاچههای داده را براساس فرمتهای استاندارد داده باز، مانند Parquet و ORC، به سیستمهایی با کارایی بالا تبدیل کرد. سپس بتوان هم عملکرد و هم ویژگیهای مدیریتی انبارهای داده را یکجا داشت. I/O سریع و مستقیم از Load کاری آنالیز پیشرفته را هم انجام داد؟» آنها استدلال میکنند که این پارادایم که به آن Data Lakehouse گفته میشود، میتواند برخی از چالشهای انبار داده را حل کند. Databricks معتقد است که Lakehouse بهدلیل نوآوریهای اخیر که مشکلات اساسی آن را برطرف میکند، توجه بیشتری را به خود جلب خواهد کرد؛ چون از مزایایی که در بخش بعد مطرح میکنیم، برخوردار است. مزایای Lakehouse برای پوشاندن ضعف Data Warehouse و Data Lake معماری Data Lakehouse با برخی مزایا همراه است که در ادامه با هرکدام آشنا خواهید شد. مدیریت دادهها بهشکل قابل اعتماد در دریاچههای داده مانند دریاچههای داده، معماری Data Lakehouse باید قادر به ذخیره دادههای خام و پشتیبانی از فرآیندهای ETL/ELT باشد. در ابتدا، دریاچههای داده یک معنا داشتند: «مجموعهای از فایلها» در قالبهای مختلف. در این حالت، ارائه برخی از ویژگیهای مدیریت کلیدی انبارهای داده، مانند Transaction یا بازگشت به نسخههای قدیمی جدول دشوار بود. بااینحال، سیستمهایی مانند Delta Lake یا Apache Iceberg یک لایه Transaction برای دریاچه داده فراهم میکنند تا به این ویژگیهای مدیریتی دسترسی داشته باشند. در این سناریو، بهطورکلی مراحل ETL کمتری وجود دارد و تحلیلگران داده میتوانند در صورت نیاز، مانند پلتفرمهای تحلیلی نسل اول، جداول دادههای خام را به سرعت جستوجو کنند. پشتیبانی از یادگیری ماشین و علم داده پشتیبانی سیستمهای ML برای خواندن مستقیم از فرمتهای دریاچه داده به آنها امکان دسترسی موثر به دادههای موجود در معماری Data Lakehouse را میدهد. عملکرد بهینه پایگاه داده SQL معماری Data Lakehouse باید عملکرد پیشرفته SQL را در راس مجموعه دادههای عظیم موجود در دریاچه ارائه دهد. Databricks نشان داد که میتوان از تکنیکهای مختلفی برای حفظ دادههای Auxiliary، با هدف دستیابی به عملکرد بالا در کنار بهینهسازی اسکیمای دادهها استفاده کرد. انگیزه ساخت Lakehouse از دیدگاه Databricks در ادامه به دلایلی اشاره میکنیم که باعث شدند Databricks معماری Lakehouse را به برطرف کردن کاستیهای انبار داده گره بزند. کیفیت و قابلیت اطمینان دادهها، مهمترین چالشهای گزارششده توسط کاربران دادههای سازمانی هستند. پیادهسازی Data Pipeline بهشکل کارآمد سخت است و معماریهای داده غالب که دریاچه و انبار را جدا میکنند، پیچیدگی بیشتری به این مشکل میافزایند. امروزه اپلیکیشنهای سازمانی، نیاز بیشتری به دادههای بهروز دارند. درحالیکه معماریهای دو لایه با داشتن یک Scope مجزا برای دادههای ورودی قبل از بارگیری آنها در انبار، با استفاده از فعالیتهای دورهای ETL/ELT، کهنگی دادهها را افزایش میدهند. اکنون حجم زیادی از دادهها، بدون ساختار هستند. انبارهای داده و دریاچهها به یادگیری ماشین و کاربردهای ضعف علم داده خدمت میکنند و در میدانهای بزرگتر و عرصههای پردادهتر، حرفی برای گفتن ندارند. در کنار انگیزههای ساخت معماری Data Lakehouse، دو نارضایتی از سوی مشتریان Data Warehouse و Data Lake وجود دارد که ثابت میکنند از مدل دو لایه ناراضی هستند: همه انبارهای بزرگ داده از جداول خارجی در قالب Parquet و ORC پشتیبانی میکنند و در قالبهای دیگر حضور ندارند. سرمایهگذاری گستردهای در موتورهای SQL وجود دارد که بهشکل مستقیم در برابر دریاچه دادهها کار میکنند؛ مانند Spark SQL یا Presto. معماری Data Lakehouse چگونه است؟ Databricks معماری Data Lakehouse خود را بهعنوان یک سیستم مدیریت داده مبتنیبر ذخیرهسازی کمهزینه تعریف میکند. این سیستم به مدیریت تحلیلی DBMS سنتی و ویژگیهای عملکردی آن مانند ACID Transactions، نسخهسازی، ذخیرهسازی و بهینهسازی کوئری بهبود میبخشد. بنابراین، Lakehouse مزایای هر دو معماری Data Lake و Data Warehouse را ترکیب میکند. نحوه پیاده سازی معماری Data Lakehouse اولین ایدهای که Databricks برای پیادهسازی Lakehouse معرفی کرد، ذخیره دادهها در یک نگهدارنده کمهزینه اشیا بود. برای مثال، ذخیرهسازی Google Cloud که با استفاده از یک فرمت استاندارد فایل مانند Apache Parquet با یک لایه متاداده Transactional در راس خود کار میکند. این فرآیند مشخص میکند که کدام اشیا به کدام متاداده تعلق دارد. لایه متاداده هم به آنها اجازه میدهد تا ویژگیهای مدیریتی مانند ACID Transactions را پیادهسازی کنند و درعینحال، به مزیت کمهزینه ذخیرهسازی اشیا هم دست یابند. برخی از پلتفرمهای مناسب برای اجرای لایه متاداده را میتوان Delta Lake، Apache Iceberg و Apache Hudi نام برد. علاوهبراین، معماری Data Lakehouse میتواند بارهای کاری تجزیهوتحلیل پیشرفته را افزایش داده و با ارائه APIها به DataFrame، به آنها در مدیریت دادهها کمک کند. بسیاری از فریمورکهای فعلی ML مانند TensorFlow و Spark MLlib، میتوانند فرمتهای فایلهای دریاچه دادهای مانند Parquet را بخوانند. تمام اینها بدان معنا است که سادهترین راه برای ادغام معماریهای دیگر با Data Lakehouse، این است که از لایه متاداده کوئری بزنید. در این کوئری زدن، میتوانید متوجه شوید که کدام فایلهای Parquet بخشی از یک جدول هستند و همان اطلاعات را به کتابخانه ML ارسال کنید. لایه متاداده در معماری Data Lakehouse سیستمهای ذخیرهسازی دریاچه دادهها مانند S3 یا HDFS، فقط یک ذخیرهسازی سطح پایین شی یا رابط سیستم فایل ارائه میدهند. در طول سالها، نیاز به لایههای مدیریت دادهها ظاهر شد که با روی کار آمدن Apache Hive این نیاز شکل گرفت. این ویژگی در موتور آپاچی، وضعیت تعلق فایلهای داده به بخشی از جدول Hive در یک جدول دیگر را پیگیری میکند. در سال ۲۰۱۶، Databricks شروع به توسعه Delta Lake کرد. Delta Lake اطلاعات مربوطبه اشیا را بررسی میکند. یعنی نشان میدهد که هر شی متعلقبه کدام جدول در ذخیرهسازی آبجکت است و آن را بهعنوان یک گزارش Transaction در فرمت Parquet ذخیره میکند. Apache Iceberg که برای اولین بار در نتفلیکس بهکار گرفته شد، از طراحی مشابهی استفاده میکند. Apache Hudi که در اوبر استفاده شد، سیستم دیگری در این زمینه است که بر جریان ورود به دریاچههای داده متمرکز شده است. در این زمینه باید به یک نکته مهم توجه کنیم: معماری Data Lakehouse برای سازمانهایی که پیشتر از یک دریاچه داده استفاده میکردند، دارند، آسان است. بهعنوان مثال، Delta Lake میتواند فهرستی از فایلهای Parquet موجود را در جدول Delta Lake سازماندهی کند. این معماری بدون اینکه دادهها را جابهجا کند، با افزودن یک گزارش Transaction روی همه فایلهای موجود این کار را انجام میدهد. علاوهبراین، لایههای متاداده میتوانند به پیادهسازی محدودیتهای کیفیت داده کمک کنند. برای مثال، APIهای محدودیتکننده Delta Lake به کاربران اجازه میدهند تا محدودیتهایی را روی دادههای جدید اعمال کنند. بنابراین کاربران قادر به استخراج فهرستی از مقادیر معتبر برای یک ستون خاص هستند. در نهایت، لایههای متاداده به پیادهسازی ویژگیهای حاکمیتی مانند کنترل دسترسی کمک میکنند؛ یعنی میتوانند دسترسی کلاینت را به جداول موجود، قبل از اعطای مجوز خواندن دادههای خام جدول بررسی کنند. عملکرد SQL در Data Lakehouse اگرچه یک لایه متاداده قابلیتهای مدیریتی خوبی را ارائه میدهد، اما برای دستیابی به قابلیت انبار به موارد بیشتری نیاز است. Databricks چند تکنیک را برای بهینهسازی عملکرد SQL در Data Lakehouse پیشنهاد میکند. این تکنیکها مستقل از فرمت انتخابی داده عمل میکنند و به شرح زیر هستند: مفهوم Caching ذخیرهسازی هنگام استفاده از لایه متاداده بهکار میرود و به معماری Data Lakehouse اجازه ذخیره فایلها را میدهد. این ذخیرهسازی، مسئول انتقال اشیا ابری به دستگاههای سریع مانند SSD و RAM است. مفهوم Auxiliary Data Lakehouse میتواند سایر دادههای کمکی برای فایل را با هدف بهینهسازی کوئریها نگهداری کند. در Delta Lake و Delta Engine، Databricks اطلاعات ستون Min-Max را برای هر فایل داده نگهداری میکند. سپس آن را در همان فایل گزارش Parquet Transaction ذخیره میکند. این شیوه موتور SQL را قادر به صرفنظر کردن از دادههای غیرضروری در مرحله اسکن میسازد. مفهوم Data layout معماری Data Lakehouse میتواند بسیاری از تصمیمات Layout داده را بهینه کند. اولین مورد، ترتیب رکوردها است که در آن آیتمهای هر جدول در کنار هم قرار میگیرند. این کار خواندن آنها را بهشکل یکجا، برای موتور SQL آسانتر میکند. این بهینهسازیها برای الگوهای معمولی دسترسی به دادهها در سیستمهای تحلیلی بهخوبی کار میکنند؛ چون کوئریهای معمولی روی یک زیرمجموعه “Hot” از دادهها، روی تجزیهوتحلیل تمرکز میکنند. بنابراین از بهینهسازی Cache هم بهرهمند میشود. ضریب عملکرد حیاتی برای دادههای “Cold” در یک Cloud Storage، مقدار اسکنشده در کوئری است. ترکیب بهینهسازیهای Data layout و ساختارهای Auxiliary Data، به سیستم Lakehouse اجازه میدهد تا حجم بار اضافی عملیات ورودی و خروجی را بهطور موثری کاهش دهد. سخن پایانی معماری Data Lakehouse در ابتدا برای پوشاندن نقطه ضعف معماری دو لایه معرفی شد: حفظ دو سیستم جداگانه برای ذخیرهسازی (Data Lake) و تجزیهوتحلیل (Data Warehouse). این معماری با آوردن قدرت تحلیل مستقیم به دریاچههای داده، عملکرد کوئرینویسی و اجرای آنالیز را بهشکل مستقیم روی دادههای خام ممکن کرد. بهلطف نوآوری در سالهای اخیر، فرمتهای جدول باز مانند Hudi، Iceberge یا Delta Lake، بهنظر میرسد که Lakeshouse هم میتواند معماری کاربردی باشد. شما چه فکری درباره این معماری نوین میکنید؟ آیا تابهحال تجربه استفاده از آن را داشتهاید؟ ما مشتاق خواندن دیدگاه و تجربه شما در بخش نظرات همین مقاله هستیم. نیک آموز در بخش نظرات، مشتاق خواندن دیدگاه و تجربه شما است؛ پس همین حالا آن را با ما در میان بگذارید. سوالات متداول معماری Data Lakehouse ۱. معماری Data Lakehouse چه نیازی را در مقایسه با نسلهای قبلی معماری داده برطرف میکند؟ معماری Data Lakehouse تلاش میکند همزمان مزایای Data Lake و Data Warehouse را ارائه دهد؛ یعنی با تکیه بر فرمتهای باز و ذخیرهسازی ارزان، هم کارایی و قابلیتهای مدیریتی انبار داده (مانند ACID، نسخهسازی و بهینهسازی کوئری) را فراهم میکند و هم امکان آنالیز مستقیم روی دادههای خام در دریاچه داده را میدهد. ۲. اصلیترین چالشهای معماری دو لایه (جدا بودن Data Lake و Data Warehouse) چیست؟ مهمترین چالشها شامل دشوار و پرهزینه بودن ادغام دریاچه و انبار داده (نیاز به ETL سنگین)، کهنگی دادهها در انبار نسبتبه دادههای دریاچه، هزینه بالای تکرار داده در دو سیستم و پیچیدگی بیشتر Data Pipeline است. ۳. نقش لایه متاداده در معماری Data Lakehouse چیست و چرا مهم است؟ لایه متاداده مشخص میکند هر فایل (مثلاً Parquet) متعلق به کدام جدول است و با نگهداری گزارش Transaction، امکان پیادهسازی ویژگیهایی مثل ACID Transactions، نسخهسازی جداول، اعمال محدودیتهای کیفیت داده و کنترل دسترسی را فراهم میکند، بدون اینکه نیاز به جابهجایی دادههای موجود باشد. ۴. Lakehouse چگونه به بهبود عملکرد SQL روی حجم عظیم دادهها کمک میکند؟ برای بهبود عملکرد SQL، معماری Data Lakehouse از تکنیکهایی مانند Caching (انتقال دادههای پرمصرف به SSD و RAM)، ذخیره Auxiliary Data مثل مقادیر Min-Max ستونها برای کاهش اسکنهای غیرضروری، و بهینهسازی Data layout (نحوه چیدن رکوردها و تقسیمبندی دادههای “Hot” و “Cold”) استفاده میکند. ۵. چرا معماری Data Lakehouse برای کاربردهای یادگیری ماشین و علم داده مناسبتر از انبارداده است؟ زیرا سیستمهای ML میتوانند مستقیماً فرمتهای باز دریاچه داده مثل Parquet را بخوانند و از طریق APIهایی مانند DataFrame به دادهها دسترسی داشته باشند؛ درحالیکه در انبار داده سنتی، دسترسی مستقیم به فرمتهای داخلی ممکن نیست و معمولاً نیاز به تبدیل دادهها به فایل و افزایش پیچیدگی است. ۶. Databricks معماری Data Lakehouse را بر چه زیرساخت و فرمتهایی پیادهسازی میکند؟ Databricks پیشنهاد میکند دادهها روی ذخیرهسازی کمهزینه اشیا (مثل Google Cloud Storage یا S3) و با یک فرمت استاندارد فایل مانند Apache Parquet ذخیره شوند و در بالای آن، یک لایه متاداده Transactional (با استفاده از ابزارهایی مثل Delta Lake، Apache Iceberg یا Apache Hudi) قرار گیرد تا ویژگیهای مدیریتی و تحلیلی موردنیاز پیادهسازی شود. 💡 مطالعههای تکمیلی برای درک بهتر معماری Data Lakehouse تکامل معماریهای داده از Data Warehouse تا Data Lake و Data Lakehouse دریاچه داده (Data Lake) چیست؟ ۷ مفهوم کلیدی و تفاوت آن با انبار داده ETL چیست؟ چه رتبه ای میدهید؟ میانگین ۳.۷ / ۵. از مجموع ۳ اولین نفر باش معرفی نویسنده مقالات 35 مقاله توسط این نویسنده نگین فاتحی از اسفند 99 مشغول گشتوگذار توی دنیای کلمات هستم؛ با این هدف که خوب بنویسم و این چشمانداز که کمکهای موثری کنم. حالا سه ساله که توی زمینههای گوناگون بازاریابی آنلاین مطالعه میکنم و یکی از حوزههای موردعلاقم، رفتارشناسی مخاطبان این فضا هست. دستاوردهای این مطالعه شده نوشتن محتوایی که امیدوارم شما بخونی، لُبکلام رو متوجه بشی، لذت ببری و با دست پر صفحه رو ترک کنی؛ شایدم بقیه نوشتههام رو بخونی :) معرفی محصول حسن احمدخانی دوره آنلاین Data Lakehouse مقدماتی طلایی55,750,000 تومان39,025,000 توماننقرهای15,750,000 تومان11,025,000 تومان مقالات مرتبط ۰۱ اسفند مهندسی داده تکامل معماریهای داده از Data Warehouse تا Data Lake و Data Lakehouse فرید طاهری ۲۴ شهریور مهندسی داده ردیس چیست؟ راهنمای کامل Redis و معرفی ۱۰ نوع Data Type در آن نگین فاتحی ۱۸ شهریور مهندسی داده ۵ مرحله ساده برای تحلیل داده با ChatGPT و پایتون نگین فاتحی ۱۰ شهریور مهندسی داده NoSQL چیست؟ معرفی ۴ نوع پایگاه داده NoSQL تیم فنی نیک آموز دیدگاه کاربران لغو پاسخ دیدگاه نام و نام خانوادگی ایمیل ذخیره نام، ایمیل و وبسایت من در مرورگر برای زمانی که دوباره دیدگاهی مینویسم. موبایل برای اطلاع از پاسخ لطفاً مرا با خبر کن ثبت دیدگاه Δ