متن خبر

نحوه مدیریت موثر شناسه های منحصر به فرد در مقیاس: از GUID ها تا شناسه های برف ریزه و سایر راه حل های مدرن

نحوه مدیریت موثر شناسه های منحصر به فرد در مقیاس: از GUID ها تا شناسه های برف ریزه و سایر راه حل های مدرن

شناسهٔ خبر: 704781 -




شناسه های منحصر به فرد چیست؟ 🪪

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

UID ها برای حفظ داده ها، امکان جستجو و بازیابی کارآمد و پشتیبانی از عملیات در مقیاس بزرگ در سیستم های توزیع شده بسیار مهم هستند. با افزایش حجم داده ها و پیچیدگی های سیستم، نیاز به راه حل های مقیاس پذیر UID اهمیت فزاینده ای پیدا می کند.

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

فهرست مطالب:

مقدمه ای بر شناسه های منحصر به فرد 🪪

زمینه تاریخی شناسه ها

مدیریت دولتی شناسه های منحصر به فرد

ساختار شماره های تامین اجتماعی

مقیاس پذیری در سیستم های دولتی

شرکت های فناوری و مقیاس آنها

متا (فیس بوک)

X (تویتر)

تلگرام

نقش شناسه های افزایش خودکار و مسائل مقیاس پذیری آنها

اعداد دنباله ای و مزایای آنها نسبت به شناسه های افزایش خودکار

UUID ها: نمای کلی و استفاده

چه چیزی در مورد UUID عالی است؟

UUID نسخه 1

UUID نسخه 4

UUID نسخه 5

UUID نسخه 7

UUID نسخه 2، 3، و 6

شناسه دانه برف

"مشکل" توسط توییتر بیان شده است:

یافتن مهر زمانی توییت

مقایسه سایر راه حل های شناسایی منحصر به فرد

زمینه تاریخی شناسه ها

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

در جوامع اولیه بشری، افراد اغلب با یک نام واحد شناسایی می شدند. این معمولاً در جوامع کوچکی که همه شخصاً یکدیگر را می شناختند کافی بود. اما با افزایش جمعیت، لازم بود بین افرادی که نام کوچک مشترک داشتند، تمایز قائل شد. این منجر به اتخاذ نام خانوادگی شد.

به عنوان مثال، در ارمنستان 🇦🇲 از نام خانوادگی برای شناسایی افراد بر اساس خانواده یا اصل و نسب استفاده می شود. فردی به نام گور را مثال بزنید. در یک گروه کوچک تا 50 نفر، فرض کنید، شناسایی گور به تنهایی با نام کوچک او آسان است.

اما از آنجایی که گروه به یک جامعه بزرگتر مثلاً 500 نفری رشد می کند، شناسه های اضافی لازم می شود. گور به عنوان گور گریگوریان شناخته می شود که نشان می دهد او به خانواده / اجداد گریگوریان تعلق دارد. این نام خانوادگی هویت واضح تری ارائه می دهد و گور را به اصل و نسب خانواده اش متصل می کند.

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

مدیریت دولتی شناسه های منحصر به فرد

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

چندین کشور پیشگام استفاده از شماره های شناسایی منحصر به فرد برای رفع این نیاز بودند:

آلمان 🇩🇪: در قرن نوزدهم، آلمان سیستمی را برای ردیابی افراد برای اهداف رفاه اجتماعی و سربازی اجباری اجرا کرد.

سوئد 🇸🇪: سوئد در دهه 1940 شروع به صدور شماره های شناسایی شخصی (Personnummer) کرد و برای هر شهروند یک شناسه منحصر به فرد برای استفاده در فرآیندهای مختلف اداری ارائه کرد.

فرانسه 🇫🇷: فرانسه شماره شناسایی ملی (Numéro de Sécurité Sociale) را در اواسط قرن بیستم برای ساده‌سازی مدیریت تامین اجتماعی و سایر خدمات دولتی معرفی کرد.

ایالات متحده 🇺🇸: ایالات متحده آمریکا شماره های تامین اجتماعی (SSNs) را در سال 1936 به عنوان بخشی از قانون تامین اجتماعی معرفی کرد. این رویکرد برای شناسایی منحصر به فرد از آن زمان در سراسر جهان اتخاذ شده است، به طوری که کشورها شماره شناسایی ملی را برای شهروندان خود صادر می کنند.

تصویر-49

(کپشن^) صفحه اطلاعات، پاسپورت ادوین جیمز تارپ، 27 مارس 1936، مجموعه رابرت و ایوا تارپ .

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

ساختار شماره های تامین اجتماعی

شماره تامین اجتماعی (SSN) در ایالات متحده یک شماره نه رقمی است که به عنوان "AAA-GG-SSSS" قالب بندی شده است. هر بخش از SSN از لحاظ تاریخی دارای اطلاعات خاصی است:

    شماره منطقه (AAA) : در اصل، سه رقم اول، که به عنوان شماره منطقه شناخته می شود، نشان دهنده منطقه جغرافیایی است که SSN در آن صادر شده است. این واگذاری منطقه ای به اطمینان از توزیع سیستماتیک اعداد در سراسر کشور کمک کرد.

    شماره گروه (GG) : دو رقم میانی که شماره گروه نامیده می شود، برای سازماندهی اعداد در یک منطقه معین استفاده می شود. شماره های گروه از 01 تا 99 متغیر بود و به ترتیب خاصی برای جلوگیری از تکرار شماره در همان منطقه صادر شد.

    شماره سریال (SSSS) : چهار رقم آخر شماره سریال است که به طور متوالی هر فرد را در یک گروه مشخص می کند. این بخش از SSN تضمین می کند که حتی اگر منطقه و شماره گروه یکسان باشند، SSN کلی منحصر به فرد باقی می ماند.

اداره تامین اجتماعی (SSA) اقدامات متعددی را برای اطمینان از اینکه هر SSN برای کل جمعیت ایالات متحده ( 341.9 میلیون نفر) منحصر به فرد است، اجرا کرده است.

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

به عنوان مثال، ایالات متحده 🇺🇸 اداره تامین اجتماعی (SSA) شماره های تامین اجتماعی (SSN) را برای بیش از 330 میلیون نفر مدیریت می کند. به طور مشابه، دولت 🇮🇳 هند شماره Aadhaar، یک شناسه منحصر به فرد 12 رقمی، را برای بیش از 1.3 میلیارد شهروند صادر کرده است. این شناسه ها برای دسترسی به خدمات دولتی، مزایا و سایر فرآیندهای رسمی بسیار مهم هستند.

تصویر-52

(Caption^) Aadhaar بزرگترین سیستم شناسه بیومتریک جهان است که به عنوان "پیچیده ترین برنامه ID در جهان" توصیف شده است.

مقیاس پذیری در سیستم های دولتی

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

شرکت های فناوری، به ویژه غول های رسانه های اجتماعی، در مقیاسی کاملاً متفاوت عمل می کنند. این شرکت ها میلیاردها کاربر را مدیریت می کنند و روزانه مقادیر زیادی داده تولید می کنند. به عنوان مثال، متا (فیسبوک سابق) بیش از 3 میلیارد کاربر فعال ماهانه در سراسر سیستم عامل های خود از جمله فیس بوک، اینستاگرام و واتس اپ دارد.

شرکت های فناوری و مقیاس آنها

بیایید چند مثال بزنیم:

متا (فیس بوک)

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

    پست ها و تعاملات : فیس بوک به تنهایی روزانه تقریباً 350 میلیون پست جدید می بیند. هر یک از این پست‌ها، همراه با نظرات، لایک‌ها و اشتراک‌گذاری‌ها به یک شناسه منحصربه‌فرد برای مدیریت مؤثر تعاملات نیاز دارند.

    پیام‌ها : کاربران واتس‌اپ روزانه حدود 100 میلیارد پیام ارسال می‌کنند که هر کدام به یک شناسه منحصربه‌فرد نیاز دارند تا مطمئن شوند پیام‌ها به درستی مسیریابی و ذخیره می‌شوند.

    ردیف های داده منحصر به فرد : با ترکیبی از نمایه های کاربر، پست ها، نظرات، لایک ها و پیام ها، Meta احتمالاً بیش از 10 تریلیون ردیف داده منحصر به فرد را مدیریت می کند. (اگر جمعیت جهان تقریباً 8 میلیارد نفر باشد، 10 تریلیون نفر حدود 1250 برابر جمعیت فعلی جهان خواهد بود).

X (تویتر)

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

تلگرام

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

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

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

نقش شناسه های افزایش خودکار و مسائل مقیاس پذیری آنها

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

جدولی برای ذخیره اطلاعات کاربر در پایگاه داده رابطه ای در نظر بگیرید. هنگامی که کاربر اول اضافه می شود، ممکن است یک شناسه 1 به آنها اختصاص داده شود. کاربر دوم یک شناسه 2 و غیره دریافت می کند.

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

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

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

    Single Point of Failure : تکیه بر یک مرجع مرکزی برای تولید شناسه‌های افزایش خودکار، یک نقطه شکست را معرفی می‌کند. اگر سرور مسئول تخصیص شناسه ها از کار بیفتد، ممکن است کل سیستم نتواند رکوردهای جدیدی اضافه کند.

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

 CREATE TABLE Admins ( Id SERIAL PRIMARY KEY , Name VARCHAR ( 255 ) NOT NULL ); CREATE TABLE Users ( Id SERIAL PRIMARY KEY , Name VARCHAR ( 255 ) NOT NULL ); INSERT INTO Admins ( Name ) VALUES ( 'GorGrigoryan' ), ( 'GorGrigoryan2' ); SELECT * FROM Admins; -- +----+---------------+ -- | Id | Name | -- +----+---------------+ -- | 1 | GorGrigoryan | -- +----+---------------+ -- | 2 | GorGrigoryan2 | -- +----+---------------+

اعداد دنباله ای و مزایای آنها نسبت به شناسه های افزایش خودکار

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

نحوه کار اعداد دنباله ای:

    مولدهای توالی متمرکز : یک سرویس مرکزی یا جدول پایگاه داده اعداد دنباله را تولید و مدیریت می کند. هر درخواست برای یک شناسه جدید شمارنده را افزایش می دهد و مقدار بعدی را برمی گرداند.

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

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

گره 1 : اعداد دنباله ای اختصاص داده شده 1,000,000 تا 1,999,999

گره 2 : اعداد دنباله ای اختصاص داده شده 2,000,000 تا 2,999,999

گره 3 : اعداد دنباله ای اختصاص داده شده از 3000000 تا 3999999

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

 CREATE SEQUENCE UserIdentifier INCREMENT 1 START 1 ; CREATE TABLE Admins ( Id INT PRIMARY KEY , Name VARCHAR ( 255 ) NOT NULL ); CREATE TABLE Users ( Id INT PRIMARY KEY , Name VARCHAR ( 255 ) NOT NULL ); INSERT INTO Admins ( Id , Name ) VALUES ( nextval ( 'UserIdentifier' ), 'GorGrigoryan' ), ( nextval ( 'UserIdentifier' ), 'GorGrigoryan2' ); INSERT INTO Users ( Id , Name ) VALUES ( nextval ( 'UserIdentifier' ), 'UserGorGrigoryan' ), ( nextval ( 'UserIdentifier' ), 'UserGorGrigoryan2' ); SELECT * FROM Admins; -- +----+---------------+ -- | Id | Name | -- +----+---------------+ -- | 1 | GorGrigoryan | -- +----+---------------+ -- | 2 | GorGrigoryan2 | -- +----+---------------+ SELECT * FROM Users ; -- +----+---------------+ -- | Id | Name | -- +----+---------------+ -- | 3 | GorGrigoryan | -- +----+---------------+ -- | 4 | GorGrigoryan2 | -- +----+---------------+

مزیت دیگر استفاده از اعداد ترتیبی این است که می توانید شناسه موجودیت را قبل از درج در پایگاه داده بدست آورید.

در مورد شناسه‌های افزایش خودکار، این تخصیص معمولاً پس از درج توسط پایگاه داده انجام می‌شود، که می‌تواند انعطاف‌پذیری را محدود کند. با اعداد دنباله ای، می توانید به راحتی شناسه را در سمت برنامه ایجاد کنید، که می تواند هنگام استفاده از برخی ORM ها به عنوان مثال EF Core ORM در C# کار آسانی باشد.

شماره های دنباله ای را در سرور SQL در اینجا تحلیل کنید.

UUID ها: نمای کلی و استفاده

GUID ها (شناسه های منحصر به فرد جهانی)، همچنین به عنوان UUID (شناسه های منحصر به فرد جهانی) شناخته می شوند، شناسه های 128 بیتی هستند که برای منحصر به فرد بودن در سطح جهانی طراحی شده اند. یک UUID معمولی در یک رشته هگزا دسیمال 32 کاراکتری نمایش داده می شود که به پنج گروه تقسیم شده توسط خط فاصله تقسیم می شود. به عنوان مثال: 126e3456-e89b-12d3-a456-426614174000 .

چه چیزی در مورد UUID عالی است؟

یکی از ویژگی های برجسته GUID ها ظرفیت عظیم آنها برای منحصر به فرد بودن است. با ساختار 128 بیتی، تعداد کل GUID های ممکن بسیار زیاد است: به طور خاص، 340,282,366,920,938,463,463,374,607,431,770,000,000 GUID موجود است. برای در نظر گرفتن آن، بیایید آن را با چیزی ملموس مقایسه کنیم.

تصویر-94

آیا می دانستید که دانشمندان تلاش کرده اند تعداد دانه های شن روی زمین را محاسبه کنند؟ دیوید بلاتنر، نویسنده علم، در کتاب طیف‌ها ، اشاره می‌کند که گروهی از محققان دانشگاه هاوایی تلاش کردند این عدد را تخمین بزنند. آنها تعیین کردند که زمین تقریباً (و ما به طور تقریبی صحبت می کنیم) 7.5 x 10<sup>18</sup> دانه شن یا هفت کوئینتیلیون و پانصد کوادریلیون دانه دارد. برای اطلاعات بیشتر، مطالعه مقاله با عنوان: " تعداد دانه های شن روی زمین یا ستارگان در آسمان کدام بیشتر است؟ "

حال برای مقایسه این اعداد:

 | GUIDs available | 340,282,366,920,938,463,463,374,607,431,770,000,000 | Sand grains | 75,000,000,000,000,000,000

اگر تصمیم گرفتید برنامه ای برای ردیابی هر دانه شن روی زمین ایجاد کنید و به هر یک از آنها یک شناسه منحصر به فرد اختصاص دهید، به راحتی می توانید با استفاده از GUID این کار را انجام دهید. بخش سرگرم کننده این است که شما در واقع می توانید این روند را 4,537,098,225,612,512,846 بار تکرار کنید بدون اینکه GUID های منحصر به فرد تمام شود! 🤯

UUID نسخه 1

UUID نسخه 1 شناسه های منحصر به فردی را بر اساس مهر زمانی، ترتیب ساعت و شناسه گره (معمولاً آدرس MAC دستگاه تولید کننده UUID) تولید می کند.

طبق RFC 4122 ، مهر زمانی تعداد نانوثانیه‌هایی است که از 15 اکتبر 1582 در نیمه‌شب UTC انجام شده است. اکثر کامپیوترها ساعتی ندارند که به اندازه کافی سریع تیک تیک بزند تا زمان را بر حسب نانوثانیه اندازه گیری کند. در عوض، اغلب از یک عدد تصادفی برای پر کردن ارقام مهر زمانی فراتر از دقت اندازه‌گیری رایانه استفاده می‌شود.

هنگامی که چندین UUID نسخه 1 در یک فراخوانی API تولید می‌شوند، ممکن است بخش تصادفی به جای ایجاد مجدد برای هر UUID افزایش یابد. این منحصر به فرد بودن را تضمین می کند و سریعتر تولید می شود.

UUID v1 همچنین دارای مک آدرس متصل به آن است. با گنجاندن یک آدرس MAC در UUID، می توانید مطمئن باشید که دو کامپیوتر مختلف هرگز یک UUID یکسان را تولید نمی کنند. از آنجا که آدرس‌های MAC در سطح جهانی منحصر به فرد هستند، اما توجه داشته باشید که UUID‌های نسخه 1 را می‌توان به رایانه‌ای که آنها را تولید کرده است ردیابی کرد.

این تضمین می کند که UUID هم در زمان و هم در مکان منحصر به فرد است. زمانی مناسب است که زمان تولید و منحصر به فرد بودن ماشین مهم باشد. اغلب در سیستم‌هایی استفاده می‌شود که مهر زمانی ایجاد مرتبط یا مورد نیاز است.

تصویر-95

(تصویر از اینجا )

UUID نسخه 4

UUID نسخه 4 با استفاده از اعداد تصادفی یا شبه تصادفی شناسه ها را تولید می کند. این روش به دلیل تعداد زیادی از GUID های ممکن، احتمال یکتایی بالایی را تضمین می کند. این رایج ترین نسخه UUID است.

2 نوع اصلی UUID وجود دارد:

نوع 1: Minecraft UUID که UUIDهای Timestamp-first نیز نامیده می شود

نوع 2: "GUID"

تصویر-96

( تصویر از اینجا )

GUID کاملا تصادفی است، تولید آن را ساده می کند و اطمینان می دهد که هر شناسه منحصر به فرد با احتمال بسیار بالا است. شناسه های منحصر به فرد از 128 بیت تشکیل شده اند. آنها به صورت 32 کاراکتر با استفاده از اعداد (0-9) و حروف (AF) نوشته می شوند. نویسه‌ها در قالب خاصی گروه‌بندی می‌شوند: 8-4-4-4-12، با خط تیره از هم جدا شده‌اند، مانند این: {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX} .

نکته مهم در مورد GUID ها این است که برای ایجاد آنها به یک سیستم مرکزی نیاز ندارید. هر کسی می تواند با استفاده از یک الگوریتم یک GUID تولید کند و همچنان در سیستم ها و برنامه های مختلف منحصر به فرد خواهد بود. آنها طوری طراحی شده اند که تقریباً در هر جایی که به یک شناسه منحصر به فرد نیاز است استفاده شود. در اینجا چند نمونه استفاده آورده شده است:

Windows: از GUID ها برای تولید کلیدهای محصول منحصر به فرد استفاده می کند

Microsoft SQL Server: از GUID ها به عنوان کلیدهای اصلی برای اطمینان از منحصر به فرد بودن جهانی در پایگاه های داده توزیع شده استفاده می کند.

AWS: از GUID ها برای شناسایی منحصربفرد منابع در زیرساخت ابری خود، مانند نمونه های EC2 و اشیاء S3 استفاده می کند.

eBay: از GUID ها برای شناسایی فهرست ها، تراکنش ها و کاربران استفاده می کند

UUID نسخه 5

UUID نسخه 5 شناسه های منحصر به فردی را بر اساس شناسه فضای نام و یک نام تولید می کند. فضای نام و نام با استفاده از SHA-1 برای تولید UUID ترکیب و هش می شوند. این تضمین می کند که فضای نام و ترکیب نام یکسان همیشه UUID یکسان را تولید می کند. در UUID، فضای نام باید یک UUID باشد و نام می تواند هر چیزی باشد.

UUID V5 برای تولید شناسه های منحصر به فرد ثابت برای داده های ورودی یکسان در سیستم ها و زمینه های مختلف مفید است. فرض کنید قصد داریم یک شناسه کاربری بر اساس نام کاربری آنها تولید کنیم. در اینجا نحوه رسیدن به این هدف در C# آمده است:

تصویر-97

در اینجا UUID نسخه 5 چندین مشکل مهم را حل می کند، به ویژه زمانی که به یک شناسه ثابت و منحصر به فرد بر اساس یک ورودی داده شده نیاز دارید.

به عنوان مثال، سناریویی را در نظر بگیرید که در آن به یک شناسه کاربری برای برقراری تماس API (یا هر چیز دیگری) نیاز دارید، اما در کد خود، فقط نام کاربری در دسترس است. اگر از UUID نسخه 4 (GUID) استفاده می کردیم، چگونه مشکل حل می شد؟ به احتمال زیاد، چیزی شبیه به این کار می کند:

 /* When using GUID (UUID v4) */ var userName = "bob" ; // Lets assume we only have username // API call or DB call to get the user id using name var userId = await userService.GetUserIdAsync(userName); await userService.ChangeUserNameAsync(userId, "bob-2" );

با استفاده از UUID نسخه 5 با یک فضای نام مشترک در تمام پروژه های خود، می توانید به راحتی شناسه کاربری را از نام کاربری بدون برقراری تماس API اضافی ایجاد کنید. پس همان کد به شکل زیر خواهد بود:

 /* When using UUID v5 */ // From some shared code var userNamespace = SharedConstants.UserNamespace; var userName = "bob" ; // Lets assume we only have username //Generate the user id in place, without additional call var userId = Uuid.NewNameBased(userNamespace, userName); await userService.ChangeUserNameAsync(userId, "bob-2" );

این رویکرد نیاز به فراخوانی اضافی API را از بین می برد. در یک سیستم توزیع‌شده، برقراری یک تماس API برای دریافت شناسه کاربری هر زمان که به آن نیاز دارید، می‌تواند ناکارآمد و کند باشد. با UUID نسخه 5، می توانید به صورت محلی شناسه کاربری را از نام کاربری (یا هر ورودی دیگر) ایجاد کنید، که نیاز به درخواست های شبکه را کاهش داده و کارایی برنامه خود را به میزان قابل توجهی بهبود می بخشد.

چه نوع مشکلی را با UUID v5 حل کرده ایم؟ فرض کنید برای برقراری تماس API به شناسه کاربری نیاز دارید، اما در کد خود، فقط یک نام کاربری دارید، اگر فضای نام در تمام پروژه‌هایتان به اشتراک گذاشته شده باشد. سپس می توانید به راحتی شناسه کاربری را با استفاده از یک نام کاربری، بدون تماس API دریافت کنید. به این دلیل که UUID v5 همیشه همان UUID را برای ورودی یکسان بازتولید می کند.

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

UUID نسخه 7

GUID نسخه 7 یک نسخه جدید پیشنهادی است که هدف آن ترکیب نقاط قوت GUID مبتنی بر مهر زمانی و مبتنی بر تصادفی است.

مشکلات UUID v4 (GUID)

UUID نسخه 4 مقادیر غیر مرتبه زمانی تولید می کند، به این معنی که شناسه های ایجاد شده متوالی نیستند. از آنجایی که این مقادیر به صورت تصادفی تولید می شوند، در یک فهرست پایگاه داده با هم دسته بندی نمی شوند. در عوض، درج‌ها در مکان‌های تصادفی رخ می‌دهند، که می‌تواند بر عملکرد ساختارهای داده شاخص رایج، مانند درختان B و انواع آن‌ها تأثیر منفی بگذارد.

در سناریویی که محصول شما نیاز به دسترسی مکرر به داده های اخیر دارد، شناسه های غیر متوالی چالش مهمی ایجاد می کنند.

با UUID نسخه 4، جدیدترین داده‌ها به‌طور تصادفی در سرتاسر فهرست درج می‌شوند، بدون خوشه‌بندی . در نتیجه، بازیابی جدیدترین داده ها از یک مجموعه داده بزرگ نیاز به پیمایش صفحات فهرست پایگاه داده های متعدد دارد.

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

راه حل با UUID v7

UUID v7 برای ارائه شناسه های منحصر به فرد و قابل مرتب سازی طراحی شده است که هم تولید آنها آسان است و هم برای سیستم های توزیع شده مفید است. از ترکیبی از مهرهای زمانی و داده های تصادفی برای اطمینان از منحصر به فرد بودن و نظم زمانی استفاده می کند.

بخش اول UUID یک مهر زمانی است که یک مؤلفه زمانی ارائه می‌کند و تضمین می‌کند که UUID‌های تولید شده نزدیک به هم در زمان نیز از نظر ارزش به هم نزدیک هستند. بخش باقیمانده با داده های تصادفی پر می شود و منحصر به فرد بودن هر شناسه را تضمین می کند.

تصویر-98

(کپشن) پست Buildkite درباره مهاجرت به UUID v7

UUID نسخه 2، 3، و 6

ممکن است متوجه شده باشید که بحث ما بر روی UUID نسخه‌های 1، 4، 5، و 7 متمرکز است و از نسخه‌های 2، 3 و 6 عبور می‌کند.

UUID نسخه 2 : این نسخه به ندرت در برنامه های مدرن استفاده می شود. این شبیه به نسخه 1 است اما شامل فیلدهای اضافی برای مواردی مانند اطلاعات دامنه (مانند POSIX UID یا GID) است. عمدتاً در سیستم های قدیمی استفاده می شد و اکنون تا حد زیادی منسوخ در نظر گرفته می شود.

UUID نسخه 3 : این نسخه بر اساس یک نام و فضای نام مشابه نسخه 5 است. تفاوت اصلی این است که نسخه 3 از الگوریتم هش MD5 استفاده می کند که نسبت به الگوریتم SHA-1 استفاده شده در نسخه 5 امنیت و کارایی کمتری دارد. نسخه 5 معمولاً ترجیح داده می شود زیرا SHA-1 قوی تر است.

UUID نسخه 6 : نسخه 6 هنوز به عنوان یک استاندارد پیشنهادی در حال پیش نویس است. قرار است یک UUID مرتب شده با زمان با عملکرد بهتر برای سیستم های توزیع شده ارائه دهد، اما از آنجایی که هنوز به طور کامل مورد استفاده قرار نگرفته است، ما روی نسخه 7 تمرکز می کنیم که ویژگی های مشابهی را ارائه می دهد و شتاب بیشتری دارد.

شناسه دانه برف

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

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

Snowflake ID یک عدد صحیح 64 بیتی است که از چندین بخش مجزا تشکیل شده است:

    مهر زمانی (41 بیت): بزرگترین بخش Snowflake ID مهر زمانی است که تعداد میلی ثانیه ها را از یک دوره سفارشی ثبت می کند (اغلب به تاریخی که سیستم برای اولین بار استقرار کرده است) تنظیم می شود. این تضمین می کند که شناسه ها بر اساس زمان مرتب شده اند و به راحتی می توان آنها را بر اساس زمان ایجاد آنها مرتب کرد.

    شناسه مرکز داده (5 بیت): این قسمت از شناسه، مرکز داده ای را که شناسه در آن تولید شده است، شناسایی می کند و به سیستم اجازه می دهد شناسه های منحصر به فرد را در چندین مرکز داده بدون درگیری ایجاد کند.

    شناسه ماشین (5 بیت): مشابه شناسه مرکز داده، شناسه ماشین سرور یا ماشین خاصی را در مرکز داده که شناسه را تولید کرده است، شناسایی می کند. این تضمین می کند که حتی در همان مرکز داده، شناسه ها منحصر به فرد باقی می مانند.

    Sequence Number (12 بیت): شماره دنباله برای تمایز بین چندین شناسه تولید شده در یک میلی ثانیه توسط یک ماشین استفاده می شود. با 12 بیت، تا 4096 شناسه منحصر به فرد را می توان در هر دستگاه در هر میلی ثانیه تولید کرد.

این قالب توسط توییتر (اکنون X) ایجاد شده است و برای شناسه های توییت ها استفاده می شود. اعتقاد عمومی بر این است که هر دانه برفی ساختار منحصر به فردی دارد، پس آنها نام "دانه برف" را گرفتند. این قالب توسط سایر شرکت ها از جمله Discord و Instagram پذیرفته شده است. شبکه اجتماعی Mastodon از نسخه اصلاح شده استفاده می کند.

این قالب برای اولین بار توسط X/Twitter در ژوئن 2010 اعلام شد. به دلیل چالش های پیاده سازی، آنها تا اواخر سال منتظر ماندند تا این به روز رسانی را ارائه کنند .

X از شناسه دانه‌های برف برای پست‌ها، پیام‌های مستقیم، کاربران، فهرست‌ها و همه اشیاء موجود در API استفاده می‌کند.

Discord همچنین از دانه‌های برف استفاده می‌کند که دوره آن‌ها به ثانیه اول سال 2015 می‌رسد.

اینستاگرام از یک نسخه اصلاح شده از فرمت استفاده می کند که دارای 41 بیت برای مهر زمانی و 10 بیت برای شماره دنباله است.

فرمت اصلاح شده Mastodon دارای 48 بیت برای یک مهر زمانی در سطح میلی ثانیه است، زیرا از دوره یونیکس استفاده می کند. 16 بیت باقی مانده برای داده های توالی است.

تصویر-3

"مشکل" توسط توییتر بیان شده است:

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

برخلاف MySQL، کاساندرا هیچ روش داخلی برای تولید شناسه‌های منحصربه‌فرد ندارد – و همچنین نباید داشته باشد، زیرا در مقیاسی که Cassandra جالب می‌شود، ارائه یک راه‌حل یک‌اندازه برای شناسه‌ها دشوار خواهد بود. همین امر در مورد MySQL خرد شده نیز صدق می کند. ما به چیزی نیاز داشتیم که بتواند ده ها هزار شناسه در ثانیه را به روشی بسیار در دسترس تولید کند.

این به طور طبیعی ما را به سمت انتخاب یک رویکرد ناهماهنگ سوق داد. این شناسه‌ها باید تقریباً قابل مرتب‌سازی باشند، به این معنی که اگر توییت‌های A و B تقریباً همزمان پست شوند، باید شناسه‌هایی در نزدیکی یکدیگر داشته باشند، زیرا ما و اکثر مشتریان توییتر توییت‌ها را به این ترتیب مرتب می‌کنیم.

علاوه بر این، این اعداد باید در 64 بیت قرار گیرند. ما قبلاً روند دردناک افزایش تعداد بیت های مورد استفاده برای ذخیره شناسه های توییت را پشت سر گذاشته ایم. زمانی که بیش از 100000 پایگاه کد مختلف درگیر هستید انجام این کار به طرز عجیبی سخت است.

برای اطلاعات بیشتر اینجا را تحلیل کنید

یافتن مهر زمانی توییت

همه ما می دانیم که حذف یک توییت واقعاً امکان پذیر نیست - وقتی توییت منتشر شد، نحوه طراحی توییتر است. با این حال، استفاده توییتر از Snowflake ID پیچ و تاب جالبی به این روایت اضافه می کند. شناسه‌های دانه‌های برف به‌گونه‌ای طراحی شده‌اند که منحصربه‌فرد و با زمان‌بندی باشند، که باعث می‌شود نه تنها شناسه‌ها، بلکه مسیری قابل ردیابی نیز باشند.

در 11 می 2019، درک ویلیس از Politwoops لیستی از شناسه های توییت حذف شده را کشف کرد. با استفاده از ساختار Snowflake، او توانست مهر زمانی را از این شناسه ها استخراج کند و 107 توییت گم شده را کشف کند. این یافته الهام بخش ایجاد TweetedAt است، ابزاری که برای بازیابی دقیق مُهرهای زمانی از شناسه‌های Snowflake و تخمین زمان توییت‌های تولید شده قبل از استفاده از Snowflake طراحی شده است.

تصویر-2

اینجا را تحلیل کنید.

مقایسه سایر راه حل های شناسایی منحصر به فرد

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

شناسه خالق مزایا معایب ویژگی های منحصر به فرد
ULID A. Feerasta -قابلیت طبقه بندی واژگانی

- سازگاری 128 بیتی با UUID
- به راحتی در بسیاری از زبان ها قابل پیاده سازی | - در اکثر پایگاه های داده به صورت بومی پشتیبانی نمی شود
- نیاز به منطق اضافی برای جلوگیری از برخورد | - در صورت اجرای صحیح، یکنواختی را در همان میلی ثانیه ایجاد می کند | LexicalUUID | توییتر | - نظم واژگانی را تضمین می کند
- ایده آل برای نمایه سازی پایگاه داده سفارشی | - نیاز به پیاده سازی سفارشی دارد
- ممکن است به اندازه UUID ها به طور جهانی شناخته یا پشتیبانی نشود - به طور خاص طراحی شده است تا با سیستم هایی که از سفارش دهی سود می برند، مانند پایگاه های داده و صف | به خوبی کار کند | دانه برف | توییتر | - بسیار مقیاس پذیر و توزیع شده است
- به صورت زمان بندی شده
- بدون نیاز به هماهنگی مرکزی | - پیچیده برای پیاده سازی صحیح
- محدود به 4096 شناسه در هر میلی ثانیه در هر گره | - ترکیبی از زمان، مرکز داده، ماشین و اعداد دنباله ای برای اطمینان از منحصر به فرد بودن در سیستم های توزیع شده | | پولک | مرز | - مشابه Snowflake، شناسه های مرتب شده و توزیع شده را ارائه می دهد
- مفید در سیستم های توزیع شده | - می تواند برای مدیریت در گره های مختلف پیچیده باشد
- نیاز به همگام سازی ساعت ثابت | - شناسه‌های K-ordered برای سیستم‌هایی که سفارش‌دهی مبتنی بر زمان حیاتی است مناسب هستند | | ShardingID | اینستاگرام | - اشتراک گذاری در پایگاه های داده توزیع شده را تسهیل می کند
- خطر برخورد بین قطعات را کاهش می دهد | - پیچیدگی پیاده سازی
- نیاز به کنترل دقیق بر تولید ID | - کمک به مقیاس بندی افقی پایگاه های داده با اطمینان از شناسه های منحصر به فرد در بین خرده ها | | KSUID | بخش | - قابل مرتب‌سازی K، که امکان مرتب‌سازی واژگانی را فراهم می‌کند
- مهر زمانی تعبیه شده
- 160 بیت، تضمین منحصر به فرد بودن بیشتر | - اندازه بزرگتر از UUID های استاندارد
- به اندازه UUID های سنتی مورد قبول یا پشتیبانی نیست | - طول بیت بیشتر منحصربه‌فرد بودن و محافظت در آینده را فراهم می‌کند | | پوسته الاستیک | پی پیرسی | - برای استفاده با Elasticsearch طراحی شده است
- زمان سفارش و توزیع | - محدود به موارد استفاده خاص مانند Elasticsearch
- انعطاف پذیری کمتر برای کاربردهای همه منظوره | - به خوبی با Elasticsearch ادغام می شود و پرس و جو و نمایه سازی کارآمد را ارائه می دهد | FlakeID | تی پاولاک | - اجرای ساده
- مرتب و مقیاس پذیر | - ویژگی های کمتر در مقایسه با Snowflake
- بالقوه محدود به محیط های خاص | - تمرکز بر سهولت استفاده و سادگی در عین حفظ مزایای اصلی ترتیب زمانی | | سونی فلیک | سونی | - بهینه شده برای شبکه های کم تاخیر
- به صورت زمان بندی شده
- مقیاس پذیر و توزیع شده | - محدود به محیط هایی با تأخیر شبکه کم
- نیاز به هماهنگ سازی ساعت مداوم | -برای عملکرد در محیط های کم تأخیر طراحی شده است ، و آن را برای سیستم های معامله ای با سرعت بالا مناسب می کند | | ordereduuid | IT Cabrera | - UUID های سفارش داده شده را تضمین می کند
- برای پایگاه داده های سفارش داده شده مفید است | - نیاز به اجرای سفارشی دارد
- ممکن است به اندازه UUIDS به طور گسترده ای شناخته نشود یا پشتیبانی نشود | - ضمن اضافه کردن سفارش بر اساس زمان خلقت ، مزایای UUID های سنتی را فراهم می کند | | Combguid | R. Tallent | - ترکیب زمانی را با تصادفی ترکیب می کند
- سازگار با قالب های استاندارد UUID | - پیچیده تر برای اجرای
- کمتر بصری برای استفاده عمومی | - UUID های سنتی را با اضافه کردن اجزای مبتنی بر زمان برای مرتب سازی بهتر تقویت می کند | | سید | A. Chilton | - تولید شناسه متوالی
- مفید در سیستم هایی که سفارش اهمیت دارد | - انعطاف پذیری محدود
- برای سیستم های توزیع شده مناسب نیست | - تضمین می کند که شناسه ها به روشی کاملاً پی در پی تولید می شوند ، برای محیط های تک سیستم مفید هستند | | pushid | Google | - به ترتیب زمان
- برای بانکهای اطلاعاتی در زمان واقعی طراحی شده است
- کوتاه و منحصر به فرد | - محدود به محیط های خاص مانند Firebase
- فضای آدرس کوچکتر در مقایسه با UUIDS | - بهینه سازی شده برای برنامه های کاربردی در زمان واقعی ، به ویژه در Firebase برای تولید کلید کارآمد و منحصر به فرد | | XID | O. Poitrey | - اندازه جمع و جور (12 بایت)
- تولید آسان
- مقاوم در برابر برخورد | - آنتروپی کمتر از UUID ها
- خارج از موارد استفاده خاص به طور گسترده پشتیبانی نمی شود | -اندازه کوچکتر و اجرای ساده تر ، آن را برای محیط های با کارایی بالا و حافظه مناسب مناسب می کند | | ObjectId | MongoDB | - شامل یک جدول زمانی است ، و آن را به ترتیب زمان بندی می کند
- کارآمد در MongoDB | - مخصوص MongoDB
- در خارج از MongoDB قابل اجرا نیست | - طراحی شده است که یکپارچه با MongoDB کار کند ، و اطمینان حاصل کند که شناسه های سند به ترتیب و منحصر به فرد هستند | | cuid | E. الیوت | - مقاوم در برابر برخورد
- کوتاه و قابل خواندن انسانی
- عالی برای سیستم های توزیع شده | - نه به عنوان UUID ها به طور گسترده ای شناخته شده است
- ممکن است به کتابخانه های اضافی برای اجرای نیاز داشته باشد | - تمرکز بر خوانایی انسان و مقاومت در برابر برخورد ، ایده آل برای سیستمهایی که نیاز به شناسه به راحتی قابل تشخیص دارند |

بسته بندی

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

از راهنماهای سنتی گرفته تا راه حل های مدرن مانند شناسه های برف ، هر سیستم شناسه مزایای مشخصی را متناسب با موارد استفاده خاص ارائه می دهد.

با تکامل فناوری ، درک این سیستم ها و پیاده سازی های آنها برای مقیاس بندی برنامه ها به طور مؤثر اهمیت پیدا می کند. با کاوش در نسخه ها و گزینه های مختلف ، می توانیم تصمیمات آگاهانه ای بگیریم که متناسب با نیازهای ما در مدیریت داده ها در مقیاس باشد.

تصویر جلد: یک پست 2017 که در فیس بوک جشن می گیرد و به 2 میلیارد کاربر می رسد .

خبرکاو

ارسال نظر

دیدگاه‌ها بسته شده‌اند.


تبليغات ايهنا تبليغات ايهنا

تمامی حقوق مادی و معنوی این سایت متعلق به خبرکاو است و استفاده از مطالب با ذکر منبع بلامانع است